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
));
53 state
->descriptors_dirty
= 0;
54 state
->pipeline
= NULL
;
55 state
->vp_state
= NULL
;
56 state
->rs_state
= NULL
;
57 state
->ds_state
= NULL
;
63 anv_cmd_state_fini(struct anv_cmd_state
*state
)
65 /* Nothing we need to finish right now */
69 anv_cmd_buffer_emit_state_base_address(struct anv_cmd_buffer
*cmd_buffer
)
71 struct anv_device
*device
= cmd_buffer
->device
;
72 struct anv_bo
*scratch_bo
= NULL
;
74 cmd_buffer
->state
.scratch_size
= device
->scratch_block_pool
.size
;
75 if (cmd_buffer
->state
.scratch_size
> 0)
76 scratch_bo
= &device
->scratch_block_pool
.bo
;
78 anv_batch_emit(&cmd_buffer
->batch
, GEN8_STATE_BASE_ADDRESS
,
79 .GeneralStateBaseAddress
= { scratch_bo
, 0 },
80 .GeneralStateMemoryObjectControlState
= GEN8_MOCS
,
81 .GeneralStateBaseAddressModifyEnable
= true,
82 .GeneralStateBufferSize
= 0xfffff,
83 .GeneralStateBufferSizeModifyEnable
= true,
85 .SurfaceStateBaseAddress
= { &cmd_buffer
->surface_batch_bo
->bo
, 0 },
86 .SurfaceStateMemoryObjectControlState
= GEN8_MOCS
,
87 .SurfaceStateBaseAddressModifyEnable
= true,
89 .DynamicStateBaseAddress
= { &device
->dynamic_state_block_pool
.bo
, 0 },
90 .DynamicStateMemoryObjectControlState
= GEN8_MOCS
,
91 .DynamicStateBaseAddressModifyEnable
= true,
92 .DynamicStateBufferSize
= 0xfffff,
93 .DynamicStateBufferSizeModifyEnable
= true,
95 .IndirectObjectBaseAddress
= { NULL
, 0 },
96 .IndirectObjectMemoryObjectControlState
= GEN8_MOCS
,
97 .IndirectObjectBaseAddressModifyEnable
= true,
98 .IndirectObjectBufferSize
= 0xfffff,
99 .IndirectObjectBufferSizeModifyEnable
= true,
101 .InstructionBaseAddress
= { &device
->instruction_block_pool
.bo
, 0 },
102 .InstructionMemoryObjectControlState
= GEN8_MOCS
,
103 .InstructionBaseAddressModifyEnable
= true,
104 .InstructionBufferSize
= 0xfffff,
105 .InstructionBuffersizeModifyEnable
= true);
108 VkResult
anv_BeginCommandBuffer(
109 VkCmdBuffer cmdBuffer
,
110 const VkCmdBufferBeginInfo
* pBeginInfo
)
112 ANV_FROM_HANDLE(anv_cmd_buffer
, cmd_buffer
, cmdBuffer
);
114 anv_cmd_buffer_emit_state_base_address(cmd_buffer
);
115 cmd_buffer
->state
.current_pipeline
= UINT32_MAX
;
120 void anv_CmdBindPipeline(
121 VkCmdBuffer cmdBuffer
,
122 VkPipelineBindPoint pipelineBindPoint
,
123 VkPipeline _pipeline
)
125 ANV_FROM_HANDLE(anv_cmd_buffer
, cmd_buffer
, cmdBuffer
);
126 ANV_FROM_HANDLE(anv_pipeline
, pipeline
, _pipeline
);
128 switch (pipelineBindPoint
) {
129 case VK_PIPELINE_BIND_POINT_COMPUTE
:
130 cmd_buffer
->state
.compute_pipeline
= pipeline
;
131 cmd_buffer
->state
.compute_dirty
|= ANV_CMD_BUFFER_PIPELINE_DIRTY
;
134 case VK_PIPELINE_BIND_POINT_GRAPHICS
:
135 cmd_buffer
->state
.pipeline
= pipeline
;
136 cmd_buffer
->state
.vb_dirty
|= pipeline
->vb_used
;
137 cmd_buffer
->state
.dirty
|= ANV_CMD_BUFFER_PIPELINE_DIRTY
;
141 assert(!"invalid bind point");
146 void anv_CmdBindDynamicViewportState(
147 VkCmdBuffer cmdBuffer
,
148 VkDynamicViewportState dynamicViewportState
)
150 ANV_FROM_HANDLE(anv_cmd_buffer
, cmd_buffer
, cmdBuffer
);
151 ANV_FROM_HANDLE(anv_dynamic_vp_state
, vp_state
, dynamicViewportState
);
153 cmd_buffer
->state
.vp_state
= vp_state
;
154 cmd_buffer
->state
.dirty
|= ANV_CMD_BUFFER_VP_DIRTY
;
157 void anv_CmdBindDynamicRasterState(
158 VkCmdBuffer cmdBuffer
,
159 VkDynamicRasterState dynamicRasterState
)
161 ANV_FROM_HANDLE(anv_cmd_buffer
, cmd_buffer
, cmdBuffer
);
162 ANV_FROM_HANDLE(anv_dynamic_rs_state
, rs_state
, dynamicRasterState
);
164 cmd_buffer
->state
.rs_state
= rs_state
;
165 cmd_buffer
->state
.dirty
|= ANV_CMD_BUFFER_RS_DIRTY
;
168 void anv_CmdBindDynamicColorBlendState(
169 VkCmdBuffer cmdBuffer
,
170 VkDynamicColorBlendState dynamicColorBlendState
)
172 ANV_FROM_HANDLE(anv_cmd_buffer
, cmd_buffer
, cmdBuffer
);
173 ANV_FROM_HANDLE(anv_dynamic_cb_state
, cb_state
, dynamicColorBlendState
);
175 cmd_buffer
->state
.cb_state
= cb_state
;
176 cmd_buffer
->state
.dirty
|= ANV_CMD_BUFFER_CB_DIRTY
;
179 void anv_CmdBindDynamicDepthStencilState(
180 VkCmdBuffer cmdBuffer
,
181 VkDynamicDepthStencilState dynamicDepthStencilState
)
183 ANV_FROM_HANDLE(anv_cmd_buffer
, cmd_buffer
, cmdBuffer
);
184 ANV_FROM_HANDLE(anv_dynamic_ds_state
, ds_state
, dynamicDepthStencilState
);
186 cmd_buffer
->state
.ds_state
= ds_state
;
187 cmd_buffer
->state
.dirty
|= ANV_CMD_BUFFER_DS_DIRTY
;
190 void anv_CmdBindDescriptorSets(
191 VkCmdBuffer cmdBuffer
,
192 VkPipelineBindPoint pipelineBindPoint
,
193 VkPipelineLayout _layout
,
196 const VkDescriptorSet
* pDescriptorSets
,
197 uint32_t dynamicOffsetCount
,
198 const uint32_t* pDynamicOffsets
)
200 ANV_FROM_HANDLE(anv_cmd_buffer
, cmd_buffer
, cmdBuffer
);
201 ANV_FROM_HANDLE(anv_pipeline_layout
, layout
, _layout
);
202 struct anv_descriptor_set_layout
*set_layout
;
204 assert(firstSet
+ setCount
< MAX_SETS
);
206 uint32_t dynamic_slot
= 0;
207 for (uint32_t i
= 0; i
< setCount
; i
++) {
208 ANV_FROM_HANDLE(anv_descriptor_set
, set
, pDescriptorSets
[i
]);
209 set_layout
= layout
->set
[firstSet
+ i
].layout
;
211 cmd_buffer
->state
.descriptors
[firstSet
+ i
].set
= set
;
213 assert(set_layout
->num_dynamic_buffers
<
214 ARRAY_SIZE(cmd_buffer
->state
.descriptors
[0].dynamic_offsets
));
215 memcpy(cmd_buffer
->state
.descriptors
[firstSet
+ i
].dynamic_offsets
,
216 pDynamicOffsets
+ dynamic_slot
,
217 set_layout
->num_dynamic_buffers
* sizeof(*pDynamicOffsets
));
219 cmd_buffer
->state
.descriptors_dirty
|= set_layout
->shader_stages
;
221 dynamic_slot
+= set_layout
->num_dynamic_buffers
;
225 void anv_CmdBindIndexBuffer(
226 VkCmdBuffer cmdBuffer
,
229 VkIndexType indexType
)
231 ANV_FROM_HANDLE(anv_cmd_buffer
, cmd_buffer
, cmdBuffer
);
232 ANV_FROM_HANDLE(anv_buffer
, buffer
, _buffer
);
234 static const uint32_t vk_to_gen_index_type
[] = {
235 [VK_INDEX_TYPE_UINT16
] = INDEX_WORD
,
236 [VK_INDEX_TYPE_UINT32
] = INDEX_DWORD
,
239 struct GEN8_3DSTATE_VF vf
= {
240 GEN8_3DSTATE_VF_header
,
241 .CutIndex
= (indexType
== VK_INDEX_TYPE_UINT16
) ? UINT16_MAX
: UINT32_MAX
,
243 GEN8_3DSTATE_VF_pack(NULL
, cmd_buffer
->state
.state_vf
, &vf
);
245 cmd_buffer
->state
.dirty
|= ANV_CMD_BUFFER_INDEX_BUFFER_DIRTY
;
247 anv_batch_emit(&cmd_buffer
->batch
, GEN8_3DSTATE_INDEX_BUFFER
,
248 .IndexFormat
= vk_to_gen_index_type
[indexType
],
249 .MemoryObjectControlState
= GEN8_MOCS
,
250 .BufferStartingAddress
= { buffer
->bo
, buffer
->offset
+ offset
},
251 .BufferSize
= buffer
->size
- offset
);
254 void anv_CmdBindVertexBuffers(
255 VkCmdBuffer cmdBuffer
,
256 uint32_t startBinding
,
257 uint32_t bindingCount
,
258 const VkBuffer
* pBuffers
,
259 const VkDeviceSize
* pOffsets
)
261 ANV_FROM_HANDLE(anv_cmd_buffer
, cmd_buffer
, cmdBuffer
);
262 struct anv_vertex_binding
*vb
= cmd_buffer
->state
.vertex_bindings
;
264 /* We have to defer setting up vertex buffer since we need the buffer
265 * stride from the pipeline. */
267 assert(startBinding
+ bindingCount
< MAX_VBS
);
268 for (uint32_t i
= 0; i
< bindingCount
; i
++) {
269 vb
[startBinding
+ i
].buffer
= anv_buffer_from_handle(pBuffers
[i
]);
270 vb
[startBinding
+ i
].offset
= pOffsets
[i
];
271 cmd_buffer
->state
.vb_dirty
|= 1 << (startBinding
+ i
);
276 cmd_buffer_emit_binding_table(struct anv_cmd_buffer
*cmd_buffer
,
277 unsigned stage
, struct anv_state
*bt_state
)
279 struct anv_framebuffer
*fb
= cmd_buffer
->state
.framebuffer
;
280 struct anv_subpass
*subpass
= cmd_buffer
->state
.subpass
;
281 struct anv_pipeline_layout
*layout
;
282 uint32_t attachments
, bias
, size
;
284 if (stage
== VK_SHADER_STAGE_COMPUTE
)
285 layout
= cmd_buffer
->state
.compute_pipeline
->layout
;
287 layout
= cmd_buffer
->state
.pipeline
->layout
;
289 if (stage
== VK_SHADER_STAGE_FRAGMENT
) {
291 attachments
= subpass
->color_count
;
297 /* This is a little awkward: layout can be NULL but we still have to
298 * allocate and set a binding table for the PS stage for render
300 uint32_t surface_count
= layout
? layout
->stage
[stage
].surface_count
: 0;
302 if (attachments
+ surface_count
== 0)
305 size
= (bias
+ surface_count
) * sizeof(uint32_t);
306 *bt_state
= anv_cmd_buffer_alloc_surface_state(cmd_buffer
, size
, 32);
307 uint32_t *bt_map
= bt_state
->map
;
309 if (bt_state
->map
== NULL
)
310 return VK_ERROR_OUT_OF_DEVICE_MEMORY
;
312 /* This is highly annoying. The Vulkan spec puts the depth-stencil
313 * attachments in with the color attachments. Unfortunately, thanks to
314 * other aspects of the API, we cana't really saparate them before this
315 * point. Therefore, we have to walk all of the attachments but only
316 * put the color attachments into the binding table.
318 for (uint32_t a
= 0; a
< attachments
; a
++) {
319 const struct anv_attachment_view
*attachment
=
320 fb
->attachments
[subpass
->color_attachments
[a
]];
322 assert(attachment
->attachment_type
== ANV_ATTACHMENT_VIEW_TYPE_COLOR
);
323 const struct anv_color_attachment_view
*view
=
324 (const struct anv_color_attachment_view
*)attachment
;
326 struct anv_state state
=
327 anv_cmd_buffer_alloc_surface_state(cmd_buffer
, 64, 64);
329 if (state
.map
== NULL
)
330 return VK_ERROR_OUT_OF_DEVICE_MEMORY
;
332 memcpy(state
.map
, view
->view
.surface_state
.map
, 64);
334 /* The address goes in dwords 8 and 9 of the SURFACE_STATE */
335 *(uint64_t *)(state
.map
+ 8 * 4) =
336 anv_reloc_list_add(&cmd_buffer
->surface_relocs
,
338 state
.offset
+ 8 * 4,
339 view
->view
.bo
, view
->view
.offset
);
341 bt_map
[a
] = state
.offset
;
347 for (uint32_t set
= 0; set
< layout
->num_sets
; set
++) {
348 struct anv_descriptor_set_binding
*d
= &cmd_buffer
->state
.descriptors
[set
];
349 struct anv_descriptor_set_layout
*set_layout
= layout
->set
[set
].layout
;
350 struct anv_descriptor_slot
*surface_slots
=
351 set_layout
->stage
[stage
].surface_start
;
353 uint32_t start
= bias
+ layout
->set
[set
].surface_start
[stage
];
355 for (uint32_t b
= 0; b
< set_layout
->stage
[stage
].surface_count
; b
++) {
356 struct anv_surface_view
*view
=
357 d
->set
->descriptors
[surface_slots
[b
].index
].view
;
362 struct anv_state state
=
363 anv_cmd_buffer_alloc_surface_state(cmd_buffer
, 64, 64);
365 if (state
.map
== NULL
)
366 return VK_ERROR_OUT_OF_DEVICE_MEMORY
;
369 if (surface_slots
[b
].dynamic_slot
>= 0) {
370 uint32_t dynamic_offset
=
371 d
->dynamic_offsets
[surface_slots
[b
].dynamic_slot
];
373 offset
= view
->offset
+ dynamic_offset
;
374 anv_fill_buffer_surface_state(state
.map
, view
->format
, offset
,
375 view
->range
- dynamic_offset
);
377 offset
= view
->offset
;
378 memcpy(state
.map
, view
->surface_state
.map
, 64);
381 /* The address goes in dwords 8 and 9 of the SURFACE_STATE */
382 *(uint64_t *)(state
.map
+ 8 * 4) =
383 anv_reloc_list_add(&cmd_buffer
->surface_relocs
,
385 state
.offset
+ 8 * 4,
388 bt_map
[start
+ b
] = state
.offset
;
396 cmd_buffer_emit_samplers(struct anv_cmd_buffer
*cmd_buffer
,
397 unsigned stage
, struct anv_state
*state
)
399 struct anv_pipeline_layout
*layout
;
400 uint32_t sampler_count
;
402 if (stage
== VK_SHADER_STAGE_COMPUTE
)
403 layout
= cmd_buffer
->state
.compute_pipeline
->layout
;
405 layout
= cmd_buffer
->state
.pipeline
->layout
;
407 sampler_count
= layout
? layout
->stage
[stage
].sampler_count
: 0;
408 if (sampler_count
== 0)
411 uint32_t size
= sampler_count
* 16;
412 *state
= anv_cmd_buffer_alloc_dynamic_state(cmd_buffer
, size
, 32);
414 if (state
->map
== NULL
)
415 return VK_ERROR_OUT_OF_DEVICE_MEMORY
;
417 for (uint32_t set
= 0; set
< layout
->num_sets
; set
++) {
418 struct anv_descriptor_set_binding
*d
= &cmd_buffer
->state
.descriptors
[set
];
419 struct anv_descriptor_set_layout
*set_layout
= layout
->set
[set
].layout
;
420 struct anv_descriptor_slot
*sampler_slots
=
421 set_layout
->stage
[stage
].sampler_start
;
423 uint32_t start
= layout
->set
[set
].sampler_start
[stage
];
425 for (uint32_t b
= 0; b
< set_layout
->stage
[stage
].sampler_count
; b
++) {
426 struct anv_sampler
*sampler
=
427 d
->set
->descriptors
[sampler_slots
[b
].index
].sampler
;
432 memcpy(state
->map
+ (start
+ b
) * 16,
433 sampler
->state
, sizeof(sampler
->state
));
441 flush_descriptor_set(struct anv_cmd_buffer
*cmd_buffer
, uint32_t stage
)
443 struct anv_state surfaces
= { 0, }, samplers
= { 0, };
446 result
= cmd_buffer_emit_samplers(cmd_buffer
, stage
, &samplers
);
447 if (result
!= VK_SUCCESS
)
449 result
= cmd_buffer_emit_binding_table(cmd_buffer
, stage
, &surfaces
);
450 if (result
!= VK_SUCCESS
)
453 static const uint32_t sampler_state_opcodes
[] = {
454 [VK_SHADER_STAGE_VERTEX
] = 43,
455 [VK_SHADER_STAGE_TESS_CONTROL
] = 44, /* HS */
456 [VK_SHADER_STAGE_TESS_EVALUATION
] = 45, /* DS */
457 [VK_SHADER_STAGE_GEOMETRY
] = 46,
458 [VK_SHADER_STAGE_FRAGMENT
] = 47,
459 [VK_SHADER_STAGE_COMPUTE
] = 0,
462 static const uint32_t binding_table_opcodes
[] = {
463 [VK_SHADER_STAGE_VERTEX
] = 38,
464 [VK_SHADER_STAGE_TESS_CONTROL
] = 39,
465 [VK_SHADER_STAGE_TESS_EVALUATION
] = 40,
466 [VK_SHADER_STAGE_GEOMETRY
] = 41,
467 [VK_SHADER_STAGE_FRAGMENT
] = 42,
468 [VK_SHADER_STAGE_COMPUTE
] = 0,
471 if (samplers
.alloc_size
> 0) {
472 anv_batch_emit(&cmd_buffer
->batch
,
473 GEN8_3DSTATE_SAMPLER_STATE_POINTERS_VS
,
474 ._3DCommandSubOpcode
= sampler_state_opcodes
[stage
],
475 .PointertoVSSamplerState
= samplers
.offset
);
478 if (surfaces
.alloc_size
> 0) {
479 anv_batch_emit(&cmd_buffer
->batch
,
480 GEN8_3DSTATE_BINDING_TABLE_POINTERS_VS
,
481 ._3DCommandSubOpcode
= binding_table_opcodes
[stage
],
482 .PointertoVSBindingTable
= surfaces
.offset
);
489 flush_descriptor_sets(struct anv_cmd_buffer
*cmd_buffer
)
491 uint32_t s
, dirty
= cmd_buffer
->state
.descriptors_dirty
&
492 cmd_buffer
->state
.pipeline
->active_stages
;
494 VkResult result
= VK_SUCCESS
;
495 for_each_bit(s
, dirty
) {
496 result
= flush_descriptor_set(cmd_buffer
, s
);
497 if (result
!= VK_SUCCESS
)
501 if (result
!= VK_SUCCESS
) {
502 assert(result
== VK_ERROR_OUT_OF_DEVICE_MEMORY
);
504 result
= anv_cmd_buffer_new_surface_state_bo(cmd_buffer
);
505 assert(result
== VK_SUCCESS
);
507 /* Re-emit all active binding tables */
508 for_each_bit(s
, cmd_buffer
->state
.pipeline
->active_stages
) {
509 result
= flush_descriptor_set(cmd_buffer
, s
);
511 /* It had better succeed this time */
512 assert(result
== VK_SUCCESS
);
516 cmd_buffer
->state
.descriptors_dirty
&= ~cmd_buffer
->state
.pipeline
->active_stages
;
519 static struct anv_state
520 anv_cmd_buffer_emit_dynamic(struct anv_cmd_buffer
*cmd_buffer
,
521 uint32_t *a
, uint32_t dwords
, uint32_t alignment
)
523 struct anv_state state
;
525 state
= anv_cmd_buffer_alloc_dynamic_state(cmd_buffer
,
526 dwords
* 4, alignment
);
527 memcpy(state
.map
, a
, dwords
* 4);
529 VG(VALGRIND_CHECK_MEM_IS_DEFINED(state
.map
, dwords
* 4));
534 static struct anv_state
535 anv_cmd_buffer_merge_dynamic(struct anv_cmd_buffer
*cmd_buffer
,
536 uint32_t *a
, uint32_t *b
,
537 uint32_t dwords
, uint32_t alignment
)
539 struct anv_state state
;
542 state
= anv_cmd_buffer_alloc_dynamic_state(cmd_buffer
,
543 dwords
* 4, alignment
);
545 for (uint32_t i
= 0; i
< dwords
; i
++)
548 VG(VALGRIND_CHECK_MEM_IS_DEFINED(p
, dwords
* 4));
554 flush_compute_descriptor_set(struct anv_cmd_buffer
*cmd_buffer
)
556 struct anv_device
*device
= cmd_buffer
->device
;
557 struct anv_pipeline
*pipeline
= cmd_buffer
->state
.compute_pipeline
;
558 struct anv_state surfaces
= { 0, }, samplers
= { 0, };
561 result
= cmd_buffer_emit_samplers(cmd_buffer
,
562 VK_SHADER_STAGE_COMPUTE
, &samplers
);
563 if (result
!= VK_SUCCESS
)
565 result
= cmd_buffer_emit_binding_table(cmd_buffer
,
566 VK_SHADER_STAGE_COMPUTE
, &surfaces
);
567 if (result
!= VK_SUCCESS
)
570 struct GEN8_INTERFACE_DESCRIPTOR_DATA desc
= {
571 .KernelStartPointer
= pipeline
->cs_simd
,
572 .KernelStartPointerHigh
= 0,
573 .BindingTablePointer
= surfaces
.offset
,
574 .BindingTableEntryCount
= 0,
575 .SamplerStatePointer
= samplers
.offset
,
577 .NumberofThreadsinGPGPUThreadGroup
= 0 /* FIXME: Really? */
580 uint32_t size
= GEN8_INTERFACE_DESCRIPTOR_DATA_length
* sizeof(uint32_t);
581 struct anv_state state
=
582 anv_state_pool_alloc(&device
->dynamic_state_pool
, size
, 64);
584 GEN8_INTERFACE_DESCRIPTOR_DATA_pack(NULL
, state
.map
, &desc
);
586 anv_batch_emit(&cmd_buffer
->batch
, GEN8_MEDIA_INTERFACE_DESCRIPTOR_LOAD
,
587 .InterfaceDescriptorTotalLength
= size
,
588 .InterfaceDescriptorDataStartAddress
= state
.offset
);
594 anv_cmd_buffer_flush_compute_state(struct anv_cmd_buffer
*cmd_buffer
)
596 struct anv_pipeline
*pipeline
= cmd_buffer
->state
.compute_pipeline
;
599 assert(pipeline
->active_stages
== VK_SHADER_STAGE_COMPUTE_BIT
);
601 if (cmd_buffer
->state
.current_pipeline
!= GPGPU
) {
602 anv_batch_emit(&cmd_buffer
->batch
, GEN8_PIPELINE_SELECT
,
603 .PipelineSelection
= GPGPU
);
604 cmd_buffer
->state
.current_pipeline
= GPGPU
;
607 if (cmd_buffer
->state
.compute_dirty
& ANV_CMD_BUFFER_PIPELINE_DIRTY
)
608 anv_batch_emit_batch(&cmd_buffer
->batch
, &pipeline
->batch
);
610 if ((cmd_buffer
->state
.descriptors_dirty
& VK_SHADER_STAGE_COMPUTE_BIT
) ||
611 (cmd_buffer
->state
.compute_dirty
& ANV_CMD_BUFFER_PIPELINE_DIRTY
)) {
612 result
= flush_compute_descriptor_set(cmd_buffer
);
613 assert(result
== VK_SUCCESS
);
614 cmd_buffer
->state
.descriptors_dirty
&= ~VK_SHADER_STAGE_COMPUTE
;
617 cmd_buffer
->state
.compute_dirty
= 0;
621 anv_cmd_buffer_flush_state(struct anv_cmd_buffer
*cmd_buffer
)
623 struct anv_pipeline
*pipeline
= cmd_buffer
->state
.pipeline
;
626 uint32_t vb_emit
= cmd_buffer
->state
.vb_dirty
& pipeline
->vb_used
;
628 assert((pipeline
->active_stages
& VK_SHADER_STAGE_COMPUTE_BIT
) == 0);
630 if (cmd_buffer
->state
.current_pipeline
!= _3D
) {
631 anv_batch_emit(&cmd_buffer
->batch
, GEN8_PIPELINE_SELECT
,
632 .PipelineSelection
= _3D
);
633 cmd_buffer
->state
.current_pipeline
= _3D
;
637 const uint32_t num_buffers
= __builtin_popcount(vb_emit
);
638 const uint32_t num_dwords
= 1 + num_buffers
* 4;
640 p
= anv_batch_emitn(&cmd_buffer
->batch
, num_dwords
,
641 GEN8_3DSTATE_VERTEX_BUFFERS
);
643 for_each_bit(vb
, vb_emit
) {
644 struct anv_buffer
*buffer
= cmd_buffer
->state
.vertex_bindings
[vb
].buffer
;
645 uint32_t offset
= cmd_buffer
->state
.vertex_bindings
[vb
].offset
;
647 struct GEN8_VERTEX_BUFFER_STATE state
= {
648 .VertexBufferIndex
= vb
,
649 .MemoryObjectControlState
= GEN8_MOCS
,
650 .AddressModifyEnable
= true,
651 .BufferPitch
= pipeline
->binding_stride
[vb
],
652 .BufferStartingAddress
= { buffer
->bo
, buffer
->offset
+ offset
},
653 .BufferSize
= buffer
->size
- offset
656 GEN8_VERTEX_BUFFER_STATE_pack(&cmd_buffer
->batch
, &p
[1 + i
* 4], &state
);
661 if (cmd_buffer
->state
.dirty
& ANV_CMD_BUFFER_PIPELINE_DIRTY
) {
662 /* If somebody compiled a pipeline after starting a command buffer the
663 * scratch bo may have grown since we started this cmd buffer (and
664 * emitted STATE_BASE_ADDRESS). If we're binding that pipeline now,
665 * reemit STATE_BASE_ADDRESS so that we use the bigger scratch bo. */
666 if (cmd_buffer
->state
.scratch_size
< pipeline
->total_scratch
)
667 anv_cmd_buffer_emit_state_base_address(cmd_buffer
);
669 anv_batch_emit_batch(&cmd_buffer
->batch
, &pipeline
->batch
);
672 if (cmd_buffer
->state
.descriptors_dirty
)
673 flush_descriptor_sets(cmd_buffer
);
675 if (cmd_buffer
->state
.dirty
& ANV_CMD_BUFFER_VP_DIRTY
) {
676 struct anv_dynamic_vp_state
*vp_state
= cmd_buffer
->state
.vp_state
;
677 anv_batch_emit(&cmd_buffer
->batch
, GEN8_3DSTATE_SCISSOR_STATE_POINTERS
,
678 .ScissorRectPointer
= vp_state
->scissor
.offset
);
679 anv_batch_emit(&cmd_buffer
->batch
, GEN8_3DSTATE_VIEWPORT_STATE_POINTERS_CC
,
680 .CCViewportPointer
= vp_state
->cc_vp
.offset
);
681 anv_batch_emit(&cmd_buffer
->batch
, GEN8_3DSTATE_VIEWPORT_STATE_POINTERS_SF_CLIP
,
682 .SFClipViewportPointer
= vp_state
->sf_clip_vp
.offset
);
685 if (cmd_buffer
->state
.dirty
& (ANV_CMD_BUFFER_PIPELINE_DIRTY
|
686 ANV_CMD_BUFFER_RS_DIRTY
)) {
687 anv_batch_emit_merge(&cmd_buffer
->batch
,
688 cmd_buffer
->state
.rs_state
->state_sf
,
690 anv_batch_emit_merge(&cmd_buffer
->batch
,
691 cmd_buffer
->state
.rs_state
->state_raster
,
692 pipeline
->state_raster
);
695 if (cmd_buffer
->state
.ds_state
&&
696 (cmd_buffer
->state
.dirty
& (ANV_CMD_BUFFER_PIPELINE_DIRTY
|
697 ANV_CMD_BUFFER_DS_DIRTY
))) {
698 anv_batch_emit_merge(&cmd_buffer
->batch
,
699 cmd_buffer
->state
.ds_state
->state_wm_depth_stencil
,
700 pipeline
->state_wm_depth_stencil
);
703 if (cmd_buffer
->state
.dirty
& (ANV_CMD_BUFFER_CB_DIRTY
|
704 ANV_CMD_BUFFER_DS_DIRTY
)) {
705 struct anv_state state
;
706 if (cmd_buffer
->state
.ds_state
== NULL
)
707 state
= anv_cmd_buffer_emit_dynamic(cmd_buffer
,
708 cmd_buffer
->state
.cb_state
->state_color_calc
,
709 GEN8_COLOR_CALC_STATE_length
, 64);
710 else if (cmd_buffer
->state
.cb_state
== NULL
)
711 state
= anv_cmd_buffer_emit_dynamic(cmd_buffer
,
712 cmd_buffer
->state
.ds_state
->state_color_calc
,
713 GEN8_COLOR_CALC_STATE_length
, 64);
715 state
= anv_cmd_buffer_merge_dynamic(cmd_buffer
,
716 cmd_buffer
->state
.ds_state
->state_color_calc
,
717 cmd_buffer
->state
.cb_state
->state_color_calc
,
718 GEN8_COLOR_CALC_STATE_length
, 64);
720 anv_batch_emit(&cmd_buffer
->batch
,
721 GEN8_3DSTATE_CC_STATE_POINTERS
,
722 .ColorCalcStatePointer
= state
.offset
,
723 .ColorCalcStatePointerValid
= true);
726 if (cmd_buffer
->state
.dirty
& (ANV_CMD_BUFFER_PIPELINE_DIRTY
|
727 ANV_CMD_BUFFER_INDEX_BUFFER_DIRTY
)) {
728 anv_batch_emit_merge(&cmd_buffer
->batch
,
729 cmd_buffer
->state
.state_vf
, pipeline
->state_vf
);
732 cmd_buffer
->state
.vb_dirty
&= ~vb_emit
;
733 cmd_buffer
->state
.dirty
= 0;
737 VkCmdBuffer cmdBuffer
,
738 uint32_t firstVertex
,
739 uint32_t vertexCount
,
740 uint32_t firstInstance
,
741 uint32_t instanceCount
)
743 ANV_FROM_HANDLE(anv_cmd_buffer
, cmd_buffer
, cmdBuffer
);
745 anv_cmd_buffer_flush_state(cmd_buffer
);
747 anv_batch_emit(&cmd_buffer
->batch
, GEN8_3DPRIMITIVE
,
748 .VertexAccessType
= SEQUENTIAL
,
749 .VertexCountPerInstance
= vertexCount
,
750 .StartVertexLocation
= firstVertex
,
751 .InstanceCount
= instanceCount
,
752 .StartInstanceLocation
= firstInstance
,
753 .BaseVertexLocation
= 0);
756 void anv_CmdDrawIndexed(
757 VkCmdBuffer cmdBuffer
,
760 int32_t vertexOffset
,
761 uint32_t firstInstance
,
762 uint32_t instanceCount
)
764 ANV_FROM_HANDLE(anv_cmd_buffer
, cmd_buffer
, cmdBuffer
);
766 anv_cmd_buffer_flush_state(cmd_buffer
);
768 anv_batch_emit(&cmd_buffer
->batch
, GEN8_3DPRIMITIVE
,
769 .VertexAccessType
= RANDOM
,
770 .VertexCountPerInstance
= indexCount
,
771 .StartVertexLocation
= firstIndex
,
772 .InstanceCount
= instanceCount
,
773 .StartInstanceLocation
= firstInstance
,
774 .BaseVertexLocation
= vertexOffset
);
778 anv_batch_lrm(struct anv_batch
*batch
,
779 uint32_t reg
, struct anv_bo
*bo
, uint32_t offset
)
781 anv_batch_emit(batch
, GEN8_MI_LOAD_REGISTER_MEM
,
782 .RegisterAddress
= reg
,
783 .MemoryAddress
= { bo
, offset
});
787 anv_batch_lri(struct anv_batch
*batch
, uint32_t reg
, uint32_t imm
)
789 anv_batch_emit(batch
, GEN8_MI_LOAD_REGISTER_IMM
,
790 .RegisterOffset
= reg
,
794 /* Auto-Draw / Indirect Registers */
795 #define GEN7_3DPRIM_END_OFFSET 0x2420
796 #define GEN7_3DPRIM_START_VERTEX 0x2430
797 #define GEN7_3DPRIM_VERTEX_COUNT 0x2434
798 #define GEN7_3DPRIM_INSTANCE_COUNT 0x2438
799 #define GEN7_3DPRIM_START_INSTANCE 0x243C
800 #define GEN7_3DPRIM_BASE_VERTEX 0x2440
802 void anv_CmdDrawIndirect(
803 VkCmdBuffer cmdBuffer
,
809 ANV_FROM_HANDLE(anv_cmd_buffer
, cmd_buffer
, cmdBuffer
);
810 ANV_FROM_HANDLE(anv_buffer
, buffer
, _buffer
);
811 struct anv_bo
*bo
= buffer
->bo
;
812 uint32_t bo_offset
= buffer
->offset
+ offset
;
814 anv_cmd_buffer_flush_state(cmd_buffer
);
816 anv_batch_lrm(&cmd_buffer
->batch
, GEN7_3DPRIM_VERTEX_COUNT
, bo
, bo_offset
);
817 anv_batch_lrm(&cmd_buffer
->batch
, GEN7_3DPRIM_INSTANCE_COUNT
, bo
, bo_offset
+ 4);
818 anv_batch_lrm(&cmd_buffer
->batch
, GEN7_3DPRIM_START_VERTEX
, bo
, bo_offset
+ 8);
819 anv_batch_lrm(&cmd_buffer
->batch
, GEN7_3DPRIM_START_INSTANCE
, bo
, bo_offset
+ 12);
820 anv_batch_lri(&cmd_buffer
->batch
, GEN7_3DPRIM_BASE_VERTEX
, 0);
822 anv_batch_emit(&cmd_buffer
->batch
, GEN8_3DPRIMITIVE
,
823 .IndirectParameterEnable
= true,
824 .VertexAccessType
= SEQUENTIAL
);
827 void anv_CmdDrawIndexedIndirect(
828 VkCmdBuffer cmdBuffer
,
834 ANV_FROM_HANDLE(anv_cmd_buffer
, cmd_buffer
, cmdBuffer
);
835 ANV_FROM_HANDLE(anv_buffer
, buffer
, _buffer
);
836 struct anv_bo
*bo
= buffer
->bo
;
837 uint32_t bo_offset
= buffer
->offset
+ offset
;
839 anv_cmd_buffer_flush_state(cmd_buffer
);
841 anv_batch_lrm(&cmd_buffer
->batch
, GEN7_3DPRIM_VERTEX_COUNT
, bo
, bo_offset
);
842 anv_batch_lrm(&cmd_buffer
->batch
, GEN7_3DPRIM_INSTANCE_COUNT
, bo
, bo_offset
+ 4);
843 anv_batch_lrm(&cmd_buffer
->batch
, GEN7_3DPRIM_START_VERTEX
, bo
, bo_offset
+ 8);
844 anv_batch_lrm(&cmd_buffer
->batch
, GEN7_3DPRIM_BASE_VERTEX
, bo
, bo_offset
+ 12);
845 anv_batch_lrm(&cmd_buffer
->batch
, GEN7_3DPRIM_START_INSTANCE
, bo
, bo_offset
+ 16);
847 anv_batch_emit(&cmd_buffer
->batch
, GEN8_3DPRIMITIVE
,
848 .IndirectParameterEnable
= true,
849 .VertexAccessType
= RANDOM
);
852 void anv_CmdDispatch(
853 VkCmdBuffer cmdBuffer
,
858 ANV_FROM_HANDLE(anv_cmd_buffer
, cmd_buffer
, cmdBuffer
);
859 struct anv_pipeline
*pipeline
= cmd_buffer
->state
.compute_pipeline
;
860 struct brw_cs_prog_data
*prog_data
= &pipeline
->cs_prog_data
;
862 anv_cmd_buffer_flush_compute_state(cmd_buffer
);
864 anv_batch_emit(&cmd_buffer
->batch
, GEN8_GPGPU_WALKER
,
865 .SIMDSize
= prog_data
->simd_size
/ 16,
866 .ThreadDepthCounterMaximum
= 0,
867 .ThreadHeightCounterMaximum
= 0,
868 .ThreadWidthCounterMaximum
= pipeline
->cs_thread_width_max
,
869 .ThreadGroupIDXDimension
= x
,
870 .ThreadGroupIDYDimension
= y
,
871 .ThreadGroupIDZDimension
= z
,
872 .RightExecutionMask
= pipeline
->cs_right_mask
,
873 .BottomExecutionMask
= 0xffffffff);
875 anv_batch_emit(&cmd_buffer
->batch
, GEN8_MEDIA_STATE_FLUSH
);
878 #define GPGPU_DISPATCHDIMX 0x2500
879 #define GPGPU_DISPATCHDIMY 0x2504
880 #define GPGPU_DISPATCHDIMZ 0x2508
882 void anv_CmdDispatchIndirect(
883 VkCmdBuffer cmdBuffer
,
887 ANV_FROM_HANDLE(anv_cmd_buffer
, cmd_buffer
, cmdBuffer
);
888 ANV_FROM_HANDLE(anv_buffer
, buffer
, _buffer
);
889 struct anv_pipeline
*pipeline
= cmd_buffer
->state
.compute_pipeline
;
890 struct brw_cs_prog_data
*prog_data
= &pipeline
->cs_prog_data
;
891 struct anv_bo
*bo
= buffer
->bo
;
892 uint32_t bo_offset
= buffer
->offset
+ offset
;
894 anv_cmd_buffer_flush_compute_state(cmd_buffer
);
896 anv_batch_lrm(&cmd_buffer
->batch
, GPGPU_DISPATCHDIMX
, bo
, bo_offset
);
897 anv_batch_lrm(&cmd_buffer
->batch
, GPGPU_DISPATCHDIMY
, bo
, bo_offset
+ 4);
898 anv_batch_lrm(&cmd_buffer
->batch
, GPGPU_DISPATCHDIMZ
, bo
, bo_offset
+ 8);
900 anv_batch_emit(&cmd_buffer
->batch
, GEN8_GPGPU_WALKER
,
901 .IndirectParameterEnable
= true,
902 .SIMDSize
= prog_data
->simd_size
/ 16,
903 .ThreadDepthCounterMaximum
= 0,
904 .ThreadHeightCounterMaximum
= 0,
905 .ThreadWidthCounterMaximum
= pipeline
->cs_thread_width_max
,
906 .RightExecutionMask
= pipeline
->cs_right_mask
,
907 .BottomExecutionMask
= 0xffffffff);
909 anv_batch_emit(&cmd_buffer
->batch
, GEN8_MEDIA_STATE_FLUSH
);
912 void anv_CmdSetEvent(
913 VkCmdBuffer cmdBuffer
,
915 VkPipelineStageFlags stageMask
)
920 void anv_CmdResetEvent(
921 VkCmdBuffer cmdBuffer
,
923 VkPipelineStageFlags stageMask
)
928 void anv_CmdWaitEvents(
929 VkCmdBuffer cmdBuffer
,
931 const VkEvent
* pEvents
,
932 VkPipelineStageFlags srcStageMask
,
933 VkPipelineStageFlags destStageMask
,
934 uint32_t memBarrierCount
,
935 const void* const* ppMemBarriers
)
940 void anv_CmdPipelineBarrier(
941 VkCmdBuffer cmdBuffer
,
942 VkPipelineStageFlags srcStageMask
,
943 VkPipelineStageFlags destStageMask
,
945 uint32_t memBarrierCount
,
946 const void* const* ppMemBarriers
)
948 ANV_FROM_HANDLE(anv_cmd_buffer
, cmd_buffer
, cmdBuffer
);
951 struct GEN8_PIPE_CONTROL cmd
= {
952 GEN8_PIPE_CONTROL_header
,
953 .PostSyncOperation
= NoWrite
,
956 /* XXX: I think waitEvent is a no-op on our HW. We should verify that. */
958 if (anv_clear_mask(&srcStageMask
, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT
)) {
959 /* This is just what PIPE_CONTROL does */
962 if (anv_clear_mask(&srcStageMask
,
963 VK_PIPELINE_STAGE_DRAW_INDIRECT_BIT
|
964 VK_PIPELINE_STAGE_VERTEX_INPUT_BIT
|
965 VK_PIPELINE_STAGE_VERTEX_SHADER_BIT
|
966 VK_PIPELINE_STAGE_TESS_CONTROL_SHADER_BIT
|
967 VK_PIPELINE_STAGE_TESS_EVALUATION_SHADER_BIT
|
968 VK_PIPELINE_STAGE_GEOMETRY_SHADER_BIT
|
969 VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT
|
970 VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT
|
971 VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT
|
972 VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT
)) {
973 cmd
.StallAtPixelScoreboard
= true;
977 if (anv_clear_mask(&srcStageMask
,
978 VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT
|
979 VK_PIPELINE_STAGE_TRANSFER_BIT
|
980 VK_PIPELINE_STAGE_TRANSITION_BIT
)) {
981 cmd
.CommandStreamerStallEnable
= true;
984 if (anv_clear_mask(&srcStageMask
, VK_PIPELINE_STAGE_HOST_BIT
)) {
985 anv_finishme("VK_PIPE_EVENT_CPU_SIGNAL_BIT");
988 /* On our hardware, all stages will wait for execution as needed. */
991 /* We checked all known VkPipeEventFlags. */
992 anv_assert(srcStageMask
== 0);
994 /* XXX: Right now, we're really dumb and just flush whatever categories
995 * the app asks for. One of these days we may make this a bit better
996 * but right now that's all the hardware allows for in most areas.
998 VkMemoryOutputFlags out_flags
= 0;
999 VkMemoryInputFlags in_flags
= 0;
1001 for (uint32_t i
= 0; i
< memBarrierCount
; i
++) {
1002 const struct anv_common
*common
= ppMemBarriers
[i
];
1003 switch (common
->sType
) {
1004 case VK_STRUCTURE_TYPE_MEMORY_BARRIER
: {
1005 ANV_COMMON_TO_STRUCT(VkMemoryBarrier
, barrier
, common
);
1006 out_flags
|= barrier
->outputMask
;
1007 in_flags
|= barrier
->inputMask
;
1010 case VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER
: {
1011 ANV_COMMON_TO_STRUCT(VkBufferMemoryBarrier
, barrier
, common
);
1012 out_flags
|= barrier
->outputMask
;
1013 in_flags
|= barrier
->inputMask
;
1016 case VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER
: {
1017 ANV_COMMON_TO_STRUCT(VkImageMemoryBarrier
, barrier
, common
);
1018 out_flags
|= barrier
->outputMask
;
1019 in_flags
|= barrier
->inputMask
;
1023 unreachable("Invalid memory barrier type");
1027 for_each_bit(b
, out_flags
) {
1028 switch ((VkMemoryOutputFlags
)(1 << b
)) {
1029 case VK_MEMORY_OUTPUT_HOST_WRITE_BIT
:
1030 break; /* FIXME: Little-core systems */
1031 case VK_MEMORY_OUTPUT_SHADER_WRITE_BIT
:
1032 cmd
.DCFlushEnable
= true;
1034 case VK_MEMORY_OUTPUT_COLOR_ATTACHMENT_BIT
:
1035 cmd
.RenderTargetCacheFlushEnable
= true;
1037 case VK_MEMORY_OUTPUT_DEPTH_STENCIL_ATTACHMENT_BIT
:
1038 cmd
.DepthCacheFlushEnable
= true;
1040 case VK_MEMORY_OUTPUT_TRANSFER_BIT
:
1041 cmd
.RenderTargetCacheFlushEnable
= true;
1042 cmd
.DepthCacheFlushEnable
= true;
1045 unreachable("Invalid memory output flag");
1049 for_each_bit(b
, out_flags
) {
1050 switch ((VkMemoryInputFlags
)(1 << b
)) {
1051 case VK_MEMORY_INPUT_HOST_READ_BIT
:
1052 break; /* FIXME: Little-core systems */
1053 case VK_MEMORY_INPUT_INDIRECT_COMMAND_BIT
:
1054 case VK_MEMORY_INPUT_INDEX_FETCH_BIT
:
1055 case VK_MEMORY_INPUT_VERTEX_ATTRIBUTE_FETCH_BIT
:
1056 cmd
.VFCacheInvalidationEnable
= true;
1058 case VK_MEMORY_INPUT_UNIFORM_READ_BIT
:
1059 cmd
.ConstantCacheInvalidationEnable
= true;
1061 case VK_MEMORY_INPUT_SHADER_READ_BIT
:
1062 cmd
.DCFlushEnable
= true;
1063 cmd
.TextureCacheInvalidationEnable
= true;
1065 case VK_MEMORY_INPUT_COLOR_ATTACHMENT_BIT
:
1066 case VK_MEMORY_INPUT_DEPTH_STENCIL_ATTACHMENT_BIT
:
1067 break; /* XXX: Hunh? */
1068 case VK_MEMORY_INPUT_TRANSFER_BIT
:
1069 cmd
.TextureCacheInvalidationEnable
= true;
1074 dw
= anv_batch_emit_dwords(&cmd_buffer
->batch
, GEN8_PIPE_CONTROL_length
);
1075 GEN8_PIPE_CONTROL_pack(&cmd_buffer
->batch
, dw
, &cmd
);
1078 void anv_CmdPushConstants(
1079 VkCmdBuffer cmdBuffer
,
1080 VkPipelineLayout layout
,
1081 VkShaderStageFlags stageFlags
,
1090 anv_cmd_buffer_emit_depth_stencil(struct anv_cmd_buffer
*cmd_buffer
)
1092 struct anv_subpass
*subpass
= cmd_buffer
->state
.subpass
;
1093 struct anv_framebuffer
*fb
= cmd_buffer
->state
.framebuffer
;
1094 const struct anv_depth_stencil_view
*view
;
1096 static const struct anv_depth_stencil_view null_view
=
1097 { .depth_format
= D16_UNORM
, .depth_stride
= 0, .stencil_stride
= 0 };
1099 if (subpass
->depth_stencil_attachment
!= VK_ATTACHMENT_UNUSED
) {
1100 const struct anv_attachment_view
*aview
=
1101 fb
->attachments
[subpass
->depth_stencil_attachment
];
1102 assert(aview
->attachment_type
== ANV_ATTACHMENT_VIEW_TYPE_DEPTH_STENCIL
);
1103 view
= (const struct anv_depth_stencil_view
*)aview
;
1108 /* FIXME: Implement the PMA stall W/A */
1109 /* FIXME: Width and Height are wrong */
1111 anv_batch_emit(&cmd_buffer
->batch
, GEN8_3DSTATE_DEPTH_BUFFER
,
1112 .SurfaceType
= SURFTYPE_2D
,
1113 .DepthWriteEnable
= view
->depth_stride
> 0,
1114 .StencilWriteEnable
= view
->stencil_stride
> 0,
1115 .HierarchicalDepthBufferEnable
= false,
1116 .SurfaceFormat
= view
->depth_format
,
1117 .SurfacePitch
= view
->depth_stride
> 0 ? view
->depth_stride
- 1 : 0,
1118 .SurfaceBaseAddress
= { view
->bo
, view
->depth_offset
},
1119 .Height
= cmd_buffer
->state
.framebuffer
->height
- 1,
1120 .Width
= cmd_buffer
->state
.framebuffer
->width
- 1,
1123 .MinimumArrayElement
= 0,
1124 .DepthBufferObjectControlState
= GEN8_MOCS
,
1125 .RenderTargetViewExtent
= 1 - 1,
1126 .SurfaceQPitch
= view
->depth_qpitch
>> 2);
1128 /* Disable hierarchial depth buffers. */
1129 anv_batch_emit(&cmd_buffer
->batch
, GEN8_3DSTATE_HIER_DEPTH_BUFFER
);
1131 anv_batch_emit(&cmd_buffer
->batch
, GEN8_3DSTATE_STENCIL_BUFFER
,
1132 .StencilBufferEnable
= view
->stencil_stride
> 0,
1133 .StencilBufferObjectControlState
= GEN8_MOCS
,
1134 .SurfacePitch
= view
->stencil_stride
> 0 ? view
->stencil_stride
- 1 : 0,
1135 .SurfaceBaseAddress
= { view
->bo
, view
->stencil_offset
},
1136 .SurfaceQPitch
= view
->stencil_qpitch
>> 2);
1138 /* Clear the clear params. */
1139 anv_batch_emit(&cmd_buffer
->batch
, GEN8_3DSTATE_CLEAR_PARAMS
);
1143 anv_cmd_buffer_begin_subpass(struct anv_cmd_buffer
*cmd_buffer
,
1144 struct anv_subpass
*subpass
)
1146 cmd_buffer
->state
.subpass
= subpass
;
1148 cmd_buffer
->state
.descriptors_dirty
|= VK_SHADER_STAGE_FRAGMENT_BIT
;
1150 anv_cmd_buffer_emit_depth_stencil(cmd_buffer
);
1153 void anv_CmdBeginRenderPass(
1154 VkCmdBuffer cmdBuffer
,
1155 const VkRenderPassBeginInfo
* pRenderPassBegin
,
1156 VkRenderPassContents contents
)
1158 ANV_FROM_HANDLE(anv_cmd_buffer
, cmd_buffer
, cmdBuffer
);
1159 ANV_FROM_HANDLE(anv_render_pass
, pass
, pRenderPassBegin
->renderPass
);
1160 ANV_FROM_HANDLE(anv_framebuffer
, framebuffer
, pRenderPassBegin
->framebuffer
);
1162 assert(contents
== VK_RENDER_PASS_CONTENTS_INLINE
);
1164 cmd_buffer
->state
.framebuffer
= framebuffer
;
1165 cmd_buffer
->state
.pass
= pass
;
1167 const VkRect2D
*render_area
= &pRenderPassBegin
->renderArea
;
1169 anv_batch_emit(&cmd_buffer
->batch
, GEN8_3DSTATE_DRAWING_RECTANGLE
,
1170 .ClippedDrawingRectangleYMin
= render_area
->offset
.y
,
1171 .ClippedDrawingRectangleXMin
= render_area
->offset
.x
,
1172 .ClippedDrawingRectangleYMax
=
1173 render_area
->offset
.y
+ render_area
->extent
.height
- 1,
1174 .ClippedDrawingRectangleXMax
=
1175 render_area
->offset
.x
+ render_area
->extent
.width
- 1,
1176 .DrawingRectangleOriginY
= 0,
1177 .DrawingRectangleOriginX
= 0);
1179 anv_cmd_buffer_clear_attachments(cmd_buffer
, pass
,
1180 pRenderPassBegin
->pAttachmentClearValues
);
1182 anv_cmd_buffer_begin_subpass(cmd_buffer
, pass
->subpasses
);
1185 void anv_CmdNextSubpass(
1186 VkCmdBuffer cmdBuffer
,
1187 VkRenderPassContents contents
)
1189 ANV_FROM_HANDLE(anv_cmd_buffer
, cmd_buffer
, cmdBuffer
);
1191 assert(contents
== VK_RENDER_PASS_CONTENTS_INLINE
);
1193 anv_cmd_buffer_begin_subpass(cmd_buffer
, cmd_buffer
->state
.subpass
+ 1);
1196 void anv_CmdEndRenderPass(
1197 VkCmdBuffer cmdBuffer
)
1199 ANV_FROM_HANDLE(anv_cmd_buffer
, cmd_buffer
, cmdBuffer
);
1201 /* Emit a flushing pipe control at the end of a pass. This is kind of a
1202 * hack but it ensures that render targets always actually get written.
1203 * Eventually, we should do flushing based on image format transitions
1204 * or something of that nature.
1206 anv_batch_emit(&cmd_buffer
->batch
, GEN8_PIPE_CONTROL
,
1207 .PostSyncOperation
= NoWrite
,
1208 .RenderTargetCacheFlushEnable
= true,
1209 .InstructionCacheInvalidateEnable
= true,
1210 .DepthCacheFlushEnable
= true,
1211 .VFCacheInvalidationEnable
= true,
1212 .TextureCacheInvalidationEnable
= true,
1213 .CommandStreamerStallEnable
= true);
1216 void anv_CmdExecuteCommands(
1217 VkCmdBuffer cmdBuffer
,
1218 uint32_t cmdBuffersCount
,
1219 const VkCmdBuffer
* pCmdBuffers
)