vk/surface_view: Add a destructor
[mesa.git] / src / vulkan / device.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 "private.h"
31
32 static int
33 anv_env_get_int(const char *name)
34 {
35 const char *val = getenv(name);
36
37 if (!val)
38 return 0;
39
40 return strtol(val, NULL, 0);
41 }
42
43 static VkResult
44 fill_physical_device(struct anv_physical_device *device,
45 struct anv_instance *instance,
46 const char *path)
47 {
48 int fd;
49
50 fd = open("/dev/dri/renderD128", O_RDWR | O_CLOEXEC);
51 if (fd < 0)
52 return vk_error(VK_ERROR_UNAVAILABLE);
53
54 device->instance = instance;
55 device->path = path;
56
57 device->chipset_id = anv_env_get_int("INTEL_DEVID_OVERRIDE");
58 device->no_hw = false;
59 if (device->chipset_id) {
60 /* INTEL_DEVID_OVERRIDE implies INTEL_NO_HW. */
61 device->no_hw = true;
62 } else {
63 device->chipset_id = anv_gem_get_param(fd, I915_PARAM_CHIPSET_ID);
64 }
65 if (!device->chipset_id)
66 goto fail;
67
68 device->name = brw_get_device_name(device->chipset_id);
69 device->info = brw_get_device_info(device->chipset_id, -1);
70 if (!device->info)
71 goto fail;
72
73 if (!anv_gem_get_param(fd, I915_PARAM_HAS_WAIT_TIMEOUT))
74 goto fail;
75
76 if (!anv_gem_get_param(fd, I915_PARAM_HAS_EXECBUF2))
77 goto fail;
78
79 if (!anv_gem_get_param(fd, I915_PARAM_HAS_LLC))
80 goto fail;
81
82 if (!anv_gem_get_param(fd, I915_PARAM_HAS_EXEC_CONSTANTS))
83 goto fail;
84
85 close(fd);
86
87 return VK_SUCCESS;
88
89 fail:
90 close(fd);
91
92 return vk_error(VK_ERROR_UNAVAILABLE);
93 }
94
95 static void *default_alloc(
96 void* pUserData,
97 size_t size,
98 size_t alignment,
99 VkSystemAllocType allocType)
100 {
101 return malloc(size);
102 }
103
104 static void default_free(
105 void* pUserData,
106 void* pMem)
107 {
108 free(pMem);
109 }
110
111 static const VkAllocCallbacks default_alloc_callbacks = {
112 .pUserData = NULL,
113 .pfnAlloc = default_alloc,
114 .pfnFree = default_free
115 };
116
117 VkResult anv_CreateInstance(
118 const VkInstanceCreateInfo* pCreateInfo,
119 VkInstance* pInstance)
120 {
121 struct anv_instance *instance;
122 const VkAllocCallbacks *alloc_callbacks = &default_alloc_callbacks;
123 void *user_data = NULL;
124 VkResult result;
125
126 assert(pCreateInfo->sType == VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO);
127
128 if (pCreateInfo->pAllocCb) {
129 alloc_callbacks = pCreateInfo->pAllocCb;
130 user_data = pCreateInfo->pAllocCb->pUserData;
131 }
132 instance = alloc_callbacks->pfnAlloc(user_data, sizeof(*instance), 8,
133 VK_SYSTEM_ALLOC_TYPE_API_OBJECT);
134 if (!instance)
135 return vk_error(VK_ERROR_OUT_OF_HOST_MEMORY);
136
137 instance->pAllocUserData = alloc_callbacks->pUserData;
138 instance->pfnAlloc = alloc_callbacks->pfnAlloc;
139 instance->pfnFree = alloc_callbacks->pfnFree;
140 instance->apiVersion = pCreateInfo->pAppInfo->apiVersion;
141
142 instance->physicalDeviceCount = 0;
143 result = fill_physical_device(&instance->physicalDevice,
144 instance, "/dev/dri/renderD128");
145
146 if (result != VK_SUCCESS)
147 return result;
148
149 instance->physicalDeviceCount++;
150 *pInstance = (VkInstance) instance;
151
152 return VK_SUCCESS;
153 }
154
155 VkResult anv_DestroyInstance(
156 VkInstance _instance)
157 {
158 struct anv_instance *instance = (struct anv_instance *) _instance;
159
160 instance->pfnFree(instance->pAllocUserData, instance);
161
162 return VK_SUCCESS;
163 }
164
165 VkResult anv_EnumeratePhysicalDevices(
166 VkInstance _instance,
167 uint32_t* pPhysicalDeviceCount,
168 VkPhysicalDevice* pPhysicalDevices)
169 {
170 struct anv_instance *instance = (struct anv_instance *) _instance;
171
172 if (*pPhysicalDeviceCount >= 1)
173 pPhysicalDevices[0] = (VkPhysicalDevice) &instance->physicalDevice;
174 *pPhysicalDeviceCount = instance->physicalDeviceCount;
175
176 return VK_SUCCESS;
177 }
178
179 VkResult anv_GetPhysicalDeviceInfo(
180 VkPhysicalDevice physicalDevice,
181 VkPhysicalDeviceInfoType infoType,
182 size_t* pDataSize,
183 void* pData)
184 {
185 struct anv_physical_device *device = (struct anv_physical_device *) physicalDevice;
186 VkPhysicalDeviceProperties *properties;
187 VkPhysicalDevicePerformance *performance;
188 VkPhysicalDeviceQueueProperties *queue_properties;
189 VkPhysicalDeviceMemoryProperties *memory_properties;
190 VkDisplayPropertiesWSI *display_properties;
191 uint64_t ns_per_tick = 80;
192
193 switch ((uint32_t) infoType) {
194 case VK_PHYSICAL_DEVICE_INFO_TYPE_PROPERTIES:
195 properties = pData;
196
197 *pDataSize = sizeof(*properties);
198 if (pData == NULL)
199 return VK_SUCCESS;
200
201 properties->apiVersion = 1;
202 properties->driverVersion = 1;
203 properties->vendorId = 0x8086;
204 properties->deviceId = device->chipset_id;
205 properties->deviceType = VK_PHYSICAL_DEVICE_TYPE_INTEGRATED_GPU;
206 strcpy(properties->deviceName, device->name);
207 properties->maxInlineMemoryUpdateSize = 0;
208 properties->maxBoundDescriptorSets = MAX_SETS;
209 properties->maxThreadGroupSize = 512;
210 properties->timestampFrequency = 1000 * 1000 * 1000 / ns_per_tick;
211 properties->multiColorAttachmentClears = true;
212 properties->maxDescriptorSets = 8;
213 properties->maxViewports = 16;
214 properties->maxColorAttachments = 8;
215 return VK_SUCCESS;
216
217 case VK_PHYSICAL_DEVICE_INFO_TYPE_PERFORMANCE:
218 performance = pData;
219
220 *pDataSize = sizeof(*performance);
221 if (pData == NULL)
222 return VK_SUCCESS;
223
224 performance->maxDeviceClock = 1.0;
225 performance->aluPerClock = 1.0;
226 performance->texPerClock = 1.0;
227 performance->primsPerClock = 1.0;
228 performance->pixelsPerClock = 1.0;
229 return VK_SUCCESS;
230
231 case VK_PHYSICAL_DEVICE_INFO_TYPE_QUEUE_PROPERTIES:
232 queue_properties = pData;
233
234 *pDataSize = sizeof(*queue_properties);
235 if (pData == NULL)
236 return VK_SUCCESS;
237
238 queue_properties->queueFlags = 0;
239 queue_properties->queueCount = 1;
240 queue_properties->maxAtomicCounters = 0;
241 queue_properties->supportsTimestamps = true;
242 queue_properties->maxMemReferences = 256;
243 return VK_SUCCESS;
244
245 case VK_PHYSICAL_DEVICE_INFO_TYPE_MEMORY_PROPERTIES:
246 memory_properties = pData;
247
248 *pDataSize = sizeof(*memory_properties);
249 if (pData == NULL)
250 return VK_SUCCESS;
251
252 memory_properties->supportsMigration = false;
253 memory_properties->supportsPinning = false;
254 return VK_SUCCESS;
255
256 case VK_PHYSICAL_DEVICE_INFO_TYPE_DISPLAY_PROPERTIES_WSI:
257 anv_finishme("VK_PHYSICAL_DEVICE_INFO_TYPE_DISPLAY_PROPERTIES_WSI");
258
259 *pDataSize = sizeof(*display_properties);
260 if (pData == NULL)
261 return VK_SUCCESS;
262
263 display_properties = pData;
264 display_properties->display = 0;
265 display_properties->physicalResolution = (VkExtent2D) { 0, 0 };
266 return VK_SUCCESS;
267
268 case VK_PHYSICAL_DEVICE_INFO_TYPE_QUEUE_PRESENT_PROPERTIES_WSI:
269 anv_finishme("VK_PHYSICAL_DEVICE_INFO_TYPE_QUEUE_PRESENT_PROPERTIES_WSI");
270 return VK_SUCCESS;
271
272
273 default:
274 return VK_UNSUPPORTED;
275 }
276
277 }
278
279 void * vkGetProcAddr(
280 VkPhysicalDevice physicalDevice,
281 const char* pName)
282 {
283 return anv_lookup_entrypoint(pName);
284 }
285
286 static void
287 parse_debug_flags(struct anv_device *device)
288 {
289 const char *debug, *p, *end;
290
291 debug = getenv("INTEL_DEBUG");
292 device->dump_aub = false;
293 if (debug) {
294 for (p = debug; *p; p = end + 1) {
295 end = strchrnul(p, ',');
296 if (end - p == 3 && memcmp(p, "aub", 3) == 0)
297 device->dump_aub = true;
298 if (end - p == 5 && memcmp(p, "no_hw", 5) == 0)
299 device->no_hw = true;
300 if (*end == '\0')
301 break;
302 }
303 }
304 }
305
306 static void
307 anv_device_init_border_colors(struct anv_device *device)
308 {
309 float float_border_colors[][4] = {
310 [VK_BORDER_COLOR_OPAQUE_WHITE] = { 1.0, 1.0, 1.0, 1.0 },
311 [VK_BORDER_COLOR_TRANSPARENT_BLACK] = { 0.0, 0.0, 0.0, 0.0 },
312 [VK_BORDER_COLOR_OPAQUE_BLACK] = { 0.0, 0.0, 0.0, 1.0 }
313 };
314
315 uint32_t uint32_border_colors[][4] = {
316 [VK_BORDER_COLOR_OPAQUE_WHITE] = { 1, 1, 1, 1 },
317 [VK_BORDER_COLOR_TRANSPARENT_BLACK] = { 0, 0, 0, 0 },
318 [VK_BORDER_COLOR_OPAQUE_BLACK] = { 0, 0, 0, 1 }
319 };
320
321 device->float_border_colors =
322 anv_state_pool_alloc(&device->dynamic_state_pool,
323 sizeof(float_border_colors), 32);
324 memcpy(device->float_border_colors.map,
325 float_border_colors, sizeof(float_border_colors));
326
327 device->uint32_border_colors =
328 anv_state_pool_alloc(&device->dynamic_state_pool,
329 sizeof(uint32_border_colors), 32);
330 memcpy(device->uint32_border_colors.map,
331 uint32_border_colors, sizeof(uint32_border_colors));
332
333 }
334
335 static const uint32_t BATCH_SIZE = 8192;
336
337 VkResult anv_CreateDevice(
338 VkPhysicalDevice _physicalDevice,
339 const VkDeviceCreateInfo* pCreateInfo,
340 VkDevice* pDevice)
341 {
342 struct anv_physical_device *physicalDevice =
343 (struct anv_physical_device *) _physicalDevice;
344 struct anv_instance *instance = physicalDevice->instance;
345 struct anv_device *device;
346
347 assert(pCreateInfo->sType == VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO);
348
349 device = instance->pfnAlloc(instance->pAllocUserData,
350 sizeof(*device), 8,
351 VK_SYSTEM_ALLOC_TYPE_API_OBJECT);
352 if (!device)
353 return vk_error(VK_ERROR_OUT_OF_HOST_MEMORY);
354
355 device->no_hw = physicalDevice->no_hw;
356 parse_debug_flags(device);
357
358 device->instance = physicalDevice->instance;
359 device->fd = open("/dev/dri/renderD128", O_RDWR | O_CLOEXEC);
360 if (device->fd == -1)
361 goto fail_device;
362
363 device->context_id = anv_gem_create_context(device);
364 if (device->context_id == -1)
365 goto fail_fd;
366
367 anv_bo_pool_init(&device->batch_bo_pool, device, BATCH_SIZE);
368
369 anv_block_pool_init(&device->dynamic_state_block_pool, device, 2048);
370
371 anv_state_pool_init(&device->dynamic_state_pool,
372 &device->dynamic_state_block_pool);
373
374 anv_block_pool_init(&device->instruction_block_pool, device, 2048);
375 anv_block_pool_init(&device->surface_state_block_pool, device, 2048);
376
377 anv_state_pool_init(&device->surface_state_pool,
378 &device->surface_state_block_pool);
379
380 device->info = *physicalDevice->info;
381
382 device->compiler = anv_compiler_create(device);
383 device->aub_writer = NULL;
384
385 pthread_mutex_init(&device->mutex, NULL);
386
387 anv_device_init_meta(device);
388
389 anv_device_init_border_colors(device);
390
391 *pDevice = (VkDevice) device;
392
393 return VK_SUCCESS;
394
395 fail_fd:
396 close(device->fd);
397 fail_device:
398 anv_device_free(device, device);
399
400 return vk_error(VK_ERROR_UNAVAILABLE);
401 }
402
403 VkResult anv_DestroyDevice(
404 VkDevice _device)
405 {
406 struct anv_device *device = (struct anv_device *) _device;
407
408 /* FIXME: We should make device destruction actually safe. */
409 return VK_UNSUPPORTED;
410
411 anv_compiler_destroy(device->compiler);
412
413
414 anv_bo_pool_finish(&device->batch_bo_pool);
415 anv_block_pool_finish(&device->dynamic_state_block_pool);
416 anv_block_pool_finish(&device->instruction_block_pool);
417 anv_block_pool_finish(&device->surface_state_block_pool);
418
419 close(device->fd);
420
421 if (device->aub_writer)
422 anv_aub_writer_destroy(device->aub_writer);
423
424 anv_device_free(device, device);
425
426 return VK_SUCCESS;
427 }
428
429 VkResult anv_GetGlobalExtensionInfo(
430 VkExtensionInfoType infoType,
431 uint32_t extensionIndex,
432 size_t* pDataSize,
433 void* pData)
434 {
435 static const VkExtensionProperties extensions[] = {
436 {
437 .extName = "VK_WSI_LunarG",
438 .version = 3
439 }
440 };
441 uint32_t count = ARRAY_SIZE(extensions);
442
443 switch (infoType) {
444 case VK_EXTENSION_INFO_TYPE_COUNT:
445 memcpy(pData, &count, sizeof(count));
446 *pDataSize = sizeof(count);
447 return VK_SUCCESS;
448
449 case VK_EXTENSION_INFO_TYPE_PROPERTIES:
450 if (extensionIndex >= count)
451 return vk_error(VK_ERROR_INVALID_EXTENSION);
452
453 memcpy(pData, &extensions[extensionIndex], sizeof(extensions[0]));
454 *pDataSize = sizeof(extensions[0]);
455 return VK_SUCCESS;
456
457 default:
458 return VK_UNSUPPORTED;
459 }
460 }
461
462 VkResult anv_GetPhysicalDeviceExtensionInfo(
463 VkPhysicalDevice physicalDevice,
464 VkExtensionInfoType infoType,
465 uint32_t extensionIndex,
466 size_t* pDataSize,
467 void* pData)
468 {
469 uint32_t *count;
470
471 switch (infoType) {
472 case VK_EXTENSION_INFO_TYPE_COUNT:
473 *pDataSize = 4;
474 if (pData == NULL)
475 return VK_SUCCESS;
476
477 count = pData;
478 *count = 0;
479 return VK_SUCCESS;
480
481 case VK_EXTENSION_INFO_TYPE_PROPERTIES:
482 return vk_error(VK_ERROR_INVALID_EXTENSION);
483
484 default:
485 return VK_UNSUPPORTED;
486 }
487 }
488
489 VkResult anv_EnumerateLayers(
490 VkPhysicalDevice physicalDevice,
491 size_t maxStringSize,
492 size_t* pLayerCount,
493 char* const* pOutLayers,
494 void* pReserved)
495 {
496 *pLayerCount = 0;
497
498 return VK_SUCCESS;
499 }
500
501 VkResult anv_GetDeviceQueue(
502 VkDevice _device,
503 uint32_t queueNodeIndex,
504 uint32_t queueIndex,
505 VkQueue* pQueue)
506 {
507 struct anv_device *device = (struct anv_device *) _device;
508 struct anv_queue *queue;
509
510 /* FIXME: Should allocate these at device create time. */
511
512 queue = anv_device_alloc(device, sizeof(*queue), 8,
513 VK_SYSTEM_ALLOC_TYPE_API_OBJECT);
514 if (queue == NULL)
515 return vk_error(VK_ERROR_OUT_OF_HOST_MEMORY);
516
517 queue->device = device;
518 queue->pool = &device->surface_state_pool;
519
520 queue->completed_serial = anv_state_pool_alloc(queue->pool, 4, 4);
521 *(uint32_t *)queue->completed_serial.map = 0;
522 queue->next_serial = 1;
523
524 *pQueue = (VkQueue) queue;
525
526 return VK_SUCCESS;
527 }
528
529 VkResult
530 anv_reloc_list_init(struct anv_reloc_list *list, struct anv_device *device)
531 {
532 list->num_relocs = 0;
533 list->array_length = 256;
534 list->relocs =
535 anv_device_alloc(device, list->array_length * sizeof(*list->relocs), 8,
536 VK_SYSTEM_ALLOC_TYPE_INTERNAL);
537
538 if (list->relocs == NULL)
539 return vk_error(VK_ERROR_OUT_OF_HOST_MEMORY);
540
541 list->reloc_bos =
542 anv_device_alloc(device, list->array_length * sizeof(*list->reloc_bos), 8,
543 VK_SYSTEM_ALLOC_TYPE_INTERNAL);
544
545 if (list->relocs == NULL) {
546 anv_device_free(device, list->relocs);
547 return vk_error(VK_ERROR_OUT_OF_HOST_MEMORY);
548 }
549
550 return VK_SUCCESS;
551 }
552
553 void
554 anv_reloc_list_finish(struct anv_reloc_list *list, struct anv_device *device)
555 {
556 anv_device_free(device, list->relocs);
557 anv_device_free(device, list->reloc_bos);
558 }
559
560 static VkResult
561 anv_reloc_list_grow(struct anv_reloc_list *list, struct anv_device *device,
562 size_t num_additional_relocs)
563 {
564 if (list->num_relocs + num_additional_relocs <= list->array_length)
565 return VK_SUCCESS;
566
567 size_t new_length = list->array_length * 2;
568 while (new_length < list->num_relocs + num_additional_relocs)
569 new_length *= 2;
570
571 struct drm_i915_gem_relocation_entry *new_relocs =
572 anv_device_alloc(device, new_length * sizeof(*list->relocs), 8,
573 VK_SYSTEM_ALLOC_TYPE_INTERNAL);
574 if (new_relocs == NULL)
575 return vk_error(VK_ERROR_OUT_OF_HOST_MEMORY);
576
577 struct anv_bo **new_reloc_bos =
578 anv_device_alloc(device, new_length * sizeof(*list->reloc_bos), 8,
579 VK_SYSTEM_ALLOC_TYPE_INTERNAL);
580 if (new_relocs == NULL) {
581 anv_device_free(device, new_relocs);
582 return vk_error(VK_ERROR_OUT_OF_HOST_MEMORY);
583 }
584
585 memcpy(new_relocs, list->relocs, list->num_relocs * sizeof(*list->relocs));
586 memcpy(new_reloc_bos, list->reloc_bos,
587 list->num_relocs * sizeof(*list->reloc_bos));
588
589 anv_device_free(device, list->relocs);
590 anv_device_free(device, list->reloc_bos);
591
592 list->relocs = new_relocs;
593 list->reloc_bos = new_reloc_bos;
594
595 return VK_SUCCESS;
596 }
597
598 static VkResult
599 anv_batch_bo_create(struct anv_device *device, struct anv_batch_bo **bbo_out)
600 {
601 VkResult result;
602
603 struct anv_batch_bo *bbo =
604 anv_device_alloc(device, sizeof(*bbo), 8, VK_SYSTEM_ALLOC_TYPE_INTERNAL);
605 if (bbo == NULL)
606 return vk_error(VK_ERROR_OUT_OF_HOST_MEMORY);
607
608 bbo->num_relocs = 0;
609 bbo->prev_batch_bo = NULL;
610
611 result = anv_bo_pool_alloc(&device->batch_bo_pool, &bbo->bo);
612 if (result != VK_SUCCESS) {
613 anv_device_free(device, bbo);
614 return result;
615 }
616
617 *bbo_out = bbo;
618
619 return VK_SUCCESS;
620 }
621
622 static void
623 anv_batch_bo_start(struct anv_batch_bo *bbo, struct anv_batch *batch,
624 size_t batch_padding)
625 {
626 batch->next = batch->start = bbo->bo.map;
627 batch->end = bbo->bo.map + bbo->bo.size - batch_padding;
628 bbo->first_reloc = batch->relocs.num_relocs;
629 }
630
631 static void
632 anv_batch_bo_finish(struct anv_batch_bo *bbo, struct anv_batch *batch)
633 {
634 assert(batch->start == bbo->bo.map);
635 bbo->length = batch->next - batch->start;
636 bbo->num_relocs = batch->relocs.num_relocs - bbo->first_reloc;
637 }
638
639 static void
640 anv_batch_bo_destroy(struct anv_batch_bo *bbo, struct anv_device *device)
641 {
642 anv_bo_pool_free(&device->batch_bo_pool, &bbo->bo);
643 anv_device_free(device, bbo);
644 }
645
646 void *
647 anv_batch_emit_dwords(struct anv_batch *batch, int num_dwords)
648 {
649 if (batch->next + num_dwords * 4 > batch->end)
650 batch->extend_cb(batch, batch->user_data);
651
652 void *p = batch->next;
653
654 batch->next += num_dwords * 4;
655 assert(batch->next <= batch->end);
656
657 return p;
658 }
659
660 static void
661 anv_reloc_list_append(struct anv_reloc_list *list, struct anv_device *device,
662 struct anv_reloc_list *other, uint32_t offset)
663 {
664 anv_reloc_list_grow(list, device, other->num_relocs);
665 /* TODO: Handle failure */
666
667 memcpy(&list->relocs[list->num_relocs], &other->relocs[0],
668 other->num_relocs * sizeof(other->relocs[0]));
669 memcpy(&list->reloc_bos[list->num_relocs], &other->reloc_bos[0],
670 other->num_relocs * sizeof(other->reloc_bos[0]));
671
672 for (uint32_t i = 0; i < other->num_relocs; i++)
673 list->relocs[i + list->num_relocs].offset += offset;
674
675 list->num_relocs += other->num_relocs;
676 }
677
678 static uint64_t
679 anv_reloc_list_add(struct anv_reloc_list *list, struct anv_device *device,
680 uint32_t offset, struct anv_bo *target_bo, uint32_t delta)
681 {
682 struct drm_i915_gem_relocation_entry *entry;
683 int index;
684
685 anv_reloc_list_grow(list, device, 1);
686 /* TODO: Handle failure */
687
688 /* XXX: Can we use I915_EXEC_HANDLE_LUT? */
689 index = list->num_relocs++;
690 list->reloc_bos[index] = target_bo;
691 entry = &list->relocs[index];
692 entry->target_handle = target_bo->gem_handle;
693 entry->delta = delta;
694 entry->offset = offset;
695 entry->presumed_offset = target_bo->offset;
696 entry->read_domains = 0;
697 entry->write_domain = 0;
698
699 return target_bo->offset + delta;
700 }
701
702 void
703 anv_batch_emit_batch(struct anv_batch *batch, struct anv_batch *other)
704 {
705 uint32_t size, offset;
706
707 size = other->next - other->start;
708 assert(size % 4 == 0);
709
710 if (batch->next + size > batch->end)
711 batch->extend_cb(batch, batch->user_data);
712
713 assert(batch->next + size <= batch->end);
714
715 memcpy(batch->next, other->start, size);
716
717 offset = batch->next - batch->start;
718 anv_reloc_list_append(&batch->relocs, batch->device,
719 &other->relocs, offset);
720
721 batch->next += size;
722 }
723
724 uint64_t
725 anv_batch_emit_reloc(struct anv_batch *batch,
726 void *location, struct anv_bo *bo, uint32_t delta)
727 {
728 return anv_reloc_list_add(&batch->relocs, batch->device,
729 location - batch->start, bo, delta);
730 }
731
732 VkResult anv_QueueSubmit(
733 VkQueue _queue,
734 uint32_t cmdBufferCount,
735 const VkCmdBuffer* pCmdBuffers,
736 VkFence _fence)
737 {
738 struct anv_queue *queue = (struct anv_queue *) _queue;
739 struct anv_device *device = queue->device;
740 struct anv_fence *fence = (struct anv_fence *) _fence;
741 int ret;
742
743 for (uint32_t i = 0; i < cmdBufferCount; i++) {
744 struct anv_cmd_buffer *cmd_buffer =
745 (struct anv_cmd_buffer *) pCmdBuffers[i];
746
747 if (device->dump_aub)
748 anv_cmd_buffer_dump(cmd_buffer);
749
750 if (!device->no_hw) {
751 ret = anv_gem_execbuffer(device, &cmd_buffer->execbuf);
752 if (ret != 0)
753 return vk_error(VK_ERROR_UNKNOWN);
754
755 if (fence) {
756 ret = anv_gem_execbuffer(device, &fence->execbuf);
757 if (ret != 0)
758 return vk_error(VK_ERROR_UNKNOWN);
759 }
760
761 for (uint32_t i = 0; i < cmd_buffer->bo_count; i++)
762 cmd_buffer->exec2_bos[i]->offset = cmd_buffer->exec2_objects[i].offset;
763 } else {
764 *(uint32_t *)queue->completed_serial.map = cmd_buffer->serial;
765 }
766 }
767
768 return VK_SUCCESS;
769 }
770
771 VkResult anv_QueueAddMemReferences(
772 VkQueue queue,
773 uint32_t count,
774 const VkDeviceMemory* pMems)
775 {
776 return VK_SUCCESS;
777 }
778
779 VkResult anv_QueueRemoveMemReferences(
780 VkQueue queue,
781 uint32_t count,
782 const VkDeviceMemory* pMems)
783 {
784 return VK_SUCCESS;
785 }
786
787 VkResult anv_QueueWaitIdle(
788 VkQueue _queue)
789 {
790 struct anv_queue *queue = (struct anv_queue *) _queue;
791
792 return vkDeviceWaitIdle((VkDevice) queue->device);
793 }
794
795 VkResult anv_DeviceWaitIdle(
796 VkDevice _device)
797 {
798 struct anv_device *device = (struct anv_device *) _device;
799 struct anv_state state;
800 struct anv_batch batch;
801 struct drm_i915_gem_execbuffer2 execbuf;
802 struct drm_i915_gem_exec_object2 exec2_objects[1];
803 struct anv_bo *bo = NULL;
804 VkResult result;
805 int64_t timeout;
806 int ret;
807
808 state = anv_state_pool_alloc(&device->dynamic_state_pool, 32, 32);
809 bo = &device->dynamic_state_pool.block_pool->bo;
810 batch.start = batch.next = state.map;
811 batch.end = state.map + 32;
812 anv_batch_emit(&batch, GEN8_MI_BATCH_BUFFER_END);
813 anv_batch_emit(&batch, GEN8_MI_NOOP);
814
815 exec2_objects[0].handle = bo->gem_handle;
816 exec2_objects[0].relocation_count = 0;
817 exec2_objects[0].relocs_ptr = 0;
818 exec2_objects[0].alignment = 0;
819 exec2_objects[0].offset = bo->offset;
820 exec2_objects[0].flags = 0;
821 exec2_objects[0].rsvd1 = 0;
822 exec2_objects[0].rsvd2 = 0;
823
824 execbuf.buffers_ptr = (uintptr_t) exec2_objects;
825 execbuf.buffer_count = 1;
826 execbuf.batch_start_offset = state.offset;
827 execbuf.batch_len = batch.next - state.map;
828 execbuf.cliprects_ptr = 0;
829 execbuf.num_cliprects = 0;
830 execbuf.DR1 = 0;
831 execbuf.DR4 = 0;
832
833 execbuf.flags =
834 I915_EXEC_HANDLE_LUT | I915_EXEC_NO_RELOC | I915_EXEC_RENDER;
835 execbuf.rsvd1 = device->context_id;
836 execbuf.rsvd2 = 0;
837
838 if (!device->no_hw) {
839 ret = anv_gem_execbuffer(device, &execbuf);
840 if (ret != 0) {
841 result = vk_error(VK_ERROR_UNKNOWN);
842 goto fail;
843 }
844
845 timeout = INT64_MAX;
846 ret = anv_gem_wait(device, bo->gem_handle, &timeout);
847 if (ret != 0) {
848 result = vk_error(VK_ERROR_UNKNOWN);
849 goto fail;
850 }
851 }
852
853 anv_state_pool_free(&device->dynamic_state_pool, state);
854
855 return VK_SUCCESS;
856
857 fail:
858 anv_state_pool_free(&device->dynamic_state_pool, state);
859
860 return result;
861 }
862
863 void *
864 anv_device_alloc(struct anv_device * device,
865 size_t size,
866 size_t alignment,
867 VkSystemAllocType allocType)
868 {
869 return device->instance->pfnAlloc(device->instance->pAllocUserData,
870 size,
871 alignment,
872 allocType);
873 }
874
875 void
876 anv_device_free(struct anv_device * device,
877 void * mem)
878 {
879 return device->instance->pfnFree(device->instance->pAllocUserData,
880 mem);
881 }
882
883 VkResult
884 anv_bo_init_new(struct anv_bo *bo, struct anv_device *device, uint64_t size)
885 {
886 bo->gem_handle = anv_gem_create(device, size);
887 if (!bo->gem_handle)
888 return vk_error(VK_ERROR_OUT_OF_DEVICE_MEMORY);
889
890 bo->map = NULL;
891 bo->index = 0;
892 bo->offset = 0;
893 bo->size = size;
894
895 return VK_SUCCESS;
896 }
897
898 VkResult anv_AllocMemory(
899 VkDevice _device,
900 const VkMemoryAllocInfo* pAllocInfo,
901 VkDeviceMemory* pMem)
902 {
903 struct anv_device *device = (struct anv_device *) _device;
904 struct anv_device_memory *mem;
905 VkResult result;
906
907 assert(pAllocInfo->sType == VK_STRUCTURE_TYPE_MEMORY_ALLOC_INFO);
908
909 mem = anv_device_alloc(device, sizeof(*mem), 8,
910 VK_SYSTEM_ALLOC_TYPE_API_OBJECT);
911 if (mem == NULL)
912 return vk_error(VK_ERROR_OUT_OF_HOST_MEMORY);
913
914 result = anv_bo_init_new(&mem->bo, device, pAllocInfo->allocationSize);
915 if (result != VK_SUCCESS)
916 goto fail;
917
918 *pMem = (VkDeviceMemory) mem;
919
920 return VK_SUCCESS;
921
922 fail:
923 anv_device_free(device, mem);
924
925 return result;
926 }
927
928 VkResult anv_FreeMemory(
929 VkDevice _device,
930 VkDeviceMemory _mem)
931 {
932 struct anv_device *device = (struct anv_device *) _device;
933 struct anv_device_memory *mem = (struct anv_device_memory *) _mem;
934
935 if (mem->bo.map)
936 anv_gem_munmap(mem->bo.map, mem->bo.size);
937
938 if (mem->bo.gem_handle != 0)
939 anv_gem_close(device, mem->bo.gem_handle);
940
941 anv_device_free(device, mem);
942
943 return VK_SUCCESS;
944 }
945
946 VkResult anv_SetMemoryPriority(
947 VkDevice device,
948 VkDeviceMemory mem,
949 VkMemoryPriority priority)
950 {
951 return VK_SUCCESS;
952 }
953
954 VkResult anv_MapMemory(
955 VkDevice _device,
956 VkDeviceMemory _mem,
957 VkDeviceSize offset,
958 VkDeviceSize size,
959 VkMemoryMapFlags flags,
960 void** ppData)
961 {
962 struct anv_device *device = (struct anv_device *) _device;
963 struct anv_device_memory *mem = (struct anv_device_memory *) _mem;
964
965 /* FIXME: Is this supposed to be thread safe? Since vkUnmapMemory() only
966 * takes a VkDeviceMemory pointer, it seems like only one map of the memory
967 * at a time is valid. We could just mmap up front and return an offset
968 * pointer here, but that may exhaust virtual memory on 32 bit
969 * userspace. */
970
971 mem->map = anv_gem_mmap(device, mem->bo.gem_handle, offset, size);
972 mem->map_size = size;
973
974 *ppData = mem->map;
975
976 return VK_SUCCESS;
977 }
978
979 VkResult anv_UnmapMemory(
980 VkDevice _device,
981 VkDeviceMemory _mem)
982 {
983 struct anv_device_memory *mem = (struct anv_device_memory *) _mem;
984
985 anv_gem_munmap(mem->map, mem->map_size);
986
987 return VK_SUCCESS;
988 }
989
990 VkResult anv_FlushMappedMemory(
991 VkDevice device,
992 VkDeviceMemory mem,
993 VkDeviceSize offset,
994 VkDeviceSize size)
995 {
996 /* clflush here for !llc platforms */
997
998 return VK_SUCCESS;
999 }
1000
1001 VkResult anv_PinSystemMemory(
1002 VkDevice device,
1003 const void* pSysMem,
1004 size_t memSize,
1005 VkDeviceMemory* pMem)
1006 {
1007 return VK_SUCCESS;
1008 }
1009
1010 VkResult anv_GetMultiDeviceCompatibility(
1011 VkPhysicalDevice physicalDevice0,
1012 VkPhysicalDevice physicalDevice1,
1013 VkPhysicalDeviceCompatibilityInfo* pInfo)
1014 {
1015 return VK_UNSUPPORTED;
1016 }
1017
1018 VkResult anv_OpenSharedMemory(
1019 VkDevice device,
1020 const VkMemoryOpenInfo* pOpenInfo,
1021 VkDeviceMemory* pMem)
1022 {
1023 return VK_UNSUPPORTED;
1024 }
1025
1026 VkResult anv_OpenSharedSemaphore(
1027 VkDevice device,
1028 const VkSemaphoreOpenInfo* pOpenInfo,
1029 VkSemaphore* pSemaphore)
1030 {
1031 return VK_UNSUPPORTED;
1032 }
1033
1034 VkResult anv_OpenPeerMemory(
1035 VkDevice device,
1036 const VkPeerMemoryOpenInfo* pOpenInfo,
1037 VkDeviceMemory* pMem)
1038 {
1039 return VK_UNSUPPORTED;
1040 }
1041
1042 VkResult anv_OpenPeerImage(
1043 VkDevice device,
1044 const VkPeerImageOpenInfo* pOpenInfo,
1045 VkImage* pImage,
1046 VkDeviceMemory* pMem)
1047 {
1048 return VK_UNSUPPORTED;
1049 }
1050
1051 VkResult anv_DestroyObject(
1052 VkDevice _device,
1053 VkObjectType objType,
1054 VkObject _object)
1055 {
1056 struct anv_device *device = (struct anv_device *) _device;
1057 struct anv_object *object = (struct anv_object *) _object;
1058
1059 switch (objType) {
1060 case VK_OBJECT_TYPE_INSTANCE:
1061 return anv_DestroyInstance((VkInstance) _object);
1062
1063 case VK_OBJECT_TYPE_PHYSICAL_DEVICE:
1064 /* We don't want to actually destroy physical devices */
1065 return VK_SUCCESS;
1066
1067 case VK_OBJECT_TYPE_DEVICE:
1068 assert(_device == (VkDevice) _object);
1069 return anv_DestroyDevice((VkDevice) _object);
1070
1071 case VK_OBJECT_TYPE_QUEUE:
1072 /* TODO */
1073 return VK_SUCCESS;
1074
1075 case VK_OBJECT_TYPE_DEVICE_MEMORY:
1076 return anv_FreeMemory(_device, (VkDeviceMemory) _object);
1077
1078 case VK_OBJECT_TYPE_DESCRIPTOR_POOL:
1079 /* These are just dummys anyway, so we don't need to destroy them */
1080 return VK_SUCCESS;
1081
1082 case VK_OBJECT_TYPE_BUFFER:
1083 case VK_OBJECT_TYPE_IMAGE:
1084 case VK_OBJECT_TYPE_DEPTH_STENCIL_VIEW:
1085 case VK_OBJECT_TYPE_SHADER:
1086 case VK_OBJECT_TYPE_PIPELINE_LAYOUT:
1087 case VK_OBJECT_TYPE_SAMPLER:
1088 case VK_OBJECT_TYPE_DESCRIPTOR_SET:
1089 case VK_OBJECT_TYPE_DESCRIPTOR_SET_LAYOUT:
1090 case VK_OBJECT_TYPE_DYNAMIC_RS_STATE:
1091 case VK_OBJECT_TYPE_DYNAMIC_CB_STATE:
1092 case VK_OBJECT_TYPE_DYNAMIC_DS_STATE:
1093 case VK_OBJECT_TYPE_RENDER_PASS:
1094 /* These are trivially destroyable */
1095 anv_device_free(device, (void *) _object);
1096 return VK_SUCCESS;
1097
1098 case VK_OBJECT_TYPE_COMMAND_BUFFER:
1099 case VK_OBJECT_TYPE_PIPELINE:
1100 case VK_OBJECT_TYPE_DYNAMIC_VP_STATE:
1101 case VK_OBJECT_TYPE_FENCE:
1102 case VK_OBJECT_TYPE_QUERY_POOL:
1103 case VK_OBJECT_TYPE_FRAMEBUFFER:
1104 case VK_OBJECT_TYPE_BUFFER_VIEW:
1105 case VK_OBJECT_TYPE_IMAGE_VIEW:
1106 case VK_OBJECT_TYPE_COLOR_ATTACHMENT_VIEW:
1107 (object->destructor)(device, object, objType);
1108 return VK_SUCCESS;
1109
1110 case VK_OBJECT_TYPE_SEMAPHORE:
1111 case VK_OBJECT_TYPE_EVENT:
1112 stub_return(VK_UNSUPPORTED);
1113
1114 default:
1115 unreachable("Invalid object type");
1116 }
1117 }
1118
1119 static void
1120 fill_memory_requirements(
1121 VkObjectType objType,
1122 VkObject object,
1123 VkMemoryRequirements * memory_requirements)
1124 {
1125 struct anv_buffer *buffer;
1126 struct anv_image *image;
1127
1128 memory_requirements->memPropsAllowed =
1129 VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT |
1130 VK_MEMORY_PROPERTY_HOST_DEVICE_COHERENT_BIT |
1131 /* VK_MEMORY_PROPERTY_HOST_UNCACHED_BIT | */
1132 VK_MEMORY_PROPERTY_HOST_WRITE_COMBINED_BIT |
1133 VK_MEMORY_PROPERTY_PREFER_HOST_LOCAL |
1134 VK_MEMORY_PROPERTY_SHAREABLE_BIT;
1135
1136 memory_requirements->memPropsRequired = 0;
1137
1138 switch (objType) {
1139 case VK_OBJECT_TYPE_BUFFER:
1140 buffer = (struct anv_buffer *) object;
1141 memory_requirements->size = buffer->size;
1142 memory_requirements->alignment = 16;
1143 break;
1144 case VK_OBJECT_TYPE_IMAGE:
1145 image = (struct anv_image *) object;
1146 memory_requirements->size = image->size;
1147 memory_requirements->alignment = image->alignment;
1148 break;
1149 default:
1150 memory_requirements->size = 0;
1151 break;
1152 }
1153 }
1154
1155 static uint32_t
1156 get_allocation_count(VkObjectType objType)
1157 {
1158 switch (objType) {
1159 case VK_OBJECT_TYPE_BUFFER:
1160 case VK_OBJECT_TYPE_IMAGE:
1161 return 1;
1162 default:
1163 return 0;
1164 }
1165 }
1166
1167 VkResult anv_GetObjectInfo(
1168 VkDevice _device,
1169 VkObjectType objType,
1170 VkObject object,
1171 VkObjectInfoType infoType,
1172 size_t* pDataSize,
1173 void* pData)
1174 {
1175 VkMemoryRequirements memory_requirements;
1176 uint32_t *count;
1177
1178 switch (infoType) {
1179 case VK_OBJECT_INFO_TYPE_MEMORY_REQUIREMENTS:
1180 *pDataSize = sizeof(memory_requirements);
1181 if (pData == NULL)
1182 return VK_SUCCESS;
1183
1184 fill_memory_requirements(objType, object, pData);
1185 return VK_SUCCESS;
1186
1187 case VK_OBJECT_INFO_TYPE_MEMORY_ALLOCATION_COUNT:
1188 *pDataSize = sizeof(count);
1189 if (pData == NULL)
1190 return VK_SUCCESS;
1191
1192 count = pData;
1193 *count = get_allocation_count(objType);
1194 return VK_SUCCESS;
1195
1196 default:
1197 return VK_UNSUPPORTED;
1198 }
1199
1200 }
1201
1202 VkResult anv_QueueBindObjectMemory(
1203 VkQueue queue,
1204 VkObjectType objType,
1205 VkObject object,
1206 uint32_t allocationIdx,
1207 VkDeviceMemory _mem,
1208 VkDeviceSize memOffset)
1209 {
1210 struct anv_buffer *buffer;
1211 struct anv_image *image;
1212 struct anv_device_memory *mem = (struct anv_device_memory *) _mem;
1213
1214 switch (objType) {
1215 case VK_OBJECT_TYPE_BUFFER:
1216 buffer = (struct anv_buffer *) object;
1217 buffer->bo = &mem->bo;
1218 buffer->offset = memOffset;
1219 break;
1220 case VK_OBJECT_TYPE_IMAGE:
1221 image = (struct anv_image *) object;
1222 image->bo = &mem->bo;
1223 image->offset = memOffset;
1224 break;
1225 default:
1226 break;
1227 }
1228
1229 return VK_SUCCESS;
1230 }
1231
1232 VkResult anv_QueueBindObjectMemoryRange(
1233 VkQueue queue,
1234 VkObjectType objType,
1235 VkObject object,
1236 uint32_t allocationIdx,
1237 VkDeviceSize rangeOffset,
1238 VkDeviceSize rangeSize,
1239 VkDeviceMemory mem,
1240 VkDeviceSize memOffset)
1241 {
1242 stub_return(VK_UNSUPPORTED);
1243 }
1244
1245 VkResult anv_QueueBindImageMemoryRange(
1246 VkQueue queue,
1247 VkImage image,
1248 uint32_t allocationIdx,
1249 const VkImageMemoryBindInfo* pBindInfo,
1250 VkDeviceMemory mem,
1251 VkDeviceSize memOffset)
1252 {
1253 stub_return(VK_UNSUPPORTED);
1254 }
1255
1256 static void
1257 anv_fence_destroy(struct anv_device *device,
1258 struct anv_object *object,
1259 VkObjectType obj_type)
1260 {
1261 struct anv_fence *fence = (struct anv_fence *) object;
1262
1263 assert(obj_type == VK_OBJECT_TYPE_FENCE);
1264
1265 anv_gem_munmap(fence->bo.map, fence->bo.size);
1266 anv_gem_close(device, fence->bo.gem_handle);
1267 anv_device_free(device, fence);
1268 }
1269
1270 VkResult anv_CreateFence(
1271 VkDevice _device,
1272 const VkFenceCreateInfo* pCreateInfo,
1273 VkFence* pFence)
1274 {
1275 struct anv_device *device = (struct anv_device *) _device;
1276 struct anv_fence *fence;
1277 struct anv_batch batch;
1278 VkResult result;
1279
1280 const uint32_t fence_size = 128;
1281
1282 assert(pCreateInfo->sType == VK_STRUCTURE_TYPE_FENCE_CREATE_INFO);
1283
1284 fence = anv_device_alloc(device, sizeof(*fence), 8,
1285 VK_SYSTEM_ALLOC_TYPE_API_OBJECT);
1286 if (fence == NULL)
1287 return vk_error(VK_ERROR_OUT_OF_HOST_MEMORY);
1288
1289 result = anv_bo_init_new(&fence->bo, device, fence_size);
1290 if (result != VK_SUCCESS)
1291 goto fail;
1292
1293 fence->base.destructor = anv_fence_destroy;
1294
1295 fence->bo.map =
1296 anv_gem_mmap(device, fence->bo.gem_handle, 0, fence->bo.size);
1297 batch.next = batch.start = fence->bo.map;
1298 batch.end = fence->bo.map + fence->bo.size;
1299 anv_batch_emit(&batch, GEN8_MI_BATCH_BUFFER_END);
1300 anv_batch_emit(&batch, GEN8_MI_NOOP);
1301
1302 fence->exec2_objects[0].handle = fence->bo.gem_handle;
1303 fence->exec2_objects[0].relocation_count = 0;
1304 fence->exec2_objects[0].relocs_ptr = 0;
1305 fence->exec2_objects[0].alignment = 0;
1306 fence->exec2_objects[0].offset = fence->bo.offset;
1307 fence->exec2_objects[0].flags = 0;
1308 fence->exec2_objects[0].rsvd1 = 0;
1309 fence->exec2_objects[0].rsvd2 = 0;
1310
1311 fence->execbuf.buffers_ptr = (uintptr_t) fence->exec2_objects;
1312 fence->execbuf.buffer_count = 1;
1313 fence->execbuf.batch_start_offset = 0;
1314 fence->execbuf.batch_len = batch.next - fence->bo.map;
1315 fence->execbuf.cliprects_ptr = 0;
1316 fence->execbuf.num_cliprects = 0;
1317 fence->execbuf.DR1 = 0;
1318 fence->execbuf.DR4 = 0;
1319
1320 fence->execbuf.flags =
1321 I915_EXEC_HANDLE_LUT | I915_EXEC_NO_RELOC | I915_EXEC_RENDER;
1322 fence->execbuf.rsvd1 = device->context_id;
1323 fence->execbuf.rsvd2 = 0;
1324
1325 *pFence = (VkFence) fence;
1326
1327 return VK_SUCCESS;
1328
1329 fail:
1330 anv_device_free(device, fence);
1331
1332 return result;
1333 }
1334
1335 VkResult anv_ResetFences(
1336 VkDevice _device,
1337 uint32_t fenceCount,
1338 VkFence* pFences)
1339 {
1340 struct anv_fence **fences = (struct anv_fence **) pFences;
1341
1342 for (uint32_t i = 0; i < fenceCount; i++)
1343 fences[i]->ready = false;
1344
1345 return VK_SUCCESS;
1346 }
1347
1348 VkResult anv_GetFenceStatus(
1349 VkDevice _device,
1350 VkFence _fence)
1351 {
1352 struct anv_device *device = (struct anv_device *) _device;
1353 struct anv_fence *fence = (struct anv_fence *) _fence;
1354 int64_t t = 0;
1355 int ret;
1356
1357 if (fence->ready)
1358 return VK_SUCCESS;
1359
1360 ret = anv_gem_wait(device, fence->bo.gem_handle, &t);
1361 if (ret == 0) {
1362 fence->ready = true;
1363 return VK_SUCCESS;
1364 }
1365
1366 return VK_NOT_READY;
1367 }
1368
1369 VkResult anv_WaitForFences(
1370 VkDevice _device,
1371 uint32_t fenceCount,
1372 const VkFence* pFences,
1373 bool32_t waitAll,
1374 uint64_t timeout)
1375 {
1376 struct anv_device *device = (struct anv_device *) _device;
1377 struct anv_fence **fences = (struct anv_fence **) pFences;
1378 int64_t t = timeout;
1379 int ret;
1380
1381 /* FIXME: handle !waitAll */
1382
1383 for (uint32_t i = 0; i < fenceCount; i++) {
1384 ret = anv_gem_wait(device, fences[i]->bo.gem_handle, &t);
1385 if (ret == -1 && errno == ETIME)
1386 return VK_TIMEOUT;
1387 else if (ret == -1)
1388 return vk_error(VK_ERROR_UNKNOWN);
1389 }
1390
1391 return VK_SUCCESS;
1392 }
1393
1394 // Queue semaphore functions
1395
1396 VkResult anv_CreateSemaphore(
1397 VkDevice device,
1398 const VkSemaphoreCreateInfo* pCreateInfo,
1399 VkSemaphore* pSemaphore)
1400 {
1401 stub_return(VK_UNSUPPORTED);
1402 }
1403
1404 VkResult anv_QueueSignalSemaphore(
1405 VkQueue queue,
1406 VkSemaphore semaphore)
1407 {
1408 stub_return(VK_UNSUPPORTED);
1409 }
1410
1411 VkResult anv_QueueWaitSemaphore(
1412 VkQueue queue,
1413 VkSemaphore semaphore)
1414 {
1415 stub_return(VK_UNSUPPORTED);
1416 }
1417
1418 // Event functions
1419
1420 VkResult anv_CreateEvent(
1421 VkDevice device,
1422 const VkEventCreateInfo* pCreateInfo,
1423 VkEvent* pEvent)
1424 {
1425 stub_return(VK_UNSUPPORTED);
1426 }
1427
1428 VkResult anv_GetEventStatus(
1429 VkDevice device,
1430 VkEvent event)
1431 {
1432 stub_return(VK_UNSUPPORTED);
1433 }
1434
1435 VkResult anv_SetEvent(
1436 VkDevice device,
1437 VkEvent event)
1438 {
1439 stub_return(VK_UNSUPPORTED);
1440 }
1441
1442 VkResult anv_ResetEvent(
1443 VkDevice device,
1444 VkEvent event)
1445 {
1446 stub_return(VK_UNSUPPORTED);
1447 }
1448
1449 // Buffer functions
1450
1451 VkResult anv_CreateBuffer(
1452 VkDevice _device,
1453 const VkBufferCreateInfo* pCreateInfo,
1454 VkBuffer* pBuffer)
1455 {
1456 struct anv_device *device = (struct anv_device *) _device;
1457 struct anv_buffer *buffer;
1458
1459 assert(pCreateInfo->sType == VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO);
1460
1461 buffer = anv_device_alloc(device, sizeof(*buffer), 8,
1462 VK_SYSTEM_ALLOC_TYPE_API_OBJECT);
1463 if (buffer == NULL)
1464 return vk_error(VK_ERROR_OUT_OF_HOST_MEMORY);
1465
1466 buffer->size = pCreateInfo->size;
1467 buffer->bo = NULL;
1468 buffer->offset = 0;
1469
1470 *pBuffer = (VkBuffer) buffer;
1471
1472 return VK_SUCCESS;
1473 }
1474
1475 // Buffer view functions
1476
1477 static void
1478 fill_buffer_surface_state(void *state, VkFormat format,
1479 uint32_t offset, uint32_t range)
1480 {
1481 const struct anv_format *info;
1482
1483 info = anv_format_for_vk_format(format);
1484 /* This assumes RGBA float format. */
1485 uint32_t stride = 4;
1486 uint32_t num_elements = range / stride;
1487
1488 struct GEN8_RENDER_SURFACE_STATE surface_state = {
1489 .SurfaceType = SURFTYPE_BUFFER,
1490 .SurfaceArray = false,
1491 .SurfaceFormat = info->format,
1492 .SurfaceVerticalAlignment = VALIGN4,
1493 .SurfaceHorizontalAlignment = HALIGN4,
1494 .TileMode = LINEAR,
1495 .VerticalLineStride = 0,
1496 .VerticalLineStrideOffset = 0,
1497 .SamplerL2BypassModeDisable = true,
1498 .RenderCacheReadWriteMode = WriteOnlyCache,
1499 .MemoryObjectControlState = GEN8_MOCS,
1500 .BaseMipLevel = 0,
1501 .SurfaceQPitch = 0,
1502 .Height = (num_elements >> 7) & 0x3fff,
1503 .Width = num_elements & 0x7f,
1504 .Depth = (num_elements >> 21) & 0x3f,
1505 .SurfacePitch = stride - 1,
1506 .MinimumArrayElement = 0,
1507 .NumberofMultisamples = MULTISAMPLECOUNT_1,
1508 .XOffset = 0,
1509 .YOffset = 0,
1510 .SurfaceMinLOD = 0,
1511 .MIPCountLOD = 0,
1512 .AuxiliarySurfaceMode = AUX_NONE,
1513 .RedClearColor = 0,
1514 .GreenClearColor = 0,
1515 .BlueClearColor = 0,
1516 .AlphaClearColor = 0,
1517 .ShaderChannelSelectRed = SCS_RED,
1518 .ShaderChannelSelectGreen = SCS_GREEN,
1519 .ShaderChannelSelectBlue = SCS_BLUE,
1520 .ShaderChannelSelectAlpha = SCS_ALPHA,
1521 .ResourceMinLOD = 0,
1522 /* FIXME: We assume that the image must be bound at this time. */
1523 .SurfaceBaseAddress = { NULL, offset },
1524 };
1525
1526 GEN8_RENDER_SURFACE_STATE_pack(NULL, state, &surface_state);
1527 }
1528
1529 VkResult anv_CreateBufferView(
1530 VkDevice _device,
1531 const VkBufferViewCreateInfo* pCreateInfo,
1532 VkBufferView* pView)
1533 {
1534 struct anv_device *device = (struct anv_device *) _device;
1535 struct anv_buffer *buffer = (struct anv_buffer *) pCreateInfo->buffer;
1536 struct anv_surface_view *view;
1537
1538 assert(pCreateInfo->sType == VK_STRUCTURE_TYPE_BUFFER_VIEW_CREATE_INFO);
1539
1540 view = anv_device_alloc(device, sizeof(*view), 8,
1541 VK_SYSTEM_ALLOC_TYPE_API_OBJECT);
1542 if (view == NULL)
1543 return vk_error(VK_ERROR_OUT_OF_HOST_MEMORY);
1544
1545 view->base.destructor = anv_surface_view_destroy;
1546
1547 view->bo = buffer->bo;
1548 view->offset = buffer->offset + pCreateInfo->offset;
1549 view->surface_state =
1550 anv_state_pool_alloc(&device->surface_state_pool, 64, 64);
1551 view->format = pCreateInfo->format;
1552 view->range = pCreateInfo->range;
1553
1554 fill_buffer_surface_state(view->surface_state.map,
1555 pCreateInfo->format, view->offset, pCreateInfo->range);
1556
1557 *pView = (VkBufferView) view;
1558
1559 return VK_SUCCESS;
1560 }
1561
1562 // Sampler functions
1563
1564 VkResult anv_CreateSampler(
1565 VkDevice _device,
1566 const VkSamplerCreateInfo* pCreateInfo,
1567 VkSampler* pSampler)
1568 {
1569 struct anv_device *device = (struct anv_device *) _device;
1570 struct anv_sampler *sampler;
1571 uint32_t mag_filter, min_filter, max_anisotropy;
1572
1573 assert(pCreateInfo->sType == VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO);
1574
1575 sampler = anv_device_alloc(device, sizeof(*sampler), 8,
1576 VK_SYSTEM_ALLOC_TYPE_API_OBJECT);
1577 if (!sampler)
1578 return vk_error(VK_ERROR_OUT_OF_HOST_MEMORY);
1579
1580 static const uint32_t vk_to_gen_tex_filter[] = {
1581 [VK_TEX_FILTER_NEAREST] = MAPFILTER_NEAREST,
1582 [VK_TEX_FILTER_LINEAR] = MAPFILTER_LINEAR
1583 };
1584
1585 static const uint32_t vk_to_gen_mipmap_mode[] = {
1586 [VK_TEX_MIPMAP_MODE_BASE] = MIPFILTER_NONE,
1587 [VK_TEX_MIPMAP_MODE_NEAREST] = MIPFILTER_NEAREST,
1588 [VK_TEX_MIPMAP_MODE_LINEAR] = MIPFILTER_LINEAR
1589 };
1590
1591 static const uint32_t vk_to_gen_tex_address[] = {
1592 [VK_TEX_ADDRESS_WRAP] = TCM_WRAP,
1593 [VK_TEX_ADDRESS_MIRROR] = TCM_MIRROR,
1594 [VK_TEX_ADDRESS_CLAMP] = TCM_CLAMP,
1595 [VK_TEX_ADDRESS_MIRROR_ONCE] = TCM_MIRROR_ONCE,
1596 [VK_TEX_ADDRESS_CLAMP_BORDER] = TCM_CLAMP_BORDER,
1597 };
1598
1599 static const uint32_t vk_to_gen_compare_op[] = {
1600 [VK_COMPARE_OP_NEVER] = PREFILTEROPNEVER,
1601 [VK_COMPARE_OP_LESS] = PREFILTEROPLESS,
1602 [VK_COMPARE_OP_EQUAL] = PREFILTEROPEQUAL,
1603 [VK_COMPARE_OP_LESS_EQUAL] = PREFILTEROPLEQUAL,
1604 [VK_COMPARE_OP_GREATER] = PREFILTEROPGREATER,
1605 [VK_COMPARE_OP_NOT_EQUAL] = PREFILTEROPNOTEQUAL,
1606 [VK_COMPARE_OP_GREATER_EQUAL] = PREFILTEROPGEQUAL,
1607 [VK_COMPARE_OP_ALWAYS] = PREFILTEROPALWAYS,
1608 };
1609
1610 if (pCreateInfo->maxAnisotropy > 1) {
1611 mag_filter = MAPFILTER_ANISOTROPIC;
1612 min_filter = MAPFILTER_ANISOTROPIC;
1613 max_anisotropy = (pCreateInfo->maxAnisotropy - 2) / 2;
1614 } else {
1615 mag_filter = vk_to_gen_tex_filter[pCreateInfo->magFilter];
1616 min_filter = vk_to_gen_tex_filter[pCreateInfo->minFilter];
1617 max_anisotropy = RATIO21;
1618 }
1619
1620 struct GEN8_SAMPLER_STATE sampler_state = {
1621 .SamplerDisable = false,
1622 .TextureBorderColorMode = DX10OGL,
1623 .LODPreClampMode = 0,
1624 .BaseMipLevel = 0,
1625 .MipModeFilter = vk_to_gen_mipmap_mode[pCreateInfo->mipMode],
1626 .MagModeFilter = mag_filter,
1627 .MinModeFilter = min_filter,
1628 .TextureLODBias = pCreateInfo->mipLodBias * 256,
1629 .AnisotropicAlgorithm = EWAApproximation,
1630 .MinLOD = pCreateInfo->minLod * 256,
1631 .MaxLOD = pCreateInfo->maxLod * 256,
1632 .ChromaKeyEnable = 0,
1633 .ChromaKeyIndex = 0,
1634 .ChromaKeyMode = 0,
1635 .ShadowFunction = vk_to_gen_compare_op[pCreateInfo->compareOp],
1636 .CubeSurfaceControlMode = 0,
1637
1638 .IndirectStatePointer =
1639 device->float_border_colors.offset +
1640 pCreateInfo->borderColor * sizeof(float) * 4,
1641
1642 .LODClampMagnificationMode = MIPNONE,
1643 .MaximumAnisotropy = max_anisotropy,
1644 .RAddressMinFilterRoundingEnable = 0,
1645 .RAddressMagFilterRoundingEnable = 0,
1646 .VAddressMinFilterRoundingEnable = 0,
1647 .VAddressMagFilterRoundingEnable = 0,
1648 .UAddressMinFilterRoundingEnable = 0,
1649 .UAddressMagFilterRoundingEnable = 0,
1650 .TrilinearFilterQuality = 0,
1651 .NonnormalizedCoordinateEnable = 0,
1652 .TCXAddressControlMode = vk_to_gen_tex_address[pCreateInfo->addressU],
1653 .TCYAddressControlMode = vk_to_gen_tex_address[pCreateInfo->addressV],
1654 .TCZAddressControlMode = vk_to_gen_tex_address[pCreateInfo->addressW],
1655 };
1656
1657 GEN8_SAMPLER_STATE_pack(NULL, sampler->state, &sampler_state);
1658
1659 *pSampler = (VkSampler) sampler;
1660
1661 return VK_SUCCESS;
1662 }
1663
1664 // Descriptor set functions
1665
1666 VkResult anv_CreateDescriptorSetLayout(
1667 VkDevice _device,
1668 const VkDescriptorSetLayoutCreateInfo* pCreateInfo,
1669 VkDescriptorSetLayout* pSetLayout)
1670 {
1671 struct anv_device *device = (struct anv_device *) _device;
1672 struct anv_descriptor_set_layout *set_layout;
1673
1674 assert(pCreateInfo->sType == VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO);
1675
1676 uint32_t sampler_count[VK_NUM_SHADER_STAGE] = { 0, };
1677 uint32_t surface_count[VK_NUM_SHADER_STAGE] = { 0, };
1678 uint32_t num_dynamic_buffers = 0;
1679 uint32_t count = 0;
1680 uint32_t stages = 0;
1681 uint32_t s;
1682
1683 for (uint32_t i = 0; i < pCreateInfo->count; i++) {
1684 switch (pCreateInfo->pBinding[i].descriptorType) {
1685 case VK_DESCRIPTOR_TYPE_SAMPLER:
1686 case VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER:
1687 for_each_bit(s, pCreateInfo->pBinding[i].stageFlags)
1688 sampler_count[s] += pCreateInfo->pBinding[i].count;
1689 break;
1690 default:
1691 break;
1692 }
1693
1694 switch (pCreateInfo->pBinding[i].descriptorType) {
1695 case VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER:
1696 case VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE:
1697 case VK_DESCRIPTOR_TYPE_STORAGE_IMAGE:
1698 case VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER:
1699 case VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER:
1700 case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER:
1701 case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER:
1702 case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC:
1703 case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC:
1704 for_each_bit(s, pCreateInfo->pBinding[i].stageFlags)
1705 surface_count[s] += pCreateInfo->pBinding[i].count;
1706 break;
1707 default:
1708 break;
1709 }
1710
1711 switch (pCreateInfo->pBinding[i].descriptorType) {
1712 case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC:
1713 case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC:
1714 num_dynamic_buffers += pCreateInfo->pBinding[i].count;
1715 break;
1716 default:
1717 break;
1718 }
1719
1720 stages |= pCreateInfo->pBinding[i].stageFlags;
1721 count += pCreateInfo->pBinding[i].count;
1722 }
1723
1724 uint32_t sampler_total = 0;
1725 uint32_t surface_total = 0;
1726 for (uint32_t s = 0; s < VK_NUM_SHADER_STAGE; s++) {
1727 sampler_total += sampler_count[s];
1728 surface_total += surface_count[s];
1729 }
1730
1731 size_t size = sizeof(*set_layout) +
1732 (sampler_total + surface_total) * sizeof(set_layout->entries[0]);
1733 set_layout = anv_device_alloc(device, size, 8,
1734 VK_SYSTEM_ALLOC_TYPE_API_OBJECT);
1735 if (!set_layout)
1736 return vk_error(VK_ERROR_OUT_OF_HOST_MEMORY);
1737
1738 set_layout->num_dynamic_buffers = num_dynamic_buffers;
1739 set_layout->count = count;
1740 set_layout->shader_stages = stages;
1741
1742 struct anv_descriptor_slot *p = set_layout->entries;
1743 struct anv_descriptor_slot *sampler[VK_NUM_SHADER_STAGE];
1744 struct anv_descriptor_slot *surface[VK_NUM_SHADER_STAGE];
1745 for (uint32_t s = 0; s < VK_NUM_SHADER_STAGE; s++) {
1746 set_layout->stage[s].surface_count = surface_count[s];
1747 set_layout->stage[s].surface_start = surface[s] = p;
1748 p += surface_count[s];
1749 set_layout->stage[s].sampler_count = sampler_count[s];
1750 set_layout->stage[s].sampler_start = sampler[s] = p;
1751 p += sampler_count[s];
1752 }
1753
1754 uint32_t descriptor = 0;
1755 int8_t dynamic_slot = 0;
1756 bool is_dynamic;
1757 for (uint32_t i = 0; i < pCreateInfo->count; i++) {
1758 switch (pCreateInfo->pBinding[i].descriptorType) {
1759 case VK_DESCRIPTOR_TYPE_SAMPLER:
1760 case VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER:
1761 for_each_bit(s, pCreateInfo->pBinding[i].stageFlags)
1762 for (uint32_t j = 0; j < pCreateInfo->pBinding[i].count; j++) {
1763 sampler[s]->index = descriptor + j;
1764 sampler[s]->dynamic_slot = -1;
1765 sampler[s]++;
1766 }
1767 break;
1768 default:
1769 break;
1770 }
1771
1772 switch (pCreateInfo->pBinding[i].descriptorType) {
1773 case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC:
1774 case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC:
1775 is_dynamic = true;
1776 break;
1777 default:
1778 is_dynamic = false;
1779 break;
1780 }
1781
1782 switch (pCreateInfo->pBinding[i].descriptorType) {
1783 case VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER:
1784 case VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE:
1785 case VK_DESCRIPTOR_TYPE_STORAGE_IMAGE:
1786 case VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER:
1787 case VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER:
1788 case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER:
1789 case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER:
1790 case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC:
1791 case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC:
1792 for_each_bit(s, pCreateInfo->pBinding[i].stageFlags)
1793 for (uint32_t j = 0; j < pCreateInfo->pBinding[i].count; j++) {
1794 surface[s]->index = descriptor + j;
1795 if (is_dynamic)
1796 surface[s]->dynamic_slot = dynamic_slot + j;
1797 else
1798 surface[s]->dynamic_slot = -1;
1799 surface[s]++;
1800 }
1801 break;
1802 default:
1803 break;
1804 }
1805
1806 if (is_dynamic)
1807 dynamic_slot += pCreateInfo->pBinding[i].count;
1808
1809 descriptor += pCreateInfo->pBinding[i].count;
1810 }
1811
1812 *pSetLayout = (VkDescriptorSetLayout) set_layout;
1813
1814 return VK_SUCCESS;
1815 }
1816
1817 VkResult anv_BeginDescriptorPoolUpdate(
1818 VkDevice device,
1819 VkDescriptorUpdateMode updateMode)
1820 {
1821 return VK_SUCCESS;
1822 }
1823
1824 VkResult anv_EndDescriptorPoolUpdate(
1825 VkDevice device,
1826 VkCmdBuffer cmd)
1827 {
1828 return VK_SUCCESS;
1829 }
1830
1831 VkResult anv_CreateDescriptorPool(
1832 VkDevice device,
1833 VkDescriptorPoolUsage poolUsage,
1834 uint32_t maxSets,
1835 const VkDescriptorPoolCreateInfo* pCreateInfo,
1836 VkDescriptorPool* pDescriptorPool)
1837 {
1838 *pDescriptorPool = 1;
1839
1840 return VK_SUCCESS;
1841 }
1842
1843 VkResult anv_ResetDescriptorPool(
1844 VkDevice device,
1845 VkDescriptorPool descriptorPool)
1846 {
1847 return VK_SUCCESS;
1848 }
1849
1850 VkResult anv_AllocDescriptorSets(
1851 VkDevice _device,
1852 VkDescriptorPool descriptorPool,
1853 VkDescriptorSetUsage setUsage,
1854 uint32_t count,
1855 const VkDescriptorSetLayout* pSetLayouts,
1856 VkDescriptorSet* pDescriptorSets,
1857 uint32_t* pCount)
1858 {
1859 struct anv_device *device = (struct anv_device *) _device;
1860 const struct anv_descriptor_set_layout *layout;
1861 struct anv_descriptor_set *set;
1862 size_t size;
1863
1864 for (uint32_t i = 0; i < count; i++) {
1865 layout = (struct anv_descriptor_set_layout *) pSetLayouts[i];
1866 size = sizeof(*set) + layout->count * sizeof(set->descriptors[0]);
1867 set = anv_device_alloc(device, size, 8,
1868 VK_SYSTEM_ALLOC_TYPE_API_OBJECT);
1869 if (!set) {
1870 *pCount = i;
1871 return vk_error(VK_ERROR_OUT_OF_HOST_MEMORY);
1872 }
1873
1874 /* Descriptor sets may not be 100% filled out so we need to memset to
1875 * ensure that we can properly detect and handle holes.
1876 */
1877 memset(set, 0, size);
1878
1879 pDescriptorSets[i] = (VkDescriptorSet) set;
1880 }
1881
1882 *pCount = count;
1883
1884 return VK_SUCCESS;
1885 }
1886
1887 void anv_ClearDescriptorSets(
1888 VkDevice device,
1889 VkDescriptorPool descriptorPool,
1890 uint32_t count,
1891 const VkDescriptorSet* pDescriptorSets)
1892 {
1893 }
1894
1895 void anv_UpdateDescriptors(
1896 VkDevice _device,
1897 VkDescriptorSet descriptorSet,
1898 uint32_t updateCount,
1899 const void** ppUpdateArray)
1900 {
1901 struct anv_descriptor_set *set = (struct anv_descriptor_set *) descriptorSet;
1902 VkUpdateSamplers *update_samplers;
1903 VkUpdateSamplerTextures *update_sampler_textures;
1904 VkUpdateImages *update_images;
1905 VkUpdateBuffers *update_buffers;
1906 VkUpdateAsCopy *update_as_copy;
1907
1908 for (uint32_t i = 0; i < updateCount; i++) {
1909 const struct anv_common *common = ppUpdateArray[i];
1910
1911 switch (common->sType) {
1912 case VK_STRUCTURE_TYPE_UPDATE_SAMPLERS:
1913 update_samplers = (VkUpdateSamplers *) common;
1914
1915 for (uint32_t j = 0; j < update_samplers->count; j++) {
1916 set->descriptors[update_samplers->binding + j].sampler =
1917 (struct anv_sampler *) update_samplers->pSamplers[j];
1918 }
1919 break;
1920
1921 case VK_STRUCTURE_TYPE_UPDATE_SAMPLER_TEXTURES:
1922 /* FIXME: Shouldn't this be *_UPDATE_SAMPLER_IMAGES? */
1923 update_sampler_textures = (VkUpdateSamplerTextures *) common;
1924
1925 for (uint32_t j = 0; j < update_sampler_textures->count; j++) {
1926 set->descriptors[update_sampler_textures->binding + j].view =
1927 (struct anv_surface_view *)
1928 update_sampler_textures->pSamplerImageViews[j].pImageView->view;
1929 set->descriptors[update_sampler_textures->binding + j].sampler =
1930 (struct anv_sampler *)
1931 update_sampler_textures->pSamplerImageViews[j].sampler;
1932 }
1933 break;
1934
1935 case VK_STRUCTURE_TYPE_UPDATE_IMAGES:
1936 update_images = (VkUpdateImages *) common;
1937
1938 for (uint32_t j = 0; j < update_images->count; j++) {
1939 set->descriptors[update_images->binding + j].view =
1940 (struct anv_surface_view *) update_images->pImageViews[j].view;
1941 }
1942 break;
1943
1944 case VK_STRUCTURE_TYPE_UPDATE_BUFFERS:
1945 update_buffers = (VkUpdateBuffers *) common;
1946
1947 for (uint32_t j = 0; j < update_buffers->count; j++) {
1948 set->descriptors[update_buffers->binding + j].view =
1949 (struct anv_surface_view *) update_buffers->pBufferViews[j].view;
1950 }
1951 /* FIXME: descriptor arrays? */
1952 break;
1953
1954 case VK_STRUCTURE_TYPE_UPDATE_AS_COPY:
1955 update_as_copy = (VkUpdateAsCopy *) common;
1956 (void) update_as_copy;
1957 break;
1958
1959 default:
1960 break;
1961 }
1962 }
1963 }
1964
1965 // State object functions
1966
1967 static inline int64_t
1968 clamp_int64(int64_t x, int64_t min, int64_t max)
1969 {
1970 if (x < min)
1971 return min;
1972 else if (x < max)
1973 return x;
1974 else
1975 return max;
1976 }
1977
1978 static void
1979 anv_dynamic_vp_state_destroy(struct anv_device *device,
1980 struct anv_object *object,
1981 VkObjectType obj_type)
1982 {
1983 struct anv_dynamic_vp_state *state = (void *)object;
1984
1985 assert(obj_type == VK_OBJECT_TYPE_DYNAMIC_VP_STATE);
1986
1987 anv_state_pool_free(&device->dynamic_state_pool, state->sf_clip_vp);
1988 anv_state_pool_free(&device->dynamic_state_pool, state->cc_vp);
1989 anv_state_pool_free(&device->dynamic_state_pool, state->scissor);
1990
1991 anv_device_free(device, state);
1992 }
1993
1994 VkResult anv_CreateDynamicViewportState(
1995 VkDevice _device,
1996 const VkDynamicVpStateCreateInfo* pCreateInfo,
1997 VkDynamicVpState* pState)
1998 {
1999 struct anv_device *device = (struct anv_device *) _device;
2000 struct anv_dynamic_vp_state *state;
2001
2002 assert(pCreateInfo->sType == VK_STRUCTURE_TYPE_DYNAMIC_VP_STATE_CREATE_INFO);
2003
2004 state = anv_device_alloc(device, sizeof(*state), 8,
2005 VK_SYSTEM_ALLOC_TYPE_API_OBJECT);
2006 if (state == NULL)
2007 return vk_error(VK_ERROR_OUT_OF_HOST_MEMORY);
2008
2009 state->base.destructor = anv_dynamic_vp_state_destroy;
2010
2011 unsigned count = pCreateInfo->viewportAndScissorCount;
2012 state->sf_clip_vp = anv_state_pool_alloc(&device->dynamic_state_pool,
2013 count * 64, 64);
2014 state->cc_vp = anv_state_pool_alloc(&device->dynamic_state_pool,
2015 count * 8, 32);
2016 state->scissor = anv_state_pool_alloc(&device->dynamic_state_pool,
2017 count * 32, 32);
2018
2019 for (uint32_t i = 0; i < pCreateInfo->viewportAndScissorCount; i++) {
2020 const VkViewport *vp = &pCreateInfo->pViewports[i];
2021 const VkRect *s = &pCreateInfo->pScissors[i];
2022
2023 struct GEN8_SF_CLIP_VIEWPORT sf_clip_viewport = {
2024 .ViewportMatrixElementm00 = vp->width / 2,
2025 .ViewportMatrixElementm11 = vp->height / 2,
2026 .ViewportMatrixElementm22 = (vp->maxDepth - vp->minDepth) / 2,
2027 .ViewportMatrixElementm30 = vp->originX + vp->width / 2,
2028 .ViewportMatrixElementm31 = vp->originY + vp->height / 2,
2029 .ViewportMatrixElementm32 = (vp->maxDepth + vp->minDepth) / 2,
2030 .XMinClipGuardband = -1.0f,
2031 .XMaxClipGuardband = 1.0f,
2032 .YMinClipGuardband = -1.0f,
2033 .YMaxClipGuardband = 1.0f,
2034 .XMinViewPort = vp->originX,
2035 .XMaxViewPort = vp->originX + vp->width - 1,
2036 .YMinViewPort = vp->originY,
2037 .YMaxViewPort = vp->originY + vp->height - 1,
2038 };
2039
2040 struct GEN8_CC_VIEWPORT cc_viewport = {
2041 .MinimumDepth = vp->minDepth,
2042 .MaximumDepth = vp->maxDepth
2043 };
2044
2045 /* Since xmax and ymax are inclusive, we have to have xmax < xmin or
2046 * ymax < ymin for empty clips. In case clip x, y, width height are all
2047 * 0, the clamps below produce 0 for xmin, ymin, xmax, ymax, which isn't
2048 * what we want. Just special case empty clips and produce a canonical
2049 * empty clip. */
2050 static const struct GEN8_SCISSOR_RECT empty_scissor = {
2051 .ScissorRectangleYMin = 1,
2052 .ScissorRectangleXMin = 1,
2053 .ScissorRectangleYMax = 0,
2054 .ScissorRectangleXMax = 0
2055 };
2056
2057 const int max = 0xffff;
2058 struct GEN8_SCISSOR_RECT scissor = {
2059 /* Do this math using int64_t so overflow gets clamped correctly. */
2060 .ScissorRectangleYMin = clamp_int64(s->offset.y, 0, max),
2061 .ScissorRectangleXMin = clamp_int64(s->offset.x, 0, max),
2062 .ScissorRectangleYMax = clamp_int64((uint64_t) s->offset.y + s->extent.height - 1, 0, max),
2063 .ScissorRectangleXMax = clamp_int64((uint64_t) s->offset.x + s->extent.width - 1, 0, max)
2064 };
2065
2066 GEN8_SF_CLIP_VIEWPORT_pack(NULL, state->sf_clip_vp.map + i * 64, &sf_clip_viewport);
2067 GEN8_CC_VIEWPORT_pack(NULL, state->cc_vp.map + i * 32, &cc_viewport);
2068
2069 if (s->extent.width <= 0 || s->extent.height <= 0) {
2070 GEN8_SCISSOR_RECT_pack(NULL, state->scissor.map + i * 32, &empty_scissor);
2071 } else {
2072 GEN8_SCISSOR_RECT_pack(NULL, state->scissor.map + i * 32, &scissor);
2073 }
2074 }
2075
2076 *pState = (VkDynamicVpState) state;
2077
2078 return VK_SUCCESS;
2079 }
2080
2081 VkResult anv_CreateDynamicRasterState(
2082 VkDevice _device,
2083 const VkDynamicRsStateCreateInfo* pCreateInfo,
2084 VkDynamicRsState* pState)
2085 {
2086 struct anv_device *device = (struct anv_device *) _device;
2087 struct anv_dynamic_rs_state *state;
2088
2089 assert(pCreateInfo->sType == VK_STRUCTURE_TYPE_DYNAMIC_RS_STATE_CREATE_INFO);
2090
2091 state = anv_device_alloc(device, sizeof(*state), 8,
2092 VK_SYSTEM_ALLOC_TYPE_API_OBJECT);
2093 if (state == NULL)
2094 return vk_error(VK_ERROR_OUT_OF_HOST_MEMORY);
2095
2096 /* Missing these:
2097 * float pointFadeThreshold;
2098 * // optional (GL45) - Size of point fade threshold
2099 */
2100
2101 struct GEN8_3DSTATE_SF sf = {
2102 GEN8_3DSTATE_SF_header,
2103 .LineWidth = pCreateInfo->lineWidth,
2104 .PointWidth = pCreateInfo->pointSize,
2105 };
2106
2107 GEN8_3DSTATE_SF_pack(NULL, state->state_sf, &sf);
2108
2109 bool enable_bias = pCreateInfo->depthBias != 0.0f ||
2110 pCreateInfo->slopeScaledDepthBias != 0.0f;
2111 struct GEN8_3DSTATE_RASTER raster = {
2112 .GlobalDepthOffsetEnableSolid = enable_bias,
2113 .GlobalDepthOffsetEnableWireframe = enable_bias,
2114 .GlobalDepthOffsetEnablePoint = enable_bias,
2115 .GlobalDepthOffsetConstant = pCreateInfo->depthBias,
2116 .GlobalDepthOffsetScale = pCreateInfo->slopeScaledDepthBias,
2117 .GlobalDepthOffsetClamp = pCreateInfo->depthBiasClamp
2118 };
2119
2120 GEN8_3DSTATE_RASTER_pack(NULL, state->state_raster, &raster);
2121
2122 *pState = (VkDynamicRsState) state;
2123
2124 return VK_SUCCESS;
2125 }
2126
2127 VkResult anv_CreateDynamicColorBlendState(
2128 VkDevice _device,
2129 const VkDynamicCbStateCreateInfo* pCreateInfo,
2130 VkDynamicCbState* pState)
2131 {
2132 struct anv_device *device = (struct anv_device *) _device;
2133 struct anv_dynamic_cb_state *state;
2134
2135 assert(pCreateInfo->sType == VK_STRUCTURE_TYPE_DYNAMIC_CB_STATE_CREATE_INFO);
2136
2137 state = anv_device_alloc(device, sizeof(*state), 8,
2138 VK_SYSTEM_ALLOC_TYPE_API_OBJECT);
2139 if (state == NULL)
2140 return vk_error(VK_ERROR_OUT_OF_HOST_MEMORY);
2141
2142 struct GEN8_COLOR_CALC_STATE color_calc_state = {
2143 .BlendConstantColorRed = pCreateInfo->blendConst[0],
2144 .BlendConstantColorGreen = pCreateInfo->blendConst[1],
2145 .BlendConstantColorBlue = pCreateInfo->blendConst[2],
2146 .BlendConstantColorAlpha = pCreateInfo->blendConst[3]
2147 };
2148
2149 GEN8_COLOR_CALC_STATE_pack(NULL, state->state_color_calc, &color_calc_state);
2150
2151 *pState = (VkDynamicCbState) state;
2152
2153 return VK_SUCCESS;
2154 }
2155
2156 VkResult anv_CreateDynamicDepthStencilState(
2157 VkDevice _device,
2158 const VkDynamicDsStateCreateInfo* pCreateInfo,
2159 VkDynamicDsState* pState)
2160 {
2161 struct anv_device *device = (struct anv_device *) _device;
2162 struct anv_dynamic_ds_state *state;
2163
2164 assert(pCreateInfo->sType == VK_STRUCTURE_TYPE_DYNAMIC_DS_STATE_CREATE_INFO);
2165
2166 state = anv_device_alloc(device, sizeof(*state), 8,
2167 VK_SYSTEM_ALLOC_TYPE_API_OBJECT);
2168 if (state == NULL)
2169 return vk_error(VK_ERROR_OUT_OF_HOST_MEMORY);
2170
2171 struct GEN8_3DSTATE_WM_DEPTH_STENCIL wm_depth_stencil = {
2172 GEN8_3DSTATE_WM_DEPTH_STENCIL_header,
2173
2174 /* Is this what we need to do? */
2175 .StencilBufferWriteEnable = pCreateInfo->stencilWriteMask != 0,
2176
2177 .StencilTestMask = pCreateInfo->stencilReadMask & 0xff,
2178 .StencilWriteMask = pCreateInfo->stencilWriteMask & 0xff,
2179
2180 .BackfaceStencilTestMask = pCreateInfo->stencilReadMask & 0xff,
2181 .BackfaceStencilWriteMask = pCreateInfo->stencilWriteMask & 0xff,
2182 };
2183
2184 GEN8_3DSTATE_WM_DEPTH_STENCIL_pack(NULL, state->state_wm_depth_stencil,
2185 &wm_depth_stencil);
2186
2187 struct GEN8_COLOR_CALC_STATE color_calc_state = {
2188 .StencilReferenceValue = pCreateInfo->stencilFrontRef,
2189 .BackFaceStencilReferenceValue = pCreateInfo->stencilBackRef
2190 };
2191
2192 GEN8_COLOR_CALC_STATE_pack(NULL, state->state_color_calc, &color_calc_state);
2193
2194 *pState = (VkDynamicDsState) state;
2195
2196 return VK_SUCCESS;
2197 }
2198
2199 // Command buffer functions
2200
2201 static void
2202 anv_cmd_buffer_destroy(struct anv_device *device,
2203 struct anv_object *object,
2204 VkObjectType obj_type)
2205 {
2206 struct anv_cmd_buffer *cmd_buffer = (struct anv_cmd_buffer *) object;
2207
2208 assert(obj_type == VK_OBJECT_TYPE_COMMAND_BUFFER);
2209
2210 /* Destroy all of the batch buffers */
2211 struct anv_batch_bo *bbo = cmd_buffer->last_batch_bo;
2212 while (bbo->prev_batch_bo) {
2213 struct anv_batch_bo *prev = bbo->prev_batch_bo;
2214 anv_batch_bo_destroy(bbo, device);
2215 bbo = prev;
2216 }
2217 anv_reloc_list_finish(&cmd_buffer->batch.relocs, device);
2218
2219 /* Destroy all of the surface state buffers */
2220 bbo = cmd_buffer->surface_batch_bo;
2221 while (bbo->prev_batch_bo) {
2222 struct anv_batch_bo *prev = bbo->prev_batch_bo;
2223 anv_batch_bo_destroy(bbo, device);
2224 bbo = prev;
2225 }
2226 anv_reloc_list_finish(&cmd_buffer->surface_relocs, device);
2227
2228 anv_state_stream_finish(&cmd_buffer->surface_state_stream);
2229 anv_state_stream_finish(&cmd_buffer->dynamic_state_stream);
2230 anv_device_free(device, cmd_buffer->exec2_objects);
2231 anv_device_free(device, cmd_buffer->exec2_bos);
2232 anv_device_free(device, cmd_buffer);
2233 }
2234
2235 static VkResult
2236 anv_cmd_buffer_chain_batch(struct anv_batch *batch, void *_data)
2237 {
2238 struct anv_cmd_buffer *cmd_buffer = _data;
2239
2240 struct anv_batch_bo *new_bbo, *old_bbo = cmd_buffer->last_batch_bo;
2241
2242 VkResult result = anv_batch_bo_create(cmd_buffer->device, &new_bbo);
2243 if (result != VK_SUCCESS)
2244 return result;
2245
2246 /* We set the end of the batch a little short so we would be sure we
2247 * have room for the chaining command. Since we're about to emit the
2248 * chaining command, let's set it back where it should go.
2249 */
2250 batch->end += GEN8_MI_BATCH_BUFFER_START_length * 4;
2251 assert(batch->end == old_bbo->bo.map + old_bbo->bo.size);
2252
2253 anv_batch_emit(batch, GEN8_MI_BATCH_BUFFER_START,
2254 GEN8_MI_BATCH_BUFFER_START_header,
2255 ._2ndLevelBatchBuffer = _1stlevelbatch,
2256 .AddressSpaceIndicator = ASI_PPGTT,
2257 .BatchBufferStartAddress = { &new_bbo->bo, 0 },
2258 );
2259
2260 /* Pad out to a 2-dword aligned boundary with zeros */
2261 if ((uintptr_t)batch->next % 8 != 0) {
2262 *(uint32_t *)batch->next = 0;
2263 batch->next += 4;
2264 }
2265
2266 anv_batch_bo_finish(cmd_buffer->last_batch_bo, batch);
2267
2268 new_bbo->prev_batch_bo = old_bbo;
2269 cmd_buffer->last_batch_bo = new_bbo;
2270
2271 anv_batch_bo_start(new_bbo, batch, GEN8_MI_BATCH_BUFFER_START_length * 4);
2272
2273 return VK_SUCCESS;
2274 }
2275
2276 VkResult anv_CreateCommandBuffer(
2277 VkDevice _device,
2278 const VkCmdBufferCreateInfo* pCreateInfo,
2279 VkCmdBuffer* pCmdBuffer)
2280 {
2281 struct anv_device *device = (struct anv_device *) _device;
2282 struct anv_cmd_buffer *cmd_buffer;
2283 VkResult result;
2284
2285 cmd_buffer = anv_device_alloc(device, sizeof(*cmd_buffer), 8,
2286 VK_SYSTEM_ALLOC_TYPE_API_OBJECT);
2287 if (cmd_buffer == NULL)
2288 return vk_error(VK_ERROR_OUT_OF_HOST_MEMORY);
2289
2290 cmd_buffer->base.destructor = anv_cmd_buffer_destroy;
2291
2292 cmd_buffer->device = device;
2293 cmd_buffer->rs_state = NULL;
2294 cmd_buffer->vp_state = NULL;
2295 cmd_buffer->cb_state = NULL;
2296 memset(&cmd_buffer->descriptors, 0, sizeof(cmd_buffer->descriptors));
2297
2298 result = anv_batch_bo_create(device, &cmd_buffer->last_batch_bo);
2299 if (result != VK_SUCCESS)
2300 goto fail;
2301
2302 result = anv_reloc_list_init(&cmd_buffer->batch.relocs, device);
2303 if (result != VK_SUCCESS)
2304 goto fail_batch_bo;
2305
2306 cmd_buffer->batch.device = device;
2307 cmd_buffer->batch.extend_cb = anv_cmd_buffer_chain_batch;
2308 cmd_buffer->batch.user_data = cmd_buffer;
2309
2310 anv_batch_bo_start(cmd_buffer->last_batch_bo, &cmd_buffer->batch,
2311 GEN8_MI_BATCH_BUFFER_START_length * 4);
2312
2313 result = anv_batch_bo_create(device, &cmd_buffer->surface_batch_bo);
2314 if (result != VK_SUCCESS)
2315 goto fail_batch_relocs;
2316 cmd_buffer->surface_batch_bo->first_reloc = 0;
2317
2318 result = anv_reloc_list_init(&cmd_buffer->surface_relocs, device);
2319 if (result != VK_SUCCESS)
2320 goto fail_ss_batch_bo;
2321
2322 /* Start surface_next at 1 so surface offset 0 is invalid. */
2323 cmd_buffer->surface_next = 1;
2324
2325 cmd_buffer->exec2_objects = NULL;
2326 cmd_buffer->exec2_bos = NULL;
2327 cmd_buffer->exec2_array_length = 0;
2328
2329 anv_state_stream_init(&cmd_buffer->surface_state_stream,
2330 &device->surface_state_block_pool);
2331 anv_state_stream_init(&cmd_buffer->dynamic_state_stream,
2332 &device->dynamic_state_block_pool);
2333
2334 cmd_buffer->dirty = 0;
2335 cmd_buffer->vb_dirty = 0;
2336 cmd_buffer->descriptors_dirty = 0;
2337 cmd_buffer->pipeline = NULL;
2338 cmd_buffer->vp_state = NULL;
2339 cmd_buffer->rs_state = NULL;
2340 cmd_buffer->ds_state = NULL;
2341
2342 *pCmdBuffer = (VkCmdBuffer) cmd_buffer;
2343
2344 return VK_SUCCESS;
2345
2346 fail_ss_batch_bo:
2347 anv_batch_bo_destroy(cmd_buffer->surface_batch_bo, device);
2348 fail_batch_relocs:
2349 anv_reloc_list_finish(&cmd_buffer->batch.relocs, device);
2350 fail_batch_bo:
2351 anv_batch_bo_destroy(cmd_buffer->last_batch_bo, device);
2352 fail:
2353 anv_device_free(device, cmd_buffer);
2354
2355 return result;
2356 }
2357
2358 static void
2359 anv_cmd_buffer_emit_state_base_address(struct anv_cmd_buffer *cmd_buffer)
2360 {
2361 struct anv_device *device = cmd_buffer->device;
2362
2363 anv_batch_emit(&cmd_buffer->batch, GEN8_STATE_BASE_ADDRESS,
2364 .GeneralStateBaseAddress = { NULL, 0 },
2365 .GeneralStateMemoryObjectControlState = GEN8_MOCS,
2366 .GeneralStateBaseAddressModifyEnable = true,
2367 .GeneralStateBufferSize = 0xfffff,
2368 .GeneralStateBufferSizeModifyEnable = true,
2369
2370 .SurfaceStateBaseAddress = { &cmd_buffer->surface_batch_bo->bo, 0 },
2371 .SurfaceStateMemoryObjectControlState = GEN8_MOCS,
2372 .SurfaceStateBaseAddressModifyEnable = true,
2373
2374 .DynamicStateBaseAddress = { &device->dynamic_state_block_pool.bo, 0 },
2375 .DynamicStateMemoryObjectControlState = GEN8_MOCS,
2376 .DynamicStateBaseAddressModifyEnable = true,
2377 .DynamicStateBufferSize = 0xfffff,
2378 .DynamicStateBufferSizeModifyEnable = true,
2379
2380 .IndirectObjectBaseAddress = { NULL, 0 },
2381 .IndirectObjectMemoryObjectControlState = GEN8_MOCS,
2382 .IndirectObjectBaseAddressModifyEnable = true,
2383 .IndirectObjectBufferSize = 0xfffff,
2384 .IndirectObjectBufferSizeModifyEnable = true,
2385
2386 .InstructionBaseAddress = { &device->instruction_block_pool.bo, 0 },
2387 .InstructionMemoryObjectControlState = GEN8_MOCS,
2388 .InstructionBaseAddressModifyEnable = true,
2389 .InstructionBufferSize = 0xfffff,
2390 .InstructionBuffersizeModifyEnable = true);
2391 }
2392
2393 VkResult anv_BeginCommandBuffer(
2394 VkCmdBuffer cmdBuffer,
2395 const VkCmdBufferBeginInfo* pBeginInfo)
2396 {
2397 struct anv_cmd_buffer *cmd_buffer = (struct anv_cmd_buffer *) cmdBuffer;
2398
2399 anv_batch_emit(&cmd_buffer->batch, GEN8_PIPELINE_SELECT,
2400 .PipelineSelection = _3D);
2401 anv_batch_emit(&cmd_buffer->batch, GEN8_STATE_SIP);
2402
2403 anv_cmd_buffer_emit_state_base_address(cmd_buffer);
2404
2405 anv_batch_emit(&cmd_buffer->batch, GEN8_3DSTATE_VF_STATISTICS,
2406 .StatisticsEnable = true);
2407 anv_batch_emit(&cmd_buffer->batch, GEN8_3DSTATE_HS, .Enable = false);
2408 anv_batch_emit(&cmd_buffer->batch, GEN8_3DSTATE_TE, .TEEnable = false);
2409 anv_batch_emit(&cmd_buffer->batch, GEN8_3DSTATE_DS, .FunctionEnable = false);
2410 anv_batch_emit(&cmd_buffer->batch, GEN8_3DSTATE_STREAMOUT, .SOFunctionEnable = false);
2411
2412 anv_batch_emit(&cmd_buffer->batch, GEN8_3DSTATE_PUSH_CONSTANT_ALLOC_VS,
2413 .ConstantBufferOffset = 0,
2414 .ConstantBufferSize = 4);
2415 anv_batch_emit(&cmd_buffer->batch, GEN8_3DSTATE_PUSH_CONSTANT_ALLOC_GS,
2416 .ConstantBufferOffset = 4,
2417 .ConstantBufferSize = 4);
2418 anv_batch_emit(&cmd_buffer->batch, GEN8_3DSTATE_PUSH_CONSTANT_ALLOC_PS,
2419 .ConstantBufferOffset = 8,
2420 .ConstantBufferSize = 4);
2421
2422 anv_batch_emit(&cmd_buffer->batch, GEN8_3DSTATE_WM_CHROMAKEY,
2423 .ChromaKeyKillEnable = false);
2424 anv_batch_emit(&cmd_buffer->batch, GEN8_3DSTATE_SBE_SWIZ);
2425 anv_batch_emit(&cmd_buffer->batch, GEN8_3DSTATE_AA_LINE_PARAMETERS);
2426
2427 return VK_SUCCESS;
2428 }
2429
2430 static VkResult
2431 anv_cmd_buffer_add_bo(struct anv_cmd_buffer *cmd_buffer,
2432 struct anv_bo *bo,
2433 struct drm_i915_gem_relocation_entry *relocs,
2434 size_t num_relocs)
2435 {
2436 struct drm_i915_gem_exec_object2 *obj;
2437
2438 if (bo->index < cmd_buffer->bo_count &&
2439 cmd_buffer->exec2_bos[bo->index] == bo)
2440 return VK_SUCCESS;
2441
2442 if (cmd_buffer->bo_count >= cmd_buffer->exec2_array_length) {
2443 uint32_t new_len = cmd_buffer->exec2_objects ?
2444 cmd_buffer->exec2_array_length * 2 : 64;
2445
2446 struct drm_i915_gem_exec_object2 *new_objects =
2447 anv_device_alloc(cmd_buffer->device, new_len * sizeof(*new_objects),
2448 8, VK_SYSTEM_ALLOC_TYPE_INTERNAL);
2449 if (new_objects == NULL)
2450 return vk_error(VK_ERROR_OUT_OF_HOST_MEMORY);
2451
2452 struct anv_bo **new_bos =
2453 anv_device_alloc(cmd_buffer->device, new_len * sizeof(*new_bos),
2454 8, VK_SYSTEM_ALLOC_TYPE_INTERNAL);
2455 if (new_objects == NULL) {
2456 anv_device_free(cmd_buffer->device, new_objects);
2457 return vk_error(VK_ERROR_OUT_OF_HOST_MEMORY);
2458 }
2459
2460 if (cmd_buffer->exec2_objects) {
2461 memcpy(new_objects, cmd_buffer->exec2_objects,
2462 cmd_buffer->bo_count * sizeof(*new_objects));
2463 memcpy(new_bos, cmd_buffer->exec2_bos,
2464 cmd_buffer->bo_count * sizeof(*new_bos));
2465 }
2466
2467 cmd_buffer->exec2_objects = new_objects;
2468 cmd_buffer->exec2_bos = new_bos;
2469 cmd_buffer->exec2_array_length = new_len;
2470 }
2471
2472 assert(cmd_buffer->bo_count < cmd_buffer->exec2_array_length);
2473
2474 bo->index = cmd_buffer->bo_count++;
2475 obj = &cmd_buffer->exec2_objects[bo->index];
2476 cmd_buffer->exec2_bos[bo->index] = bo;
2477
2478 obj->handle = bo->gem_handle;
2479 obj->relocation_count = 0;
2480 obj->relocs_ptr = 0;
2481 obj->alignment = 0;
2482 obj->offset = bo->offset;
2483 obj->flags = 0;
2484 obj->rsvd1 = 0;
2485 obj->rsvd2 = 0;
2486
2487 if (relocs) {
2488 obj->relocation_count = num_relocs;
2489 obj->relocs_ptr = (uintptr_t) relocs;
2490 }
2491
2492 return VK_SUCCESS;
2493 }
2494
2495 static void
2496 anv_cmd_buffer_add_validate_bos(struct anv_cmd_buffer *cmd_buffer,
2497 struct anv_reloc_list *list)
2498 {
2499 for (size_t i = 0; i < list->num_relocs; i++)
2500 anv_cmd_buffer_add_bo(cmd_buffer, list->reloc_bos[i], NULL, 0);
2501 }
2502
2503 static void
2504 anv_cmd_buffer_process_relocs(struct anv_cmd_buffer *cmd_buffer,
2505 struct anv_reloc_list *list)
2506 {
2507 struct anv_bo *bo;
2508
2509 /* If the kernel supports I915_EXEC_NO_RELOC, it will compare offset in
2510 * struct drm_i915_gem_exec_object2 against the bos current offset and if
2511 * all bos haven't moved it will skip relocation processing alltogether.
2512 * If I915_EXEC_NO_RELOC is not supported, the kernel ignores the incoming
2513 * value of offset so we can set it either way. For that to work we need
2514 * to make sure all relocs use the same presumed offset.
2515 */
2516
2517 for (size_t i = 0; i < list->num_relocs; i++) {
2518 bo = list->reloc_bos[i];
2519 if (bo->offset != list->relocs[i].presumed_offset)
2520 cmd_buffer->need_reloc = true;
2521
2522 list->relocs[i].target_handle = bo->index;
2523 }
2524 }
2525
2526 VkResult anv_EndCommandBuffer(
2527 VkCmdBuffer cmdBuffer)
2528 {
2529 struct anv_cmd_buffer *cmd_buffer = (struct anv_cmd_buffer *) cmdBuffer;
2530 struct anv_device *device = cmd_buffer->device;
2531 struct anv_batch *batch = &cmd_buffer->batch;
2532
2533 anv_batch_emit(batch, GEN8_MI_BATCH_BUFFER_END);
2534
2535 /* Round batch up to an even number of dwords. */
2536 if ((batch->next - batch->start) & 4)
2537 anv_batch_emit(batch, GEN8_MI_NOOP);
2538
2539 anv_batch_bo_finish(cmd_buffer->last_batch_bo, &cmd_buffer->batch);
2540 cmd_buffer->surface_batch_bo->num_relocs =
2541 cmd_buffer->surface_relocs.num_relocs - cmd_buffer->surface_batch_bo->first_reloc;
2542 cmd_buffer->surface_batch_bo->length = cmd_buffer->surface_next;
2543
2544 cmd_buffer->bo_count = 0;
2545 cmd_buffer->need_reloc = false;
2546
2547 /* Lock for access to bo->index. */
2548 pthread_mutex_lock(&device->mutex);
2549
2550 /* Add surface state bos first so we can add them with their relocs. */
2551 for (struct anv_batch_bo *bbo = cmd_buffer->surface_batch_bo;
2552 bbo != NULL; bbo = bbo->prev_batch_bo) {
2553 anv_cmd_buffer_add_bo(cmd_buffer, &bbo->bo,
2554 &cmd_buffer->surface_relocs.relocs[bbo->first_reloc],
2555 bbo->num_relocs);
2556 }
2557
2558 /* Add all of the BOs referenced by surface state */
2559 anv_cmd_buffer_add_validate_bos(cmd_buffer, &cmd_buffer->surface_relocs);
2560
2561 /* Add all but the first batch BO */
2562 struct anv_batch_bo *batch_bo = cmd_buffer->last_batch_bo;
2563 while (batch_bo->prev_batch_bo) {
2564 anv_cmd_buffer_add_bo(cmd_buffer, &batch_bo->bo,
2565 &batch->relocs.relocs[batch_bo->first_reloc],
2566 batch_bo->num_relocs);
2567 batch_bo = batch_bo->prev_batch_bo;
2568 }
2569
2570 /* Add everything referenced by the batches */
2571 anv_cmd_buffer_add_validate_bos(cmd_buffer, &batch->relocs);
2572
2573 /* Add the first batch bo last */
2574 assert(batch_bo->prev_batch_bo == NULL && batch_bo->first_reloc == 0);
2575 anv_cmd_buffer_add_bo(cmd_buffer, &batch_bo->bo,
2576 &batch->relocs.relocs[batch_bo->first_reloc],
2577 batch_bo->num_relocs);
2578 assert(batch_bo->bo.index == cmd_buffer->bo_count - 1);
2579
2580 anv_cmd_buffer_process_relocs(cmd_buffer, &cmd_buffer->surface_relocs);
2581 anv_cmd_buffer_process_relocs(cmd_buffer, &batch->relocs);
2582
2583 cmd_buffer->execbuf.buffers_ptr = (uintptr_t) cmd_buffer->exec2_objects;
2584 cmd_buffer->execbuf.buffer_count = cmd_buffer->bo_count;
2585 cmd_buffer->execbuf.batch_start_offset = 0;
2586 cmd_buffer->execbuf.batch_len = batch->next - batch->start;
2587 cmd_buffer->execbuf.cliprects_ptr = 0;
2588 cmd_buffer->execbuf.num_cliprects = 0;
2589 cmd_buffer->execbuf.DR1 = 0;
2590 cmd_buffer->execbuf.DR4 = 0;
2591
2592 cmd_buffer->execbuf.flags = I915_EXEC_HANDLE_LUT;
2593 if (!cmd_buffer->need_reloc)
2594 cmd_buffer->execbuf.flags |= I915_EXEC_NO_RELOC;
2595 cmd_buffer->execbuf.flags |= I915_EXEC_RENDER;
2596 cmd_buffer->execbuf.rsvd1 = device->context_id;
2597 cmd_buffer->execbuf.rsvd2 = 0;
2598
2599 pthread_mutex_unlock(&device->mutex);
2600
2601 return VK_SUCCESS;
2602 }
2603
2604 VkResult anv_ResetCommandBuffer(
2605 VkCmdBuffer cmdBuffer)
2606 {
2607 struct anv_cmd_buffer *cmd_buffer = (struct anv_cmd_buffer *) cmdBuffer;
2608
2609 /* Delete all but the first batch bo */
2610 while (cmd_buffer->last_batch_bo->prev_batch_bo) {
2611 struct anv_batch_bo *prev = cmd_buffer->last_batch_bo->prev_batch_bo;
2612 anv_batch_bo_destroy(cmd_buffer->last_batch_bo, cmd_buffer->device);
2613 cmd_buffer->last_batch_bo = prev;
2614 }
2615 assert(cmd_buffer->last_batch_bo->prev_batch_bo == NULL);
2616
2617 cmd_buffer->batch.relocs.num_relocs = 0;
2618 anv_batch_bo_start(cmd_buffer->last_batch_bo, &cmd_buffer->batch,
2619 GEN8_MI_BATCH_BUFFER_START_length * 4);
2620
2621 /* Delete all but the first batch bo */
2622 while (cmd_buffer->surface_batch_bo->prev_batch_bo) {
2623 struct anv_batch_bo *prev = cmd_buffer->surface_batch_bo->prev_batch_bo;
2624 anv_batch_bo_destroy(cmd_buffer->surface_batch_bo, cmd_buffer->device);
2625 cmd_buffer->surface_batch_bo = prev;
2626 }
2627 assert(cmd_buffer->surface_batch_bo->prev_batch_bo == NULL);
2628
2629 cmd_buffer->surface_next = 1;
2630 cmd_buffer->surface_relocs.num_relocs = 0;
2631
2632 return VK_SUCCESS;
2633 }
2634
2635 // Command buffer building functions
2636
2637 void anv_CmdBindPipeline(
2638 VkCmdBuffer cmdBuffer,
2639 VkPipelineBindPoint pipelineBindPoint,
2640 VkPipeline _pipeline)
2641 {
2642 struct anv_cmd_buffer *cmd_buffer = (struct anv_cmd_buffer *) cmdBuffer;
2643 struct anv_pipeline *pipeline = (struct anv_pipeline *) _pipeline;
2644
2645 cmd_buffer->pipeline = pipeline;
2646 cmd_buffer->vb_dirty |= pipeline->vb_used;
2647 cmd_buffer->dirty |= ANV_CMD_BUFFER_PIPELINE_DIRTY;
2648 }
2649
2650 void anv_CmdBindDynamicStateObject(
2651 VkCmdBuffer cmdBuffer,
2652 VkStateBindPoint stateBindPoint,
2653 VkDynamicStateObject dynamicState)
2654 {
2655 struct anv_cmd_buffer *cmd_buffer = (struct anv_cmd_buffer *) cmdBuffer;
2656 struct anv_dynamic_vp_state *vp_state;
2657
2658 switch (stateBindPoint) {
2659 case VK_STATE_BIND_POINT_VIEWPORT:
2660 vp_state = (struct anv_dynamic_vp_state *) dynamicState;
2661 /* We emit state immediately, but set cmd_buffer->vp_state to indicate
2662 * that vp state has been set in this command buffer. */
2663 cmd_buffer->vp_state = vp_state;
2664 anv_batch_emit(&cmd_buffer->batch, GEN8_3DSTATE_SCISSOR_STATE_POINTERS,
2665 .ScissorRectPointer = vp_state->scissor.offset);
2666 anv_batch_emit(&cmd_buffer->batch, GEN8_3DSTATE_VIEWPORT_STATE_POINTERS_CC,
2667 .CCViewportPointer = vp_state->cc_vp.offset);
2668 anv_batch_emit(&cmd_buffer->batch, GEN8_3DSTATE_VIEWPORT_STATE_POINTERS_SF_CLIP,
2669 .SFClipViewportPointer = vp_state->sf_clip_vp.offset);
2670 break;
2671 case VK_STATE_BIND_POINT_RASTER:
2672 cmd_buffer->rs_state = (struct anv_dynamic_rs_state *) dynamicState;
2673 cmd_buffer->dirty |= ANV_CMD_BUFFER_RS_DIRTY;
2674 break;
2675 case VK_STATE_BIND_POINT_COLOR_BLEND:
2676 cmd_buffer->cb_state = (struct anv_dynamic_cb_state *) dynamicState;
2677 cmd_buffer->dirty |= ANV_CMD_BUFFER_CB_DIRTY;
2678 break;
2679 case VK_STATE_BIND_POINT_DEPTH_STENCIL:
2680 cmd_buffer->ds_state = (struct anv_dynamic_ds_state *) dynamicState;
2681 cmd_buffer->dirty |= ANV_CMD_BUFFER_DS_DIRTY;
2682 break;
2683 default:
2684 break;
2685 };
2686 }
2687
2688 static struct anv_state
2689 anv_cmd_buffer_alloc_surface_state(struct anv_cmd_buffer *cmd_buffer,
2690 uint32_t size, uint32_t alignment)
2691 {
2692 struct anv_state state;
2693
2694 state.offset = ALIGN_U32(cmd_buffer->surface_next, alignment);
2695 if (state.offset + size > cmd_buffer->surface_batch_bo->bo.size)
2696 return (struct anv_state) { 0 };
2697
2698 state.map = cmd_buffer->surface_batch_bo->bo.map + state.offset;
2699 state.alloc_size = size;
2700 cmd_buffer->surface_next = state.offset + size;
2701
2702 assert(state.offset + size <= cmd_buffer->surface_batch_bo->bo.size);
2703
2704 return state;
2705 }
2706
2707 static VkResult
2708 anv_cmd_buffer_new_surface_state_bo(struct anv_cmd_buffer *cmd_buffer)
2709 {
2710 struct anv_batch_bo *new_bbo, *old_bbo = cmd_buffer->surface_batch_bo;
2711
2712 /* Finish off the old buffer */
2713 old_bbo->num_relocs =
2714 cmd_buffer->surface_relocs.num_relocs - old_bbo->first_reloc;
2715 old_bbo->length = cmd_buffer->surface_next;
2716
2717 VkResult result = anv_batch_bo_create(cmd_buffer->device, &new_bbo);
2718 if (result != VK_SUCCESS)
2719 return result;
2720
2721 new_bbo->first_reloc = cmd_buffer->surface_relocs.num_relocs;
2722 cmd_buffer->surface_next = 1;
2723
2724 new_bbo->prev_batch_bo = old_bbo;
2725 cmd_buffer->surface_batch_bo = new_bbo;
2726
2727 /* Re-emit state base addresses so we get the new surface state base
2728 * address before we start emitting binding tables etc.
2729 */
2730 anv_cmd_buffer_emit_state_base_address(cmd_buffer);
2731
2732 /* It seems like just changing the state base addresses isn't enough.
2733 * Invalidating the cache seems to be enough to cause things to
2734 * propagate. However, I'm not 100% sure what we're supposed to do.
2735 */
2736 anv_batch_emit(&cmd_buffer->batch, GEN8_PIPE_CONTROL,
2737 .TextureCacheInvalidationEnable = true);
2738
2739 return VK_SUCCESS;
2740 }
2741
2742 void anv_CmdBindDescriptorSets(
2743 VkCmdBuffer cmdBuffer,
2744 VkPipelineBindPoint pipelineBindPoint,
2745 uint32_t firstSet,
2746 uint32_t setCount,
2747 const VkDescriptorSet* pDescriptorSets,
2748 uint32_t dynamicOffsetCount,
2749 const uint32_t* pDynamicOffsets)
2750 {
2751 struct anv_cmd_buffer *cmd_buffer = (struct anv_cmd_buffer *) cmdBuffer;
2752 struct anv_pipeline_layout *layout = cmd_buffer->pipeline->layout;
2753 struct anv_descriptor_set *set;
2754 struct anv_descriptor_set_layout *set_layout;
2755
2756 assert(firstSet + setCount < MAX_SETS);
2757
2758 uint32_t dynamic_slot = 0;
2759 for (uint32_t i = 0; i < setCount; i++) {
2760 set = (struct anv_descriptor_set *) pDescriptorSets[i];
2761 set_layout = layout->set[firstSet + i].layout;
2762
2763 cmd_buffer->descriptors[firstSet + i].set = set;
2764
2765 assert(set_layout->num_dynamic_buffers <
2766 ARRAY_SIZE(cmd_buffer->descriptors[0].dynamic_offsets));
2767 memcpy(cmd_buffer->descriptors[firstSet + i].dynamic_offsets,
2768 pDynamicOffsets + dynamic_slot,
2769 set_layout->num_dynamic_buffers * sizeof(*pDynamicOffsets));
2770
2771 cmd_buffer->descriptors_dirty |= set_layout->shader_stages;
2772
2773 dynamic_slot += set_layout->num_dynamic_buffers;
2774 }
2775 }
2776
2777 void anv_CmdBindIndexBuffer(
2778 VkCmdBuffer cmdBuffer,
2779 VkBuffer _buffer,
2780 VkDeviceSize offset,
2781 VkIndexType indexType)
2782 {
2783 struct anv_cmd_buffer *cmd_buffer = (struct anv_cmd_buffer *) cmdBuffer;
2784 struct anv_buffer *buffer = (struct anv_buffer *) _buffer;
2785
2786 static const uint32_t vk_to_gen_index_type[] = {
2787 [VK_INDEX_TYPE_UINT8] = INDEX_BYTE,
2788 [VK_INDEX_TYPE_UINT16] = INDEX_WORD,
2789 [VK_INDEX_TYPE_UINT32] = INDEX_DWORD,
2790 };
2791
2792 anv_batch_emit(&cmd_buffer->batch, GEN8_3DSTATE_INDEX_BUFFER,
2793 .IndexFormat = vk_to_gen_index_type[indexType],
2794 .MemoryObjectControlState = GEN8_MOCS,
2795 .BufferStartingAddress = { buffer->bo, buffer->offset + offset },
2796 .BufferSize = buffer->size - offset);
2797 }
2798
2799 void anv_CmdBindVertexBuffers(
2800 VkCmdBuffer cmdBuffer,
2801 uint32_t startBinding,
2802 uint32_t bindingCount,
2803 const VkBuffer* pBuffers,
2804 const VkDeviceSize* pOffsets)
2805 {
2806 struct anv_cmd_buffer *cmd_buffer = (struct anv_cmd_buffer *) cmdBuffer;
2807 struct anv_vertex_binding *vb = cmd_buffer->vertex_bindings;
2808
2809 /* We have to defer setting up vertex buffer since we need the buffer
2810 * stride from the pipeline. */
2811
2812 assert(startBinding + bindingCount < MAX_VBS);
2813 for (uint32_t i = 0; i < bindingCount; i++) {
2814 vb[startBinding + i].buffer = (struct anv_buffer *) pBuffers[i];
2815 vb[startBinding + i].offset = pOffsets[i];
2816 cmd_buffer->vb_dirty |= 1 << (startBinding + i);
2817 }
2818 }
2819
2820 static VkResult
2821 cmd_buffer_emit_binding_table(struct anv_cmd_buffer *cmd_buffer,
2822 unsigned stage)
2823 {
2824 struct anv_pipeline_layout *layout = cmd_buffer->pipeline->layout;
2825 uint32_t color_attachments, bias, size;
2826 struct anv_state bt_state;
2827
2828 if (stage == VK_SHADER_STAGE_FRAGMENT) {
2829 bias = MAX_RTS;
2830 color_attachments = cmd_buffer->framebuffer->color_attachment_count;
2831 } else {
2832 bias = 0;
2833 color_attachments = 0;
2834 }
2835
2836 /* This is a little awkward: layout can be NULL but we still have to
2837 * allocate and set a binding table for the PS stage for render
2838 * targets. */
2839 uint32_t surface_count = layout ? layout->stage[stage].surface_count : 0;
2840
2841 if (color_attachments + surface_count == 0)
2842 return VK_SUCCESS;
2843
2844 size = (bias + surface_count) * sizeof(uint32_t);
2845 bt_state = anv_cmd_buffer_alloc_surface_state(cmd_buffer, size, 32);
2846 uint32_t *bt_map = bt_state.map;
2847
2848 if (bt_state.map == NULL)
2849 return VK_ERROR_OUT_OF_DEVICE_MEMORY;
2850
2851 static const uint32_t binding_table_opcodes[] = {
2852 [VK_SHADER_STAGE_VERTEX] = 38,
2853 [VK_SHADER_STAGE_TESS_CONTROL] = 39,
2854 [VK_SHADER_STAGE_TESS_EVALUATION] = 40,
2855 [VK_SHADER_STAGE_GEOMETRY] = 41,
2856 [VK_SHADER_STAGE_FRAGMENT] = 42,
2857 [VK_SHADER_STAGE_COMPUTE] = 0,
2858 };
2859
2860 anv_batch_emit(&cmd_buffer->batch,
2861 GEN8_3DSTATE_BINDING_TABLE_POINTERS_VS,
2862 ._3DCommandSubOpcode = binding_table_opcodes[stage],
2863 .PointertoVSBindingTable = bt_state.offset);
2864
2865 for (uint32_t ca = 0; ca < color_attachments; ca++) {
2866 const struct anv_surface_view *view =
2867 cmd_buffer->framebuffer->color_attachments[ca];
2868
2869 struct anv_state state =
2870 anv_cmd_buffer_alloc_surface_state(cmd_buffer, 64, 64);
2871
2872 if (state.map == NULL)
2873 return VK_ERROR_OUT_OF_DEVICE_MEMORY;
2874
2875 memcpy(state.map, view->surface_state.map, 64);
2876
2877 /* The address goes in dwords 8 and 9 of the SURFACE_STATE */
2878 *(uint64_t *)(state.map + 8 * 4) =
2879 anv_reloc_list_add(&cmd_buffer->surface_relocs,
2880 cmd_buffer->device,
2881 state.offset + 8 * 4,
2882 view->bo, view->offset);
2883
2884 bt_map[ca] = state.offset;
2885 }
2886
2887 if (layout == NULL)
2888 return VK_SUCCESS;
2889
2890 for (uint32_t set = 0; set < layout->num_sets; set++) {
2891 struct anv_descriptor_set_binding *d = &cmd_buffer->descriptors[set];
2892 struct anv_descriptor_set_layout *set_layout = layout->set[set].layout;
2893 struct anv_descriptor_slot *surface_slots =
2894 set_layout->stage[stage].surface_start;
2895
2896 uint32_t start = bias + layout->set[set].surface_start[stage];
2897
2898 for (uint32_t b = 0; b < set_layout->stage[stage].surface_count; b++) {
2899 struct anv_surface_view *view =
2900 d->set->descriptors[surface_slots[b].index].view;
2901
2902 if (!view)
2903 continue;
2904
2905 struct anv_state state =
2906 anv_cmd_buffer_alloc_surface_state(cmd_buffer, 64, 64);
2907
2908 if (state.map == NULL)
2909 return VK_ERROR_OUT_OF_DEVICE_MEMORY;
2910
2911 uint32_t offset;
2912 if (surface_slots[b].dynamic_slot >= 0) {
2913 uint32_t dynamic_offset =
2914 d->dynamic_offsets[surface_slots[b].dynamic_slot];
2915
2916 offset = view->offset + dynamic_offset;
2917 fill_buffer_surface_state(state.map, view->format, offset,
2918 view->range - dynamic_offset);
2919 } else {
2920 offset = view->offset;
2921 memcpy(state.map, view->surface_state.map, 64);
2922 }
2923
2924 /* The address goes in dwords 8 and 9 of the SURFACE_STATE */
2925 *(uint64_t *)(state.map + 8 * 4) =
2926 anv_reloc_list_add(&cmd_buffer->surface_relocs,
2927 cmd_buffer->device,
2928 state.offset + 8 * 4,
2929 view->bo, offset);
2930
2931 bt_map[start + b] = state.offset;
2932 }
2933 }
2934
2935 return VK_SUCCESS;
2936 }
2937
2938 static VkResult
2939 cmd_buffer_emit_samplers(struct anv_cmd_buffer *cmd_buffer, unsigned stage)
2940 {
2941 struct anv_pipeline_layout *layout = cmd_buffer->pipeline->layout;
2942 struct anv_state state;
2943
2944 if (!layout)
2945 return VK_SUCCESS;
2946
2947 uint32_t sampler_count = layout->stage[stage].sampler_count;
2948
2949 if (sampler_count == 0)
2950 return VK_SUCCESS;
2951
2952 uint32_t size = sampler_count * 16;
2953 state = anv_state_stream_alloc(&cmd_buffer->dynamic_state_stream, size, 32);
2954
2955 if (state.map == NULL)
2956 return VK_ERROR_OUT_OF_DEVICE_MEMORY;
2957
2958 static const uint32_t sampler_state_opcodes[] = {
2959 [VK_SHADER_STAGE_VERTEX] = 43,
2960 [VK_SHADER_STAGE_TESS_CONTROL] = 44, /* HS */
2961 [VK_SHADER_STAGE_TESS_EVALUATION] = 45, /* DS */
2962 [VK_SHADER_STAGE_GEOMETRY] = 46,
2963 [VK_SHADER_STAGE_FRAGMENT] = 47,
2964 [VK_SHADER_STAGE_COMPUTE] = 0,
2965 };
2966
2967 anv_batch_emit(&cmd_buffer->batch,
2968 GEN8_3DSTATE_SAMPLER_STATE_POINTERS_VS,
2969 ._3DCommandSubOpcode = sampler_state_opcodes[stage],
2970 .PointertoVSSamplerState = state.offset);
2971
2972 for (uint32_t set = 0; set < layout->num_sets; set++) {
2973 struct anv_descriptor_set_binding *d = &cmd_buffer->descriptors[set];
2974 struct anv_descriptor_set_layout *set_layout = layout->set[set].layout;
2975 struct anv_descriptor_slot *sampler_slots =
2976 set_layout->stage[stage].sampler_start;
2977
2978 uint32_t start = layout->set[set].sampler_start[stage];
2979
2980 for (uint32_t b = 0; b < set_layout->stage[stage].sampler_count; b++) {
2981 struct anv_sampler *sampler =
2982 d->set->descriptors[sampler_slots[b].index].sampler;
2983
2984 if (!sampler)
2985 continue;
2986
2987 memcpy(state.map + (start + b) * 16,
2988 sampler->state, sizeof(sampler->state));
2989 }
2990 }
2991
2992 return VK_SUCCESS;
2993 }
2994
2995 static void
2996 flush_descriptor_sets(struct anv_cmd_buffer *cmd_buffer)
2997 {
2998 uint32_t s, dirty = cmd_buffer->descriptors_dirty &
2999 cmd_buffer->pipeline->active_stages;
3000
3001 VkResult result;
3002 for_each_bit(s, dirty) {
3003 result = cmd_buffer_emit_binding_table(cmd_buffer, s);
3004 if (result != VK_SUCCESS)
3005 break;
3006
3007 result = cmd_buffer_emit_samplers(cmd_buffer, s);
3008 if (result != VK_SUCCESS)
3009 break;
3010 }
3011
3012 if (result != VK_SUCCESS) {
3013 assert(result == VK_ERROR_OUT_OF_DEVICE_MEMORY);
3014
3015 result = anv_cmd_buffer_new_surface_state_bo(cmd_buffer);
3016 assert(result == VK_SUCCESS);
3017
3018 /* Re-emit all active binding tables */
3019 for_each_bit(s, cmd_buffer->pipeline->active_stages) {
3020 result = cmd_buffer_emit_binding_table(cmd_buffer, s);
3021 result = cmd_buffer_emit_samplers(cmd_buffer, s);
3022 }
3023
3024 /* It had better succeed this time */
3025 assert(result == VK_SUCCESS);
3026 }
3027
3028 cmd_buffer->descriptors_dirty &= ~cmd_buffer->pipeline->active_stages;
3029 }
3030
3031 static struct anv_state
3032 anv_cmd_buffer_emit_dynamic(struct anv_cmd_buffer *cmd_buffer,
3033 uint32_t *a, uint32_t dwords, uint32_t alignment)
3034 {
3035 struct anv_state state;
3036
3037 state = anv_state_stream_alloc(&cmd_buffer->dynamic_state_stream,
3038 dwords * 4, alignment);
3039 memcpy(state.map, a, dwords * 4);
3040
3041 return state;
3042 }
3043
3044 static struct anv_state
3045 anv_cmd_buffer_merge_dynamic(struct anv_cmd_buffer *cmd_buffer,
3046 uint32_t *a, uint32_t *b,
3047 uint32_t dwords, uint32_t alignment)
3048 {
3049 struct anv_state state;
3050 uint32_t *p;
3051
3052 state = anv_state_stream_alloc(&cmd_buffer->dynamic_state_stream,
3053 dwords * 4, alignment);
3054 p = state.map;
3055 for (uint32_t i = 0; i < dwords; i++)
3056 p[i] = a[i] | b[i];
3057
3058 return state;
3059 }
3060
3061 static void
3062 anv_cmd_buffer_flush_state(struct anv_cmd_buffer *cmd_buffer)
3063 {
3064 struct anv_pipeline *pipeline = cmd_buffer->pipeline;
3065 uint32_t *p;
3066
3067 uint32_t vb_emit = cmd_buffer->vb_dirty & pipeline->vb_used;
3068
3069 if (vb_emit) {
3070 const uint32_t num_buffers = __builtin_popcount(vb_emit);
3071 const uint32_t num_dwords = 1 + num_buffers * 4;
3072
3073 p = anv_batch_emitn(&cmd_buffer->batch, num_dwords,
3074 GEN8_3DSTATE_VERTEX_BUFFERS);
3075 uint32_t vb, i = 0;
3076 for_each_bit(vb, vb_emit) {
3077 struct anv_buffer *buffer = cmd_buffer->vertex_bindings[vb].buffer;
3078 uint32_t offset = cmd_buffer->vertex_bindings[vb].offset;
3079
3080 struct GEN8_VERTEX_BUFFER_STATE state = {
3081 .VertexBufferIndex = vb,
3082 .MemoryObjectControlState = GEN8_MOCS,
3083 .AddressModifyEnable = true,
3084 .BufferPitch = pipeline->binding_stride[vb],
3085 .BufferStartingAddress = { buffer->bo, buffer->offset + offset },
3086 .BufferSize = buffer->size - offset
3087 };
3088
3089 GEN8_VERTEX_BUFFER_STATE_pack(&cmd_buffer->batch, &p[1 + i * 4], &state);
3090 i++;
3091 }
3092 }
3093
3094 if (cmd_buffer->dirty & ANV_CMD_BUFFER_PIPELINE_DIRTY)
3095 anv_batch_emit_batch(&cmd_buffer->batch, &pipeline->batch);
3096
3097 if (cmd_buffer->descriptors_dirty)
3098 flush_descriptor_sets(cmd_buffer);
3099
3100 if (cmd_buffer->dirty & (ANV_CMD_BUFFER_PIPELINE_DIRTY | ANV_CMD_BUFFER_RS_DIRTY)) {
3101 anv_batch_emit_merge(&cmd_buffer->batch,
3102 cmd_buffer->rs_state->state_sf, pipeline->state_sf);
3103 anv_batch_emit_merge(&cmd_buffer->batch,
3104 cmd_buffer->rs_state->state_raster, pipeline->state_raster);
3105 }
3106
3107 if (cmd_buffer->ds_state &&
3108 (cmd_buffer->dirty & (ANV_CMD_BUFFER_PIPELINE_DIRTY | ANV_CMD_BUFFER_DS_DIRTY)))
3109 anv_batch_emit_merge(&cmd_buffer->batch,
3110 cmd_buffer->ds_state->state_wm_depth_stencil,
3111 pipeline->state_wm_depth_stencil);
3112
3113 if (cmd_buffer->dirty & (ANV_CMD_BUFFER_CB_DIRTY | ANV_CMD_BUFFER_DS_DIRTY)) {
3114 struct anv_state state;
3115 if (cmd_buffer->ds_state == NULL)
3116 state = anv_cmd_buffer_emit_dynamic(cmd_buffer,
3117 cmd_buffer->cb_state->state_color_calc,
3118 GEN8_COLOR_CALC_STATE_length, 64);
3119 else if (cmd_buffer->cb_state == NULL)
3120 state = anv_cmd_buffer_emit_dynamic(cmd_buffer,
3121 cmd_buffer->ds_state->state_color_calc,
3122 GEN8_COLOR_CALC_STATE_length, 64);
3123 else
3124 state = anv_cmd_buffer_merge_dynamic(cmd_buffer,
3125 cmd_buffer->ds_state->state_color_calc,
3126 cmd_buffer->cb_state->state_color_calc,
3127 GEN8_COLOR_CALC_STATE_length, 64);
3128
3129 anv_batch_emit(&cmd_buffer->batch,
3130 GEN8_3DSTATE_CC_STATE_POINTERS,
3131 .ColorCalcStatePointer = state.offset,
3132 .ColorCalcStatePointerValid = true);
3133 }
3134
3135 cmd_buffer->vb_dirty &= ~vb_emit;
3136 cmd_buffer->dirty = 0;
3137 }
3138
3139 void anv_CmdDraw(
3140 VkCmdBuffer cmdBuffer,
3141 uint32_t firstVertex,
3142 uint32_t vertexCount,
3143 uint32_t firstInstance,
3144 uint32_t instanceCount)
3145 {
3146 struct anv_cmd_buffer *cmd_buffer = (struct anv_cmd_buffer *) cmdBuffer;
3147
3148 anv_cmd_buffer_flush_state(cmd_buffer);
3149
3150 anv_batch_emit(&cmd_buffer->batch, GEN8_3DPRIMITIVE,
3151 .VertexAccessType = SEQUENTIAL,
3152 .VertexCountPerInstance = vertexCount,
3153 .StartVertexLocation = firstVertex,
3154 .InstanceCount = instanceCount,
3155 .StartInstanceLocation = firstInstance,
3156 .BaseVertexLocation = 0);
3157 }
3158
3159 void anv_CmdDrawIndexed(
3160 VkCmdBuffer cmdBuffer,
3161 uint32_t firstIndex,
3162 uint32_t indexCount,
3163 int32_t vertexOffset,
3164 uint32_t firstInstance,
3165 uint32_t instanceCount)
3166 {
3167 struct anv_cmd_buffer *cmd_buffer = (struct anv_cmd_buffer *) cmdBuffer;
3168
3169 anv_cmd_buffer_flush_state(cmd_buffer);
3170
3171 anv_batch_emit(&cmd_buffer->batch, GEN8_3DPRIMITIVE,
3172 .VertexAccessType = RANDOM,
3173 .VertexCountPerInstance = indexCount,
3174 .StartVertexLocation = firstIndex,
3175 .InstanceCount = instanceCount,
3176 .StartInstanceLocation = firstInstance,
3177 .BaseVertexLocation = vertexOffset);
3178 }
3179
3180 static void
3181 anv_batch_lrm(struct anv_batch *batch,
3182 uint32_t reg, struct anv_bo *bo, uint32_t offset)
3183 {
3184 anv_batch_emit(batch, GEN8_MI_LOAD_REGISTER_MEM,
3185 .RegisterAddress = reg,
3186 .MemoryAddress = { bo, offset });
3187 }
3188
3189 static void
3190 anv_batch_lri(struct anv_batch *batch, uint32_t reg, uint32_t imm)
3191 {
3192 anv_batch_emit(batch, GEN8_MI_LOAD_REGISTER_IMM,
3193 .RegisterOffset = reg,
3194 .DataDWord = imm);
3195 }
3196
3197 /* Auto-Draw / Indirect Registers */
3198 #define GEN7_3DPRIM_END_OFFSET 0x2420
3199 #define GEN7_3DPRIM_START_VERTEX 0x2430
3200 #define GEN7_3DPRIM_VERTEX_COUNT 0x2434
3201 #define GEN7_3DPRIM_INSTANCE_COUNT 0x2438
3202 #define GEN7_3DPRIM_START_INSTANCE 0x243C
3203 #define GEN7_3DPRIM_BASE_VERTEX 0x2440
3204
3205 void anv_CmdDrawIndirect(
3206 VkCmdBuffer cmdBuffer,
3207 VkBuffer _buffer,
3208 VkDeviceSize offset,
3209 uint32_t count,
3210 uint32_t stride)
3211 {
3212 struct anv_cmd_buffer *cmd_buffer = (struct anv_cmd_buffer *) cmdBuffer;
3213 struct anv_buffer *buffer = (struct anv_buffer *) _buffer;
3214 struct anv_bo *bo = buffer->bo;
3215 uint32_t bo_offset = buffer->offset + offset;
3216
3217 anv_cmd_buffer_flush_state(cmd_buffer);
3218
3219 anv_batch_lrm(&cmd_buffer->batch, GEN7_3DPRIM_VERTEX_COUNT, bo, bo_offset);
3220 anv_batch_lrm(&cmd_buffer->batch, GEN7_3DPRIM_INSTANCE_COUNT, bo, bo_offset + 4);
3221 anv_batch_lrm(&cmd_buffer->batch, GEN7_3DPRIM_START_VERTEX, bo, bo_offset + 8);
3222 anv_batch_lrm(&cmd_buffer->batch, GEN7_3DPRIM_START_INSTANCE, bo, bo_offset + 12);
3223 anv_batch_lri(&cmd_buffer->batch, GEN7_3DPRIM_BASE_VERTEX, 0);
3224
3225 anv_batch_emit(&cmd_buffer->batch, GEN8_3DPRIMITIVE,
3226 .IndirectParameterEnable = true,
3227 .VertexAccessType = SEQUENTIAL);
3228 }
3229
3230 void anv_CmdDrawIndexedIndirect(
3231 VkCmdBuffer cmdBuffer,
3232 VkBuffer _buffer,
3233 VkDeviceSize offset,
3234 uint32_t count,
3235 uint32_t stride)
3236 {
3237 struct anv_cmd_buffer *cmd_buffer = (struct anv_cmd_buffer *) cmdBuffer;
3238 struct anv_buffer *buffer = (struct anv_buffer *) _buffer;
3239 struct anv_bo *bo = buffer->bo;
3240 uint32_t bo_offset = buffer->offset + offset;
3241
3242 anv_cmd_buffer_flush_state(cmd_buffer);
3243
3244 anv_batch_lrm(&cmd_buffer->batch, GEN7_3DPRIM_VERTEX_COUNT, bo, bo_offset);
3245 anv_batch_lrm(&cmd_buffer->batch, GEN7_3DPRIM_INSTANCE_COUNT, bo, bo_offset + 4);
3246 anv_batch_lrm(&cmd_buffer->batch, GEN7_3DPRIM_START_VERTEX, bo, bo_offset + 8);
3247 anv_batch_lrm(&cmd_buffer->batch, GEN7_3DPRIM_BASE_VERTEX, bo, bo_offset + 12);
3248 anv_batch_lrm(&cmd_buffer->batch, GEN7_3DPRIM_START_INSTANCE, bo, bo_offset + 16);
3249
3250 anv_batch_emit(&cmd_buffer->batch, GEN8_3DPRIMITIVE,
3251 .IndirectParameterEnable = true,
3252 .VertexAccessType = RANDOM);
3253 }
3254
3255 void anv_CmdDispatch(
3256 VkCmdBuffer cmdBuffer,
3257 uint32_t x,
3258 uint32_t y,
3259 uint32_t z)
3260 {
3261 stub();
3262 }
3263
3264 void anv_CmdDispatchIndirect(
3265 VkCmdBuffer cmdBuffer,
3266 VkBuffer buffer,
3267 VkDeviceSize offset)
3268 {
3269 stub();
3270 }
3271
3272 void anv_CmdSetEvent(
3273 VkCmdBuffer cmdBuffer,
3274 VkEvent event,
3275 VkPipeEvent pipeEvent)
3276 {
3277 stub();
3278 }
3279
3280 void anv_CmdResetEvent(
3281 VkCmdBuffer cmdBuffer,
3282 VkEvent event,
3283 VkPipeEvent pipeEvent)
3284 {
3285 stub();
3286 }
3287
3288 void anv_CmdWaitEvents(
3289 VkCmdBuffer cmdBuffer,
3290 VkWaitEvent waitEvent,
3291 uint32_t eventCount,
3292 const VkEvent* pEvents,
3293 uint32_t memBarrierCount,
3294 const void** ppMemBarriers)
3295 {
3296 stub();
3297 }
3298
3299 void anv_CmdPipelineBarrier(
3300 VkCmdBuffer cmdBuffer,
3301 VkWaitEvent waitEvent,
3302 uint32_t pipeEventCount,
3303 const VkPipeEvent* pPipeEvents,
3304 uint32_t memBarrierCount,
3305 const void** ppMemBarriers)
3306 {
3307 stub();
3308 }
3309
3310 void anv_CmdInitAtomicCounters(
3311 VkCmdBuffer cmdBuffer,
3312 VkPipelineBindPoint pipelineBindPoint,
3313 uint32_t startCounter,
3314 uint32_t counterCount,
3315 const uint32_t* pData)
3316 {
3317 stub();
3318 }
3319
3320 void anv_CmdLoadAtomicCounters(
3321 VkCmdBuffer cmdBuffer,
3322 VkPipelineBindPoint pipelineBindPoint,
3323 uint32_t startCounter,
3324 uint32_t counterCount,
3325 VkBuffer srcBuffer,
3326 VkDeviceSize srcOffset)
3327 {
3328 stub();
3329 }
3330
3331 void anv_CmdSaveAtomicCounters(
3332 VkCmdBuffer cmdBuffer,
3333 VkPipelineBindPoint pipelineBindPoint,
3334 uint32_t startCounter,
3335 uint32_t counterCount,
3336 VkBuffer destBuffer,
3337 VkDeviceSize destOffset)
3338 {
3339 stub();
3340 }
3341
3342 static void
3343 anv_framebuffer_destroy(struct anv_device *device,
3344 struct anv_object *object,
3345 VkObjectType obj_type)
3346 {
3347 struct anv_framebuffer *fb = (struct anv_framebuffer *)object;
3348
3349 assert(obj_type == VK_OBJECT_TYPE_FRAMEBUFFER);
3350
3351 anv_DestroyObject((VkDevice) device,
3352 VK_OBJECT_TYPE_DYNAMIC_VP_STATE,
3353 fb->vp_state);
3354
3355 anv_device_free(device, fb);
3356 }
3357
3358 VkResult anv_CreateFramebuffer(
3359 VkDevice _device,
3360 const VkFramebufferCreateInfo* pCreateInfo,
3361 VkFramebuffer* pFramebuffer)
3362 {
3363 struct anv_device *device = (struct anv_device *) _device;
3364 struct anv_framebuffer *framebuffer;
3365
3366 static const struct anv_depth_stencil_view null_view =
3367 { .depth_format = D16_UNORM, .depth_stride = 0, .stencil_stride = 0 };
3368
3369 assert(pCreateInfo->sType == VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO);
3370
3371 framebuffer = anv_device_alloc(device, sizeof(*framebuffer), 8,
3372 VK_SYSTEM_ALLOC_TYPE_API_OBJECT);
3373 if (framebuffer == NULL)
3374 return vk_error(VK_ERROR_OUT_OF_HOST_MEMORY);
3375
3376 framebuffer->base.destructor = anv_framebuffer_destroy;
3377
3378 framebuffer->color_attachment_count = pCreateInfo->colorAttachmentCount;
3379 for (uint32_t i = 0; i < pCreateInfo->colorAttachmentCount; i++) {
3380 framebuffer->color_attachments[i] =
3381 (struct anv_surface_view *) pCreateInfo->pColorAttachments[i].view;
3382 }
3383
3384 if (pCreateInfo->pDepthStencilAttachment) {
3385 framebuffer->depth_stencil =
3386 (struct anv_depth_stencil_view *) pCreateInfo->pDepthStencilAttachment->view;
3387 } else {
3388 framebuffer->depth_stencil = &null_view;
3389 }
3390
3391 framebuffer->sample_count = pCreateInfo->sampleCount;
3392 framebuffer->width = pCreateInfo->width;
3393 framebuffer->height = pCreateInfo->height;
3394 framebuffer->layers = pCreateInfo->layers;
3395
3396 vkCreateDynamicViewportState((VkDevice) device,
3397 &(VkDynamicVpStateCreateInfo) {
3398 .sType = VK_STRUCTURE_TYPE_DYNAMIC_VP_STATE_CREATE_INFO,
3399 .viewportAndScissorCount = 1,
3400 .pViewports = (VkViewport[]) {
3401 {
3402 .originX = 0,
3403 .originY = 0,
3404 .width = pCreateInfo->width,
3405 .height = pCreateInfo->height,
3406 .minDepth = 0,
3407 .maxDepth = 1
3408 },
3409 },
3410 .pScissors = (VkRect[]) {
3411 { { 0, 0 },
3412 { pCreateInfo->width, pCreateInfo->height } },
3413 }
3414 },
3415 &framebuffer->vp_state);
3416
3417 *pFramebuffer = (VkFramebuffer) framebuffer;
3418
3419 return VK_SUCCESS;
3420 }
3421
3422 VkResult anv_CreateRenderPass(
3423 VkDevice _device,
3424 const VkRenderPassCreateInfo* pCreateInfo,
3425 VkRenderPass* pRenderPass)
3426 {
3427 struct anv_device *device = (struct anv_device *) _device;
3428 struct anv_render_pass *pass;
3429 size_t size;
3430
3431 assert(pCreateInfo->sType == VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO);
3432
3433 size = sizeof(*pass) +
3434 pCreateInfo->layers * sizeof(struct anv_render_pass_layer);
3435 pass = anv_device_alloc(device, size, 8,
3436 VK_SYSTEM_ALLOC_TYPE_API_OBJECT);
3437 if (pass == NULL)
3438 return vk_error(VK_ERROR_OUT_OF_HOST_MEMORY);
3439
3440 pass->render_area = pCreateInfo->renderArea;
3441
3442 pass->num_layers = pCreateInfo->layers;
3443
3444 pass->num_clear_layers = 0;
3445 for (uint32_t i = 0; i < pCreateInfo->layers; i++) {
3446 pass->layers[i].color_load_op = pCreateInfo->pColorLoadOps[i];
3447 pass->layers[i].clear_color = pCreateInfo->pColorLoadClearValues[i];
3448 if (pass->layers[i].color_load_op == VK_ATTACHMENT_LOAD_OP_CLEAR)
3449 pass->num_clear_layers++;
3450 }
3451
3452 *pRenderPass = (VkRenderPass) pass;
3453
3454 return VK_SUCCESS;
3455 }
3456
3457 static void
3458 anv_cmd_buffer_emit_depth_stencil(struct anv_cmd_buffer *cmd_buffer,
3459 struct anv_render_pass *pass)
3460 {
3461 const struct anv_depth_stencil_view *view =
3462 cmd_buffer->framebuffer->depth_stencil;
3463
3464 /* FIXME: Implement the PMA stall W/A */
3465
3466 anv_batch_emit(&cmd_buffer->batch, GEN8_3DSTATE_DEPTH_BUFFER,
3467 .SurfaceType = SURFTYPE_2D,
3468 .DepthWriteEnable = view->depth_stride > 0,
3469 .StencilWriteEnable = view->stencil_stride > 0,
3470 .HierarchicalDepthBufferEnable = false,
3471 .SurfaceFormat = view->depth_format,
3472 .SurfacePitch = view->depth_stride > 0 ? view->depth_stride - 1 : 0,
3473 .SurfaceBaseAddress = { view->bo, view->depth_offset },
3474 .Height = pass->render_area.extent.height - 1,
3475 .Width = pass->render_area.extent.width - 1,
3476 .LOD = 0,
3477 .Depth = 1 - 1,
3478 .MinimumArrayElement = 0,
3479 .DepthBufferObjectControlState = GEN8_MOCS,
3480 .RenderTargetViewExtent = 1 - 1,
3481 .SurfaceQPitch = 0);
3482
3483 /* Disable hierarchial depth buffers. */
3484 anv_batch_emit(&cmd_buffer->batch, GEN8_3DSTATE_HIER_DEPTH_BUFFER);
3485
3486 anv_batch_emit(&cmd_buffer->batch, GEN8_3DSTATE_STENCIL_BUFFER,
3487 .StencilBufferEnable = view->stencil_stride > 0,
3488 .StencilBufferObjectControlState = GEN8_MOCS,
3489 .SurfacePitch = view->stencil_stride > 0 ? view->stencil_stride - 1 : 0,
3490 .SurfaceBaseAddress = { view->bo, view->stencil_offset },
3491 .SurfaceQPitch = 0);
3492
3493 /* Clear the clear params. */
3494 anv_batch_emit(&cmd_buffer->batch, GEN8_3DSTATE_CLEAR_PARAMS);
3495 }
3496
3497 void anv_CmdBeginRenderPass(
3498 VkCmdBuffer cmdBuffer,
3499 const VkRenderPassBegin* pRenderPassBegin)
3500 {
3501 struct anv_cmd_buffer *cmd_buffer = (struct anv_cmd_buffer *) cmdBuffer;
3502 struct anv_render_pass *pass = (struct anv_render_pass *) pRenderPassBegin->renderPass;
3503 struct anv_framebuffer *framebuffer =
3504 (struct anv_framebuffer *) pRenderPassBegin->framebuffer;
3505
3506 cmd_buffer->framebuffer = framebuffer;
3507
3508 cmd_buffer->descriptors_dirty |= VK_SHADER_STAGE_FRAGMENT_BIT;
3509
3510 anv_batch_emit(&cmd_buffer->batch, GEN8_3DSTATE_DRAWING_RECTANGLE,
3511 .ClippedDrawingRectangleYMin = pass->render_area.offset.y,
3512 .ClippedDrawingRectangleXMin = pass->render_area.offset.x,
3513 .ClippedDrawingRectangleYMax =
3514 pass->render_area.offset.y + pass->render_area.extent.height - 1,
3515 .ClippedDrawingRectangleXMax =
3516 pass->render_area.offset.x + pass->render_area.extent.width - 1,
3517 .DrawingRectangleOriginY = 0,
3518 .DrawingRectangleOriginX = 0);
3519
3520 anv_cmd_buffer_emit_depth_stencil(cmd_buffer, pass);
3521
3522 anv_cmd_buffer_clear(cmd_buffer, pass);
3523 }
3524
3525 void anv_CmdEndRenderPass(
3526 VkCmdBuffer cmdBuffer,
3527 VkRenderPass renderPass)
3528 {
3529 /* Emit a flushing pipe control at the end of a pass. This is kind of a
3530 * hack but it ensures that render targets always actually get written.
3531 * Eventually, we should do flushing based on image format transitions
3532 * or something of that nature.
3533 */
3534 struct anv_cmd_buffer *cmd_buffer = (struct anv_cmd_buffer *)cmdBuffer;
3535 anv_batch_emit(&cmd_buffer->batch, GEN8_PIPE_CONTROL,
3536 .PostSyncOperation = NoWrite,
3537 .RenderTargetCacheFlushEnable = true,
3538 .InstructionCacheInvalidateEnable = true,
3539 .DepthCacheFlushEnable = true,
3540 .VFCacheInvalidationEnable = true,
3541 .TextureCacheInvalidationEnable = true,
3542 .CommandStreamerStallEnable = true);
3543 }
3544
3545 void vkCmdDbgMarkerBegin(
3546 VkCmdBuffer cmdBuffer,
3547 const char* pMarker)
3548 __attribute__ ((visibility ("default")));
3549
3550 void vkCmdDbgMarkerEnd(
3551 VkCmdBuffer cmdBuffer)
3552 __attribute__ ((visibility ("default")));
3553
3554 VkResult vkDbgSetObjectTag(
3555 VkDevice device,
3556 VkObject object,
3557 size_t tagSize,
3558 const void* pTag)
3559 __attribute__ ((visibility ("default")));
3560
3561
3562 void vkCmdDbgMarkerBegin(
3563 VkCmdBuffer cmdBuffer,
3564 const char* pMarker)
3565 {
3566 }
3567
3568 void vkCmdDbgMarkerEnd(
3569 VkCmdBuffer cmdBuffer)
3570 {
3571 }
3572
3573 VkResult vkDbgSetObjectTag(
3574 VkDevice device,
3575 VkObject object,
3576 size_t tagSize,
3577 const void* pTag)
3578 {
3579 return VK_SUCCESS;
3580 }