vk: Use a separate block pool and state stream for binding tables
[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_batch_finish(&cmd_buffer->batch, device);
930 anv_device_free(device, cmd_buffer->exec2_objects);
931 anv_device_free(device, cmd_buffer->exec2_bos);
932 anv_device_free(device, cmd_buffer);
933
934 return VK_SUCCESS;
935 }
936
937 static VkResult
938 anv_pipeline_destructor(struct anv_device * device,
939 VkObject object)
940 {
941 struct anv_pipeline *pipeline = (struct anv_pipeline *) object;
942
943 return anv_pipeline_destroy(pipeline);
944 }
945
946 static VkResult
947 anv_free_destructor(struct anv_device * device,
948 VkObject object)
949 {
950 anv_device_free(device, (void *) object);
951
952 return VK_SUCCESS;
953 }
954
955 static VkResult
956 anv_fence_destructor(struct anv_device * device,
957 VkObject object)
958 {
959 struct anv_fence *fence = (struct anv_fence *) object;
960
961 anv_gem_munmap(fence->bo.map, fence->bo.size);
962 anv_gem_close(device, fence->bo.gem_handle);
963 anv_device_free(device, fence);
964
965 return VK_SUCCESS;
966 }
967
968 static VkResult
969 anv_query_pool_destructor(struct anv_device * device,
970 VkObject object)
971 {
972 struct anv_query_pool *pool = (struct anv_query_pool *) object;
973
974 anv_gem_munmap(pool->bo.map, pool->bo.size);
975 anv_gem_close(device, pool->bo.gem_handle);
976 anv_device_free(device, pool);
977
978 return VK_SUCCESS;
979 }
980
981 static VkResult (*anv_object_destructors[])(struct anv_device *device,
982 VkObject object) = {
983 [VK_OBJECT_TYPE_INSTANCE] = anv_instance_destructor,
984 [VK_OBJECT_TYPE_PHYSICAL_DEVICE] = anv_noop_destructor,
985 [VK_OBJECT_TYPE_DEVICE] = anv_device_destructor,
986 [VK_OBJECT_TYPE_QUEUE] = anv_noop_destructor,
987 [VK_OBJECT_TYPE_COMMAND_BUFFER] = anv_cmd_buffer_destructor,
988 [VK_OBJECT_TYPE_PIPELINE] = anv_pipeline_destructor,
989 [VK_OBJECT_TYPE_SHADER] = anv_free_destructor,
990 [VK_OBJECT_TYPE_BUFFER] = anv_free_destructor,
991 [VK_OBJECT_TYPE_IMAGE] = anv_free_destructor,
992 [VK_OBJECT_TYPE_RENDER_PASS] = anv_free_destructor,
993 [VK_OBJECT_TYPE_FENCE] = anv_fence_destructor,
994 [VK_OBJECT_TYPE_QUERY_POOL] = anv_query_pool_destructor
995 };
996
997 VkResult anv_DestroyObject(
998 VkDevice _device,
999 VkObjectType objType,
1000 VkObject object)
1001 {
1002 struct anv_device *device = (struct anv_device *) _device;
1003
1004 assert(objType < ARRAY_SIZE(anv_object_destructors) &&
1005 anv_object_destructors[objType] != NULL);
1006
1007 return anv_object_destructors[objType](device, object);
1008 }
1009
1010 static void
1011 fill_memory_requirements(
1012 VkObjectType objType,
1013 VkObject object,
1014 VkMemoryRequirements * memory_requirements)
1015 {
1016 struct anv_buffer *buffer;
1017 struct anv_image *image;
1018
1019 memory_requirements->memPropsAllowed =
1020 VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT |
1021 VK_MEMORY_PROPERTY_HOST_DEVICE_COHERENT_BIT |
1022 /* VK_MEMORY_PROPERTY_HOST_UNCACHED_BIT | */
1023 VK_MEMORY_PROPERTY_HOST_WRITE_COMBINED_BIT |
1024 VK_MEMORY_PROPERTY_PREFER_HOST_LOCAL |
1025 VK_MEMORY_PROPERTY_SHAREABLE_BIT;
1026
1027 memory_requirements->memPropsRequired = 0;
1028
1029 switch (objType) {
1030 case VK_OBJECT_TYPE_BUFFER:
1031 buffer = (struct anv_buffer *) object;
1032 memory_requirements->size = buffer->size;
1033 memory_requirements->alignment = 16;
1034 break;
1035 case VK_OBJECT_TYPE_IMAGE:
1036 image = (struct anv_image *) object;
1037 memory_requirements->size = image->size;
1038 memory_requirements->alignment = image->alignment;
1039 break;
1040 default:
1041 memory_requirements->size = 0;
1042 break;
1043 }
1044 }
1045
1046 static uint32_t
1047 get_allocation_count(VkObjectType objType)
1048 {
1049 switch (objType) {
1050 case VK_OBJECT_TYPE_BUFFER:
1051 case VK_OBJECT_TYPE_IMAGE:
1052 return 1;
1053 default:
1054 return 0;
1055 }
1056 }
1057
1058 VkResult anv_GetObjectInfo(
1059 VkDevice _device,
1060 VkObjectType objType,
1061 VkObject object,
1062 VkObjectInfoType infoType,
1063 size_t* pDataSize,
1064 void* pData)
1065 {
1066 VkMemoryRequirements memory_requirements;
1067 uint32_t *count;
1068
1069 switch (infoType) {
1070 case VK_OBJECT_INFO_TYPE_MEMORY_REQUIREMENTS:
1071 *pDataSize = sizeof(memory_requirements);
1072 if (pData == NULL)
1073 return VK_SUCCESS;
1074
1075 fill_memory_requirements(objType, object, pData);
1076 return VK_SUCCESS;
1077
1078 case VK_OBJECT_INFO_TYPE_MEMORY_ALLOCATION_COUNT:
1079 *pDataSize = sizeof(count);
1080 if (pData == NULL)
1081 return VK_SUCCESS;
1082
1083 count = pData;
1084 *count = get_allocation_count(objType);
1085 return VK_SUCCESS;
1086
1087 default:
1088 return VK_UNSUPPORTED;
1089 }
1090
1091 }
1092
1093 VkResult anv_QueueBindObjectMemory(
1094 VkQueue queue,
1095 VkObjectType objType,
1096 VkObject object,
1097 uint32_t allocationIdx,
1098 VkDeviceMemory _mem,
1099 VkDeviceSize memOffset)
1100 {
1101 struct anv_buffer *buffer;
1102 struct anv_image *image;
1103 struct anv_device_memory *mem = (struct anv_device_memory *) _mem;
1104
1105 switch (objType) {
1106 case VK_OBJECT_TYPE_BUFFER:
1107 buffer = (struct anv_buffer *) object;
1108 buffer->bo = &mem->bo;
1109 buffer->offset = memOffset;
1110 break;
1111 case VK_OBJECT_TYPE_IMAGE:
1112 image = (struct anv_image *) object;
1113 image->bo = &mem->bo;
1114 image->offset = memOffset;
1115 break;
1116 default:
1117 break;
1118 }
1119
1120 return VK_SUCCESS;
1121 }
1122
1123 VkResult anv_QueueBindObjectMemoryRange(
1124 VkQueue queue,
1125 VkObjectType objType,
1126 VkObject object,
1127 uint32_t allocationIdx,
1128 VkDeviceSize rangeOffset,
1129 VkDeviceSize rangeSize,
1130 VkDeviceMemory mem,
1131 VkDeviceSize memOffset)
1132 {
1133 stub_return(VK_UNSUPPORTED);
1134 }
1135
1136 VkResult anv_QueueBindImageMemoryRange(
1137 VkQueue queue,
1138 VkImage image,
1139 uint32_t allocationIdx,
1140 const VkImageMemoryBindInfo* pBindInfo,
1141 VkDeviceMemory mem,
1142 VkDeviceSize memOffset)
1143 {
1144 stub_return(VK_UNSUPPORTED);
1145 }
1146
1147 VkResult anv_CreateFence(
1148 VkDevice _device,
1149 const VkFenceCreateInfo* pCreateInfo,
1150 VkFence* pFence)
1151 {
1152 struct anv_device *device = (struct anv_device *) _device;
1153 struct anv_fence *fence;
1154 struct anv_batch batch;
1155 VkResult result;
1156
1157 const uint32_t fence_size = 128;
1158
1159 assert(pCreateInfo->sType == VK_STRUCTURE_TYPE_FENCE_CREATE_INFO);
1160
1161 fence = anv_device_alloc(device, sizeof(*fence), 8,
1162 VK_SYSTEM_ALLOC_TYPE_API_OBJECT);
1163 if (fence == NULL)
1164 return vk_error(VK_ERROR_OUT_OF_HOST_MEMORY);
1165
1166 result = anv_bo_init_new(&fence->bo, device, fence_size);
1167 if (result != VK_SUCCESS)
1168 goto fail;
1169
1170 fence->bo.map =
1171 anv_gem_mmap(device, fence->bo.gem_handle, 0, fence->bo.size);
1172 batch.next = fence->bo.map;
1173 anv_batch_emit(&batch, GEN8_MI_BATCH_BUFFER_END);
1174 anv_batch_emit(&batch, GEN8_MI_NOOP);
1175
1176 fence->exec2_objects[0].handle = fence->bo.gem_handle;
1177 fence->exec2_objects[0].relocation_count = 0;
1178 fence->exec2_objects[0].relocs_ptr = 0;
1179 fence->exec2_objects[0].alignment = 0;
1180 fence->exec2_objects[0].offset = fence->bo.offset;
1181 fence->exec2_objects[0].flags = 0;
1182 fence->exec2_objects[0].rsvd1 = 0;
1183 fence->exec2_objects[0].rsvd2 = 0;
1184
1185 fence->execbuf.buffers_ptr = (uintptr_t) fence->exec2_objects;
1186 fence->execbuf.buffer_count = 1;
1187 fence->execbuf.batch_start_offset = 0;
1188 fence->execbuf.batch_len = batch.next - fence->bo.map;
1189 fence->execbuf.cliprects_ptr = 0;
1190 fence->execbuf.num_cliprects = 0;
1191 fence->execbuf.DR1 = 0;
1192 fence->execbuf.DR4 = 0;
1193
1194 fence->execbuf.flags =
1195 I915_EXEC_HANDLE_LUT | I915_EXEC_NO_RELOC | I915_EXEC_RENDER;
1196 fence->execbuf.rsvd1 = device->context_id;
1197 fence->execbuf.rsvd2 = 0;
1198
1199 *pFence = (VkQueryPool) fence;
1200
1201 return VK_SUCCESS;
1202
1203 fail:
1204 anv_device_free(device, fence);
1205
1206 return result;
1207 }
1208
1209 VkResult anv_ResetFences(
1210 VkDevice _device,
1211 uint32_t fenceCount,
1212 VkFence* pFences)
1213 {
1214 struct anv_fence **fences = (struct anv_fence **) pFences;
1215
1216 for (uint32_t i; i < fenceCount; i++)
1217 fences[i]->ready = false;
1218
1219 return VK_SUCCESS;
1220 }
1221
1222 VkResult anv_GetFenceStatus(
1223 VkDevice _device,
1224 VkFence _fence)
1225 {
1226 struct anv_device *device = (struct anv_device *) _device;
1227 struct anv_fence *fence = (struct anv_fence *) _fence;
1228 int64_t t = 0;
1229 int ret;
1230
1231 if (fence->ready)
1232 return VK_SUCCESS;
1233
1234 ret = anv_gem_wait(device, fence->bo.gem_handle, &t);
1235 if (ret == 0) {
1236 fence->ready = true;
1237 return VK_SUCCESS;
1238 }
1239
1240 return VK_NOT_READY;
1241 }
1242
1243 VkResult anv_WaitForFences(
1244 VkDevice _device,
1245 uint32_t fenceCount,
1246 const VkFence* pFences,
1247 bool32_t waitAll,
1248 uint64_t timeout)
1249 {
1250 struct anv_device *device = (struct anv_device *) _device;
1251 struct anv_fence **fences = (struct anv_fence **) pFences;
1252 int64_t t = timeout;
1253 int ret;
1254
1255 /* FIXME: handle !waitAll */
1256
1257 for (uint32_t i = 0; i < fenceCount; i++) {
1258 ret = anv_gem_wait(device, fences[i]->bo.gem_handle, &t);
1259 if (ret == -1 && errno == ETIME)
1260 return VK_TIMEOUT;
1261 else if (ret == -1)
1262 return vk_error(VK_ERROR_UNKNOWN);
1263 }
1264
1265 return VK_SUCCESS;
1266 }
1267
1268 // Queue semaphore functions
1269
1270 VkResult anv_CreateSemaphore(
1271 VkDevice device,
1272 const VkSemaphoreCreateInfo* pCreateInfo,
1273 VkSemaphore* pSemaphore)
1274 {
1275 stub_return(VK_UNSUPPORTED);
1276 }
1277
1278 VkResult anv_QueueSignalSemaphore(
1279 VkQueue queue,
1280 VkSemaphore semaphore)
1281 {
1282 stub_return(VK_UNSUPPORTED);
1283 }
1284
1285 VkResult anv_QueueWaitSemaphore(
1286 VkQueue queue,
1287 VkSemaphore semaphore)
1288 {
1289 stub_return(VK_UNSUPPORTED);
1290 }
1291
1292 // Event functions
1293
1294 VkResult anv_CreateEvent(
1295 VkDevice device,
1296 const VkEventCreateInfo* pCreateInfo,
1297 VkEvent* pEvent)
1298 {
1299 stub_return(VK_UNSUPPORTED);
1300 }
1301
1302 VkResult anv_GetEventStatus(
1303 VkDevice device,
1304 VkEvent event)
1305 {
1306 stub_return(VK_UNSUPPORTED);
1307 }
1308
1309 VkResult anv_SetEvent(
1310 VkDevice device,
1311 VkEvent event)
1312 {
1313 stub_return(VK_UNSUPPORTED);
1314 }
1315
1316 VkResult anv_ResetEvent(
1317 VkDevice device,
1318 VkEvent event)
1319 {
1320 stub_return(VK_UNSUPPORTED);
1321 }
1322
1323 // Query functions
1324
1325 VkResult anv_CreateQueryPool(
1326 VkDevice _device,
1327 const VkQueryPoolCreateInfo* pCreateInfo,
1328 VkQueryPool* pQueryPool)
1329 {
1330 struct anv_device *device = (struct anv_device *) _device;
1331 struct anv_query_pool *pool;
1332 VkResult result;
1333 size_t size;
1334
1335 assert(pCreateInfo->sType == VK_STRUCTURE_TYPE_QUERY_POOL_CREATE_INFO);
1336
1337 switch (pCreateInfo->queryType) {
1338 case VK_QUERY_TYPE_OCCLUSION:
1339 break;
1340 case VK_QUERY_TYPE_PIPELINE_STATISTICS:
1341 return VK_UNSUPPORTED;
1342 default:
1343 unreachable("");
1344 }
1345
1346 pool = anv_device_alloc(device, sizeof(*pool), 8,
1347 VK_SYSTEM_ALLOC_TYPE_API_OBJECT);
1348 if (pool == NULL)
1349 return vk_error(VK_ERROR_OUT_OF_HOST_MEMORY);
1350
1351 pool->type = pCreateInfo->queryType;
1352 size = pCreateInfo->slots * sizeof(struct anv_query_pool_slot);
1353 result = anv_bo_init_new(&pool->bo, device, size);
1354 if (result != VK_SUCCESS)
1355 goto fail;
1356
1357 pool->bo.map = anv_gem_mmap(device, pool->bo.gem_handle, 0, size);
1358
1359 *pQueryPool = (VkQueryPool) pool;
1360
1361 return VK_SUCCESS;
1362
1363 fail:
1364 anv_device_free(device, pool);
1365
1366 return result;
1367 }
1368
1369 VkResult anv_GetQueryPoolResults(
1370 VkDevice _device,
1371 VkQueryPool queryPool,
1372 uint32_t startQuery,
1373 uint32_t queryCount,
1374 size_t* pDataSize,
1375 void* pData,
1376 VkQueryResultFlags flags)
1377 {
1378 struct anv_device *device = (struct anv_device *) _device;
1379 struct anv_query_pool *pool = (struct anv_query_pool *) queryPool;
1380 struct anv_query_pool_slot *slot = pool->bo.map;
1381 int64_t timeout = INT64_MAX;
1382 uint32_t *dst32 = pData;
1383 uint64_t *dst64 = pData;
1384 uint64_t result;
1385 int ret;
1386
1387 if (flags & VK_QUERY_RESULT_WITH_AVAILABILITY_BIT) {
1388 /* Where is the availabilty info supposed to go? */
1389 anv_finishme("VK_QUERY_RESULT_WITH_AVAILABILITY_BIT");
1390 return VK_UNSUPPORTED;
1391 }
1392
1393 assert(pool->type == VK_QUERY_TYPE_OCCLUSION);
1394
1395 if (flags & VK_QUERY_RESULT_64_BIT)
1396 *pDataSize = queryCount * sizeof(uint64_t);
1397 else
1398 *pDataSize = queryCount * sizeof(uint32_t);
1399
1400 if (pData == NULL)
1401 return VK_SUCCESS;
1402
1403 if (flags & VK_QUERY_RESULT_WAIT_BIT) {
1404 ret = anv_gem_wait(device, pool->bo.gem_handle, &timeout);
1405 if (ret == -1)
1406 return vk_error(VK_ERROR_UNKNOWN);
1407 }
1408
1409 for (uint32_t i = 0; i < queryCount; i++) {
1410 result = slot[startQuery + i].end - slot[startQuery + i].begin;
1411 if (flags & VK_QUERY_RESULT_64_BIT) {
1412 *dst64++ = result;
1413 } else {
1414 if (result > UINT32_MAX)
1415 result = UINT32_MAX;
1416 *dst32++ = result;
1417 }
1418 }
1419
1420 return VK_SUCCESS;
1421 }
1422
1423 // Buffer functions
1424
1425 VkResult anv_CreateBuffer(
1426 VkDevice _device,
1427 const VkBufferCreateInfo* pCreateInfo,
1428 VkBuffer* pBuffer)
1429 {
1430 struct anv_device *device = (struct anv_device *) _device;
1431 struct anv_buffer *buffer;
1432
1433 assert(pCreateInfo->sType == VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO);
1434
1435 buffer = anv_device_alloc(device, sizeof(*buffer), 8,
1436 VK_SYSTEM_ALLOC_TYPE_API_OBJECT);
1437 if (buffer == NULL)
1438 return vk_error(VK_ERROR_OUT_OF_HOST_MEMORY);
1439
1440 buffer->size = pCreateInfo->size;
1441 buffer->bo = NULL;
1442 buffer->offset = 0;
1443
1444 *pBuffer = (VkBuffer) buffer;
1445
1446 return VK_SUCCESS;
1447 }
1448
1449 // Buffer view functions
1450
1451 VkResult anv_CreateBufferView(
1452 VkDevice _device,
1453 const VkBufferViewCreateInfo* pCreateInfo,
1454 VkBufferView* pView)
1455 {
1456 struct anv_device *device = (struct anv_device *) _device;
1457 struct anv_buffer *buffer = (struct anv_buffer *) pCreateInfo->buffer;
1458 struct anv_surface_view *view;
1459 const struct anv_format *format;
1460
1461 assert(pCreateInfo->sType == VK_STRUCTURE_TYPE_BUFFER_VIEW_CREATE_INFO);
1462
1463 view = anv_device_alloc(device, sizeof(*view), 8,
1464 VK_SYSTEM_ALLOC_TYPE_API_OBJECT);
1465 if (view == NULL)
1466 return vk_error(VK_ERROR_OUT_OF_HOST_MEMORY);
1467
1468 view->bo = buffer->bo;
1469 view->offset = buffer->offset + pCreateInfo->offset;
1470 view->surface_state =
1471 anv_state_pool_alloc(&device->surface_state_pool, 64, 64);
1472 view->format = pCreateInfo->format;
1473
1474 format = anv_format_for_vk_format(pCreateInfo->format);
1475 /* This assumes RGBA float format. */
1476 uint32_t stride = 4;
1477 uint32_t num_elements = pCreateInfo->range / stride;
1478 struct GEN8_RENDER_SURFACE_STATE surface_state = {
1479 .SurfaceType = SURFTYPE_BUFFER,
1480 .SurfaceArray = false,
1481 .SurfaceFormat = format->format,
1482 .SurfaceVerticalAlignment = VALIGN4,
1483 .SurfaceHorizontalAlignment = HALIGN4,
1484 .TileMode = LINEAR,
1485 .VerticalLineStride = 0,
1486 .VerticalLineStrideOffset = 0,
1487 .SamplerL2BypassModeDisable = true,
1488 .RenderCacheReadWriteMode = WriteOnlyCache,
1489 .MemoryObjectControlState = 0, /* FIXME: MOCS */
1490 .BaseMipLevel = 0,
1491 .SurfaceQPitch = 0,
1492 .Height = (num_elements >> 7) & 0x3fff,
1493 .Width = num_elements & 0x7f,
1494 .Depth = (num_elements >> 21) & 0x3f,
1495 .SurfacePitch = stride - 1,
1496 .MinimumArrayElement = 0,
1497 .NumberofMultisamples = MULTISAMPLECOUNT_1,
1498 .XOffset = 0,
1499 .YOffset = 0,
1500 .SurfaceMinLOD = 0,
1501 .MIPCountLOD = 0,
1502 .AuxiliarySurfaceMode = AUX_NONE,
1503 .RedClearColor = 0,
1504 .GreenClearColor = 0,
1505 .BlueClearColor = 0,
1506 .AlphaClearColor = 0,
1507 .ShaderChannelSelectRed = SCS_RED,
1508 .ShaderChannelSelectGreen = SCS_GREEN,
1509 .ShaderChannelSelectBlue = SCS_BLUE,
1510 .ShaderChannelSelectAlpha = SCS_ALPHA,
1511 .ResourceMinLOD = 0,
1512 /* FIXME: We assume that the image must be bound at this time. */
1513 .SurfaceBaseAddress = { NULL, view->offset },
1514 };
1515
1516 GEN8_RENDER_SURFACE_STATE_pack(NULL, view->surface_state.map, &surface_state);
1517
1518 *pView = (VkImageView) view;
1519
1520 return VK_SUCCESS;
1521 }
1522
1523 // Sampler functions
1524
1525 VkResult anv_CreateSampler(
1526 VkDevice _device,
1527 const VkSamplerCreateInfo* pCreateInfo,
1528 VkSampler* pSampler)
1529 {
1530 struct anv_device *device = (struct anv_device *) _device;
1531 struct anv_sampler *sampler;
1532
1533 assert(pCreateInfo->sType == VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO);
1534
1535 sampler = anv_device_alloc(device, sizeof(*sampler), 8,
1536 VK_SYSTEM_ALLOC_TYPE_API_OBJECT);
1537 if (!sampler)
1538 return vk_error(VK_ERROR_OUT_OF_HOST_MEMORY);
1539
1540 static const uint32_t vk_to_gen_tex_filter[] = {
1541 [VK_TEX_FILTER_NEAREST] = MAPFILTER_NEAREST,
1542 [VK_TEX_FILTER_LINEAR] = MAPFILTER_LINEAR
1543 };
1544
1545 static const uint32_t vk_to_gen_mipmap_mode[] = {
1546 [VK_TEX_MIPMAP_MODE_BASE] = MIPFILTER_NONE,
1547 [VK_TEX_MIPMAP_MODE_NEAREST] = MIPFILTER_NEAREST,
1548 [VK_TEX_MIPMAP_MODE_LINEAR] = MIPFILTER_LINEAR
1549 };
1550
1551 static const uint32_t vk_to_gen_tex_address[] = {
1552 [VK_TEX_ADDRESS_WRAP] = TCM_WRAP,
1553 [VK_TEX_ADDRESS_MIRROR] = TCM_MIRROR,
1554 [VK_TEX_ADDRESS_CLAMP] = TCM_CLAMP,
1555 [VK_TEX_ADDRESS_MIRROR_ONCE] = TCM_MIRROR_ONCE,
1556 [VK_TEX_ADDRESS_CLAMP_BORDER] = TCM_CLAMP_BORDER,
1557 };
1558
1559 static const uint32_t vk_to_gen_compare_op[] = {
1560 [VK_COMPARE_OP_NEVER] = PREFILTEROPNEVER,
1561 [VK_COMPARE_OP_LESS] = PREFILTEROPLESS,
1562 [VK_COMPARE_OP_EQUAL] = PREFILTEROPEQUAL,
1563 [VK_COMPARE_OP_LESS_EQUAL] = PREFILTEROPLEQUAL,
1564 [VK_COMPARE_OP_GREATER] = PREFILTEROPGREATER,
1565 [VK_COMPARE_OP_NOT_EQUAL] = PREFILTEROPNOTEQUAL,
1566 [VK_COMPARE_OP_GREATER_EQUAL] = PREFILTEROPGEQUAL,
1567 [VK_COMPARE_OP_ALWAYS] = PREFILTEROPALWAYS,
1568 };
1569
1570 if (pCreateInfo->maxAnisotropy > 0)
1571 anv_finishme("missing support for anisotropic filtering");
1572
1573 struct GEN8_SAMPLER_STATE sampler_state = {
1574 .SamplerDisable = false,
1575 .TextureBorderColorMode = DX10OGL,
1576 .LODPreClampMode = 0,
1577 .BaseMipLevel = 0,
1578 .MipModeFilter = vk_to_gen_mipmap_mode[pCreateInfo->mipMode],
1579 .MagModeFilter = vk_to_gen_tex_filter[pCreateInfo->magFilter],
1580 .MinModeFilter = vk_to_gen_tex_filter[pCreateInfo->minFilter],
1581 .TextureLODBias = pCreateInfo->mipLodBias * 256,
1582 .AnisotropicAlgorithm = EWAApproximation,
1583 .MinLOD = pCreateInfo->minLod * 256,
1584 .MaxLOD = pCreateInfo->maxLod * 256,
1585 .ChromaKeyEnable = 0,
1586 .ChromaKeyIndex = 0,
1587 .ChromaKeyMode = 0,
1588 .ShadowFunction = vk_to_gen_compare_op[pCreateInfo->compareOp],
1589 .CubeSurfaceControlMode = 0,
1590 .IndirectStatePointer = 0,
1591 .LODClampMagnificationMode = MIPNONE,
1592 .MaximumAnisotropy = 0,
1593 .RAddressMinFilterRoundingEnable = 0,
1594 .RAddressMagFilterRoundingEnable = 0,
1595 .VAddressMinFilterRoundingEnable = 0,
1596 .VAddressMagFilterRoundingEnable = 0,
1597 .UAddressMinFilterRoundingEnable = 0,
1598 .UAddressMagFilterRoundingEnable = 0,
1599 .TrilinearFilterQuality = 0,
1600 .NonnormalizedCoordinateEnable = 0,
1601 .TCXAddressControlMode = vk_to_gen_tex_address[pCreateInfo->addressU],
1602 .TCYAddressControlMode = vk_to_gen_tex_address[pCreateInfo->addressV],
1603 .TCZAddressControlMode = vk_to_gen_tex_address[pCreateInfo->addressW],
1604 };
1605
1606 GEN8_SAMPLER_STATE_pack(NULL, sampler->state, &sampler_state);
1607
1608 *pSampler = (VkSampler) sampler;
1609
1610 return VK_SUCCESS;
1611 }
1612
1613 // Descriptor set functions
1614
1615 VkResult anv_CreateDescriptorSetLayout(
1616 VkDevice _device,
1617 const VkDescriptorSetLayoutCreateInfo* pCreateInfo,
1618 VkDescriptorSetLayout* pSetLayout)
1619 {
1620 struct anv_device *device = (struct anv_device *) _device;
1621 struct anv_descriptor_set_layout *set_layout;
1622
1623 assert(pCreateInfo->sType == VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO);
1624
1625 uint32_t sampler_count[VK_NUM_SHADER_STAGE] = { 0, };
1626 uint32_t surface_count[VK_NUM_SHADER_STAGE] = { 0, };
1627 uint32_t num_dynamic_buffers = 0;
1628 uint32_t count = 0;
1629 uint32_t s;
1630
1631 for (uint32_t i = 0; i < pCreateInfo->count; i++) {
1632 switch (pCreateInfo->pBinding[i].descriptorType) {
1633 case VK_DESCRIPTOR_TYPE_SAMPLER:
1634 for_each_bit(s, pCreateInfo->pBinding[i].stageFlags)
1635 sampler_count[s] += pCreateInfo->pBinding[i].count;
1636 break;
1637
1638 case VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER:
1639 for_each_bit(s, pCreateInfo->pBinding[i].stageFlags)
1640 sampler_count[s] += pCreateInfo->pBinding[i].count;
1641
1642 /* fall through */
1643
1644 case VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE:
1645 case VK_DESCRIPTOR_TYPE_STORAGE_IMAGE:
1646 case VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER:
1647 case VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER:
1648 case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER:
1649 case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER:
1650 case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC:
1651 case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC:
1652 for_each_bit(s, pCreateInfo->pBinding[i].stageFlags)
1653 surface_count[s] += pCreateInfo->pBinding[i].count;
1654 break;
1655 default:
1656 break;
1657 }
1658
1659 count += pCreateInfo->pBinding[i].count;
1660 }
1661
1662 for (uint32_t i = 0; i < pCreateInfo->count; i++) {
1663 switch (pCreateInfo->pBinding[i].descriptorType) {
1664 case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC:
1665 case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC:
1666 num_dynamic_buffers++;
1667 break;
1668 default:
1669 break;
1670 }
1671 }
1672
1673 uint32_t sampler_total = 0;
1674 uint32_t surface_total = 0;
1675 for (uint32_t s = 0; s < VK_NUM_SHADER_STAGE; s++) {
1676 sampler_total += sampler_count[s];
1677 surface_total += surface_count[s];
1678 }
1679
1680 size_t size = sizeof(*set_layout) +
1681 (sampler_total + surface_total) * sizeof(uint32_t);
1682 set_layout = anv_device_alloc(device, size, 8,
1683 VK_SYSTEM_ALLOC_TYPE_API_OBJECT);
1684 if (!set_layout)
1685 return vk_error(VK_ERROR_OUT_OF_HOST_MEMORY);
1686
1687 set_layout->num_dynamic_buffers = num_dynamic_buffers;
1688 set_layout->count = count;
1689
1690 uint32_t *p = set_layout->entries;
1691 uint32_t *sampler[VK_NUM_SHADER_STAGE];
1692 uint32_t *surface[VK_NUM_SHADER_STAGE];
1693 for (uint32_t s = 0; s < VK_NUM_SHADER_STAGE; s++) {
1694 set_layout->stage[s].surface_count = surface_count[s];
1695 set_layout->stage[s].surface_start = surface[s] = p;
1696 p += surface_count[s];
1697 set_layout->stage[s].sampler_count = sampler_count[s];
1698 set_layout->stage[s].sampler_start = sampler[s] = p;
1699 p += sampler_count[s];
1700 }
1701
1702 uint32_t descriptor = 0;
1703 for (uint32_t i = 0; i < pCreateInfo->count; i++) {
1704 switch (pCreateInfo->pBinding[i].descriptorType) {
1705 case VK_DESCRIPTOR_TYPE_SAMPLER:
1706 for_each_bit(s, pCreateInfo->pBinding[i].stageFlags)
1707 for (uint32_t j = 0; j < pCreateInfo->pBinding[i].count; j++)
1708 *(sampler[s])++ = descriptor + j;
1709 break;
1710
1711 case VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER:
1712 for_each_bit(s, pCreateInfo->pBinding[i].stageFlags)
1713 for (uint32_t j = 0; j < pCreateInfo->pBinding[i].count; j++)
1714 *(sampler[s])++ = descriptor + j;
1715
1716 /* fallthrough */
1717
1718 case VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE:
1719 case VK_DESCRIPTOR_TYPE_STORAGE_IMAGE:
1720 case VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER:
1721 case VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER:
1722 case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER:
1723 case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER:
1724 case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC:
1725 case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC:
1726 for_each_bit(s, pCreateInfo->pBinding[i].stageFlags)
1727 for (uint32_t j = 0; j < pCreateInfo->pBinding[i].count; j++) {
1728 *(surface[s])++ = descriptor + j;
1729 }
1730 break;
1731 default:
1732 unreachable("");
1733 }
1734 descriptor += pCreateInfo->pBinding[i].count;
1735 }
1736
1737 *pSetLayout = (VkDescriptorSetLayout) set_layout;
1738
1739 return VK_SUCCESS;
1740 }
1741
1742 VkResult anv_BeginDescriptorPoolUpdate(
1743 VkDevice device,
1744 VkDescriptorUpdateMode updateMode)
1745 {
1746 return VK_SUCCESS;
1747 }
1748
1749 VkResult anv_EndDescriptorPoolUpdate(
1750 VkDevice device,
1751 VkCmdBuffer cmd)
1752 {
1753 return VK_SUCCESS;
1754 }
1755
1756 VkResult anv_CreateDescriptorPool(
1757 VkDevice device,
1758 VkDescriptorPoolUsage poolUsage,
1759 uint32_t maxSets,
1760 const VkDescriptorPoolCreateInfo* pCreateInfo,
1761 VkDescriptorPool* pDescriptorPool)
1762 {
1763 *pDescriptorPool = 1;
1764
1765 return VK_SUCCESS;
1766 }
1767
1768 VkResult anv_ResetDescriptorPool(
1769 VkDevice device,
1770 VkDescriptorPool descriptorPool)
1771 {
1772 return VK_SUCCESS;
1773 }
1774
1775 VkResult anv_AllocDescriptorSets(
1776 VkDevice _device,
1777 VkDescriptorPool descriptorPool,
1778 VkDescriptorSetUsage setUsage,
1779 uint32_t count,
1780 const VkDescriptorSetLayout* pSetLayouts,
1781 VkDescriptorSet* pDescriptorSets,
1782 uint32_t* pCount)
1783 {
1784 struct anv_device *device = (struct anv_device *) _device;
1785 const struct anv_descriptor_set_layout *layout;
1786 struct anv_descriptor_set *set;
1787 size_t size;
1788
1789 for (uint32_t i = 0; i < count; i++) {
1790 layout = (struct anv_descriptor_set_layout *) pSetLayouts[i];
1791 size = sizeof(*set) + layout->count * sizeof(set->descriptors[0]);
1792 set = anv_device_alloc(device, size, 8,
1793 VK_SYSTEM_ALLOC_TYPE_API_OBJECT);
1794 if (!set) {
1795 *pCount = i;
1796 return vk_error(VK_ERROR_OUT_OF_HOST_MEMORY);
1797 }
1798
1799 pDescriptorSets[i] = (VkDescriptorSet) set;
1800 }
1801
1802 *pCount = count;
1803
1804 return VK_SUCCESS;
1805 }
1806
1807 void anv_ClearDescriptorSets(
1808 VkDevice device,
1809 VkDescriptorPool descriptorPool,
1810 uint32_t count,
1811 const VkDescriptorSet* pDescriptorSets)
1812 {
1813 }
1814
1815 void anv_UpdateDescriptors(
1816 VkDevice _device,
1817 VkDescriptorSet descriptorSet,
1818 uint32_t updateCount,
1819 const void** ppUpdateArray)
1820 {
1821 struct anv_descriptor_set *set = (struct anv_descriptor_set *) descriptorSet;
1822 VkUpdateSamplers *update_samplers;
1823 VkUpdateSamplerTextures *update_sampler_textures;
1824 VkUpdateImages *update_images;
1825 VkUpdateBuffers *update_buffers;
1826 VkUpdateAsCopy *update_as_copy;
1827
1828 for (uint32_t i = 0; i < updateCount; i++) {
1829 const struct anv_common *common = ppUpdateArray[i];
1830
1831 switch (common->sType) {
1832 case VK_STRUCTURE_TYPE_UPDATE_SAMPLERS:
1833 update_samplers = (VkUpdateSamplers *) common;
1834
1835 for (uint32_t j = 0; j < update_samplers->count; j++) {
1836 set->descriptors[update_samplers->binding + j].sampler =
1837 (struct anv_sampler *) update_samplers->pSamplers[j];
1838 }
1839 break;
1840
1841 case VK_STRUCTURE_TYPE_UPDATE_SAMPLER_TEXTURES:
1842 /* FIXME: Shouldn't this be *_UPDATE_SAMPLER_IMAGES? */
1843 update_sampler_textures = (VkUpdateSamplerTextures *) common;
1844
1845 for (uint32_t j = 0; j < update_sampler_textures->count; j++) {
1846 set->descriptors[update_sampler_textures->binding + j].view =
1847 (struct anv_surface_view *)
1848 update_sampler_textures->pSamplerImageViews[j].pImageView->view;
1849 set->descriptors[update_sampler_textures->binding + j].sampler =
1850 (struct anv_sampler *)
1851 update_sampler_textures->pSamplerImageViews[j].sampler;
1852 }
1853 break;
1854
1855 case VK_STRUCTURE_TYPE_UPDATE_IMAGES:
1856 update_images = (VkUpdateImages *) common;
1857
1858 for (uint32_t j = 0; j < update_images->count; j++) {
1859 set->descriptors[update_images->binding + j].view =
1860 (struct anv_surface_view *) update_images->pImageViews[j].view;
1861 }
1862 break;
1863
1864 case VK_STRUCTURE_TYPE_UPDATE_BUFFERS:
1865 update_buffers = (VkUpdateBuffers *) common;
1866
1867 for (uint32_t j = 0; j < update_buffers->count; j++) {
1868 set->descriptors[update_buffers->binding + j].view =
1869 (struct anv_surface_view *) update_buffers->pBufferViews[j].view;
1870 }
1871 /* FIXME: descriptor arrays? */
1872 break;
1873
1874 case VK_STRUCTURE_TYPE_UPDATE_AS_COPY:
1875 update_as_copy = (VkUpdateAsCopy *) common;
1876 (void) update_as_copy;
1877 break;
1878
1879 default:
1880 break;
1881 }
1882 }
1883 }
1884
1885 // State object functions
1886
1887 static inline int64_t
1888 clamp_int64(int64_t x, int64_t min, int64_t max)
1889 {
1890 if (x < min)
1891 return min;
1892 else if (x < max)
1893 return x;
1894 else
1895 return max;
1896 }
1897
1898 VkResult anv_CreateDynamicViewportState(
1899 VkDevice _device,
1900 const VkDynamicVpStateCreateInfo* pCreateInfo,
1901 VkDynamicVpState* pState)
1902 {
1903 struct anv_device *device = (struct anv_device *) _device;
1904 struct anv_dynamic_vp_state *state;
1905
1906 assert(pCreateInfo->sType == VK_STRUCTURE_TYPE_DYNAMIC_VP_STATE_CREATE_INFO);
1907
1908 state = anv_device_alloc(device, sizeof(*state), 8,
1909 VK_SYSTEM_ALLOC_TYPE_API_OBJECT);
1910 if (state == NULL)
1911 return vk_error(VK_ERROR_OUT_OF_HOST_MEMORY);
1912
1913 unsigned count = pCreateInfo->viewportAndScissorCount;
1914 state->sf_clip_vp = anv_state_pool_alloc(&device->dynamic_state_pool,
1915 count * 64, 64);
1916 state->cc_vp = anv_state_pool_alloc(&device->dynamic_state_pool,
1917 count * 8, 32);
1918 state->scissor = anv_state_pool_alloc(&device->dynamic_state_pool,
1919 count * 32, 32);
1920
1921 for (uint32_t i = 0; i < pCreateInfo->viewportAndScissorCount; i++) {
1922 const VkViewport *vp = &pCreateInfo->pViewports[i];
1923 const VkRect *s = &pCreateInfo->pScissors[i];
1924
1925 struct GEN8_SF_CLIP_VIEWPORT sf_clip_viewport = {
1926 .ViewportMatrixElementm00 = vp->width / 2,
1927 .ViewportMatrixElementm11 = vp->height / 2,
1928 .ViewportMatrixElementm22 = (vp->maxDepth - vp->minDepth) / 2,
1929 .ViewportMatrixElementm30 = vp->originX + vp->width / 2,
1930 .ViewportMatrixElementm31 = vp->originY + vp->height / 2,
1931 .ViewportMatrixElementm32 = (vp->maxDepth + vp->minDepth) / 2,
1932 .XMinClipGuardband = -1.0f,
1933 .XMaxClipGuardband = 1.0f,
1934 .YMinClipGuardband = -1.0f,
1935 .YMaxClipGuardband = 1.0f,
1936 .XMinViewPort = vp->originX,
1937 .XMaxViewPort = vp->originX + vp->width - 1,
1938 .YMinViewPort = vp->originY,
1939 .YMaxViewPort = vp->originY + vp->height - 1,
1940 };
1941
1942 struct GEN8_CC_VIEWPORT cc_viewport = {
1943 .MinimumDepth = vp->minDepth,
1944 .MaximumDepth = vp->maxDepth
1945 };
1946
1947 /* Since xmax and ymax are inclusive, we have to have xmax < xmin or
1948 * ymax < ymin for empty clips. In case clip x, y, width height are all
1949 * 0, the clamps below produce 0 for xmin, ymin, xmax, ymax, which isn't
1950 * what we want. Just special case empty clips and produce a canonical
1951 * empty clip. */
1952 static const struct GEN8_SCISSOR_RECT empty_scissor = {
1953 .ScissorRectangleYMin = 1,
1954 .ScissorRectangleXMin = 1,
1955 .ScissorRectangleYMax = 0,
1956 .ScissorRectangleXMax = 0
1957 };
1958
1959 const int max = 0xffff;
1960 struct GEN8_SCISSOR_RECT scissor = {
1961 /* Do this math using int64_t so overflow gets clamped correctly. */
1962 .ScissorRectangleYMin = clamp_int64(s->offset.y, 0, max),
1963 .ScissorRectangleXMin = clamp_int64(s->offset.x, 0, max),
1964 .ScissorRectangleYMax = clamp_int64((uint64_t) s->offset.y + s->extent.height - 1, 0, max),
1965 .ScissorRectangleXMax = clamp_int64((uint64_t) s->offset.x + s->extent.width - 1, 0, max)
1966 };
1967
1968 GEN8_SF_CLIP_VIEWPORT_pack(NULL, state->sf_clip_vp.map + i * 64, &sf_clip_viewport);
1969 GEN8_CC_VIEWPORT_pack(NULL, state->cc_vp.map + i * 32, &cc_viewport);
1970
1971 if (s->extent.width <= 0 || s->extent.height <= 0) {
1972 GEN8_SCISSOR_RECT_pack(NULL, state->scissor.map + i * 32, &empty_scissor);
1973 } else {
1974 GEN8_SCISSOR_RECT_pack(NULL, state->scissor.map + i * 32, &scissor);
1975 }
1976 }
1977
1978 *pState = (VkDynamicVpState) state;
1979
1980 return VK_SUCCESS;
1981 }
1982
1983 VkResult anv_CreateDynamicRasterState(
1984 VkDevice _device,
1985 const VkDynamicRsStateCreateInfo* pCreateInfo,
1986 VkDynamicRsState* pState)
1987 {
1988 struct anv_device *device = (struct anv_device *) _device;
1989 struct anv_dynamic_rs_state *state;
1990
1991 assert(pCreateInfo->sType == VK_STRUCTURE_TYPE_DYNAMIC_RS_STATE_CREATE_INFO);
1992
1993 state = anv_device_alloc(device, sizeof(*state), 8,
1994 VK_SYSTEM_ALLOC_TYPE_API_OBJECT);
1995 if (state == NULL)
1996 return vk_error(VK_ERROR_OUT_OF_HOST_MEMORY);
1997
1998 /* Missing these:
1999 * float depthBias;
2000 * float depthBiasClamp;
2001 * float slopeScaledDepthBias;
2002 * float pointFadeThreshold;
2003 * // optional (GL45) - Size of point fade threshold
2004 */
2005
2006 struct GEN8_3DSTATE_SF sf = {
2007 GEN8_3DSTATE_SF_header,
2008 .LineWidth = pCreateInfo->lineWidth,
2009 .PointWidth = pCreateInfo->pointSize,
2010 };
2011
2012 GEN8_3DSTATE_SF_pack(NULL, state->state_sf, &sf);
2013
2014 *pState = (VkDynamicRsState) state;
2015
2016 return VK_SUCCESS;
2017 }
2018
2019 VkResult anv_CreateDynamicColorBlendState(
2020 VkDevice _device,
2021 const VkDynamicCbStateCreateInfo* pCreateInfo,
2022 VkDynamicCbState* pState)
2023 {
2024 struct anv_device *device = (struct anv_device *) _device;
2025 struct anv_dynamic_cb_state *state;
2026
2027 assert(pCreateInfo->sType == VK_STRUCTURE_TYPE_DYNAMIC_CB_STATE_CREATE_INFO);
2028
2029 state = anv_device_alloc(device, sizeof(*state), 8,
2030 VK_SYSTEM_ALLOC_TYPE_API_OBJECT);
2031 if (state == NULL)
2032 return vk_error(VK_ERROR_OUT_OF_HOST_MEMORY);
2033
2034 *pState = (VkDynamicCbState) state;
2035
2036 return VK_SUCCESS;
2037 }
2038
2039 VkResult anv_CreateDynamicDepthStencilState(
2040 VkDevice device,
2041 const VkDynamicDsStateCreateInfo* pCreateInfo,
2042 VkDynamicDsState* pState)
2043 {
2044 stub_return(VK_UNSUPPORTED);
2045 }
2046
2047 // Command buffer functions
2048
2049 VkResult anv_CreateCommandBuffer(
2050 VkDevice _device,
2051 const VkCmdBufferCreateInfo* pCreateInfo,
2052 VkCmdBuffer* pCmdBuffer)
2053 {
2054 struct anv_device *device = (struct anv_device *) _device;
2055 struct anv_cmd_buffer *cmd_buffer;
2056 VkResult result;
2057
2058 cmd_buffer = anv_device_alloc(device, sizeof(*cmd_buffer), 8,
2059 VK_SYSTEM_ALLOC_TYPE_API_OBJECT);
2060 if (cmd_buffer == NULL)
2061 return vk_error(VK_ERROR_OUT_OF_HOST_MEMORY);
2062
2063 cmd_buffer->device = device;
2064 cmd_buffer->rs_state = NULL;
2065 cmd_buffer->vp_state = NULL;
2066 memset(&cmd_buffer->default_bindings, 0, sizeof(cmd_buffer->default_bindings));
2067 cmd_buffer->bindings = &cmd_buffer->default_bindings;
2068
2069 result = anv_batch_init(&cmd_buffer->batch, device);
2070 if (result != VK_SUCCESS)
2071 goto fail;
2072
2073 cmd_buffer->exec2_objects =
2074 anv_device_alloc(device, 8192 * sizeof(cmd_buffer->exec2_objects[0]), 8,
2075 VK_SYSTEM_ALLOC_TYPE_API_OBJECT);
2076 if (cmd_buffer->exec2_objects == NULL) {
2077 result = vk_error(VK_ERROR_OUT_OF_HOST_MEMORY);
2078 goto fail_batch;
2079 }
2080
2081 cmd_buffer->exec2_bos =
2082 anv_device_alloc(device, 8192 * sizeof(cmd_buffer->exec2_bos[0]), 8,
2083 VK_SYSTEM_ALLOC_TYPE_API_OBJECT);
2084 if (cmd_buffer->exec2_bos == NULL) {
2085 result = vk_error(VK_ERROR_OUT_OF_HOST_MEMORY);
2086 goto fail_exec2_objects;
2087 }
2088
2089 anv_state_stream_init(&cmd_buffer->binding_table_state_stream,
2090 &device->binding_table_block_pool);
2091 anv_state_stream_init(&cmd_buffer->surface_state_stream,
2092 &device->surface_state_block_pool);
2093 anv_state_stream_init(&cmd_buffer->dynamic_state_stream,
2094 &device->dynamic_state_block_pool);
2095
2096 cmd_buffer->dirty = 0;
2097 cmd_buffer->vb_dirty = 0;
2098
2099 *pCmdBuffer = (VkCmdBuffer) cmd_buffer;
2100
2101 return VK_SUCCESS;
2102
2103 fail_exec2_objects:
2104 anv_device_free(device, cmd_buffer->exec2_objects);
2105 fail_batch:
2106 anv_batch_finish(&cmd_buffer->batch, device);
2107 fail:
2108 anv_device_free(device, cmd_buffer);
2109
2110 return result;
2111 }
2112
2113 VkResult anv_BeginCommandBuffer(
2114 VkCmdBuffer cmdBuffer,
2115 const VkCmdBufferBeginInfo* pBeginInfo)
2116 {
2117 struct anv_cmd_buffer *cmd_buffer = (struct anv_cmd_buffer *) cmdBuffer;
2118 struct anv_device *device = cmd_buffer->device;
2119
2120 anv_batch_emit(&cmd_buffer->batch, GEN8_PIPELINE_SELECT,
2121 .PipelineSelection = _3D);
2122 anv_batch_emit(&cmd_buffer->batch, GEN8_STATE_SIP);
2123
2124 anv_batch_emit(&cmd_buffer->batch, GEN8_STATE_BASE_ADDRESS,
2125 .GeneralStateBaseAddress = { NULL, 0 },
2126 .GeneralStateBaseAddressModifyEnable = true,
2127 .GeneralStateBufferSize = 0xfffff,
2128 .GeneralStateBufferSizeModifyEnable = true,
2129
2130 .SurfaceStateBaseAddress = { &device->surface_state_block_pool.bo, 0 },
2131 .SurfaceStateMemoryObjectControlState = 0, /* FIXME: MOCS */
2132 .SurfaceStateBaseAddressModifyEnable = true,
2133
2134 .DynamicStateBaseAddress = { &device->dynamic_state_block_pool.bo, 0 },
2135 .DynamicStateBaseAddressModifyEnable = true,
2136 .DynamicStateBufferSize = 0xfffff,
2137 .DynamicStateBufferSizeModifyEnable = true,
2138
2139 .IndirectObjectBaseAddress = { NULL, 0 },
2140 .IndirectObjectBaseAddressModifyEnable = true,
2141 .IndirectObjectBufferSize = 0xfffff,
2142 .IndirectObjectBufferSizeModifyEnable = true,
2143
2144 .InstructionBaseAddress = { &device->instruction_block_pool.bo, 0 },
2145 .InstructionBaseAddressModifyEnable = true,
2146 .InstructionBufferSize = 0xfffff,
2147 .InstructionBuffersizeModifyEnable = true);
2148
2149 anv_batch_emit(&cmd_buffer->batch, GEN8_3DSTATE_VF_STATISTICS,
2150 .StatisticsEnable = true);
2151 anv_batch_emit(&cmd_buffer->batch, GEN8_3DSTATE_HS, .Enable = false);
2152 anv_batch_emit(&cmd_buffer->batch, GEN8_3DSTATE_TE, .TEEnable = false);
2153 anv_batch_emit(&cmd_buffer->batch, GEN8_3DSTATE_DS, .FunctionEnable = false);
2154 anv_batch_emit(&cmd_buffer->batch, GEN8_3DSTATE_STREAMOUT, .SOFunctionEnable = false);
2155
2156 anv_batch_emit(&cmd_buffer->batch, GEN8_3DSTATE_PUSH_CONSTANT_ALLOC_VS,
2157 .ConstantBufferOffset = 0,
2158 .ConstantBufferSize = 4);
2159 anv_batch_emit(&cmd_buffer->batch, GEN8_3DSTATE_PUSH_CONSTANT_ALLOC_GS,
2160 .ConstantBufferOffset = 4,
2161 .ConstantBufferSize = 4);
2162 anv_batch_emit(&cmd_buffer->batch, GEN8_3DSTATE_PUSH_CONSTANT_ALLOC_PS,
2163 .ConstantBufferOffset = 8,
2164 .ConstantBufferSize = 4);
2165
2166 anv_batch_emit(&cmd_buffer->batch, GEN8_3DSTATE_WM_CHROMAKEY,
2167 .ChromaKeyKillEnable = false);
2168 anv_batch_emit(&cmd_buffer->batch, GEN8_3DSTATE_SBE_SWIZ);
2169 anv_batch_emit(&cmd_buffer->batch, GEN8_3DSTATE_AA_LINE_PARAMETERS);
2170
2171 /* Hardcoded state: */
2172 anv_batch_emit(&cmd_buffer->batch, GEN8_3DSTATE_DEPTH_BUFFER,
2173 .SurfaceType = SURFTYPE_2D,
2174 .Width = 1,
2175 .Height = 1,
2176 .SurfaceFormat = D16_UNORM,
2177 .SurfaceBaseAddress = { NULL, 0 },
2178 .HierarchicalDepthBufferEnable = 0);
2179
2180 anv_batch_emit(&cmd_buffer->batch, GEN8_3DSTATE_WM_DEPTH_STENCIL,
2181 .DepthTestEnable = false,
2182 .DepthBufferWriteEnable = false);
2183
2184 return VK_SUCCESS;
2185 }
2186
2187 static void
2188 anv_cmd_buffer_add_bo(struct anv_cmd_buffer *cmd_buffer,
2189 struct anv_bo *bo, struct anv_reloc_list *list)
2190 {
2191 struct drm_i915_gem_exec_object2 *obj;
2192
2193 bo->index = cmd_buffer->bo_count;
2194 obj = &cmd_buffer->exec2_objects[bo->index];
2195 cmd_buffer->exec2_bos[bo->index] = bo;
2196 cmd_buffer->bo_count++;
2197
2198 obj->handle = bo->gem_handle;
2199 obj->relocation_count = 0;
2200 obj->relocs_ptr = 0;
2201 obj->alignment = 0;
2202 obj->offset = bo->offset;
2203 obj->flags = 0;
2204 obj->rsvd1 = 0;
2205 obj->rsvd2 = 0;
2206
2207 if (list) {
2208 obj->relocation_count = list->num_relocs;
2209 obj->relocs_ptr = (uintptr_t) list->relocs;
2210 }
2211 }
2212
2213 static void
2214 anv_cmd_buffer_add_validate_bos(struct anv_cmd_buffer *cmd_buffer,
2215 struct anv_reloc_list *list)
2216 {
2217 struct anv_bo *bo, *batch_bo;
2218
2219 batch_bo = &cmd_buffer->batch.bo;
2220 for (size_t i = 0; i < list->num_relocs; i++) {
2221 bo = list->reloc_bos[i];
2222 /* Skip any relocations targeting the batch bo. We need to make sure
2223 * it's the last in the list so we'll add it manually later.
2224 */
2225 if (bo == batch_bo)
2226 continue;
2227 if (bo->index < cmd_buffer->bo_count && cmd_buffer->exec2_bos[bo->index] == bo)
2228 continue;
2229
2230 anv_cmd_buffer_add_bo(cmd_buffer, bo, NULL);
2231 }
2232 }
2233
2234 static void
2235 anv_cmd_buffer_process_relocs(struct anv_cmd_buffer *cmd_buffer,
2236 struct anv_reloc_list *list)
2237 {
2238 struct anv_bo *bo;
2239
2240 /* If the kernel supports I915_EXEC_NO_RELOC, it will compare offset in
2241 * struct drm_i915_gem_exec_object2 against the bos current offset and if
2242 * all bos haven't moved it will skip relocation processing alltogether.
2243 * If I915_EXEC_NO_RELOC is not supported, the kernel ignores the incoming
2244 * value of offset so we can set it either way. For that to work we need
2245 * to make sure all relocs use the same presumed offset.
2246 */
2247
2248 for (size_t i = 0; i < list->num_relocs; i++) {
2249 bo = list->reloc_bos[i];
2250 if (bo->offset != list->relocs[i].presumed_offset)
2251 cmd_buffer->need_reloc = true;
2252
2253 list->relocs[i].target_handle = bo->index;
2254 }
2255 }
2256
2257 VkResult anv_EndCommandBuffer(
2258 VkCmdBuffer cmdBuffer)
2259 {
2260 struct anv_cmd_buffer *cmd_buffer = (struct anv_cmd_buffer *) cmdBuffer;
2261 struct anv_device *device = cmd_buffer->device;
2262 struct anv_batch *batch = &cmd_buffer->batch;
2263
2264 anv_batch_emit(batch, GEN8_MI_BATCH_BUFFER_END);
2265
2266 /* Round batch up to an even number of dwords. */
2267 if ((batch->next - batch->bo.map) & 4)
2268 anv_batch_emit(batch, GEN8_MI_NOOP);
2269
2270 cmd_buffer->bo_count = 0;
2271 cmd_buffer->need_reloc = false;
2272
2273 /* Lock for access to bo->index. */
2274 pthread_mutex_lock(&device->mutex);
2275
2276 /* Add block pool bos first so we can add them with their relocs. */
2277 anv_cmd_buffer_add_bo(cmd_buffer, &device->surface_state_block_pool.bo,
2278 &batch->surf_relocs);
2279
2280 anv_cmd_buffer_add_validate_bos(cmd_buffer, &batch->surf_relocs);
2281 anv_cmd_buffer_add_validate_bos(cmd_buffer, &batch->cmd_relocs);
2282 anv_cmd_buffer_add_bo(cmd_buffer, &batch->bo, &batch->cmd_relocs);
2283 anv_cmd_buffer_process_relocs(cmd_buffer, &batch->surf_relocs);
2284 anv_cmd_buffer_process_relocs(cmd_buffer, &batch->cmd_relocs);
2285
2286 cmd_buffer->execbuf.buffers_ptr = (uintptr_t) cmd_buffer->exec2_objects;
2287 cmd_buffer->execbuf.buffer_count = cmd_buffer->bo_count;
2288 cmd_buffer->execbuf.batch_start_offset = 0;
2289 cmd_buffer->execbuf.batch_len = batch->next - batch->bo.map;
2290 cmd_buffer->execbuf.cliprects_ptr = 0;
2291 cmd_buffer->execbuf.num_cliprects = 0;
2292 cmd_buffer->execbuf.DR1 = 0;
2293 cmd_buffer->execbuf.DR4 = 0;
2294
2295 cmd_buffer->execbuf.flags = I915_EXEC_HANDLE_LUT;
2296 if (!cmd_buffer->need_reloc)
2297 cmd_buffer->execbuf.flags |= I915_EXEC_NO_RELOC;
2298 cmd_buffer->execbuf.flags |= I915_EXEC_RENDER;
2299 cmd_buffer->execbuf.rsvd1 = device->context_id;
2300 cmd_buffer->execbuf.rsvd2 = 0;
2301
2302 pthread_mutex_unlock(&device->mutex);
2303
2304 return VK_SUCCESS;
2305 }
2306
2307 VkResult anv_ResetCommandBuffer(
2308 VkCmdBuffer cmdBuffer)
2309 {
2310 struct anv_cmd_buffer *cmd_buffer = (struct anv_cmd_buffer *) cmdBuffer;
2311
2312 anv_batch_reset(&cmd_buffer->batch);
2313
2314 return VK_SUCCESS;
2315 }
2316
2317 // Command buffer building functions
2318
2319 void anv_CmdBindPipeline(
2320 VkCmdBuffer cmdBuffer,
2321 VkPipelineBindPoint pipelineBindPoint,
2322 VkPipeline _pipeline)
2323 {
2324 struct anv_cmd_buffer *cmd_buffer = (struct anv_cmd_buffer *) cmdBuffer;
2325
2326 cmd_buffer->pipeline = (struct anv_pipeline *) _pipeline;
2327 cmd_buffer->dirty |= ANV_CMD_BUFFER_PIPELINE_DIRTY;
2328 }
2329
2330 void anv_CmdBindDynamicStateObject(
2331 VkCmdBuffer cmdBuffer,
2332 VkStateBindPoint stateBindPoint,
2333 VkDynamicStateObject dynamicState)
2334 {
2335 struct anv_cmd_buffer *cmd_buffer = (struct anv_cmd_buffer *) cmdBuffer;
2336 struct anv_dynamic_vp_state *vp_state;
2337
2338 switch (stateBindPoint) {
2339 case VK_STATE_BIND_POINT_VIEWPORT:
2340 vp_state = (struct anv_dynamic_vp_state *) dynamicState;
2341 /* We emit state immediately, but set cmd_buffer->vp_state to indicate
2342 * that vp state has been set in this command buffer. */
2343 cmd_buffer->vp_state = vp_state;
2344 anv_batch_emit(&cmd_buffer->batch, GEN8_3DSTATE_SCISSOR_STATE_POINTERS,
2345 .ScissorRectPointer = vp_state->scissor.offset);
2346 anv_batch_emit(&cmd_buffer->batch, GEN8_3DSTATE_VIEWPORT_STATE_POINTERS_CC,
2347 .CCViewportPointer = vp_state->cc_vp.offset);
2348 anv_batch_emit(&cmd_buffer->batch, GEN8_3DSTATE_VIEWPORT_STATE_POINTERS_SF_CLIP,
2349 .SFClipViewportPointer = vp_state->sf_clip_vp.offset);
2350 break;
2351 case VK_STATE_BIND_POINT_RASTER:
2352 cmd_buffer->rs_state = (struct anv_dynamic_rs_state *) dynamicState;
2353 cmd_buffer->dirty |= ANV_CMD_BUFFER_RS_DIRTY;
2354 break;
2355 case VK_STATE_BIND_POINT_COLOR_BLEND:
2356 case VK_STATE_BIND_POINT_DEPTH_STENCIL:
2357 break;
2358 default:
2359 break;
2360 };
2361 }
2362
2363 void anv_CmdBindDescriptorSets(
2364 VkCmdBuffer cmdBuffer,
2365 VkPipelineBindPoint pipelineBindPoint,
2366 uint32_t firstSet,
2367 uint32_t setCount,
2368 const VkDescriptorSet* pDescriptorSets,
2369 uint32_t dynamicOffsetCount,
2370 const uint32_t* pDynamicOffsets)
2371 {
2372 struct anv_cmd_buffer *cmd_buffer = (struct anv_cmd_buffer *) cmdBuffer;
2373 struct anv_pipeline_layout *layout = cmd_buffer->pipeline->layout;
2374 struct anv_bindings *bindings = cmd_buffer->bindings;
2375
2376 uint32_t offset = 0;
2377 for (uint32_t i = 0; i < setCount; i++) {
2378 struct anv_descriptor_set *set =
2379 (struct anv_descriptor_set *) pDescriptorSets[i];
2380 struct anv_descriptor_set_layout *set_layout = layout->set[firstSet + i].layout;
2381
2382 for (uint32_t s = 0; s < VK_NUM_SHADER_STAGE; s++) {
2383 uint32_t *surface_to_desc = set_layout->stage[s].surface_start;
2384 uint32_t *sampler_to_desc = set_layout->stage[s].sampler_start;
2385 uint32_t bias = s == VK_SHADER_STAGE_FRAGMENT ? MAX_RTS : 0;
2386 uint32_t start;
2387
2388 start = bias + layout->set[firstSet + i].surface_start[s];
2389 for (uint32_t b = 0; b < set_layout->stage[s].surface_count; b++) {
2390 struct anv_surface_view *view = set->descriptors[surface_to_desc[b]].view;
2391
2392 bindings->descriptors[s].surfaces[start + b] =
2393 view->surface_state.offset;
2394 bindings->descriptors[s].relocs[start + b].bo = view->bo;
2395 bindings->descriptors[s].relocs[start + b].offset = view->offset;
2396 }
2397
2398 start = layout->set[firstSet + i].sampler_start[s];
2399 for (uint32_t b = 0; b < set_layout->stage[s].sampler_count; b++) {
2400 struct anv_sampler *sampler = set->descriptors[sampler_to_desc[b]].sampler;
2401
2402 memcpy(&bindings->descriptors[s].samplers[start + b],
2403 sampler->state, sizeof(sampler->state));
2404 }
2405 }
2406
2407 offset += layout->set[firstSet + i].layout->num_dynamic_buffers;
2408 }
2409
2410 cmd_buffer->dirty |= ANV_CMD_BUFFER_DESCRIPTOR_SET_DIRTY;
2411 }
2412
2413 void anv_CmdBindIndexBuffer(
2414 VkCmdBuffer cmdBuffer,
2415 VkBuffer _buffer,
2416 VkDeviceSize offset,
2417 VkIndexType indexType)
2418 {
2419 struct anv_cmd_buffer *cmd_buffer = (struct anv_cmd_buffer *) cmdBuffer;
2420 struct anv_buffer *buffer = (struct anv_buffer *) _buffer;
2421
2422 static const uint32_t vk_to_gen_index_type[] = {
2423 [VK_INDEX_TYPE_UINT8] = INDEX_BYTE,
2424 [VK_INDEX_TYPE_UINT16] = INDEX_WORD,
2425 [VK_INDEX_TYPE_UINT32] = INDEX_DWORD,
2426 };
2427
2428 anv_batch_emit(&cmd_buffer->batch, GEN8_3DSTATE_INDEX_BUFFER,
2429 .IndexFormat = vk_to_gen_index_type[indexType],
2430 .MemoryObjectControlState = 0,
2431 .BufferStartingAddress = { buffer->bo, buffer->offset + offset },
2432 .BufferSize = buffer->size - offset);
2433 }
2434
2435 void anv_CmdBindVertexBuffers(
2436 VkCmdBuffer cmdBuffer,
2437 uint32_t startBinding,
2438 uint32_t bindingCount,
2439 const VkBuffer* pBuffers,
2440 const VkDeviceSize* pOffsets)
2441 {
2442 struct anv_cmd_buffer *cmd_buffer = (struct anv_cmd_buffer *) cmdBuffer;
2443 struct anv_bindings *bindings = cmd_buffer->bindings;
2444
2445 /* We have to defer setting up vertex buffer since we need the buffer
2446 * stride from the pipeline. */
2447
2448 for (uint32_t i = 0; i < bindingCount; i++) {
2449 bindings->vb[startBinding + i].buffer = (struct anv_buffer *) pBuffers[i];
2450 bindings->vb[startBinding + i].offset = pOffsets[i];
2451 cmd_buffer->vb_dirty |= 1 << (startBinding + i);
2452 }
2453 }
2454
2455 static void
2456 flush_descriptor_sets(struct anv_cmd_buffer *cmd_buffer)
2457 {
2458 struct anv_pipeline_layout *layout = cmd_buffer->pipeline->layout;
2459 struct anv_bindings *bindings = cmd_buffer->bindings;
2460 uint32_t layers = cmd_buffer->framebuffer->layers;
2461
2462 for (uint32_t s = 0; s < VK_NUM_SHADER_STAGE; s++) {
2463 uint32_t bias;
2464
2465 if (s == VK_SHADER_STAGE_FRAGMENT) {
2466 bias = MAX_RTS;
2467 layers = cmd_buffer->framebuffer->layers;
2468 } else {
2469 bias = 0;
2470 layers = 0;
2471 }
2472
2473 /* This is a little awkward: layout can be NULL but we still have to
2474 * allocate and set a binding table for the PS stage for render
2475 * targets. */
2476 uint32_t surface_count = layout ? layout->stage[s].surface_count : 0;
2477
2478 if (layers + surface_count > 0) {
2479 struct anv_state state;
2480 uint32_t size;
2481
2482 size = (bias + surface_count) * sizeof(uint32_t);
2483 state = anv_state_stream_alloc(&cmd_buffer->binding_table_state_stream,
2484 size, 32);
2485 memcpy(state.map, bindings->descriptors[s].surfaces, size);
2486
2487 for (uint32_t i = 0; i < layers; i++)
2488 anv_reloc_list_add(&cmd_buffer->batch.surf_relocs,
2489 bindings->descriptors[s].surfaces[i] + 8 * sizeof(int32_t),
2490 bindings->descriptors[s].relocs[i].bo,
2491 bindings->descriptors[s].relocs[i].offset);
2492
2493 for (uint32_t i = 0; i < surface_count; i++)
2494 anv_reloc_list_add(&cmd_buffer->batch.surf_relocs,
2495 bindings->descriptors[s].surfaces[bias + i] + 8 * sizeof(int32_t),
2496 bindings->descriptors[s].relocs[bias + i].bo,
2497 bindings->descriptors[s].relocs[bias + i].offset);
2498
2499 static const uint32_t binding_table_opcodes[] = {
2500 [VK_SHADER_STAGE_VERTEX] = 38,
2501 [VK_SHADER_STAGE_TESS_CONTROL] = 39,
2502 [VK_SHADER_STAGE_TESS_EVALUATION] = 40,
2503 [VK_SHADER_STAGE_GEOMETRY] = 41,
2504 [VK_SHADER_STAGE_FRAGMENT] = 42,
2505 [VK_SHADER_STAGE_COMPUTE] = 0,
2506 };
2507
2508 anv_batch_emit(&cmd_buffer->batch,
2509 GEN8_3DSTATE_BINDING_TABLE_POINTERS_VS,
2510 ._3DCommandSubOpcode = binding_table_opcodes[s],
2511 .PointertoVSBindingTable = state.offset);
2512 }
2513
2514 if (layout && layout->stage[s].sampler_count > 0) {
2515 struct anv_state state;
2516 size_t size;
2517
2518 size = layout->stage[s].sampler_count * 16;
2519 state = anv_state_stream_alloc(&cmd_buffer->dynamic_state_stream, size, 32);
2520 memcpy(state.map, bindings->descriptors[s].samplers, size);
2521
2522 static const uint32_t sampler_state_opcodes[] = {
2523 [VK_SHADER_STAGE_VERTEX] = 43,
2524 [VK_SHADER_STAGE_TESS_CONTROL] = 44, /* HS */
2525 [VK_SHADER_STAGE_TESS_EVALUATION] = 45, /* DS */
2526 [VK_SHADER_STAGE_GEOMETRY] = 46,
2527 [VK_SHADER_STAGE_FRAGMENT] = 47,
2528 [VK_SHADER_STAGE_COMPUTE] = 0,
2529 };
2530
2531 anv_batch_emit(&cmd_buffer->batch,
2532 GEN8_3DSTATE_SAMPLER_STATE_POINTERS_VS,
2533 ._3DCommandSubOpcode = sampler_state_opcodes[s],
2534 .PointertoVSSamplerState = state.offset);
2535 }
2536 }
2537 }
2538
2539 static void
2540 anv_cmd_buffer_flush_state(struct anv_cmd_buffer *cmd_buffer)
2541 {
2542 struct anv_pipeline *pipeline = cmd_buffer->pipeline;
2543 struct anv_bindings *bindings = cmd_buffer->bindings;
2544 const uint32_t num_buffers = __builtin_popcount(cmd_buffer->vb_dirty);
2545 const uint32_t num_dwords = 1 + num_buffers * 4;
2546 uint32_t *p;
2547
2548 if (cmd_buffer->vb_dirty) {
2549 p = anv_batch_emitn(&cmd_buffer->batch, num_dwords,
2550 GEN8_3DSTATE_VERTEX_BUFFERS);
2551 uint32_t vb, i = 0;
2552 for_each_bit(vb, cmd_buffer->vb_dirty) {
2553 struct anv_buffer *buffer = bindings->vb[vb].buffer;
2554 uint32_t offset = bindings->vb[vb].offset;
2555
2556 struct GEN8_VERTEX_BUFFER_STATE state = {
2557 .VertexBufferIndex = vb,
2558 .MemoryObjectControlState = 0,
2559 .AddressModifyEnable = true,
2560 .BufferPitch = pipeline->binding_stride[vb],
2561 .BufferStartingAddress = { buffer->bo, buffer->offset + offset },
2562 .BufferSize = buffer->size - offset
2563 };
2564
2565 GEN8_VERTEX_BUFFER_STATE_pack(&cmd_buffer->batch, &p[1 + i * 4], &state);
2566 i++;
2567 }
2568 }
2569
2570 if (cmd_buffer->dirty & ANV_CMD_BUFFER_PIPELINE_DIRTY)
2571 anv_batch_emit_batch(&cmd_buffer->batch, &pipeline->batch);
2572
2573 if (cmd_buffer->dirty & ANV_CMD_BUFFER_DESCRIPTOR_SET_DIRTY)
2574 flush_descriptor_sets(cmd_buffer);
2575
2576 if (cmd_buffer->dirty & (ANV_CMD_BUFFER_PIPELINE_DIRTY | ANV_CMD_BUFFER_RS_DIRTY))
2577 anv_batch_emit_merge(&cmd_buffer->batch,
2578 cmd_buffer->rs_state->state_sf, pipeline->state_sf);
2579
2580 cmd_buffer->vb_dirty = 0;
2581 cmd_buffer->dirty = 0;
2582 }
2583
2584 void anv_CmdDraw(
2585 VkCmdBuffer cmdBuffer,
2586 uint32_t firstVertex,
2587 uint32_t vertexCount,
2588 uint32_t firstInstance,
2589 uint32_t instanceCount)
2590 {
2591 struct anv_cmd_buffer *cmd_buffer = (struct anv_cmd_buffer *) cmdBuffer;
2592
2593 anv_cmd_buffer_flush_state(cmd_buffer);
2594
2595 anv_batch_emit(&cmd_buffer->batch, GEN8_3DPRIMITIVE,
2596 .VertexAccessType = SEQUENTIAL,
2597 .VertexCountPerInstance = vertexCount,
2598 .StartVertexLocation = firstVertex,
2599 .InstanceCount = instanceCount,
2600 .StartInstanceLocation = firstInstance,
2601 .BaseVertexLocation = 0);
2602 }
2603
2604 void anv_CmdDrawIndexed(
2605 VkCmdBuffer cmdBuffer,
2606 uint32_t firstIndex,
2607 uint32_t indexCount,
2608 int32_t vertexOffset,
2609 uint32_t firstInstance,
2610 uint32_t instanceCount)
2611 {
2612 struct anv_cmd_buffer *cmd_buffer = (struct anv_cmd_buffer *) cmdBuffer;
2613
2614 anv_cmd_buffer_flush_state(cmd_buffer);
2615
2616 anv_batch_emit(&cmd_buffer->batch, GEN8_3DPRIMITIVE,
2617 .VertexAccessType = RANDOM,
2618 .VertexCountPerInstance = indexCount,
2619 .StartVertexLocation = firstIndex,
2620 .InstanceCount = instanceCount,
2621 .StartInstanceLocation = firstInstance,
2622 .BaseVertexLocation = 0);
2623 }
2624
2625 static void
2626 anv_batch_lrm(struct anv_batch *batch,
2627 uint32_t reg, struct anv_bo *bo, uint32_t offset)
2628 {
2629 anv_batch_emit(batch, GEN8_MI_LOAD_REGISTER_MEM,
2630 .RegisterAddress = reg,
2631 .MemoryAddress = { bo, offset });
2632 }
2633
2634 static void
2635 anv_batch_lri(struct anv_batch *batch, uint32_t reg, uint32_t imm)
2636 {
2637 anv_batch_emit(batch, GEN8_MI_LOAD_REGISTER_IMM,
2638 .RegisterOffset = reg,
2639 .DataDWord = imm);
2640 }
2641
2642 /* Auto-Draw / Indirect Registers */
2643 #define GEN7_3DPRIM_END_OFFSET 0x2420
2644 #define GEN7_3DPRIM_START_VERTEX 0x2430
2645 #define GEN7_3DPRIM_VERTEX_COUNT 0x2434
2646 #define GEN7_3DPRIM_INSTANCE_COUNT 0x2438
2647 #define GEN7_3DPRIM_START_INSTANCE 0x243C
2648 #define GEN7_3DPRIM_BASE_VERTEX 0x2440
2649
2650 void anv_CmdDrawIndirect(
2651 VkCmdBuffer cmdBuffer,
2652 VkBuffer _buffer,
2653 VkDeviceSize offset,
2654 uint32_t count,
2655 uint32_t stride)
2656 {
2657 struct anv_cmd_buffer *cmd_buffer = (struct anv_cmd_buffer *) cmdBuffer;
2658 struct anv_buffer *buffer = (struct anv_buffer *) _buffer;
2659 struct anv_bo *bo = buffer->bo;
2660 uint32_t bo_offset = buffer->offset + offset;
2661
2662 anv_cmd_buffer_flush_state(cmd_buffer);
2663
2664 anv_batch_lrm(&cmd_buffer->batch, GEN7_3DPRIM_VERTEX_COUNT, bo, bo_offset);
2665 anv_batch_lrm(&cmd_buffer->batch, GEN7_3DPRIM_INSTANCE_COUNT, bo, bo_offset + 4);
2666 anv_batch_lrm(&cmd_buffer->batch, GEN7_3DPRIM_START_VERTEX, bo, bo_offset + 8);
2667 anv_batch_lrm(&cmd_buffer->batch, GEN7_3DPRIM_START_INSTANCE, bo, bo_offset + 12);
2668 anv_batch_lri(&cmd_buffer->batch, GEN7_3DPRIM_BASE_VERTEX, 0);
2669
2670 anv_batch_emit(&cmd_buffer->batch, GEN8_3DPRIMITIVE,
2671 .IndirectParameterEnable = true,
2672 .VertexAccessType = SEQUENTIAL);
2673 }
2674
2675 void anv_CmdDrawIndexedIndirect(
2676 VkCmdBuffer cmdBuffer,
2677 VkBuffer _buffer,
2678 VkDeviceSize offset,
2679 uint32_t count,
2680 uint32_t stride)
2681 {
2682 struct anv_cmd_buffer *cmd_buffer = (struct anv_cmd_buffer *) cmdBuffer;
2683 struct anv_buffer *buffer = (struct anv_buffer *) _buffer;
2684 struct anv_bo *bo = buffer->bo;
2685 uint32_t bo_offset = buffer->offset + offset;
2686
2687 anv_cmd_buffer_flush_state(cmd_buffer);
2688
2689 anv_batch_lrm(&cmd_buffer->batch, GEN7_3DPRIM_VERTEX_COUNT, bo, bo_offset);
2690 anv_batch_lrm(&cmd_buffer->batch, GEN7_3DPRIM_INSTANCE_COUNT, bo, bo_offset + 4);
2691 anv_batch_lrm(&cmd_buffer->batch, GEN7_3DPRIM_START_VERTEX, bo, bo_offset + 8);
2692 anv_batch_lrm(&cmd_buffer->batch, GEN7_3DPRIM_BASE_VERTEX, bo, bo_offset + 12);
2693 anv_batch_lrm(&cmd_buffer->batch, GEN7_3DPRIM_START_INSTANCE, bo, bo_offset + 16);
2694
2695 anv_batch_emit(&cmd_buffer->batch, GEN8_3DPRIMITIVE,
2696 .IndirectParameterEnable = true,
2697 .VertexAccessType = RANDOM);
2698 }
2699
2700 void anv_CmdDispatch(
2701 VkCmdBuffer cmdBuffer,
2702 uint32_t x,
2703 uint32_t y,
2704 uint32_t z)
2705 {
2706 stub();
2707 }
2708
2709 void anv_CmdDispatchIndirect(
2710 VkCmdBuffer cmdBuffer,
2711 VkBuffer buffer,
2712 VkDeviceSize offset)
2713 {
2714 stub();
2715 }
2716
2717 void anv_CmdSetEvent(
2718 VkCmdBuffer cmdBuffer,
2719 VkEvent event,
2720 VkPipeEvent pipeEvent)
2721 {
2722 stub();
2723 }
2724
2725 void anv_CmdResetEvent(
2726 VkCmdBuffer cmdBuffer,
2727 VkEvent event,
2728 VkPipeEvent pipeEvent)
2729 {
2730 stub();
2731 }
2732
2733 void anv_CmdWaitEvents(
2734 VkCmdBuffer cmdBuffer,
2735 VkWaitEvent waitEvent,
2736 uint32_t eventCount,
2737 const VkEvent* pEvents,
2738 uint32_t memBarrierCount,
2739 const void** ppMemBarriers)
2740 {
2741 stub();
2742 }
2743
2744 void anv_CmdPipelineBarrier(
2745 VkCmdBuffer cmdBuffer,
2746 VkWaitEvent waitEvent,
2747 uint32_t pipeEventCount,
2748 const VkPipeEvent* pPipeEvents,
2749 uint32_t memBarrierCount,
2750 const void** ppMemBarriers)
2751 {
2752 stub();
2753 }
2754
2755 static void
2756 anv_batch_emit_ps_depth_count(struct anv_batch *batch,
2757 struct anv_bo *bo, uint32_t offset)
2758 {
2759 anv_batch_emit(batch, GEN8_PIPE_CONTROL,
2760 .DestinationAddressType = DAT_PPGTT,
2761 .PostSyncOperation = WritePSDepthCount,
2762 .Address = { bo, offset }); /* FIXME: This is only lower 32 bits */
2763 }
2764
2765 void anv_CmdBeginQuery(
2766 VkCmdBuffer cmdBuffer,
2767 VkQueryPool queryPool,
2768 uint32_t slot,
2769 VkQueryControlFlags flags)
2770 {
2771 struct anv_cmd_buffer *cmd_buffer = (struct anv_cmd_buffer *) cmdBuffer;
2772 struct anv_query_pool *pool = (struct anv_query_pool *) queryPool;
2773
2774 switch (pool->type) {
2775 case VK_QUERY_TYPE_OCCLUSION:
2776 anv_batch_emit_ps_depth_count(&cmd_buffer->batch, &pool->bo,
2777 slot * sizeof(struct anv_query_pool_slot));
2778 break;
2779
2780 case VK_QUERY_TYPE_PIPELINE_STATISTICS:
2781 default:
2782 unreachable("");
2783 }
2784 }
2785
2786 void anv_CmdEndQuery(
2787 VkCmdBuffer cmdBuffer,
2788 VkQueryPool queryPool,
2789 uint32_t slot)
2790 {
2791 struct anv_cmd_buffer *cmd_buffer = (struct anv_cmd_buffer *) cmdBuffer;
2792 struct anv_query_pool *pool = (struct anv_query_pool *) queryPool;
2793
2794 switch (pool->type) {
2795 case VK_QUERY_TYPE_OCCLUSION:
2796 anv_batch_emit_ps_depth_count(&cmd_buffer->batch, &pool->bo,
2797 slot * sizeof(struct anv_query_pool_slot) + 8);
2798 break;
2799
2800 case VK_QUERY_TYPE_PIPELINE_STATISTICS:
2801 default:
2802 unreachable("");
2803 }
2804 }
2805
2806 void anv_CmdResetQueryPool(
2807 VkCmdBuffer cmdBuffer,
2808 VkQueryPool queryPool,
2809 uint32_t startQuery,
2810 uint32_t queryCount)
2811 {
2812 stub();
2813 }
2814
2815 #define TIMESTAMP 0x2358
2816
2817 void anv_CmdWriteTimestamp(
2818 VkCmdBuffer cmdBuffer,
2819 VkTimestampType timestampType,
2820 VkBuffer destBuffer,
2821 VkDeviceSize destOffset)
2822 {
2823 struct anv_cmd_buffer *cmd_buffer = (struct anv_cmd_buffer *) cmdBuffer;
2824 struct anv_buffer *buffer = (struct anv_buffer *) destBuffer;
2825 struct anv_bo *bo = buffer->bo;
2826
2827 switch (timestampType) {
2828 case VK_TIMESTAMP_TYPE_TOP:
2829 anv_batch_emit(&cmd_buffer->batch, GEN8_MI_STORE_REGISTER_MEM,
2830 .RegisterAddress = TIMESTAMP,
2831 .MemoryAddress = { bo, buffer->offset + destOffset });
2832 anv_batch_emit(&cmd_buffer->batch, GEN8_MI_STORE_REGISTER_MEM,
2833 .RegisterAddress = TIMESTAMP + 4,
2834 .MemoryAddress = { bo, buffer->offset + destOffset + 4 });
2835 break;
2836
2837 case VK_TIMESTAMP_TYPE_BOTTOM:
2838 anv_batch_emit(&cmd_buffer->batch, GEN8_PIPE_CONTROL,
2839 .DestinationAddressType = DAT_PPGTT,
2840 .PostSyncOperation = WriteTimestamp,
2841 .Address = /* FIXME: This is only lower 32 bits */
2842 { bo, buffer->offset + destOffset });
2843 break;
2844
2845 default:
2846 break;
2847 }
2848 }
2849
2850 #define alu_opcode(v) __gen_field((v), 20, 31)
2851 #define alu_operand1(v) __gen_field((v), 10, 19)
2852 #define alu_operand2(v) __gen_field((v), 0, 9)
2853 #define alu(opcode, operand1, operand2) \
2854 alu_opcode(opcode) | alu_operand1(operand1) | alu_operand2(operand2)
2855
2856 #define OPCODE_NOOP 0x000
2857 #define OPCODE_LOAD 0x080
2858 #define OPCODE_LOADINV 0x480
2859 #define OPCODE_LOAD0 0x081
2860 #define OPCODE_LOAD1 0x481
2861 #define OPCODE_ADD 0x100
2862 #define OPCODE_SUB 0x101
2863 #define OPCODE_AND 0x102
2864 #define OPCODE_OR 0x103
2865 #define OPCODE_XOR 0x104
2866 #define OPCODE_STORE 0x180
2867 #define OPCODE_STOREINV 0x580
2868
2869 #define OPERAND_R0 0x00
2870 #define OPERAND_R1 0x01
2871 #define OPERAND_R2 0x02
2872 #define OPERAND_R3 0x03
2873 #define OPERAND_R4 0x04
2874 #define OPERAND_SRCA 0x20
2875 #define OPERAND_SRCB 0x21
2876 #define OPERAND_ACCU 0x31
2877 #define OPERAND_ZF 0x32
2878 #define OPERAND_CF 0x33
2879
2880 #define CS_GPR(n) (0x2600 + (n) * 8)
2881
2882 static void
2883 emit_load_alu_reg_u64(struct anv_batch *batch, uint32_t reg,
2884 struct anv_bo *bo, uint32_t offset)
2885 {
2886 anv_batch_emit(batch, GEN8_MI_LOAD_REGISTER_MEM,
2887 .RegisterAddress = reg,
2888 .MemoryAddress = { bo, offset });
2889 anv_batch_emit(batch, GEN8_MI_LOAD_REGISTER_MEM,
2890 .RegisterAddress = reg + 4,
2891 .MemoryAddress = { bo, offset + 4 });
2892 }
2893
2894 void anv_CmdCopyQueryPoolResults(
2895 VkCmdBuffer cmdBuffer,
2896 VkQueryPool queryPool,
2897 uint32_t startQuery,
2898 uint32_t queryCount,
2899 VkBuffer destBuffer,
2900 VkDeviceSize destOffset,
2901 VkDeviceSize destStride,
2902 VkQueryResultFlags flags)
2903 {
2904 struct anv_cmd_buffer *cmd_buffer = (struct anv_cmd_buffer *) cmdBuffer;
2905 struct anv_query_pool *pool = (struct anv_query_pool *) queryPool;
2906 struct anv_buffer *buffer = (struct anv_buffer *) destBuffer;
2907 uint32_t slot_offset, dst_offset;
2908
2909 if (flags & VK_QUERY_RESULT_WITH_AVAILABILITY_BIT) {
2910 /* Where is the availabilty info supposed to go? */
2911 anv_finishme("VK_QUERY_RESULT_WITH_AVAILABILITY_BIT");
2912 return;
2913 }
2914
2915 assert(pool->type == VK_QUERY_TYPE_OCCLUSION);
2916
2917 /* FIXME: If we're not waiting, should we just do this on the CPU? */
2918 if (flags & VK_QUERY_RESULT_WAIT_BIT)
2919 anv_batch_emit(&cmd_buffer->batch, GEN8_PIPE_CONTROL,
2920 .CommandStreamerStallEnable = true);
2921
2922 dst_offset = buffer->offset + destOffset;
2923 for (uint32_t i = 0; i < queryCount; i++) {
2924
2925 slot_offset = (startQuery + i) * sizeof(struct anv_query_pool_slot);
2926
2927 emit_load_alu_reg_u64(&cmd_buffer->batch, CS_GPR(0), &pool->bo, slot_offset);
2928 emit_load_alu_reg_u64(&cmd_buffer->batch, CS_GPR(1), &pool->bo, slot_offset + 8);
2929
2930 /* FIXME: We need to clamp the result for 32 bit. */
2931
2932 uint32_t *dw = anv_batch_emitn(&cmd_buffer->batch, 5, GEN8_MI_MATH);
2933 dw[1] = alu(OPCODE_LOAD, OPERAND_SRCA, OPERAND_R1);
2934 dw[2] = alu(OPCODE_LOAD, OPERAND_SRCB, OPERAND_R0);
2935 dw[3] = alu(OPCODE_SUB, 0, 0);
2936 dw[4] = alu(OPCODE_STORE, OPERAND_R2, OPERAND_ACCU);
2937
2938 anv_batch_emit(&cmd_buffer->batch, GEN8_MI_STORE_REGISTER_MEM,
2939 .RegisterAddress = CS_GPR(2),
2940 /* FIXME: This is only lower 32 bits */
2941 .MemoryAddress = { buffer->bo, dst_offset });
2942
2943 if (flags & VK_QUERY_RESULT_64_BIT)
2944 anv_batch_emit(&cmd_buffer->batch, GEN8_MI_STORE_REGISTER_MEM,
2945 .RegisterAddress = CS_GPR(2) + 4,
2946 /* FIXME: This is only lower 32 bits */
2947 .MemoryAddress = { buffer->bo, dst_offset + 4 });
2948
2949 dst_offset += destStride;
2950 }
2951 }
2952
2953 void anv_CmdInitAtomicCounters(
2954 VkCmdBuffer cmdBuffer,
2955 VkPipelineBindPoint pipelineBindPoint,
2956 uint32_t startCounter,
2957 uint32_t counterCount,
2958 const uint32_t* pData)
2959 {
2960 stub();
2961 }
2962
2963 void anv_CmdLoadAtomicCounters(
2964 VkCmdBuffer cmdBuffer,
2965 VkPipelineBindPoint pipelineBindPoint,
2966 uint32_t startCounter,
2967 uint32_t counterCount,
2968 VkBuffer srcBuffer,
2969 VkDeviceSize srcOffset)
2970 {
2971 stub();
2972 }
2973
2974 void anv_CmdSaveAtomicCounters(
2975 VkCmdBuffer cmdBuffer,
2976 VkPipelineBindPoint pipelineBindPoint,
2977 uint32_t startCounter,
2978 uint32_t counterCount,
2979 VkBuffer destBuffer,
2980 VkDeviceSize destOffset)
2981 {
2982 stub();
2983 }
2984
2985 VkResult anv_CreateFramebuffer(
2986 VkDevice _device,
2987 const VkFramebufferCreateInfo* pCreateInfo,
2988 VkFramebuffer* pFramebuffer)
2989 {
2990 struct anv_device *device = (struct anv_device *) _device;
2991 struct anv_framebuffer *framebuffer;
2992
2993 assert(pCreateInfo->sType == VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO);
2994
2995 framebuffer = anv_device_alloc(device, sizeof(*framebuffer), 8,
2996 VK_SYSTEM_ALLOC_TYPE_API_OBJECT);
2997 if (framebuffer == NULL)
2998 return vk_error(VK_ERROR_OUT_OF_HOST_MEMORY);
2999
3000 framebuffer->color_attachment_count = pCreateInfo->colorAttachmentCount;
3001 for (uint32_t i = 0; i < pCreateInfo->colorAttachmentCount; i++) {
3002 framebuffer->color_attachments[i] =
3003 (struct anv_surface_view *) pCreateInfo->pColorAttachments[i].view;
3004 }
3005
3006 if (pCreateInfo->pDepthStencilAttachment) {
3007 framebuffer->depth_stencil =
3008 (struct anv_depth_stencil_view *) pCreateInfo->pDepthStencilAttachment->view;
3009 }
3010
3011 framebuffer->sample_count = pCreateInfo->sampleCount;
3012 framebuffer->width = pCreateInfo->width;
3013 framebuffer->height = pCreateInfo->height;
3014 framebuffer->layers = pCreateInfo->layers;
3015
3016 vkCreateDynamicViewportState((VkDevice) device,
3017 &(VkDynamicVpStateCreateInfo) {
3018 .sType = VK_STRUCTURE_TYPE_DYNAMIC_VP_STATE_CREATE_INFO,
3019 .viewportAndScissorCount = 2,
3020 .pViewports = (VkViewport[]) {
3021 {
3022 .originX = 0,
3023 .originY = 0,
3024 .width = pCreateInfo->width,
3025 .height = pCreateInfo->height,
3026 .minDepth = 0,
3027 .maxDepth = 1
3028 },
3029 },
3030 .pScissors = (VkRect[]) {
3031 { { 0, 0 },
3032 { pCreateInfo->width, pCreateInfo->height } },
3033 }
3034 },
3035 &framebuffer->vp_state);
3036
3037 *pFramebuffer = (VkFramebuffer) framebuffer;
3038
3039 return VK_SUCCESS;
3040 }
3041
3042 VkResult anv_CreateRenderPass(
3043 VkDevice _device,
3044 const VkRenderPassCreateInfo* pCreateInfo,
3045 VkRenderPass* pRenderPass)
3046 {
3047 struct anv_device *device = (struct anv_device *) _device;
3048 struct anv_render_pass *pass;
3049 size_t size;
3050
3051 assert(pCreateInfo->sType == VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO);
3052
3053 size = sizeof(*pass) +
3054 pCreateInfo->layers * sizeof(struct anv_render_pass_layer);
3055 pass = anv_device_alloc(device, size, 8,
3056 VK_SYSTEM_ALLOC_TYPE_API_OBJECT);
3057 if (pass == NULL)
3058 return vk_error(VK_ERROR_OUT_OF_HOST_MEMORY);
3059
3060 pass->render_area = pCreateInfo->renderArea;
3061
3062 pass->num_layers = pCreateInfo->layers;
3063
3064 pass->num_clear_layers = 0;
3065 for (uint32_t i = 0; i < pCreateInfo->layers; i++) {
3066 pass->layers[i].color_load_op = pCreateInfo->pColorLoadOps[i];
3067 pass->layers[i].clear_color = pCreateInfo->pColorLoadClearValues[i];
3068 if (pass->layers[i].color_load_op == VK_ATTACHMENT_LOAD_OP_CLEAR)
3069 pass->num_clear_layers++;
3070 }
3071
3072 *pRenderPass = (VkRenderPass) pass;
3073
3074 return VK_SUCCESS;
3075 }
3076
3077 void
3078 anv_cmd_buffer_fill_render_targets(struct anv_cmd_buffer *cmd_buffer)
3079 {
3080 struct anv_framebuffer *framebuffer = cmd_buffer->framebuffer;
3081 struct anv_bindings *bindings = cmd_buffer->bindings;
3082
3083 for (uint32_t i = 0; i < framebuffer->color_attachment_count; i++) {
3084 struct anv_surface_view *view = framebuffer->color_attachments[i];
3085
3086 bindings->descriptors[VK_SHADER_STAGE_FRAGMENT].surfaces[i] = view->surface_state.offset;
3087 bindings->descriptors[VK_SHADER_STAGE_FRAGMENT].relocs[i].bo = view->bo;
3088 bindings->descriptors[VK_SHADER_STAGE_FRAGMENT].relocs[i].offset = view->offset;
3089 }
3090 cmd_buffer->dirty |= ANV_CMD_BUFFER_DESCRIPTOR_SET_DIRTY;
3091 }
3092
3093 void anv_CmdBeginRenderPass(
3094 VkCmdBuffer cmdBuffer,
3095 const VkRenderPassBegin* pRenderPassBegin)
3096 {
3097 struct anv_cmd_buffer *cmd_buffer = (struct anv_cmd_buffer *) cmdBuffer;
3098 struct anv_render_pass *pass = (struct anv_render_pass *) pRenderPassBegin->renderPass;
3099 struct anv_framebuffer *framebuffer =
3100 (struct anv_framebuffer *) pRenderPassBegin->framebuffer;
3101
3102 cmd_buffer->framebuffer = framebuffer;
3103
3104 anv_batch_emit(&cmd_buffer->batch, GEN8_3DSTATE_DRAWING_RECTANGLE,
3105 .ClippedDrawingRectangleYMin = pass->render_area.offset.y,
3106 .ClippedDrawingRectangleXMin = pass->render_area.offset.x,
3107 .ClippedDrawingRectangleYMax =
3108 pass->render_area.offset.y + pass->render_area.extent.height - 1,
3109 .ClippedDrawingRectangleXMax =
3110 pass->render_area.offset.x + pass->render_area.extent.width - 1,
3111 .DrawingRectangleOriginY = 0,
3112 .DrawingRectangleOriginX = 0);
3113
3114 anv_cmd_buffer_fill_render_targets(cmd_buffer);
3115
3116 anv_cmd_buffer_clear(cmd_buffer, pass);
3117 }
3118
3119 void anv_CmdEndRenderPass(
3120 VkCmdBuffer cmdBuffer,
3121 VkRenderPass renderPass)
3122 {
3123 /* Emit a flushing pipe control at the end of a pass. This is kind of a
3124 * hack but it ensures that render targets always actually get written.
3125 * Eventually, we should do flushing based on image format transitions
3126 * or something of that nature.
3127 */
3128 struct anv_cmd_buffer *cmd_buffer = (struct anv_cmd_buffer *)cmdBuffer;
3129 anv_batch_emit(&cmd_buffer->batch, GEN8_PIPE_CONTROL,
3130 .PostSyncOperation = NoWrite,
3131 .RenderTargetCacheFlushEnable = true,
3132 .InstructionCacheInvalidateEnable = true,
3133 .DepthCacheFlushEnable = true,
3134 .VFCacheInvalidationEnable = true,
3135 .TextureCacheInvalidationEnable = true,
3136 .CommandStreamerStallEnable = true);
3137
3138 stub();
3139 }