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