OSDN Git Service

anv/cmd_buffer: add a status field to anv_batch
[android-x86/external-mesa.git] / src / intel / vulkan / anv_cmd_buffer.c
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
34 /** \file anv_cmd_buffer.c
35  *
36  * This file contains all of the stuff for emitting commands into a command
37  * buffer.  This includes implementations of most of the vkCmd*
38  * entrypoints.  This file is concerned entirely with state emission and
39  * not with the command buffer data structure itself.  As far as this file
40  * is concerned, most of anv_cmd_buffer is magic.
41  */
42
43 /* TODO: These are taken from GLES.  We should check the Vulkan spec */
44 const struct anv_dynamic_state default_dynamic_state = {
45    .viewport = {
46       .count = 0,
47    },
48    .scissor = {
49       .count = 0,
50    },
51    .line_width = 1.0f,
52    .depth_bias = {
53       .bias = 0.0f,
54       .clamp = 0.0f,
55       .slope = 0.0f,
56    },
57    .blend_constants = { 0.0f, 0.0f, 0.0f, 0.0f },
58    .depth_bounds = {
59       .min = 0.0f,
60       .max = 1.0f,
61    },
62    .stencil_compare_mask = {
63       .front = ~0u,
64       .back = ~0u,
65    },
66    .stencil_write_mask = {
67       .front = ~0u,
68       .back = ~0u,
69    },
70    .stencil_reference = {
71       .front = 0u,
72       .back = 0u,
73    },
74 };
75
76 void
77 anv_dynamic_state_copy(struct anv_dynamic_state *dest,
78                        const struct anv_dynamic_state *src,
79                        uint32_t copy_mask)
80 {
81    if (copy_mask & (1 << VK_DYNAMIC_STATE_VIEWPORT)) {
82       dest->viewport.count = src->viewport.count;
83       typed_memcpy(dest->viewport.viewports, src->viewport.viewports,
84                    src->viewport.count);
85    }
86
87    if (copy_mask & (1 << VK_DYNAMIC_STATE_SCISSOR)) {
88       dest->scissor.count = src->scissor.count;
89       typed_memcpy(dest->scissor.scissors, src->scissor.scissors,
90                    src->scissor.count);
91    }
92
93    if (copy_mask & (1 << VK_DYNAMIC_STATE_LINE_WIDTH))
94       dest->line_width = src->line_width;
95
96    if (copy_mask & (1 << VK_DYNAMIC_STATE_DEPTH_BIAS))
97       dest->depth_bias = src->depth_bias;
98
99    if (copy_mask & (1 << VK_DYNAMIC_STATE_BLEND_CONSTANTS))
100       typed_memcpy(dest->blend_constants, src->blend_constants, 4);
101
102    if (copy_mask & (1 << VK_DYNAMIC_STATE_DEPTH_BOUNDS))
103       dest->depth_bounds = src->depth_bounds;
104
105    if (copy_mask & (1 << VK_DYNAMIC_STATE_STENCIL_COMPARE_MASK))
106       dest->stencil_compare_mask = src->stencil_compare_mask;
107
108    if (copy_mask & (1 << VK_DYNAMIC_STATE_STENCIL_WRITE_MASK))
109       dest->stencil_write_mask = src->stencil_write_mask;
110
111    if (copy_mask & (1 << VK_DYNAMIC_STATE_STENCIL_REFERENCE))
112       dest->stencil_reference = src->stencil_reference;
113 }
114
115 static void
116 anv_cmd_state_reset(struct anv_cmd_buffer *cmd_buffer)
117 {
118    struct anv_cmd_state *state = &cmd_buffer->state;
119
120    cmd_buffer->batch.status = VK_SUCCESS;
121
122    memset(&state->descriptors, 0, sizeof(state->descriptors));
123    memset(&state->push_constants, 0, sizeof(state->push_constants));
124    memset(state->binding_tables, 0, sizeof(state->binding_tables));
125    memset(state->samplers, 0, sizeof(state->samplers));
126
127    /* 0 isn't a valid config.  This ensures that we always configure L3$. */
128    cmd_buffer->state.current_l3_config = 0;
129
130    state->dirty = 0;
131    state->vb_dirty = 0;
132    state->pending_pipe_bits = 0;
133    state->descriptors_dirty = 0;
134    state->push_constants_dirty = 0;
135    state->pipeline = NULL;
136    state->framebuffer = NULL;
137    state->pass = NULL;
138    state->subpass = NULL;
139    state->push_constant_stages = 0;
140    state->restart_index = UINT32_MAX;
141    state->dynamic = default_dynamic_state;
142    state->need_query_wa = true;
143    state->pma_fix_enabled = false;
144    state->hiz_enabled = false;
145
146    if (state->attachments != NULL) {
147       vk_free(&cmd_buffer->pool->alloc, state->attachments);
148       state->attachments = NULL;
149    }
150
151    state->gen7.index_buffer = NULL;
152 }
153
154 VkResult
155 anv_cmd_buffer_ensure_push_constants_size(struct anv_cmd_buffer *cmd_buffer,
156                                           gl_shader_stage stage, uint32_t size)
157 {
158    struct anv_push_constants **ptr = &cmd_buffer->state.push_constants[stage];
159
160    if (*ptr == NULL) {
161       *ptr = vk_alloc(&cmd_buffer->pool->alloc, size, 8,
162                        VK_SYSTEM_ALLOCATION_SCOPE_OBJECT);
163       if (*ptr == NULL)
164          return vk_error(VK_ERROR_OUT_OF_HOST_MEMORY);
165    } else if ((*ptr)->size < size) {
166       *ptr = vk_realloc(&cmd_buffer->pool->alloc, *ptr, size, 8,
167                          VK_SYSTEM_ALLOCATION_SCOPE_OBJECT);
168       if (*ptr == NULL)
169          return vk_error(VK_ERROR_OUT_OF_HOST_MEMORY);
170    }
171    (*ptr)->size = size;
172
173    return VK_SUCCESS;
174 }
175
176 static VkResult anv_create_cmd_buffer(
177     struct anv_device *                         device,
178     struct anv_cmd_pool *                       pool,
179     VkCommandBufferLevel                        level,
180     VkCommandBuffer*                            pCommandBuffer)
181 {
182    struct anv_cmd_buffer *cmd_buffer;
183    VkResult result;
184
185    cmd_buffer = vk_alloc(&pool->alloc, sizeof(*cmd_buffer), 8,
186                           VK_SYSTEM_ALLOCATION_SCOPE_OBJECT);
187    if (cmd_buffer == NULL)
188       return vk_error(VK_ERROR_OUT_OF_HOST_MEMORY);
189
190    cmd_buffer->batch.status = VK_SUCCESS;
191
192    cmd_buffer->_loader_data.loaderMagic = ICD_LOADER_MAGIC;
193    cmd_buffer->device = device;
194    cmd_buffer->pool = pool;
195    cmd_buffer->level = level;
196    cmd_buffer->state.attachments = NULL;
197
198    result = anv_cmd_buffer_init_batch_bo_chain(cmd_buffer);
199    if (result != VK_SUCCESS)
200       goto fail;
201
202    anv_state_stream_init(&cmd_buffer->surface_state_stream,
203                          &device->surface_state_block_pool);
204    anv_state_stream_init(&cmd_buffer->dynamic_state_stream,
205                          &device->dynamic_state_block_pool);
206
207    memset(&cmd_buffer->state.push_descriptor, 0,
208           sizeof(cmd_buffer->state.push_descriptor));
209
210    if (pool) {
211       list_addtail(&cmd_buffer->pool_link, &pool->cmd_buffers);
212    } else {
213       /* Init the pool_link so we can safefly call list_del when we destroy
214        * the command buffer
215        */
216       list_inithead(&cmd_buffer->pool_link);
217    }
218
219    *pCommandBuffer = anv_cmd_buffer_to_handle(cmd_buffer);
220
221    return VK_SUCCESS;
222
223  fail:
224    vk_free(&cmd_buffer->pool->alloc, cmd_buffer);
225
226    return result;
227 }
228
229 VkResult anv_AllocateCommandBuffers(
230     VkDevice                                    _device,
231     const VkCommandBufferAllocateInfo*          pAllocateInfo,
232     VkCommandBuffer*                            pCommandBuffers)
233 {
234    ANV_FROM_HANDLE(anv_device, device, _device);
235    ANV_FROM_HANDLE(anv_cmd_pool, pool, pAllocateInfo->commandPool);
236
237    VkResult result = VK_SUCCESS;
238    uint32_t i;
239
240    for (i = 0; i < pAllocateInfo->commandBufferCount; i++) {
241       result = anv_create_cmd_buffer(device, pool, pAllocateInfo->level,
242                                      &pCommandBuffers[i]);
243       if (result != VK_SUCCESS)
244          break;
245    }
246
247    if (result != VK_SUCCESS) {
248       anv_FreeCommandBuffers(_device, pAllocateInfo->commandPool,
249                              i, pCommandBuffers);
250       for (i = 0; i < pAllocateInfo->commandBufferCount; i++)
251          pCommandBuffers[i] = VK_NULL_HANDLE;
252    }
253
254    return result;
255 }
256
257 static void
258 anv_cmd_buffer_destroy(struct anv_cmd_buffer *cmd_buffer)
259 {
260    list_del(&cmd_buffer->pool_link);
261
262    anv_cmd_buffer_fini_batch_bo_chain(cmd_buffer);
263
264    anv_state_stream_finish(&cmd_buffer->surface_state_stream);
265    anv_state_stream_finish(&cmd_buffer->dynamic_state_stream);
266
267    vk_free(&cmd_buffer->pool->alloc, cmd_buffer->state.attachments);
268    vk_free(&cmd_buffer->pool->alloc, cmd_buffer);
269 }
270
271 void anv_FreeCommandBuffers(
272     VkDevice                                    device,
273     VkCommandPool                               commandPool,
274     uint32_t                                    commandBufferCount,
275     const VkCommandBuffer*                      pCommandBuffers)
276 {
277    for (uint32_t i = 0; i < commandBufferCount; i++) {
278       ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, pCommandBuffers[i]);
279
280       if (!cmd_buffer)
281          continue;
282
283       anv_cmd_buffer_destroy(cmd_buffer);
284    }
285 }
286
287 VkResult
288 anv_cmd_buffer_reset(struct anv_cmd_buffer *cmd_buffer)
289 {
290    cmd_buffer->usage_flags = 0;
291    cmd_buffer->state.current_pipeline = UINT32_MAX;
292    anv_cmd_buffer_reset_batch_bo_chain(cmd_buffer);
293    anv_cmd_state_reset(cmd_buffer);
294
295    anv_state_stream_finish(&cmd_buffer->surface_state_stream);
296    anv_state_stream_init(&cmd_buffer->surface_state_stream,
297                          &cmd_buffer->device->surface_state_block_pool);
298
299    anv_state_stream_finish(&cmd_buffer->dynamic_state_stream);
300    anv_state_stream_init(&cmd_buffer->dynamic_state_stream,
301                          &cmd_buffer->device->dynamic_state_block_pool);
302    return VK_SUCCESS;
303 }
304
305 VkResult anv_ResetCommandBuffer(
306     VkCommandBuffer                             commandBuffer,
307     VkCommandBufferResetFlags                   flags)
308 {
309    ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, commandBuffer);
310    return anv_cmd_buffer_reset(cmd_buffer);
311 }
312
313 void
314 anv_cmd_buffer_emit_state_base_address(struct anv_cmd_buffer *cmd_buffer)
315 {
316    switch (cmd_buffer->device->info.gen) {
317    case 7:
318       if (cmd_buffer->device->info.is_haswell)
319          return gen75_cmd_buffer_emit_state_base_address(cmd_buffer);
320       else
321          return gen7_cmd_buffer_emit_state_base_address(cmd_buffer);
322    case 8:
323       return gen8_cmd_buffer_emit_state_base_address(cmd_buffer);
324    case 9:
325       return gen9_cmd_buffer_emit_state_base_address(cmd_buffer);
326    default:
327       unreachable("unsupported gen\n");
328    }
329 }
330
331 void anv_CmdBindPipeline(
332     VkCommandBuffer                             commandBuffer,
333     VkPipelineBindPoint                         pipelineBindPoint,
334     VkPipeline                                  _pipeline)
335 {
336    ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, commandBuffer);
337    ANV_FROM_HANDLE(anv_pipeline, pipeline, _pipeline);
338
339    switch (pipelineBindPoint) {
340    case VK_PIPELINE_BIND_POINT_COMPUTE:
341       cmd_buffer->state.compute_pipeline = pipeline;
342       cmd_buffer->state.compute_dirty |= ANV_CMD_DIRTY_PIPELINE;
343       cmd_buffer->state.push_constants_dirty |= VK_SHADER_STAGE_COMPUTE_BIT;
344       cmd_buffer->state.descriptors_dirty |= VK_SHADER_STAGE_COMPUTE_BIT;
345       break;
346
347    case VK_PIPELINE_BIND_POINT_GRAPHICS:
348       cmd_buffer->state.pipeline = pipeline;
349       cmd_buffer->state.vb_dirty |= pipeline->vb_used;
350       cmd_buffer->state.dirty |= ANV_CMD_DIRTY_PIPELINE;
351       cmd_buffer->state.push_constants_dirty |= pipeline->active_stages;
352       cmd_buffer->state.descriptors_dirty |= pipeline->active_stages;
353
354       /* Apply the dynamic state from the pipeline */
355       cmd_buffer->state.dirty |= pipeline->dynamic_state_mask;
356       anv_dynamic_state_copy(&cmd_buffer->state.dynamic,
357                              &pipeline->dynamic_state,
358                              pipeline->dynamic_state_mask);
359       break;
360
361    default:
362       assert(!"invalid bind point");
363       break;
364    }
365 }
366
367 void anv_CmdSetViewport(
368     VkCommandBuffer                             commandBuffer,
369     uint32_t                                    firstViewport,
370     uint32_t                                    viewportCount,
371     const VkViewport*                           pViewports)
372 {
373    ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, commandBuffer);
374
375    const uint32_t total_count = firstViewport + viewportCount;
376    if (cmd_buffer->state.dynamic.viewport.count < total_count)
377       cmd_buffer->state.dynamic.viewport.count = total_count;
378
379    memcpy(cmd_buffer->state.dynamic.viewport.viewports + firstViewport,
380           pViewports, viewportCount * sizeof(*pViewports));
381
382    cmd_buffer->state.dirty |= ANV_CMD_DIRTY_DYNAMIC_VIEWPORT;
383 }
384
385 void anv_CmdSetScissor(
386     VkCommandBuffer                             commandBuffer,
387     uint32_t                                    firstScissor,
388     uint32_t                                    scissorCount,
389     const VkRect2D*                             pScissors)
390 {
391    ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, commandBuffer);
392
393    const uint32_t total_count = firstScissor + scissorCount;
394    if (cmd_buffer->state.dynamic.scissor.count < total_count)
395       cmd_buffer->state.dynamic.scissor.count = total_count;
396
397    memcpy(cmd_buffer->state.dynamic.scissor.scissors + firstScissor,
398           pScissors, scissorCount * sizeof(*pScissors));
399
400    cmd_buffer->state.dirty |= ANV_CMD_DIRTY_DYNAMIC_SCISSOR;
401 }
402
403 void anv_CmdSetLineWidth(
404     VkCommandBuffer                             commandBuffer,
405     float                                       lineWidth)
406 {
407    ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, commandBuffer);
408
409    cmd_buffer->state.dynamic.line_width = lineWidth;
410    cmd_buffer->state.dirty |= ANV_CMD_DIRTY_DYNAMIC_LINE_WIDTH;
411 }
412
413 void anv_CmdSetDepthBias(
414     VkCommandBuffer                             commandBuffer,
415     float                                       depthBiasConstantFactor,
416     float                                       depthBiasClamp,
417     float                                       depthBiasSlopeFactor)
418 {
419    ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, commandBuffer);
420
421    cmd_buffer->state.dynamic.depth_bias.bias = depthBiasConstantFactor;
422    cmd_buffer->state.dynamic.depth_bias.clamp = depthBiasClamp;
423    cmd_buffer->state.dynamic.depth_bias.slope = depthBiasSlopeFactor;
424
425    cmd_buffer->state.dirty |= ANV_CMD_DIRTY_DYNAMIC_DEPTH_BIAS;
426 }
427
428 void anv_CmdSetBlendConstants(
429     VkCommandBuffer                             commandBuffer,
430     const float                                 blendConstants[4])
431 {
432    ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, commandBuffer);
433
434    memcpy(cmd_buffer->state.dynamic.blend_constants,
435           blendConstants, sizeof(float) * 4);
436
437    cmd_buffer->state.dirty |= ANV_CMD_DIRTY_DYNAMIC_BLEND_CONSTANTS;
438 }
439
440 void anv_CmdSetDepthBounds(
441     VkCommandBuffer                             commandBuffer,
442     float                                       minDepthBounds,
443     float                                       maxDepthBounds)
444 {
445    ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, commandBuffer);
446
447    cmd_buffer->state.dynamic.depth_bounds.min = minDepthBounds;
448    cmd_buffer->state.dynamic.depth_bounds.max = maxDepthBounds;
449
450    cmd_buffer->state.dirty |= ANV_CMD_DIRTY_DYNAMIC_DEPTH_BOUNDS;
451 }
452
453 void anv_CmdSetStencilCompareMask(
454     VkCommandBuffer                             commandBuffer,
455     VkStencilFaceFlags                          faceMask,
456     uint32_t                                    compareMask)
457 {
458    ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, commandBuffer);
459
460    if (faceMask & VK_STENCIL_FACE_FRONT_BIT)
461       cmd_buffer->state.dynamic.stencil_compare_mask.front = compareMask;
462    if (faceMask & VK_STENCIL_FACE_BACK_BIT)
463       cmd_buffer->state.dynamic.stencil_compare_mask.back = compareMask;
464
465    cmd_buffer->state.dirty |= ANV_CMD_DIRTY_DYNAMIC_STENCIL_COMPARE_MASK;
466 }
467
468 void anv_CmdSetStencilWriteMask(
469     VkCommandBuffer                             commandBuffer,
470     VkStencilFaceFlags                          faceMask,
471     uint32_t                                    writeMask)
472 {
473    ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, commandBuffer);
474
475    if (faceMask & VK_STENCIL_FACE_FRONT_BIT)
476       cmd_buffer->state.dynamic.stencil_write_mask.front = writeMask;
477    if (faceMask & VK_STENCIL_FACE_BACK_BIT)
478       cmd_buffer->state.dynamic.stencil_write_mask.back = writeMask;
479
480    cmd_buffer->state.dirty |= ANV_CMD_DIRTY_DYNAMIC_STENCIL_WRITE_MASK;
481 }
482
483 void anv_CmdSetStencilReference(
484     VkCommandBuffer                             commandBuffer,
485     VkStencilFaceFlags                          faceMask,
486     uint32_t                                    reference)
487 {
488    ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, commandBuffer);
489
490    if (faceMask & VK_STENCIL_FACE_FRONT_BIT)
491       cmd_buffer->state.dynamic.stencil_reference.front = reference;
492    if (faceMask & VK_STENCIL_FACE_BACK_BIT)
493       cmd_buffer->state.dynamic.stencil_reference.back = reference;
494
495    cmd_buffer->state.dirty |= ANV_CMD_DIRTY_DYNAMIC_STENCIL_REFERENCE;
496 }
497
498 void anv_CmdBindDescriptorSets(
499     VkCommandBuffer                             commandBuffer,
500     VkPipelineBindPoint                         pipelineBindPoint,
501     VkPipelineLayout                            _layout,
502     uint32_t                                    firstSet,
503     uint32_t                                    descriptorSetCount,
504     const VkDescriptorSet*                      pDescriptorSets,
505     uint32_t                                    dynamicOffsetCount,
506     const uint32_t*                             pDynamicOffsets)
507 {
508    ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, commandBuffer);
509    ANV_FROM_HANDLE(anv_pipeline_layout, layout, _layout);
510    struct anv_descriptor_set_layout *set_layout;
511
512    assert(firstSet + descriptorSetCount < MAX_SETS);
513
514    uint32_t dynamic_slot = 0;
515    for (uint32_t i = 0; i < descriptorSetCount; i++) {
516       ANV_FROM_HANDLE(anv_descriptor_set, set, pDescriptorSets[i]);
517       set_layout = layout->set[firstSet + i].layout;
518
519       cmd_buffer->state.descriptors[firstSet + i] = set;
520
521       if (set_layout->dynamic_offset_count > 0) {
522          uint32_t dynamic_offset_start =
523             layout->set[firstSet + i].dynamic_offset_start;
524
525          /* Assert that everything is in range */
526          assert(dynamic_offset_start + set_layout->dynamic_offset_count <=
527                 ARRAY_SIZE(cmd_buffer->state.dynamic_offsets));
528          assert(dynamic_slot + set_layout->dynamic_offset_count <=
529                 dynamicOffsetCount);
530
531          typed_memcpy(&cmd_buffer->state.dynamic_offsets[dynamic_offset_start],
532                       &pDynamicOffsets[dynamic_slot],
533                       set_layout->dynamic_offset_count);
534
535          dynamic_slot += set_layout->dynamic_offset_count;
536       }
537
538       cmd_buffer->state.descriptors_dirty |= set_layout->shader_stages;
539    }
540 }
541
542 void anv_CmdBindVertexBuffers(
543     VkCommandBuffer                             commandBuffer,
544     uint32_t                                    firstBinding,
545     uint32_t                                    bindingCount,
546     const VkBuffer*                             pBuffers,
547     const VkDeviceSize*                         pOffsets)
548 {
549    ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, commandBuffer);
550    struct anv_vertex_binding *vb = cmd_buffer->state.vertex_bindings;
551
552    /* We have to defer setting up vertex buffer since we need the buffer
553     * stride from the pipeline. */
554
555    assert(firstBinding + bindingCount < MAX_VBS);
556    for (uint32_t i = 0; i < bindingCount; i++) {
557       vb[firstBinding + i].buffer = anv_buffer_from_handle(pBuffers[i]);
558       vb[firstBinding + i].offset = pOffsets[i];
559       cmd_buffer->state.vb_dirty |= 1 << (firstBinding + i);
560    }
561 }
562
563 enum isl_format
564 anv_isl_format_for_descriptor_type(VkDescriptorType type)
565 {
566    switch (type) {
567    case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER:
568    case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC:
569       return ISL_FORMAT_R32G32B32A32_FLOAT;
570
571    case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER:
572    case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC:
573       return ISL_FORMAT_RAW;
574
575    default:
576       unreachable("Invalid descriptor type");
577    }
578 }
579
580 struct anv_state
581 anv_cmd_buffer_emit_dynamic(struct anv_cmd_buffer *cmd_buffer,
582                             const void *data, uint32_t size, uint32_t alignment)
583 {
584    struct anv_state state;
585
586    state = anv_cmd_buffer_alloc_dynamic_state(cmd_buffer, size, alignment);
587    memcpy(state.map, data, size);
588
589    anv_state_flush(cmd_buffer->device, state);
590
591    VG(VALGRIND_CHECK_MEM_IS_DEFINED(state.map, size));
592
593    return state;
594 }
595
596 struct anv_state
597 anv_cmd_buffer_merge_dynamic(struct anv_cmd_buffer *cmd_buffer,
598                              uint32_t *a, uint32_t *b,
599                              uint32_t dwords, uint32_t alignment)
600 {
601    struct anv_state state;
602    uint32_t *p;
603
604    state = anv_cmd_buffer_alloc_dynamic_state(cmd_buffer,
605                                               dwords * 4, alignment);
606    p = state.map;
607    for (uint32_t i = 0; i < dwords; i++)
608       p[i] = a[i] | b[i];
609
610    anv_state_flush(cmd_buffer->device, state);
611
612    VG(VALGRIND_CHECK_MEM_IS_DEFINED(p, dwords * 4));
613
614    return state;
615 }
616
617 struct anv_state
618 anv_cmd_buffer_push_constants(struct anv_cmd_buffer *cmd_buffer,
619                               gl_shader_stage stage)
620 {
621    /* If we don't have this stage, bail. */
622    if (!anv_pipeline_has_stage(cmd_buffer->state.pipeline, stage))
623       return (struct anv_state) { .offset = 0 };
624
625    struct anv_push_constants *data =
626       cmd_buffer->state.push_constants[stage];
627    const struct brw_stage_prog_data *prog_data =
628       cmd_buffer->state.pipeline->shaders[stage]->prog_data;
629
630    /* If we don't actually have any push constants, bail. */
631    if (data == NULL || prog_data == NULL || prog_data->nr_params == 0)
632       return (struct anv_state) { .offset = 0 };
633
634    struct anv_state state =
635       anv_cmd_buffer_alloc_dynamic_state(cmd_buffer,
636                                          prog_data->nr_params * sizeof(float),
637                                          32 /* bottom 5 bits MBZ */);
638
639    /* Walk through the param array and fill the buffer with data */
640    uint32_t *u32_map = state.map;
641    for (unsigned i = 0; i < prog_data->nr_params; i++) {
642       uint32_t offset = (uintptr_t)prog_data->param[i];
643       u32_map[i] = *(uint32_t *)((uint8_t *)data + offset);
644    }
645
646    anv_state_flush(cmd_buffer->device, state);
647
648    return state;
649 }
650
651 struct anv_state
652 anv_cmd_buffer_cs_push_constants(struct anv_cmd_buffer *cmd_buffer)
653 {
654    struct anv_push_constants *data =
655       cmd_buffer->state.push_constants[MESA_SHADER_COMPUTE];
656    struct anv_pipeline *pipeline = cmd_buffer->state.compute_pipeline;
657    const struct brw_cs_prog_data *cs_prog_data = get_cs_prog_data(pipeline);
658    const struct brw_stage_prog_data *prog_data = &cs_prog_data->base;
659
660    /* If we don't actually have any push constants, bail. */
661    if (cs_prog_data->push.total.size == 0)
662       return (struct anv_state) { .offset = 0 };
663
664    const unsigned push_constant_alignment =
665       cmd_buffer->device->info.gen < 8 ? 32 : 64;
666    const unsigned aligned_total_push_constants_size =
667       ALIGN(cs_prog_data->push.total.size, push_constant_alignment);
668    struct anv_state state =
669       anv_cmd_buffer_alloc_dynamic_state(cmd_buffer,
670                                          aligned_total_push_constants_size,
671                                          push_constant_alignment);
672
673    /* Walk through the param array and fill the buffer with data */
674    uint32_t *u32_map = state.map;
675
676    if (cs_prog_data->push.cross_thread.size > 0) {
677       assert(cs_prog_data->thread_local_id_index < 0 ||
678              cs_prog_data->thread_local_id_index >=
679                 cs_prog_data->push.cross_thread.dwords);
680       for (unsigned i = 0;
681            i < cs_prog_data->push.cross_thread.dwords;
682            i++) {
683          uint32_t offset = (uintptr_t)prog_data->param[i];
684          u32_map[i] = *(uint32_t *)((uint8_t *)data + offset);
685       }
686    }
687
688    if (cs_prog_data->push.per_thread.size > 0) {
689       for (unsigned t = 0; t < cs_prog_data->threads; t++) {
690          unsigned dst =
691             8 * (cs_prog_data->push.per_thread.regs * t +
692                  cs_prog_data->push.cross_thread.regs);
693          unsigned src = cs_prog_data->push.cross_thread.dwords;
694          for ( ; src < prog_data->nr_params; src++, dst++) {
695             if (src != cs_prog_data->thread_local_id_index) {
696                uint32_t offset = (uintptr_t)prog_data->param[src];
697                u32_map[dst] = *(uint32_t *)((uint8_t *)data + offset);
698             } else {
699                u32_map[dst] = t * cs_prog_data->simd_size;
700             }
701          }
702       }
703    }
704
705    anv_state_flush(cmd_buffer->device, state);
706
707    return state;
708 }
709
710 void anv_CmdPushConstants(
711     VkCommandBuffer                             commandBuffer,
712     VkPipelineLayout                            layout,
713     VkShaderStageFlags                          stageFlags,
714     uint32_t                                    offset,
715     uint32_t                                    size,
716     const void*                                 pValues)
717 {
718    ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, commandBuffer);
719
720    anv_foreach_stage(stage, stageFlags) {
721       anv_cmd_buffer_ensure_push_constant_field(cmd_buffer, stage, client_data);
722
723       memcpy(cmd_buffer->state.push_constants[stage]->client_data + offset,
724              pValues, size);
725    }
726
727    cmd_buffer->state.push_constants_dirty |= stageFlags;
728 }
729
730 VkResult anv_CreateCommandPool(
731     VkDevice                                    _device,
732     const VkCommandPoolCreateInfo*              pCreateInfo,
733     const VkAllocationCallbacks*                pAllocator,
734     VkCommandPool*                              pCmdPool)
735 {
736    ANV_FROM_HANDLE(anv_device, device, _device);
737    struct anv_cmd_pool *pool;
738
739    pool = vk_alloc2(&device->alloc, pAllocator, sizeof(*pool), 8,
740                      VK_SYSTEM_ALLOCATION_SCOPE_OBJECT);
741    if (pool == NULL)
742       return vk_error(VK_ERROR_OUT_OF_HOST_MEMORY);
743
744    if (pAllocator)
745       pool->alloc = *pAllocator;
746    else
747       pool->alloc = device->alloc;
748
749    list_inithead(&pool->cmd_buffers);
750
751    *pCmdPool = anv_cmd_pool_to_handle(pool);
752
753    return VK_SUCCESS;
754 }
755
756 void anv_DestroyCommandPool(
757     VkDevice                                    _device,
758     VkCommandPool                               commandPool,
759     const VkAllocationCallbacks*                pAllocator)
760 {
761    ANV_FROM_HANDLE(anv_device, device, _device);
762    ANV_FROM_HANDLE(anv_cmd_pool, pool, commandPool);
763
764    if (!pool)
765       return;
766
767    list_for_each_entry_safe(struct anv_cmd_buffer, cmd_buffer,
768                             &pool->cmd_buffers, pool_link) {
769       anv_cmd_buffer_destroy(cmd_buffer);
770    }
771
772    vk_free2(&device->alloc, pAllocator, pool);
773 }
774
775 VkResult anv_ResetCommandPool(
776     VkDevice                                    device,
777     VkCommandPool                               commandPool,
778     VkCommandPoolResetFlags                     flags)
779 {
780    ANV_FROM_HANDLE(anv_cmd_pool, pool, commandPool);
781
782    list_for_each_entry(struct anv_cmd_buffer, cmd_buffer,
783                        &pool->cmd_buffers, pool_link) {
784       anv_cmd_buffer_reset(cmd_buffer);
785    }
786
787    return VK_SUCCESS;
788 }
789
790 void anv_TrimCommandPoolKHR(
791     VkDevice                                    device,
792     VkCommandPool                               commandPool,
793     VkCommandPoolTrimFlagsKHR                   flags)
794 {
795    /* Nothing for us to do here.  Our pools stay pretty tidy. */
796 }
797
798 /**
799  * Return NULL if the current subpass has no depthstencil attachment.
800  */
801 const struct anv_image_view *
802 anv_cmd_buffer_get_depth_stencil_view(const struct anv_cmd_buffer *cmd_buffer)
803 {
804    const struct anv_subpass *subpass = cmd_buffer->state.subpass;
805    const struct anv_framebuffer *fb = cmd_buffer->state.framebuffer;
806
807    if (subpass->depth_stencil_attachment.attachment == VK_ATTACHMENT_UNUSED)
808       return NULL;
809
810    const struct anv_image_view *iview =
811       fb->attachments[subpass->depth_stencil_attachment.attachment];
812
813    assert(iview->aspect_mask & (VK_IMAGE_ASPECT_DEPTH_BIT |
814                                 VK_IMAGE_ASPECT_STENCIL_BIT));
815
816    return iview;
817 }
818
819 void anv_CmdPushDescriptorSetKHR(
820     VkCommandBuffer commandBuffer,
821     VkPipelineBindPoint pipelineBindPoint,
822     VkPipelineLayout _layout,
823     uint32_t _set,
824     uint32_t descriptorWriteCount,
825     const VkWriteDescriptorSet* pDescriptorWrites)
826 {
827    ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, commandBuffer);
828    ANV_FROM_HANDLE(anv_pipeline_layout, layout, _layout);
829
830    assert(pipelineBindPoint == VK_PIPELINE_BIND_POINT_GRAPHICS ||
831           pipelineBindPoint == VK_PIPELINE_BIND_POINT_COMPUTE);
832    assert(_set < MAX_SETS);
833
834    const struct anv_descriptor_set_layout *set_layout =
835       layout->set[_set].layout;
836    struct anv_descriptor_set *set = &cmd_buffer->state.push_descriptor.set;
837
838    set->layout = set_layout;
839    set->size = anv_descriptor_set_layout_size(set_layout);
840    set->buffer_count = set_layout->buffer_count;
841    set->buffer_views = cmd_buffer->state.push_descriptor.buffer_views;
842
843    /* Go through the user supplied descriptors. */
844    for (uint32_t i = 0; i < descriptorWriteCount; i++) {
845       const VkWriteDescriptorSet *write = &pDescriptorWrites[i];
846
847       switch (write->descriptorType) {
848       case VK_DESCRIPTOR_TYPE_SAMPLER:
849       case VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER:
850       case VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE:
851       case VK_DESCRIPTOR_TYPE_STORAGE_IMAGE:
852       case VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT:
853          for (uint32_t j = 0; j < write->descriptorCount; j++) {
854             anv_descriptor_set_write_image_view(set, &cmd_buffer->device->info,
855                                                 write->pImageInfo + j,
856                                                 write->descriptorType,
857                                                 write->dstBinding,
858                                                 write->dstArrayElement + j);
859          }
860          break;
861
862       case VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER:
863       case VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER:
864          for (uint32_t j = 0; j < write->descriptorCount; j++) {
865             ANV_FROM_HANDLE(anv_buffer_view, bview,
866                             write->pTexelBufferView[j]);
867
868             anv_descriptor_set_write_buffer_view(set,
869                                                  write->descriptorType,
870                                                  bview,
871                                                  write->dstBinding,
872                                                  write->dstArrayElement + j);
873          }
874          break;
875
876       case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER:
877       case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER:
878       case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC:
879       case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC:
880          for (uint32_t j = 0; j < write->descriptorCount; j++) {
881             assert(write->pBufferInfo[j].buffer);
882             ANV_FROM_HANDLE(anv_buffer, buffer, write->pBufferInfo[j].buffer);
883             assert(buffer);
884
885             anv_descriptor_set_write_buffer(set,
886                                             cmd_buffer->device,
887                                             &cmd_buffer->surface_state_stream,
888                                             write->descriptorType,
889                                             buffer,
890                                             write->dstBinding,
891                                             write->dstArrayElement + j,
892                                             write->pBufferInfo[j].offset,
893                                             write->pBufferInfo[j].range);
894          }
895          break;
896
897       default:
898          break;
899       }
900    }
901
902    cmd_buffer->state.descriptors[_set] = set;
903    cmd_buffer->state.descriptors_dirty |= set_layout->shader_stages;
904 }
905
906 void anv_CmdPushDescriptorSetWithTemplateKHR(
907     VkCommandBuffer                             commandBuffer,
908     VkDescriptorUpdateTemplateKHR               descriptorUpdateTemplate,
909     VkPipelineLayout                            _layout,
910     uint32_t                                    _set,
911     const void*                                 pData)
912 {
913    ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, commandBuffer);
914    ANV_FROM_HANDLE(anv_descriptor_update_template, template,
915                    descriptorUpdateTemplate);
916    ANV_FROM_HANDLE(anv_pipeline_layout, layout, _layout);
917
918    assert(_set < MAX_PUSH_DESCRIPTORS);
919
920    const struct anv_descriptor_set_layout *set_layout =
921       layout->set[_set].layout;
922    struct anv_descriptor_set *set = &cmd_buffer->state.push_descriptor.set;
923
924    set->layout = set_layout;
925    set->size = anv_descriptor_set_layout_size(set_layout);
926    set->buffer_count = set_layout->buffer_count;
927    set->buffer_views = cmd_buffer->state.push_descriptor.buffer_views;
928
929    anv_descriptor_set_write_template(set,
930                                      cmd_buffer->device,
931                                      &cmd_buffer->surface_state_stream,
932                                      template,
933                                      pData);
934
935    cmd_buffer->state.descriptors[_set] = set;
936    cmd_buffer->state.descriptors_dirty |= set_layout->shader_stages;
937 }