vk: Prefix most filenames with anv
[mesa.git] / src / vulkan / anv_cmd_emit.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 /** \file anv_cmd_buffer.c
33 *
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.
39 */
40
41 VkResult
42 anv_cmd_state_init(struct anv_cmd_state *state)
43 {
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
51 state->dirty = 0;
52 state->vb_dirty = 0;
53 state->descriptors_dirty = 0;
54 state->pipeline = NULL;
55 state->vp_state = NULL;
56 state->rs_state = NULL;
57 state->ds_state = NULL;
58
59 return VK_SUCCESS;
60 }
61
62 void
63 anv_cmd_state_fini(struct anv_cmd_state *state)
64 {
65 /* Nothing we need to finish right now */
66 }
67
68 void
69 anv_cmd_buffer_emit_state_base_address(struct anv_cmd_buffer *cmd_buffer)
70 {
71 struct anv_device *device = cmd_buffer->device;
72 struct anv_bo *scratch_bo = NULL;
73
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;
77
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,
84
85 .SurfaceStateBaseAddress = { &cmd_buffer->surface_batch_bo->bo, 0 },
86 .SurfaceStateMemoryObjectControlState = GEN8_MOCS,
87 .SurfaceStateBaseAddressModifyEnable = true,
88
89 .DynamicStateBaseAddress = { &device->dynamic_state_block_pool.bo, 0 },
90 .DynamicStateMemoryObjectControlState = GEN8_MOCS,
91 .DynamicStateBaseAddressModifyEnable = true,
92 .DynamicStateBufferSize = 0xfffff,
93 .DynamicStateBufferSizeModifyEnable = true,
94
95 .IndirectObjectBaseAddress = { NULL, 0 },
96 .IndirectObjectMemoryObjectControlState = GEN8_MOCS,
97 .IndirectObjectBaseAddressModifyEnable = true,
98 .IndirectObjectBufferSize = 0xfffff,
99 .IndirectObjectBufferSizeModifyEnable = true,
100
101 .InstructionBaseAddress = { &device->instruction_block_pool.bo, 0 },
102 .InstructionMemoryObjectControlState = GEN8_MOCS,
103 .InstructionBaseAddressModifyEnable = true,
104 .InstructionBufferSize = 0xfffff,
105 .InstructionBuffersizeModifyEnable = true);
106 }
107
108 VkResult anv_BeginCommandBuffer(
109 VkCmdBuffer cmdBuffer,
110 const VkCmdBufferBeginInfo* pBeginInfo)
111 {
112 ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, cmdBuffer);
113
114 anv_cmd_buffer_emit_state_base_address(cmd_buffer);
115 cmd_buffer->state.current_pipeline = UINT32_MAX;
116
117 return VK_SUCCESS;
118 }
119
120 void anv_CmdBindPipeline(
121 VkCmdBuffer cmdBuffer,
122 VkPipelineBindPoint pipelineBindPoint,
123 VkPipeline _pipeline)
124 {
125 ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, cmdBuffer);
126 ANV_FROM_HANDLE(anv_pipeline, pipeline, _pipeline);
127
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;
132 break;
133
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;
138 break;
139
140 default:
141 assert(!"invalid bind point");
142 break;
143 }
144 }
145
146 void anv_CmdBindDynamicViewportState(
147 VkCmdBuffer cmdBuffer,
148 VkDynamicViewportState dynamicViewportState)
149 {
150 ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, cmdBuffer);
151 ANV_FROM_HANDLE(anv_dynamic_vp_state, vp_state, dynamicViewportState);
152
153 cmd_buffer->state.vp_state = vp_state;
154 cmd_buffer->state.dirty |= ANV_CMD_BUFFER_VP_DIRTY;
155 }
156
157 void anv_CmdBindDynamicRasterState(
158 VkCmdBuffer cmdBuffer,
159 VkDynamicRasterState dynamicRasterState)
160 {
161 ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, cmdBuffer);
162 ANV_FROM_HANDLE(anv_dynamic_rs_state, rs_state, dynamicRasterState);
163
164 cmd_buffer->state.rs_state = rs_state;
165 cmd_buffer->state.dirty |= ANV_CMD_BUFFER_RS_DIRTY;
166 }
167
168 void anv_CmdBindDynamicColorBlendState(
169 VkCmdBuffer cmdBuffer,
170 VkDynamicColorBlendState dynamicColorBlendState)
171 {
172 ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, cmdBuffer);
173 ANV_FROM_HANDLE(anv_dynamic_cb_state, cb_state, dynamicColorBlendState);
174
175 cmd_buffer->state.cb_state = cb_state;
176 cmd_buffer->state.dirty |= ANV_CMD_BUFFER_CB_DIRTY;
177 }
178
179 void anv_CmdBindDynamicDepthStencilState(
180 VkCmdBuffer cmdBuffer,
181 VkDynamicDepthStencilState dynamicDepthStencilState)
182 {
183 ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, cmdBuffer);
184 ANV_FROM_HANDLE(anv_dynamic_ds_state, ds_state, dynamicDepthStencilState);
185
186 cmd_buffer->state.ds_state = ds_state;
187 cmd_buffer->state.dirty |= ANV_CMD_BUFFER_DS_DIRTY;
188 }
189
190 void anv_CmdBindDescriptorSets(
191 VkCmdBuffer cmdBuffer,
192 VkPipelineBindPoint pipelineBindPoint,
193 VkPipelineLayout _layout,
194 uint32_t firstSet,
195 uint32_t setCount,
196 const VkDescriptorSet* pDescriptorSets,
197 uint32_t dynamicOffsetCount,
198 const uint32_t* pDynamicOffsets)
199 {
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;
203
204 assert(firstSet + setCount < MAX_SETS);
205
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;
210
211 cmd_buffer->state.descriptors[firstSet + i].set = set;
212
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));
218
219 cmd_buffer->state.descriptors_dirty |= set_layout->shader_stages;
220
221 dynamic_slot += set_layout->num_dynamic_buffers;
222 }
223 }
224
225 void anv_CmdBindIndexBuffer(
226 VkCmdBuffer cmdBuffer,
227 VkBuffer _buffer,
228 VkDeviceSize offset,
229 VkIndexType indexType)
230 {
231 ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, cmdBuffer);
232 ANV_FROM_HANDLE(anv_buffer, buffer, _buffer);
233
234 static const uint32_t vk_to_gen_index_type[] = {
235 [VK_INDEX_TYPE_UINT16] = INDEX_WORD,
236 [VK_INDEX_TYPE_UINT32] = INDEX_DWORD,
237 };
238
239 struct GEN8_3DSTATE_VF vf = {
240 GEN8_3DSTATE_VF_header,
241 .CutIndex = (indexType == VK_INDEX_TYPE_UINT16) ? UINT16_MAX : UINT32_MAX,
242 };
243 GEN8_3DSTATE_VF_pack(NULL, cmd_buffer->state.state_vf, &vf);
244
245 cmd_buffer->state.dirty |= ANV_CMD_BUFFER_INDEX_BUFFER_DIRTY;
246
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);
252 }
253
254 void anv_CmdBindVertexBuffers(
255 VkCmdBuffer cmdBuffer,
256 uint32_t startBinding,
257 uint32_t bindingCount,
258 const VkBuffer* pBuffers,
259 const VkDeviceSize* pOffsets)
260 {
261 ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, cmdBuffer);
262 struct anv_vertex_binding *vb = cmd_buffer->state.vertex_bindings;
263
264 /* We have to defer setting up vertex buffer since we need the buffer
265 * stride from the pipeline. */
266
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);
272 }
273 }
274
275 static VkResult
276 cmd_buffer_emit_binding_table(struct anv_cmd_buffer *cmd_buffer,
277 unsigned stage, struct anv_state *bt_state)
278 {
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;
283
284 if (stage == VK_SHADER_STAGE_COMPUTE)
285 layout = cmd_buffer->state.compute_pipeline->layout;
286 else
287 layout = cmd_buffer->state.pipeline->layout;
288
289 if (stage == VK_SHADER_STAGE_FRAGMENT) {
290 bias = MAX_RTS;
291 attachments = subpass->color_count;
292 } else {
293 bias = 0;
294 attachments = 0;
295 }
296
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
299 * targets. */
300 uint32_t surface_count = layout ? layout->stage[stage].surface_count : 0;
301
302 if (attachments + surface_count == 0)
303 return VK_SUCCESS;
304
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;
308
309 if (bt_state->map == NULL)
310 return VK_ERROR_OUT_OF_DEVICE_MEMORY;
311
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.
317 */
318 for (uint32_t a = 0; a < attachments; a++) {
319 const struct anv_attachment_view *attachment =
320 fb->attachments[subpass->color_attachments[a]];
321
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;
325
326 struct anv_state state =
327 anv_cmd_buffer_alloc_surface_state(cmd_buffer, 64, 64);
328
329 if (state.map == NULL)
330 return VK_ERROR_OUT_OF_DEVICE_MEMORY;
331
332 memcpy(state.map, view->view.surface_state.map, 64);
333
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,
337 cmd_buffer->device,
338 state.offset + 8 * 4,
339 view->view.bo, view->view.offset);
340
341 bt_map[a] = state.offset;
342 }
343
344 if (layout == NULL)
345 return VK_SUCCESS;
346
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;
352
353 uint32_t start = bias + layout->set[set].surface_start[stage];
354
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;
358
359 if (!view)
360 continue;
361
362 struct anv_state state =
363 anv_cmd_buffer_alloc_surface_state(cmd_buffer, 64, 64);
364
365 if (state.map == NULL)
366 return VK_ERROR_OUT_OF_DEVICE_MEMORY;
367
368 uint32_t offset;
369 if (surface_slots[b].dynamic_slot >= 0) {
370 uint32_t dynamic_offset =
371 d->dynamic_offsets[surface_slots[b].dynamic_slot];
372
373 offset = view->offset + dynamic_offset;
374 anv_fill_buffer_surface_state(state.map, view->format, offset,
375 view->range - dynamic_offset);
376 } else {
377 offset = view->offset;
378 memcpy(state.map, view->surface_state.map, 64);
379 }
380
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,
384 cmd_buffer->device,
385 state.offset + 8 * 4,
386 view->bo, offset);
387
388 bt_map[start + b] = state.offset;
389 }
390 }
391
392 return VK_SUCCESS;
393 }
394
395 static VkResult
396 cmd_buffer_emit_samplers(struct anv_cmd_buffer *cmd_buffer,
397 unsigned stage, struct anv_state *state)
398 {
399 struct anv_pipeline_layout *layout;
400 uint32_t sampler_count;
401
402 if (stage == VK_SHADER_STAGE_COMPUTE)
403 layout = cmd_buffer->state.compute_pipeline->layout;
404 else
405 layout = cmd_buffer->state.pipeline->layout;
406
407 sampler_count = layout ? layout->stage[stage].sampler_count : 0;
408 if (sampler_count == 0)
409 return VK_SUCCESS;
410
411 uint32_t size = sampler_count * 16;
412 *state = anv_cmd_buffer_alloc_dynamic_state(cmd_buffer, size, 32);
413
414 if (state->map == NULL)
415 return VK_ERROR_OUT_OF_DEVICE_MEMORY;
416
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;
422
423 uint32_t start = layout->set[set].sampler_start[stage];
424
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;
428
429 if (!sampler)
430 continue;
431
432 memcpy(state->map + (start + b) * 16,
433 sampler->state, sizeof(sampler->state));
434 }
435 }
436
437 return VK_SUCCESS;
438 }
439
440 static VkResult
441 flush_descriptor_set(struct anv_cmd_buffer *cmd_buffer, uint32_t stage)
442 {
443 struct anv_state surfaces = { 0, }, samplers = { 0, };
444 VkResult result;
445
446 result = cmd_buffer_emit_samplers(cmd_buffer, stage, &samplers);
447 if (result != VK_SUCCESS)
448 return result;
449 result = cmd_buffer_emit_binding_table(cmd_buffer, stage, &surfaces);
450 if (result != VK_SUCCESS)
451 return result;
452
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,
460 };
461
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,
469 };
470
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);
476 }
477
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);
483 }
484
485 return VK_SUCCESS;
486 }
487
488 static void
489 flush_descriptor_sets(struct anv_cmd_buffer *cmd_buffer)
490 {
491 uint32_t s, dirty = cmd_buffer->state.descriptors_dirty &
492 cmd_buffer->state.pipeline->active_stages;
493
494 VkResult result = VK_SUCCESS;
495 for_each_bit(s, dirty) {
496 result = flush_descriptor_set(cmd_buffer, s);
497 if (result != VK_SUCCESS)
498 break;
499 }
500
501 if (result != VK_SUCCESS) {
502 assert(result == VK_ERROR_OUT_OF_DEVICE_MEMORY);
503
504 result = anv_cmd_buffer_new_surface_state_bo(cmd_buffer);
505 assert(result == VK_SUCCESS);
506
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);
510
511 /* It had better succeed this time */
512 assert(result == VK_SUCCESS);
513 }
514 }
515
516 cmd_buffer->state.descriptors_dirty &= ~cmd_buffer->state.pipeline->active_stages;
517 }
518
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)
522 {
523 struct anv_state state;
524
525 state = anv_cmd_buffer_alloc_dynamic_state(cmd_buffer,
526 dwords * 4, alignment);
527 memcpy(state.map, a, dwords * 4);
528
529 VG(VALGRIND_CHECK_MEM_IS_DEFINED(state.map, dwords * 4));
530
531 return state;
532 }
533
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)
538 {
539 struct anv_state state;
540 uint32_t *p;
541
542 state = anv_cmd_buffer_alloc_dynamic_state(cmd_buffer,
543 dwords * 4, alignment);
544 p = state.map;
545 for (uint32_t i = 0; i < dwords; i++)
546 p[i] = a[i] | b[i];
547
548 VG(VALGRIND_CHECK_MEM_IS_DEFINED(p, dwords * 4));
549
550 return state;
551 }
552
553 static VkResult
554 flush_compute_descriptor_set(struct anv_cmd_buffer *cmd_buffer)
555 {
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, };
559 VkResult result;
560
561 result = cmd_buffer_emit_samplers(cmd_buffer,
562 VK_SHADER_STAGE_COMPUTE, &samplers);
563 if (result != VK_SUCCESS)
564 return result;
565 result = cmd_buffer_emit_binding_table(cmd_buffer,
566 VK_SHADER_STAGE_COMPUTE, &surfaces);
567 if (result != VK_SUCCESS)
568 return result;
569
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,
576 .SamplerCount = 0,
577 .NumberofThreadsinGPGPUThreadGroup = 0 /* FIXME: Really? */
578 };
579
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);
583
584 GEN8_INTERFACE_DESCRIPTOR_DATA_pack(NULL, state.map, &desc);
585
586 anv_batch_emit(&cmd_buffer->batch, GEN8_MEDIA_INTERFACE_DESCRIPTOR_LOAD,
587 .InterfaceDescriptorTotalLength = size,
588 .InterfaceDescriptorDataStartAddress = state.offset);
589
590 return VK_SUCCESS;
591 }
592
593 static void
594 anv_cmd_buffer_flush_compute_state(struct anv_cmd_buffer *cmd_buffer)
595 {
596 struct anv_pipeline *pipeline = cmd_buffer->state.compute_pipeline;
597 VkResult result;
598
599 assert(pipeline->active_stages == VK_SHADER_STAGE_COMPUTE_BIT);
600
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;
605 }
606
607 if (cmd_buffer->state.compute_dirty & ANV_CMD_BUFFER_PIPELINE_DIRTY)
608 anv_batch_emit_batch(&cmd_buffer->batch, &pipeline->batch);
609
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;
615 }
616
617 cmd_buffer->state.compute_dirty = 0;
618 }
619
620 static void
621 anv_cmd_buffer_flush_state(struct anv_cmd_buffer *cmd_buffer)
622 {
623 struct anv_pipeline *pipeline = cmd_buffer->state.pipeline;
624 uint32_t *p;
625
626 uint32_t vb_emit = cmd_buffer->state.vb_dirty & pipeline->vb_used;
627
628 assert((pipeline->active_stages & VK_SHADER_STAGE_COMPUTE_BIT) == 0);
629
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;
634 }
635
636 if (vb_emit) {
637 const uint32_t num_buffers = __builtin_popcount(vb_emit);
638 const uint32_t num_dwords = 1 + num_buffers * 4;
639
640 p = anv_batch_emitn(&cmd_buffer->batch, num_dwords,
641 GEN8_3DSTATE_VERTEX_BUFFERS);
642 uint32_t vb, i = 0;
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;
646
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
654 };
655
656 GEN8_VERTEX_BUFFER_STATE_pack(&cmd_buffer->batch, &p[1 + i * 4], &state);
657 i++;
658 }
659 }
660
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);
668
669 anv_batch_emit_batch(&cmd_buffer->batch, &pipeline->batch);
670 }
671
672 if (cmd_buffer->state.descriptors_dirty)
673 flush_descriptor_sets(cmd_buffer);
674
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);
683 }
684
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,
689 pipeline->state_sf);
690 anv_batch_emit_merge(&cmd_buffer->batch,
691 cmd_buffer->state.rs_state->state_raster,
692 pipeline->state_raster);
693 }
694
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);
701 }
702
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);
714 else
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);
719
720 anv_batch_emit(&cmd_buffer->batch,
721 GEN8_3DSTATE_CC_STATE_POINTERS,
722 .ColorCalcStatePointer = state.offset,
723 .ColorCalcStatePointerValid = true);
724 }
725
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);
730 }
731
732 cmd_buffer->state.vb_dirty &= ~vb_emit;
733 cmd_buffer->state.dirty = 0;
734 }
735
736 void anv_CmdDraw(
737 VkCmdBuffer cmdBuffer,
738 uint32_t firstVertex,
739 uint32_t vertexCount,
740 uint32_t firstInstance,
741 uint32_t instanceCount)
742 {
743 ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, cmdBuffer);
744
745 anv_cmd_buffer_flush_state(cmd_buffer);
746
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);
754 }
755
756 void anv_CmdDrawIndexed(
757 VkCmdBuffer cmdBuffer,
758 uint32_t firstIndex,
759 uint32_t indexCount,
760 int32_t vertexOffset,
761 uint32_t firstInstance,
762 uint32_t instanceCount)
763 {
764 ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, cmdBuffer);
765
766 anv_cmd_buffer_flush_state(cmd_buffer);
767
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);
775 }
776
777 static void
778 anv_batch_lrm(struct anv_batch *batch,
779 uint32_t reg, struct anv_bo *bo, uint32_t offset)
780 {
781 anv_batch_emit(batch, GEN8_MI_LOAD_REGISTER_MEM,
782 .RegisterAddress = reg,
783 .MemoryAddress = { bo, offset });
784 }
785
786 static void
787 anv_batch_lri(struct anv_batch *batch, uint32_t reg, uint32_t imm)
788 {
789 anv_batch_emit(batch, GEN8_MI_LOAD_REGISTER_IMM,
790 .RegisterOffset = reg,
791 .DataDWord = imm);
792 }
793
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
801
802 void anv_CmdDrawIndirect(
803 VkCmdBuffer cmdBuffer,
804 VkBuffer _buffer,
805 VkDeviceSize offset,
806 uint32_t count,
807 uint32_t stride)
808 {
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;
813
814 anv_cmd_buffer_flush_state(cmd_buffer);
815
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);
821
822 anv_batch_emit(&cmd_buffer->batch, GEN8_3DPRIMITIVE,
823 .IndirectParameterEnable = true,
824 .VertexAccessType = SEQUENTIAL);
825 }
826
827 void anv_CmdDrawIndexedIndirect(
828 VkCmdBuffer cmdBuffer,
829 VkBuffer _buffer,
830 VkDeviceSize offset,
831 uint32_t count,
832 uint32_t stride)
833 {
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;
838
839 anv_cmd_buffer_flush_state(cmd_buffer);
840
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);
846
847 anv_batch_emit(&cmd_buffer->batch, GEN8_3DPRIMITIVE,
848 .IndirectParameterEnable = true,
849 .VertexAccessType = RANDOM);
850 }
851
852 void anv_CmdDispatch(
853 VkCmdBuffer cmdBuffer,
854 uint32_t x,
855 uint32_t y,
856 uint32_t z)
857 {
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;
861
862 anv_cmd_buffer_flush_compute_state(cmd_buffer);
863
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);
874
875 anv_batch_emit(&cmd_buffer->batch, GEN8_MEDIA_STATE_FLUSH);
876 }
877
878 #define GPGPU_DISPATCHDIMX 0x2500
879 #define GPGPU_DISPATCHDIMY 0x2504
880 #define GPGPU_DISPATCHDIMZ 0x2508
881
882 void anv_CmdDispatchIndirect(
883 VkCmdBuffer cmdBuffer,
884 VkBuffer _buffer,
885 VkDeviceSize offset)
886 {
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;
893
894 anv_cmd_buffer_flush_compute_state(cmd_buffer);
895
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);
899
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);
908
909 anv_batch_emit(&cmd_buffer->batch, GEN8_MEDIA_STATE_FLUSH);
910 }
911
912 void anv_CmdSetEvent(
913 VkCmdBuffer cmdBuffer,
914 VkEvent event,
915 VkPipelineStageFlags stageMask)
916 {
917 stub();
918 }
919
920 void anv_CmdResetEvent(
921 VkCmdBuffer cmdBuffer,
922 VkEvent event,
923 VkPipelineStageFlags stageMask)
924 {
925 stub();
926 }
927
928 void anv_CmdWaitEvents(
929 VkCmdBuffer cmdBuffer,
930 uint32_t eventCount,
931 const VkEvent* pEvents,
932 VkPipelineStageFlags srcStageMask,
933 VkPipelineStageFlags destStageMask,
934 uint32_t memBarrierCount,
935 const void* const* ppMemBarriers)
936 {
937 stub();
938 }
939
940 void anv_CmdPipelineBarrier(
941 VkCmdBuffer cmdBuffer,
942 VkPipelineStageFlags srcStageMask,
943 VkPipelineStageFlags destStageMask,
944 VkBool32 byRegion,
945 uint32_t memBarrierCount,
946 const void* const* ppMemBarriers)
947 {
948 ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, cmdBuffer);
949 uint32_t b, *dw;
950
951 struct GEN8_PIPE_CONTROL cmd = {
952 GEN8_PIPE_CONTROL_header,
953 .PostSyncOperation = NoWrite,
954 };
955
956 /* XXX: I think waitEvent is a no-op on our HW. We should verify that. */
957
958 if (anv_clear_mask(&srcStageMask, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT)) {
959 /* This is just what PIPE_CONTROL does */
960 }
961
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;
974 }
975
976
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;
982 }
983
984 if (anv_clear_mask(&srcStageMask, VK_PIPELINE_STAGE_HOST_BIT)) {
985 anv_finishme("VK_PIPE_EVENT_CPU_SIGNAL_BIT");
986 }
987
988 /* On our hardware, all stages will wait for execution as needed. */
989 (void)destStageMask;
990
991 /* We checked all known VkPipeEventFlags. */
992 anv_assert(srcStageMask == 0);
993
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.
997 */
998 VkMemoryOutputFlags out_flags = 0;
999 VkMemoryInputFlags in_flags = 0;
1000
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;
1008 break;
1009 }
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;
1014 break;
1015 }
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;
1020 break;
1021 }
1022 default:
1023 unreachable("Invalid memory barrier type");
1024 }
1025 }
1026
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;
1033 break;
1034 case VK_MEMORY_OUTPUT_COLOR_ATTACHMENT_BIT:
1035 cmd.RenderTargetCacheFlushEnable = true;
1036 break;
1037 case VK_MEMORY_OUTPUT_DEPTH_STENCIL_ATTACHMENT_BIT:
1038 cmd.DepthCacheFlushEnable = true;
1039 break;
1040 case VK_MEMORY_OUTPUT_TRANSFER_BIT:
1041 cmd.RenderTargetCacheFlushEnable = true;
1042 cmd.DepthCacheFlushEnable = true;
1043 break;
1044 default:
1045 unreachable("Invalid memory output flag");
1046 }
1047 }
1048
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;
1057 break;
1058 case VK_MEMORY_INPUT_UNIFORM_READ_BIT:
1059 cmd.ConstantCacheInvalidationEnable = true;
1060 /* fallthrough */
1061 case VK_MEMORY_INPUT_SHADER_READ_BIT:
1062 cmd.DCFlushEnable = true;
1063 cmd.TextureCacheInvalidationEnable = true;
1064 break;
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;
1070 break;
1071 }
1072 }
1073
1074 dw = anv_batch_emit_dwords(&cmd_buffer->batch, GEN8_PIPE_CONTROL_length);
1075 GEN8_PIPE_CONTROL_pack(&cmd_buffer->batch, dw, &cmd);
1076 }
1077
1078 void anv_CmdPushConstants(
1079 VkCmdBuffer cmdBuffer,
1080 VkPipelineLayout layout,
1081 VkShaderStageFlags stageFlags,
1082 uint32_t start,
1083 uint32_t length,
1084 const void* values)
1085 {
1086 stub();
1087 }
1088
1089 static void
1090 anv_cmd_buffer_emit_depth_stencil(struct anv_cmd_buffer *cmd_buffer)
1091 {
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;
1095
1096 static const struct anv_depth_stencil_view null_view =
1097 { .depth_format = D16_UNORM, .depth_stride = 0, .stencil_stride = 0 };
1098
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;
1104 } else {
1105 view = &null_view;
1106 }
1107
1108 /* FIXME: Implement the PMA stall W/A */
1109 /* FIXME: Width and Height are wrong */
1110
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,
1121 .LOD = 0,
1122 .Depth = 1 - 1,
1123 .MinimumArrayElement = 0,
1124 .DepthBufferObjectControlState = GEN8_MOCS,
1125 .RenderTargetViewExtent = 1 - 1,
1126 .SurfaceQPitch = view->depth_qpitch >> 2);
1127
1128 /* Disable hierarchial depth buffers. */
1129 anv_batch_emit(&cmd_buffer->batch, GEN8_3DSTATE_HIER_DEPTH_BUFFER);
1130
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);
1137
1138 /* Clear the clear params. */
1139 anv_batch_emit(&cmd_buffer->batch, GEN8_3DSTATE_CLEAR_PARAMS);
1140 }
1141
1142 void
1143 anv_cmd_buffer_begin_subpass(struct anv_cmd_buffer *cmd_buffer,
1144 struct anv_subpass *subpass)
1145 {
1146 cmd_buffer->state.subpass = subpass;
1147
1148 cmd_buffer->state.descriptors_dirty |= VK_SHADER_STAGE_FRAGMENT_BIT;
1149
1150 anv_cmd_buffer_emit_depth_stencil(cmd_buffer);
1151 }
1152
1153 void anv_CmdBeginRenderPass(
1154 VkCmdBuffer cmdBuffer,
1155 const VkRenderPassBeginInfo* pRenderPassBegin,
1156 VkRenderPassContents contents)
1157 {
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);
1161
1162 assert(contents == VK_RENDER_PASS_CONTENTS_INLINE);
1163
1164 cmd_buffer->state.framebuffer = framebuffer;
1165 cmd_buffer->state.pass = pass;
1166
1167 const VkRect2D *render_area = &pRenderPassBegin->renderArea;
1168
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);
1178
1179 anv_cmd_buffer_clear_attachments(cmd_buffer, pass,
1180 pRenderPassBegin->pAttachmentClearValues);
1181
1182 anv_cmd_buffer_begin_subpass(cmd_buffer, pass->subpasses);
1183 }
1184
1185 void anv_CmdNextSubpass(
1186 VkCmdBuffer cmdBuffer,
1187 VkRenderPassContents contents)
1188 {
1189 ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, cmdBuffer);
1190
1191 assert(contents == VK_RENDER_PASS_CONTENTS_INLINE);
1192
1193 anv_cmd_buffer_begin_subpass(cmd_buffer, cmd_buffer->state.subpass + 1);
1194 }
1195
1196 void anv_CmdEndRenderPass(
1197 VkCmdBuffer cmdBuffer)
1198 {
1199 ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, cmdBuffer);
1200
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.
1205 */
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);
1214 }
1215
1216 void anv_CmdExecuteCommands(
1217 VkCmdBuffer cmdBuffer,
1218 uint32_t cmdBuffersCount,
1219 const VkCmdBuffer* pCmdBuffers)
1220 {
1221 stub();
1222 }