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