OSDN Git Service

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