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