2 * Copyright © 2015 Intel Corporation
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:
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
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
30 #include "anv_private.h"
32 /** \file anv_cmd_buffer.c
34 * This file contains all of the stuff for emitting commands into a command
35 * buffer. This includes implementations of most of the vkCmd*
36 * entrypoints. This file is concerned entirely with state emission and
37 * not with the command buffer data structure itself. As far as this file
38 * is concerned, most of anv_cmd_buffer is magic.
42 anv_cmd_state_init(struct anv_cmd_state
*state
)
44 state
->rs_state
= NULL
;
45 state
->vp_state
= NULL
;
46 state
->cb_state
= NULL
;
47 state
->ds_state
= NULL
;
48 memset(&state
->state_vf
, 0, sizeof(state
->state_vf
));
49 memset(&state
->descriptors
, 0, sizeof(state
->descriptors
));
50 memset(&state
->push_constants
, 0, sizeof(state
->push_constants
));
54 state
->descriptors_dirty
= 0;
55 state
->push_constants_dirty
= 0;
56 state
->pipeline
= NULL
;
57 state
->vp_state
= NULL
;
58 state
->rs_state
= NULL
;
59 state
->ds_state
= NULL
;
61 state
->gen7
.index_buffer
= NULL
;
65 anv_cmd_buffer_ensure_push_constants_size(struct anv_cmd_buffer
*cmd_buffer
,
66 VkShaderStage stage
, uint32_t size
)
68 struct anv_push_constants
**ptr
= &cmd_buffer
->state
.push_constants
[stage
];
71 *ptr
= anv_device_alloc(cmd_buffer
->device
, size
, 8,
72 VK_SYSTEM_ALLOC_TYPE_INTERNAL
);
74 return vk_error(VK_ERROR_OUT_OF_HOST_MEMORY
);
76 } else if ((*ptr
)->size
< size
) {
77 void *new_data
= anv_device_alloc(cmd_buffer
->device
, size
, 8,
78 VK_SYSTEM_ALLOC_TYPE_INTERNAL
);
80 return vk_error(VK_ERROR_OUT_OF_HOST_MEMORY
);
82 memcpy(new_data
, *ptr
, (*ptr
)->size
);
83 anv_device_free(cmd_buffer
->device
, *ptr
);
92 #define anv_cmd_buffer_ensure_push_constant_field(cmd_buffer, stage, field) \
93 anv_cmd_buffer_ensure_push_constants_size(cmd_buffer, stage, \
94 (offsetof(struct anv_push_constants, field) + \
95 sizeof(cmd_buffer->state.push_constants[0]->field)))
97 VkResult
anv_CreateCommandBuffer(
99 const VkCmdBufferCreateInfo
* pCreateInfo
,
100 VkCmdBuffer
* pCmdBuffer
)
102 ANV_FROM_HANDLE(anv_device
, device
, _device
);
103 ANV_FROM_HANDLE(anv_cmd_pool
, pool
, pCreateInfo
->cmdPool
);
104 struct anv_cmd_buffer
*cmd_buffer
;
107 cmd_buffer
= anv_device_alloc(device
, sizeof(*cmd_buffer
), 8,
108 VK_SYSTEM_ALLOC_TYPE_API_OBJECT
);
109 if (cmd_buffer
== NULL
)
110 return vk_error(VK_ERROR_OUT_OF_HOST_MEMORY
);
112 cmd_buffer
->_loader_data
.loaderMagic
= ICD_LOADER_MAGIC
;
113 cmd_buffer
->device
= device
;
115 result
= anv_cmd_buffer_init_batch_bo_chain(cmd_buffer
);
116 if (result
!= VK_SUCCESS
)
119 anv_state_stream_init(&cmd_buffer
->surface_state_stream
,
120 &device
->surface_state_block_pool
);
121 anv_state_stream_init(&cmd_buffer
->dynamic_state_stream
,
122 &device
->dynamic_state_block_pool
);
124 cmd_buffer
->level
= pCreateInfo
->level
;
125 cmd_buffer
->opt_flags
= 0;
127 anv_cmd_state_init(&cmd_buffer
->state
);
130 list_addtail(&cmd_buffer
->pool_link
, &pool
->cmd_buffers
);
132 /* Init the pool_link so we can safefly call list_del when we destroy
135 list_inithead(&cmd_buffer
->pool_link
);
138 *pCmdBuffer
= anv_cmd_buffer_to_handle(cmd_buffer
);
142 fail
: anv_device_free(device
, cmd_buffer
);
147 VkResult
anv_DestroyCommandBuffer(
149 VkCmdBuffer _cmd_buffer
)
151 ANV_FROM_HANDLE(anv_device
, device
, _device
);
152 ANV_FROM_HANDLE(anv_cmd_buffer
, cmd_buffer
, _cmd_buffer
);
154 list_del(&cmd_buffer
->pool_link
);
156 anv_cmd_buffer_fini_batch_bo_chain(cmd_buffer
);
158 anv_state_stream_finish(&cmd_buffer
->surface_state_stream
);
159 anv_state_stream_finish(&cmd_buffer
->dynamic_state_stream
);
160 anv_device_free(device
, cmd_buffer
);
165 VkResult
anv_ResetCommandBuffer(
166 VkCmdBuffer cmdBuffer
,
167 VkCmdBufferResetFlags flags
)
169 ANV_FROM_HANDLE(anv_cmd_buffer
, cmd_buffer
, cmdBuffer
);
171 anv_cmd_buffer_reset_batch_bo_chain(cmd_buffer
);
173 anv_cmd_state_init(&cmd_buffer
->state
);
179 anv_cmd_buffer_emit_state_base_address(struct anv_cmd_buffer
*cmd_buffer
)
181 switch (cmd_buffer
->device
->info
.gen
) {
183 return gen7_cmd_buffer_emit_state_base_address(cmd_buffer
);
185 return gen8_cmd_buffer_emit_state_base_address(cmd_buffer
);
187 unreachable("unsupported gen\n");
191 VkResult
anv_BeginCommandBuffer(
192 VkCmdBuffer cmdBuffer
,
193 const VkCmdBufferBeginInfo
* pBeginInfo
)
195 ANV_FROM_HANDLE(anv_cmd_buffer
, cmd_buffer
, cmdBuffer
);
197 cmd_buffer
->opt_flags
= pBeginInfo
->flags
;
199 if (cmd_buffer
->level
== VK_CMD_BUFFER_LEVEL_SECONDARY
) {
200 cmd_buffer
->state
.framebuffer
=
201 anv_framebuffer_from_handle(pBeginInfo
->framebuffer
);
202 cmd_buffer
->state
.pass
=
203 anv_render_pass_from_handle(pBeginInfo
->renderPass
);
205 /* FIXME: We shouldn't be starting on the first subpass */
206 anv_cmd_buffer_begin_subpass(cmd_buffer
,
207 &cmd_buffer
->state
.pass
->subpasses
[0]);
210 anv_cmd_buffer_emit_state_base_address(cmd_buffer
);
211 cmd_buffer
->state
.current_pipeline
= UINT32_MAX
;
216 VkResult
anv_EndCommandBuffer(
217 VkCmdBuffer cmdBuffer
)
219 ANV_FROM_HANDLE(anv_cmd_buffer
, cmd_buffer
, cmdBuffer
);
220 struct anv_device
*device
= cmd_buffer
->device
;
222 anv_cmd_buffer_end_batch_buffer(cmd_buffer
);
224 if (cmd_buffer
->level
== VK_CMD_BUFFER_LEVEL_PRIMARY
) {
225 /* The algorithm used to compute the validate list is not threadsafe as
226 * it uses the bo->index field. We have to lock the device around it.
227 * Fortunately, the chances for contention here are probably very low.
229 pthread_mutex_lock(&device
->mutex
);
230 anv_cmd_buffer_prepare_execbuf(cmd_buffer
);
231 pthread_mutex_unlock(&device
->mutex
);
237 void anv_CmdBindPipeline(
238 VkCmdBuffer cmdBuffer
,
239 VkPipelineBindPoint pipelineBindPoint
,
240 VkPipeline _pipeline
)
242 ANV_FROM_HANDLE(anv_cmd_buffer
, cmd_buffer
, cmdBuffer
);
243 ANV_FROM_HANDLE(anv_pipeline
, pipeline
, _pipeline
);
245 switch (pipelineBindPoint
) {
246 case VK_PIPELINE_BIND_POINT_COMPUTE
:
247 cmd_buffer
->state
.compute_pipeline
= pipeline
;
248 cmd_buffer
->state
.compute_dirty
|= ANV_CMD_BUFFER_PIPELINE_DIRTY
;
249 cmd_buffer
->state
.push_constants_dirty
|= VK_SHADER_STAGE_COMPUTE_BIT
;
252 case VK_PIPELINE_BIND_POINT_GRAPHICS
:
253 cmd_buffer
->state
.pipeline
= pipeline
;
254 cmd_buffer
->state
.vb_dirty
|= pipeline
->vb_used
;
255 cmd_buffer
->state
.dirty
|= ANV_CMD_BUFFER_PIPELINE_DIRTY
;
256 cmd_buffer
->state
.push_constants_dirty
|= pipeline
->active_stages
;
260 assert(!"invalid bind point");
265 void anv_CmdBindDynamicViewportState(
266 VkCmdBuffer cmdBuffer
,
267 VkDynamicViewportState dynamicViewportState
)
269 ANV_FROM_HANDLE(anv_cmd_buffer
, cmd_buffer
, cmdBuffer
);
270 ANV_FROM_HANDLE(anv_dynamic_vp_state
, vp_state
, dynamicViewportState
);
272 cmd_buffer
->state
.vp_state
= vp_state
;
273 cmd_buffer
->state
.dirty
|= ANV_CMD_BUFFER_VP_DIRTY
;
276 void anv_CmdBindDynamicRasterState(
277 VkCmdBuffer cmdBuffer
,
278 VkDynamicRasterState dynamicRasterState
)
280 ANV_FROM_HANDLE(anv_cmd_buffer
, cmd_buffer
, cmdBuffer
);
281 ANV_FROM_HANDLE(anv_dynamic_rs_state
, rs_state
, dynamicRasterState
);
283 cmd_buffer
->state
.rs_state
= rs_state
;
284 cmd_buffer
->state
.dirty
|= ANV_CMD_BUFFER_RS_DIRTY
;
287 void anv_CmdBindDynamicColorBlendState(
288 VkCmdBuffer cmdBuffer
,
289 VkDynamicColorBlendState dynamicColorBlendState
)
291 ANV_FROM_HANDLE(anv_cmd_buffer
, cmd_buffer
, cmdBuffer
);
292 ANV_FROM_HANDLE(anv_dynamic_cb_state
, cb_state
, dynamicColorBlendState
);
294 cmd_buffer
->state
.cb_state
= cb_state
;
295 cmd_buffer
->state
.dirty
|= ANV_CMD_BUFFER_CB_DIRTY
;
298 void anv_CmdBindDynamicDepthStencilState(
299 VkCmdBuffer cmdBuffer
,
300 VkDynamicDepthStencilState dynamicDepthStencilState
)
302 ANV_FROM_HANDLE(anv_cmd_buffer
, cmd_buffer
, cmdBuffer
);
303 ANV_FROM_HANDLE(anv_dynamic_ds_state
, ds_state
, dynamicDepthStencilState
);
305 cmd_buffer
->state
.ds_state
= ds_state
;
306 cmd_buffer
->state
.dirty
|= ANV_CMD_BUFFER_DS_DIRTY
;
309 void anv_CmdBindDescriptorSets(
310 VkCmdBuffer cmdBuffer
,
311 VkPipelineBindPoint pipelineBindPoint
,
312 VkPipelineLayout _layout
,
315 const VkDescriptorSet
* pDescriptorSets
,
316 uint32_t dynamicOffsetCount
,
317 const uint32_t* pDynamicOffsets
)
319 ANV_FROM_HANDLE(anv_cmd_buffer
, cmd_buffer
, cmdBuffer
);
320 ANV_FROM_HANDLE(anv_pipeline_layout
, layout
, _layout
);
321 struct anv_descriptor_set_layout
*set_layout
;
323 assert(firstSet
+ setCount
< MAX_SETS
);
325 uint32_t dynamic_slot
= 0;
326 for (uint32_t i
= 0; i
< setCount
; i
++) {
327 ANV_FROM_HANDLE(anv_descriptor_set
, set
, pDescriptorSets
[i
]);
328 set_layout
= layout
->set
[firstSet
+ i
].layout
;
330 if (cmd_buffer
->state
.descriptors
[firstSet
+ i
].set
!= set
) {
331 cmd_buffer
->state
.descriptors
[firstSet
+ i
].set
= set
;
332 cmd_buffer
->state
.descriptors_dirty
|= set_layout
->shader_stages
;
335 if (set_layout
->num_dynamic_buffers
> 0) {
337 for_each_bit(s
, set_layout
->shader_stages
) {
338 anv_cmd_buffer_ensure_push_constant_field(cmd_buffer
, s
,
341 cmd_buffer
->state
.push_constants
[s
]->dynamic_offsets
+
342 layout
->set
[firstSet
+ i
].dynamic_offset_start
;
344 memcpy(offsets
, pDynamicOffsets
+ dynamic_slot
,
345 set_layout
->num_dynamic_buffers
* sizeof(*pDynamicOffsets
));
348 cmd_buffer
->state
.push_constants_dirty
|= set_layout
->shader_stages
;
350 dynamic_slot
+= set_layout
->num_dynamic_buffers
;
355 void anv_CmdBindVertexBuffers(
356 VkCmdBuffer cmdBuffer
,
357 uint32_t startBinding
,
358 uint32_t bindingCount
,
359 const VkBuffer
* pBuffers
,
360 const VkDeviceSize
* pOffsets
)
362 ANV_FROM_HANDLE(anv_cmd_buffer
, cmd_buffer
, cmdBuffer
);
363 struct anv_vertex_binding
*vb
= cmd_buffer
->state
.vertex_bindings
;
365 /* We have to defer setting up vertex buffer since we need the buffer
366 * stride from the pipeline. */
368 assert(startBinding
+ bindingCount
< MAX_VBS
);
369 for (uint32_t i
= 0; i
< bindingCount
; i
++) {
370 vb
[startBinding
+ i
].buffer
= anv_buffer_from_handle(pBuffers
[i
]);
371 vb
[startBinding
+ i
].offset
= pOffsets
[i
];
372 cmd_buffer
->state
.vb_dirty
|= 1 << (startBinding
+ i
);
377 add_surface_state_reloc(struct anv_cmd_buffer
*cmd_buffer
,
378 struct anv_state state
, struct anv_bo
*bo
, uint32_t offset
)
380 /* The address goes in SURFACE_STATE dword 1 for gens < 8 and dwords 8 and
381 * 9 for gen8+. We only write the first dword for gen8+ here and rely on
382 * the initial state to set the high bits to 0. */
384 const uint32_t dword
= cmd_buffer
->device
->info
.gen
< 8 ? 1 : 8;
386 anv_reloc_list_add(&cmd_buffer
->surface_relocs
, cmd_buffer
->device
,
387 state
.offset
+ dword
* 4, bo
, offset
);
391 anv_cmd_buffer_emit_binding_table(struct anv_cmd_buffer
*cmd_buffer
,
392 unsigned stage
, struct anv_state
*bt_state
)
394 struct anv_framebuffer
*fb
= cmd_buffer
->state
.framebuffer
;
395 struct anv_subpass
*subpass
= cmd_buffer
->state
.subpass
;
396 struct anv_pipeline_layout
*layout
;
397 uint32_t attachments
, bias
, state_offset
;
399 if (stage
== VK_SHADER_STAGE_COMPUTE
)
400 layout
= cmd_buffer
->state
.compute_pipeline
->layout
;
402 layout
= cmd_buffer
->state
.pipeline
->layout
;
404 if (stage
== VK_SHADER_STAGE_FRAGMENT
) {
406 attachments
= subpass
->color_count
;
412 /* This is a little awkward: layout can be NULL but we still have to
413 * allocate and set a binding table for the PS stage for render
415 uint32_t surface_count
= layout
? layout
->stage
[stage
].surface_count
: 0;
417 if (attachments
+ surface_count
== 0)
420 *bt_state
= anv_cmd_buffer_alloc_binding_table(cmd_buffer
,
421 bias
+ surface_count
,
423 uint32_t *bt_map
= bt_state
->map
;
425 if (bt_state
->map
== NULL
)
426 return VK_ERROR_OUT_OF_DEVICE_MEMORY
;
428 /* This is highly annoying. The Vulkan spec puts the depth-stencil
429 * attachments in with the color attachments. Unfortunately, thanks to
430 * other aspects of the API, we cana't really saparate them before this
431 * point. Therefore, we have to walk all of the attachments but only
432 * put the color attachments into the binding table.
434 for (uint32_t a
= 0; a
< attachments
; a
++) {
435 const struct anv_attachment_view
*attachment
=
436 fb
->attachments
[subpass
->color_attachments
[a
]];
438 assert(attachment
->attachment_type
== ANV_ATTACHMENT_VIEW_TYPE_COLOR
);
439 const struct anv_color_attachment_view
*view
=
440 (const struct anv_color_attachment_view
*)attachment
;
442 bt_map
[a
] = view
->view
.surface_state
.offset
+ state_offset
;
443 add_surface_state_reloc(cmd_buffer
, view
->view
.surface_state
,
444 view
->view
.bo
, view
->view
.offset
);
450 for (uint32_t set
= 0; set
< layout
->num_sets
; set
++) {
451 struct anv_descriptor_set_binding
*d
= &cmd_buffer
->state
.descriptors
[set
];
452 struct anv_descriptor_set_layout
*set_layout
= layout
->set
[set
].layout
;
453 struct anv_descriptor_slot
*surface_slots
=
454 set_layout
->stage
[stage
].surface_start
;
456 uint32_t start
= bias
+ layout
->set
[set
].stage
[stage
].surface_start
;
458 for (uint32_t b
= 0; b
< set_layout
->stage
[stage
].surface_count
; b
++) {
459 struct anv_surface_view
*view
=
460 d
->set
->descriptors
[surface_slots
[b
].index
].view
;
465 bt_map
[start
+ b
] = view
->surface_state
.offset
+ state_offset
;
466 add_surface_state_reloc(cmd_buffer
, view
->surface_state
,
467 view
->bo
, view
->offset
);
475 anv_cmd_buffer_emit_samplers(struct anv_cmd_buffer
*cmd_buffer
,
476 unsigned stage
, struct anv_state
*state
)
478 struct anv_pipeline_layout
*layout
;
479 uint32_t sampler_count
;
481 if (stage
== VK_SHADER_STAGE_COMPUTE
)
482 layout
= cmd_buffer
->state
.compute_pipeline
->layout
;
484 layout
= cmd_buffer
->state
.pipeline
->layout
;
486 sampler_count
= layout
? layout
->stage
[stage
].sampler_count
: 0;
487 if (sampler_count
== 0)
490 uint32_t size
= sampler_count
* 16;
491 *state
= anv_cmd_buffer_alloc_dynamic_state(cmd_buffer
, size
, 32);
493 if (state
->map
== NULL
)
494 return VK_ERROR_OUT_OF_DEVICE_MEMORY
;
496 for (uint32_t set
= 0; set
< layout
->num_sets
; set
++) {
497 struct anv_descriptor_set_binding
*d
= &cmd_buffer
->state
.descriptors
[set
];
498 struct anv_descriptor_set_layout
*set_layout
= layout
->set
[set
].layout
;
499 struct anv_descriptor_slot
*sampler_slots
=
500 set_layout
->stage
[stage
].sampler_start
;
502 uint32_t start
= layout
->set
[set
].stage
[stage
].sampler_start
;
504 for (uint32_t b
= 0; b
< set_layout
->stage
[stage
].sampler_count
; b
++) {
505 struct anv_sampler
*sampler
=
506 d
->set
->descriptors
[sampler_slots
[b
].index
].sampler
;
511 memcpy(state
->map
+ (start
+ b
) * 16,
512 sampler
->state
, sizeof(sampler
->state
));
520 flush_descriptor_set(struct anv_cmd_buffer
*cmd_buffer
, uint32_t stage
)
522 struct anv_state surfaces
= { 0, }, samplers
= { 0, };
525 result
= anv_cmd_buffer_emit_samplers(cmd_buffer
, stage
, &samplers
);
526 if (result
!= VK_SUCCESS
)
528 result
= anv_cmd_buffer_emit_binding_table(cmd_buffer
, stage
, &surfaces
);
529 if (result
!= VK_SUCCESS
)
532 static const uint32_t sampler_state_opcodes
[] = {
533 [VK_SHADER_STAGE_VERTEX
] = 43,
534 [VK_SHADER_STAGE_TESS_CONTROL
] = 44, /* HS */
535 [VK_SHADER_STAGE_TESS_EVALUATION
] = 45, /* DS */
536 [VK_SHADER_STAGE_GEOMETRY
] = 46,
537 [VK_SHADER_STAGE_FRAGMENT
] = 47,
538 [VK_SHADER_STAGE_COMPUTE
] = 0,
541 static const uint32_t binding_table_opcodes
[] = {
542 [VK_SHADER_STAGE_VERTEX
] = 38,
543 [VK_SHADER_STAGE_TESS_CONTROL
] = 39,
544 [VK_SHADER_STAGE_TESS_EVALUATION
] = 40,
545 [VK_SHADER_STAGE_GEOMETRY
] = 41,
546 [VK_SHADER_STAGE_FRAGMENT
] = 42,
547 [VK_SHADER_STAGE_COMPUTE
] = 0,
550 if (samplers
.alloc_size
> 0) {
551 anv_batch_emit(&cmd_buffer
->batch
,
552 GEN7_3DSTATE_SAMPLER_STATE_POINTERS_VS
,
553 ._3DCommandSubOpcode
= sampler_state_opcodes
[stage
],
554 .PointertoVSSamplerState
= samplers
.offset
);
557 if (surfaces
.alloc_size
> 0) {
558 anv_batch_emit(&cmd_buffer
->batch
,
559 GEN7_3DSTATE_BINDING_TABLE_POINTERS_VS
,
560 ._3DCommandSubOpcode
= binding_table_opcodes
[stage
],
561 .PointertoVSBindingTable
= surfaces
.offset
);
568 anv_flush_descriptor_sets(struct anv_cmd_buffer
*cmd_buffer
)
570 uint32_t s
, dirty
= cmd_buffer
->state
.descriptors_dirty
&
571 cmd_buffer
->state
.pipeline
->active_stages
;
573 VkResult result
= VK_SUCCESS
;
574 for_each_bit(s
, dirty
) {
575 result
= flush_descriptor_set(cmd_buffer
, s
);
576 if (result
!= VK_SUCCESS
)
580 if (result
!= VK_SUCCESS
) {
581 assert(result
== VK_ERROR_OUT_OF_DEVICE_MEMORY
);
583 result
= anv_cmd_buffer_new_binding_table_block(cmd_buffer
);
584 assert(result
== VK_SUCCESS
);
586 /* Re-emit state base addresses so we get the new surface state base
587 * address before we start emitting binding tables etc.
589 anv_cmd_buffer_emit_state_base_address(cmd_buffer
);
591 /* Re-emit all active binding tables */
592 for_each_bit(s
, cmd_buffer
->state
.pipeline
->active_stages
) {
593 result
= flush_descriptor_set(cmd_buffer
, s
);
595 /* It had better succeed this time */
596 assert(result
== VK_SUCCESS
);
600 cmd_buffer
->state
.descriptors_dirty
&= ~cmd_buffer
->state
.pipeline
->active_stages
;
604 anv_cmd_buffer_emit_dynamic(struct anv_cmd_buffer
*cmd_buffer
,
605 uint32_t *a
, uint32_t dwords
, uint32_t alignment
)
607 struct anv_state state
;
609 state
= anv_cmd_buffer_alloc_dynamic_state(cmd_buffer
,
610 dwords
* 4, alignment
);
611 memcpy(state
.map
, a
, dwords
* 4);
613 VG(VALGRIND_CHECK_MEM_IS_DEFINED(state
.map
, dwords
* 4));
619 anv_cmd_buffer_merge_dynamic(struct anv_cmd_buffer
*cmd_buffer
,
620 uint32_t *a
, uint32_t *b
,
621 uint32_t dwords
, uint32_t alignment
)
623 struct anv_state state
;
626 state
= anv_cmd_buffer_alloc_dynamic_state(cmd_buffer
,
627 dwords
* 4, alignment
);
629 for (uint32_t i
= 0; i
< dwords
; i
++)
632 VG(VALGRIND_CHECK_MEM_IS_DEFINED(p
, dwords
* 4));
638 anv_cmd_buffer_begin_subpass(struct anv_cmd_buffer
*cmd_buffer
,
639 struct anv_subpass
*subpass
)
641 switch (cmd_buffer
->device
->info
.gen
) {
643 gen7_cmd_buffer_begin_subpass(cmd_buffer
, subpass
);
646 gen8_cmd_buffer_begin_subpass(cmd_buffer
, subpass
);
649 unreachable("unsupported gen\n");
653 void anv_CmdSetEvent(
654 VkCmdBuffer cmdBuffer
,
656 VkPipelineStageFlags stageMask
)
661 void anv_CmdResetEvent(
662 VkCmdBuffer cmdBuffer
,
664 VkPipelineStageFlags stageMask
)
669 void anv_CmdWaitEvents(
670 VkCmdBuffer cmdBuffer
,
672 const VkEvent
* pEvents
,
673 VkPipelineStageFlags srcStageMask
,
674 VkPipelineStageFlags destStageMask
,
675 uint32_t memBarrierCount
,
676 const void* const* ppMemBarriers
)
682 anv_cmd_buffer_push_constants(struct anv_cmd_buffer
*cmd_buffer
,
685 struct anv_push_constants
*data
=
686 cmd_buffer
->state
.push_constants
[stage
];
687 struct brw_stage_prog_data
*prog_data
=
688 cmd_buffer
->state
.pipeline
->prog_data
[stage
];
690 /* If we don't actually have any push constants, bail. */
691 if (data
== NULL
|| prog_data
->nr_params
== 0)
692 return (struct anv_state
) { .offset
= 0 };
694 struct anv_state state
=
695 anv_cmd_buffer_alloc_dynamic_state(cmd_buffer
,
696 prog_data
->nr_params
* sizeof(float),
697 32 /* bottom 5 bits MBZ */);
699 /* Walk through the param array and fill the buffer with data */
700 uint32_t *u32_map
= state
.map
;
701 for (unsigned i
= 0; i
< prog_data
->nr_params
; i
++) {
702 uint32_t offset
= (uintptr_t)prog_data
->param
[i
];
703 u32_map
[i
] = *(uint32_t *)((uint8_t *)data
+ offset
);
709 void anv_CmdPushConstants(
710 VkCmdBuffer cmdBuffer
,
711 VkPipelineLayout layout
,
712 VkShaderStageFlags stageFlags
,
717 ANV_FROM_HANDLE(anv_cmd_buffer
, cmd_buffer
, cmdBuffer
);
720 for_each_bit(stage
, stageFlags
) {
721 anv_cmd_buffer_ensure_push_constant_field(cmd_buffer
, stage
, client_data
);
723 memcpy(cmd_buffer
->state
.push_constants
[stage
]->client_data
+ start
,
727 cmd_buffer
->state
.push_constants_dirty
|= stageFlags
;
730 void anv_CmdExecuteCommands(
731 VkCmdBuffer cmdBuffer
,
732 uint32_t cmdBuffersCount
,
733 const VkCmdBuffer
* pCmdBuffers
)
735 ANV_FROM_HANDLE(anv_cmd_buffer
, primary
, cmdBuffer
);
737 assert(primary
->level
== VK_CMD_BUFFER_LEVEL_PRIMARY
);
739 anv_assert(primary
->state
.subpass
== &primary
->state
.pass
->subpasses
[0]);
741 for (uint32_t i
= 0; i
< cmdBuffersCount
; i
++) {
742 ANV_FROM_HANDLE(anv_cmd_buffer
, secondary
, pCmdBuffers
[i
]);
744 assert(secondary
->level
== VK_CMD_BUFFER_LEVEL_SECONDARY
);
746 anv_cmd_buffer_add_secondary(primary
, secondary
);
750 VkResult
anv_CreateCommandPool(
752 const VkCmdPoolCreateInfo
* pCreateInfo
,
755 ANV_FROM_HANDLE(anv_device
, device
, _device
);
756 struct anv_cmd_pool
*pool
;
758 pool
= anv_device_alloc(device
, sizeof(*pool
), 8,
759 VK_SYSTEM_ALLOC_TYPE_API_OBJECT
);
761 return vk_error(VK_ERROR_OUT_OF_HOST_MEMORY
);
763 list_inithead(&pool
->cmd_buffers
);
765 *pCmdPool
= anv_cmd_pool_to_handle(pool
);
770 VkResult
anv_DestroyCommandPool(
774 ANV_FROM_HANDLE(anv_device
, device
, _device
);
775 ANV_FROM_HANDLE(anv_cmd_pool
, pool
, cmdPool
);
777 anv_ResetCommandPool(_device
, cmdPool
, 0);
779 anv_device_free(device
, pool
);
784 VkResult
anv_ResetCommandPool(
787 VkCmdPoolResetFlags flags
)
789 ANV_FROM_HANDLE(anv_cmd_pool
, pool
, cmdPool
);
791 list_for_each_entry_safe(struct anv_cmd_buffer
, cmd_buffer
,
792 &pool
->cmd_buffers
, pool_link
) {
793 anv_DestroyCommandBuffer(device
, anv_cmd_buffer_to_handle(cmd_buffer
));
800 * Return NULL if the current subpass has no depthstencil attachment.
802 const struct anv_depth_stencil_view
*
803 anv_cmd_buffer_get_depth_stencil_view(const struct anv_cmd_buffer
*cmd_buffer
)
805 const struct anv_subpass
*subpass
= cmd_buffer
->state
.subpass
;
806 const struct anv_framebuffer
*fb
= cmd_buffer
->state
.framebuffer
;
808 if (subpass
->depth_stencil_attachment
== VK_ATTACHMENT_UNUSED
)
811 const struct anv_attachment_view
*aview
=
812 fb
->attachments
[subpass
->depth_stencil_attachment
];
814 assert(aview
->attachment_type
== ANV_ATTACHMENT_VIEW_TYPE_DEPTH_STENCIL
);
816 return (const struct anv_depth_stencil_view
*) aview
;