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