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