2 * Copyright © 2015 Intel Corporation
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:
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
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
33 anv_env_get_int(const char *name
)
35 const char *val
= getenv(name
);
40 return strtol(val
, NULL
, 0);
44 fill_physical_device(struct anv_physical_device
*device
,
45 struct anv_instance
*instance
,
50 fd
= open("/dev/dri/renderD128", O_RDWR
| O_CLOEXEC
);
52 return vk_error(VK_ERROR_UNAVAILABLE
);
54 device
->instance
= instance
;
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. */
63 device
->chipset_id
= anv_gem_get_param(fd
, I915_PARAM_CHIPSET_ID
);
65 if (!device
->chipset_id
)
68 device
->name
= brw_get_device_name(device
->chipset_id
);
69 device
->info
= brw_get_device_info(device
->chipset_id
, -1);
73 if (!anv_gem_get_param(fd
, I915_PARAM_HAS_WAIT_TIMEOUT
))
76 if (!anv_gem_get_param(fd
, I915_PARAM_HAS_EXECBUF2
))
79 if (!anv_gem_get_param(fd
, I915_PARAM_HAS_LLC
))
82 if (!anv_gem_get_param(fd
, I915_PARAM_HAS_EXEC_CONSTANTS
))
92 return vk_error(VK_ERROR_UNAVAILABLE
);
95 static void *default_alloc(
99 VkSystemAllocType allocType
)
104 static void default_free(
111 static const VkAllocCallbacks default_alloc_callbacks
= {
113 .pfnAlloc
= default_alloc
,
114 .pfnFree
= default_free
117 VkResult
anv_CreateInstance(
118 const VkInstanceCreateInfo
* pCreateInfo
,
119 VkInstance
* pInstance
)
121 struct anv_instance
*instance
;
122 const VkAllocCallbacks
*alloc_callbacks
= &default_alloc_callbacks
;
123 void *user_data
= NULL
;
126 assert(pCreateInfo
->sType
== VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO
);
128 if (pCreateInfo
->pAllocCb
) {
129 alloc_callbacks
= pCreateInfo
->pAllocCb
;
130 user_data
= pCreateInfo
->pAllocCb
->pUserData
;
132 instance
= alloc_callbacks
->pfnAlloc(user_data
, sizeof(*instance
), 8,
133 VK_SYSTEM_ALLOC_TYPE_API_OBJECT
);
135 return vk_error(VK_ERROR_OUT_OF_HOST_MEMORY
);
137 instance
->pAllocUserData
= alloc_callbacks
->pUserData
;
138 instance
->pfnAlloc
= alloc_callbacks
->pfnAlloc
;
139 instance
->pfnFree
= alloc_callbacks
->pfnFree
;
140 instance
->apiVersion
= pCreateInfo
->pAppInfo
->apiVersion
;
142 instance
->physicalDeviceCount
= 0;
143 result
= fill_physical_device(&instance
->physicalDevice
,
144 instance
, "/dev/dri/renderD128");
145 if (result
== VK_SUCCESS
)
146 instance
->physicalDeviceCount
++;
148 *pInstance
= (VkInstance
) instance
;
153 VkResult
anv_DestroyInstance(
154 VkInstance _instance
)
156 struct anv_instance
*instance
= (struct anv_instance
*) _instance
;
158 instance
->pfnFree(instance
->pAllocUserData
, instance
);
163 VkResult
anv_EnumeratePhysicalDevices(
164 VkInstance _instance
,
165 uint32_t* pPhysicalDeviceCount
,
166 VkPhysicalDevice
* pPhysicalDevices
)
168 struct anv_instance
*instance
= (struct anv_instance
*) _instance
;
170 if (*pPhysicalDeviceCount
>= 1)
171 pPhysicalDevices
[0] = (VkPhysicalDevice
) &instance
->physicalDevice
;
172 *pPhysicalDeviceCount
= instance
->physicalDeviceCount
;
177 VkResult
anv_GetPhysicalDeviceInfo(
178 VkPhysicalDevice physicalDevice
,
179 VkPhysicalDeviceInfoType infoType
,
183 struct anv_physical_device
*device
= (struct anv_physical_device
*) physicalDevice
;
184 VkPhysicalDeviceProperties
*properties
;
185 VkPhysicalDevicePerformance
*performance
;
186 VkPhysicalDeviceQueueProperties
*queue_properties
;
187 VkPhysicalDeviceMemoryProperties
*memory_properties
;
188 uint64_t ns_per_tick
= 80;
191 case VK_PHYSICAL_DEVICE_INFO_TYPE_PROPERTIES
:
194 *pDataSize
= sizeof(*properties
);
198 properties
->apiVersion
= 1;
199 properties
->driverVersion
= 1;
200 properties
->vendorId
= 0x8086;
201 properties
->deviceId
= device
->chipset_id
;
202 properties
->deviceType
= VK_PHYSICAL_DEVICE_TYPE_INTEGRATED_GPU
;
203 strcpy(properties
->deviceName
, device
->name
);
204 properties
->maxInlineMemoryUpdateSize
= 0;
205 properties
->maxBoundDescriptorSets
= MAX_SETS
;
206 properties
->maxThreadGroupSize
= 512;
207 properties
->timestampFrequency
= 1000 * 1000 * 1000 / ns_per_tick
;
208 properties
->multiColorAttachmentClears
= true;
209 properties
->maxDescriptorSets
= 8;
210 properties
->maxViewports
= 16;
211 properties
->maxColorAttachments
= 8;
214 case VK_PHYSICAL_DEVICE_INFO_TYPE_PERFORMANCE
:
217 *pDataSize
= sizeof(*performance
);
221 performance
->maxDeviceClock
= 1.0;
222 performance
->aluPerClock
= 1.0;
223 performance
->texPerClock
= 1.0;
224 performance
->primsPerClock
= 1.0;
225 performance
->pixelsPerClock
= 1.0;
228 case VK_PHYSICAL_DEVICE_INFO_TYPE_QUEUE_PROPERTIES
:
229 queue_properties
= pData
;
231 *pDataSize
= sizeof(*queue_properties
);
235 queue_properties
->queueFlags
= 0;
236 queue_properties
->queueCount
= 1;
237 queue_properties
->maxAtomicCounters
= 0;
238 queue_properties
->supportsTimestamps
= true;
239 queue_properties
->maxMemReferences
= 256;
242 case VK_PHYSICAL_DEVICE_INFO_TYPE_MEMORY_PROPERTIES
:
243 memory_properties
= pData
;
245 *pDataSize
= sizeof(*memory_properties
);
249 memory_properties
->supportsMigration
= false;
250 memory_properties
->supportsPinning
= false;
254 return VK_UNSUPPORTED
;
259 void * vkGetProcAddr(
260 VkPhysicalDevice physicalDevice
,
263 return anv_lookup_entrypoint(pName
);
267 parse_debug_flags(struct anv_device
*device
)
269 const char *debug
, *p
, *end
;
271 debug
= getenv("INTEL_DEBUG");
272 device
->dump_aub
= false;
274 for (p
= debug
; *p
; p
= end
+ 1) {
275 end
= strchrnul(p
, ',');
276 if (end
- p
== 3 && memcmp(p
, "aub", 3) == 0)
277 device
->dump_aub
= true;
278 if (end
- p
== 5 && memcmp(p
, "no_hw", 5) == 0)
279 device
->no_hw
= true;
286 VkResult
anv_CreateDevice(
287 VkPhysicalDevice _physicalDevice
,
288 const VkDeviceCreateInfo
* pCreateInfo
,
291 struct anv_physical_device
*physicalDevice
=
292 (struct anv_physical_device
*) _physicalDevice
;
293 struct anv_instance
*instance
= physicalDevice
->instance
;
294 struct anv_device
*device
;
296 assert(pCreateInfo
->sType
== VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO
);
298 device
= instance
->pfnAlloc(instance
->pAllocUserData
,
300 VK_SYSTEM_ALLOC_TYPE_API_OBJECT
);
302 return vk_error(VK_ERROR_OUT_OF_HOST_MEMORY
);
304 device
->no_hw
= physicalDevice
->no_hw
;
305 parse_debug_flags(device
);
307 device
->instance
= physicalDevice
->instance
;
308 device
->fd
= open("/dev/dri/renderD128", O_RDWR
| O_CLOEXEC
);
309 if (device
->fd
== -1)
312 device
->context_id
= anv_gem_create_context(device
);
313 if (device
->context_id
== -1)
316 anv_block_pool_init(&device
->dynamic_state_block_pool
, device
, 2048);
318 anv_state_pool_init(&device
->dynamic_state_pool
,
319 &device
->dynamic_state_block_pool
);
321 anv_block_pool_init(&device
->instruction_block_pool
, device
, 2048);
322 anv_block_pool_init(&device
->surface_state_block_pool
, device
, 2048);
325 /* Binding table pointers are only 16 bits so we have to make sure that
326 * they get allocated at the beginning of the surface state BO. To
327 * handle this, we create a separate block pool that works out of the
328 * first 64 KB of the surface state BO.
330 anv_block_pool_init_slave(&device
->binding_table_block_pool
,
331 &device
->surface_state_block_pool
, 32);
333 anv_state_pool_init(&device
->surface_state_pool
,
334 &device
->surface_state_block_pool
);
336 device
->compiler
= anv_compiler_create(device
->fd
);
337 device
->aub_writer
= NULL
;
339 device
->info
= *physicalDevice
->info
;
341 pthread_mutex_init(&device
->mutex
, NULL
);
343 anv_device_init_meta(device
);
345 *pDevice
= (VkDevice
) device
;
352 anv_device_free(device
, device
);
354 return vk_error(VK_ERROR_UNAVAILABLE
);
357 VkResult
anv_DestroyDevice(
360 struct anv_device
*device
= (struct anv_device
*) _device
;
362 anv_compiler_destroy(device
->compiler
);
364 anv_block_pool_finish(&device
->dynamic_state_block_pool
);
365 anv_block_pool_finish(&device
->instruction_block_pool
);
366 anv_block_pool_finish(&device
->surface_state_block_pool
);
370 if (device
->aub_writer
)
371 anv_aub_writer_destroy(device
->aub_writer
);
373 anv_device_free(device
, device
);
378 VkResult
anv_GetGlobalExtensionInfo(
379 VkExtensionInfoType infoType
,
380 uint32_t extensionIndex
,
387 case VK_EXTENSION_INFO_TYPE_COUNT
:
389 assert(*pDataSize
== 4);
393 case VK_EXTENSION_INFO_TYPE_PROPERTIES
:
394 return vk_error(VK_ERROR_INVALID_EXTENSION
);
397 return VK_UNSUPPORTED
;
401 VkResult
anv_GetPhysicalDeviceExtensionInfo(
402 VkPhysicalDevice physicalDevice
,
403 VkExtensionInfoType infoType
,
404 uint32_t extensionIndex
,
411 case VK_EXTENSION_INFO_TYPE_COUNT
:
420 case VK_EXTENSION_INFO_TYPE_PROPERTIES
:
421 return vk_error(VK_ERROR_INVALID_EXTENSION
);
424 return VK_UNSUPPORTED
;
428 VkResult
anv_EnumerateLayers(
429 VkPhysicalDevice physicalDevice
,
430 size_t maxStringSize
,
432 char* const* pOutLayers
,
440 VkResult
anv_GetDeviceQueue(
442 uint32_t queueNodeIndex
,
446 struct anv_device
*device
= (struct anv_device
*) _device
;
447 struct anv_queue
*queue
;
449 /* FIXME: Should allocate these at device create time. */
451 queue
= anv_device_alloc(device
, sizeof(*queue
), 8,
452 VK_SYSTEM_ALLOC_TYPE_API_OBJECT
);
454 return vk_error(VK_ERROR_OUT_OF_HOST_MEMORY
);
456 queue
->device
= device
;
457 queue
->pool
= &device
->surface_state_pool
;
459 queue
->completed_serial
= anv_state_pool_alloc(queue
->pool
, 4, 4);
460 *(uint32_t *)queue
->completed_serial
.map
= 0;
461 queue
->next_serial
= 1;
463 *pQueue
= (VkQueue
) queue
;
468 static const uint32_t BATCH_SIZE
= 8192;
471 anv_batch_init(struct anv_batch
*batch
, struct anv_device
*device
)
475 result
= anv_bo_init_new(&batch
->bo
, device
, BATCH_SIZE
);
476 if (result
!= VK_SUCCESS
)
480 anv_gem_mmap(device
, batch
->bo
.gem_handle
, 0, BATCH_SIZE
);
481 if (batch
->bo
.map
== NULL
) {
482 anv_gem_close(device
, batch
->bo
.gem_handle
);
483 return vk_error(VK_ERROR_MEMORY_MAP_FAILED
);
486 batch
->cmd_relocs
.num_relocs
= 0;
487 batch
->surf_relocs
.num_relocs
= 0;
488 batch
->next
= batch
->bo
.map
;
494 anv_batch_finish(struct anv_batch
*batch
, struct anv_device
*device
)
496 anv_gem_munmap(batch
->bo
.map
, BATCH_SIZE
);
497 anv_gem_close(device
, batch
->bo
.gem_handle
);
501 anv_batch_reset(struct anv_batch
*batch
)
503 batch
->next
= batch
->bo
.map
;
504 batch
->cmd_relocs
.num_relocs
= 0;
505 batch
->surf_relocs
.num_relocs
= 0;
509 anv_batch_emit_dwords(struct anv_batch
*batch
, int num_dwords
)
511 void *p
= batch
->next
;
513 batch
->next
+= num_dwords
* 4;
519 anv_reloc_list_append(struct anv_reloc_list
*list
,
520 struct anv_reloc_list
*other
, uint32_t offset
)
524 count
= list
->num_relocs
;
525 memcpy(&list
->relocs
[count
], &other
->relocs
[0],
526 other
->num_relocs
* sizeof(other
->relocs
[0]));
527 memcpy(&list
->reloc_bos
[count
], &other
->reloc_bos
[0],
528 other
->num_relocs
* sizeof(other
->reloc_bos
[0]));
529 for (i
= 0; i
< other
->num_relocs
; i
++)
530 list
->relocs
[i
+ count
].offset
+= offset
;
532 count
+= other
->num_relocs
;
536 anv_reloc_list_add(struct anv_reloc_list
*list
,
538 struct anv_bo
*target_bo
, uint32_t delta
)
540 struct drm_i915_gem_relocation_entry
*entry
;
543 assert(list
->num_relocs
< ANV_BATCH_MAX_RELOCS
);
545 /* XXX: Can we use I915_EXEC_HANDLE_LUT? */
546 index
= list
->num_relocs
++;
547 list
->reloc_bos
[index
] = target_bo
;
548 entry
= &list
->relocs
[index
];
549 entry
->target_handle
= target_bo
->gem_handle
;
550 entry
->delta
= delta
;
551 entry
->offset
= offset
;
552 entry
->presumed_offset
= target_bo
->offset
;
553 entry
->read_domains
= 0;
554 entry
->write_domain
= 0;
556 return target_bo
->offset
+ delta
;
560 anv_batch_emit_batch(struct anv_batch
*batch
, struct anv_batch
*other
)
562 uint32_t size
, offset
;
564 size
= other
->next
- other
->bo
.map
;
565 memcpy(batch
->next
, other
->bo
.map
, size
);
567 offset
= batch
->next
- batch
->bo
.map
;
568 anv_reloc_list_append(&batch
->cmd_relocs
, &other
->cmd_relocs
, offset
);
569 anv_reloc_list_append(&batch
->surf_relocs
, &other
->surf_relocs
, offset
);
575 anv_batch_emit_reloc(struct anv_batch
*batch
,
576 void *location
, struct anv_bo
*bo
, uint32_t delta
)
578 return anv_reloc_list_add(&batch
->cmd_relocs
,
579 location
- batch
->bo
.map
, bo
, delta
);
582 VkResult
anv_QueueSubmit(
584 uint32_t cmdBufferCount
,
585 const VkCmdBuffer
* pCmdBuffers
,
588 struct anv_queue
*queue
= (struct anv_queue
*) _queue
;
589 struct anv_device
*device
= queue
->device
;
590 struct anv_fence
*fence
= (struct anv_fence
*) _fence
;
593 for (uint32_t i
= 0; i
< cmdBufferCount
; i
++) {
594 struct anv_cmd_buffer
*cmd_buffer
=
595 (struct anv_cmd_buffer
*) pCmdBuffers
[i
];
597 if (device
->dump_aub
)
598 anv_cmd_buffer_dump(cmd_buffer
);
600 if (!device
->no_hw
) {
601 ret
= anv_gem_execbuffer(device
, &cmd_buffer
->execbuf
);
603 return vk_error(VK_ERROR_UNKNOWN
);
606 ret
= anv_gem_execbuffer(device
, &fence
->execbuf
);
608 return vk_error(VK_ERROR_UNKNOWN
);
611 for (uint32_t i
= 0; i
< cmd_buffer
->bo_count
; i
++)
612 cmd_buffer
->exec2_bos
[i
]->offset
= cmd_buffer
->exec2_objects
[i
].offset
;
614 *(uint32_t *)queue
->completed_serial
.map
= cmd_buffer
->serial
;
621 VkResult
anv_QueueAddMemReferences(
624 const VkDeviceMemory
* pMems
)
629 VkResult
anv_QueueRemoveMemReferences(
632 const VkDeviceMemory
* pMems
)
637 VkResult
anv_QueueWaitIdle(
640 struct anv_queue
*queue
= (struct anv_queue
*) _queue
;
642 return vkDeviceWaitIdle((VkDevice
) queue
->device
);
645 VkResult
anv_DeviceWaitIdle(
648 struct anv_device
*device
= (struct anv_device
*) _device
;
649 struct anv_state state
;
650 struct anv_batch batch
;
651 struct drm_i915_gem_execbuffer2 execbuf
;
652 struct drm_i915_gem_exec_object2 exec2_objects
[1];
653 struct anv_bo
*bo
= NULL
;
658 state
= anv_state_pool_alloc(&device
->dynamic_state_pool
, 32, 32);
659 bo
= &device
->dynamic_state_pool
.block_pool
->bo
;
660 batch
.next
= state
.map
;
661 anv_batch_emit(&batch
, GEN8_MI_BATCH_BUFFER_END
);
662 anv_batch_emit(&batch
, GEN8_MI_NOOP
);
664 exec2_objects
[0].handle
= bo
->gem_handle
;
665 exec2_objects
[0].relocation_count
= 0;
666 exec2_objects
[0].relocs_ptr
= 0;
667 exec2_objects
[0].alignment
= 0;
668 exec2_objects
[0].offset
= bo
->offset
;
669 exec2_objects
[0].flags
= 0;
670 exec2_objects
[0].rsvd1
= 0;
671 exec2_objects
[0].rsvd2
= 0;
673 execbuf
.buffers_ptr
= (uintptr_t) exec2_objects
;
674 execbuf
.buffer_count
= 1;
675 execbuf
.batch_start_offset
= state
.offset
;
676 execbuf
.batch_len
= batch
.next
- state
.map
;
677 execbuf
.cliprects_ptr
= 0;
678 execbuf
.num_cliprects
= 0;
683 I915_EXEC_HANDLE_LUT
| I915_EXEC_NO_RELOC
| I915_EXEC_RENDER
;
684 execbuf
.rsvd1
= device
->context_id
;
687 if (!device
->no_hw
) {
688 ret
= anv_gem_execbuffer(device
, &execbuf
);
690 result
= vk_error(VK_ERROR_UNKNOWN
);
695 ret
= anv_gem_wait(device
, bo
->gem_handle
, &timeout
);
697 result
= vk_error(VK_ERROR_UNKNOWN
);
702 anv_state_pool_free(&device
->dynamic_state_pool
, state
);
707 anv_state_pool_free(&device
->dynamic_state_pool
, state
);
713 anv_device_alloc(struct anv_device
* device
,
716 VkSystemAllocType allocType
)
718 return device
->instance
->pfnAlloc(device
->instance
->pAllocUserData
,
725 anv_device_free(struct anv_device
* device
,
728 return device
->instance
->pfnFree(device
->instance
->pAllocUserData
,
733 anv_bo_init_new(struct anv_bo
*bo
, struct anv_device
*device
, uint64_t size
)
735 bo
->gem_handle
= anv_gem_create(device
, size
);
737 return vk_error(VK_ERROR_OUT_OF_DEVICE_MEMORY
);
747 VkResult
anv_AllocMemory(
749 const VkMemoryAllocInfo
* pAllocInfo
,
750 VkDeviceMemory
* pMem
)
752 struct anv_device
*device
= (struct anv_device
*) _device
;
753 struct anv_device_memory
*mem
;
756 assert(pAllocInfo
->sType
== VK_STRUCTURE_TYPE_MEMORY_ALLOC_INFO
);
758 mem
= anv_device_alloc(device
, sizeof(*mem
), 8,
759 VK_SYSTEM_ALLOC_TYPE_API_OBJECT
);
761 return vk_error(VK_ERROR_OUT_OF_HOST_MEMORY
);
763 result
= anv_bo_init_new(&mem
->bo
, device
, pAllocInfo
->allocationSize
);
764 if (result
!= VK_SUCCESS
)
767 *pMem
= (VkDeviceMemory
) mem
;
772 anv_device_free(device
, mem
);
777 VkResult
anv_FreeMemory(
781 struct anv_device
*device
= (struct anv_device
*) _device
;
782 struct anv_device_memory
*mem
= (struct anv_device_memory
*) _mem
;
785 anv_gem_munmap(mem
->bo
.map
, mem
->bo
.size
);
787 if (mem
->bo
.gem_handle
!= 0)
788 anv_gem_close(device
, mem
->bo
.gem_handle
);
790 anv_device_free(device
, mem
);
795 VkResult
anv_SetMemoryPriority(
798 VkMemoryPriority priority
)
803 VkResult
anv_MapMemory(
808 VkMemoryMapFlags flags
,
811 struct anv_device
*device
= (struct anv_device
*) _device
;
812 struct anv_device_memory
*mem
= (struct anv_device_memory
*) _mem
;
814 /* FIXME: Is this supposed to be thread safe? Since vkUnmapMemory() only
815 * takes a VkDeviceMemory pointer, it seems like only one map of the memory
816 * at a time is valid. We could just mmap up front and return an offset
817 * pointer here, but that may exhaust virtual memory on 32 bit
820 mem
->map
= anv_gem_mmap(device
, mem
->bo
.gem_handle
, offset
, size
);
821 mem
->map_size
= size
;
828 VkResult
anv_UnmapMemory(
832 struct anv_device_memory
*mem
= (struct anv_device_memory
*) _mem
;
834 anv_gem_munmap(mem
->map
, mem
->map_size
);
839 VkResult
anv_FlushMappedMemory(
845 /* clflush here for !llc platforms */
850 VkResult
anv_PinSystemMemory(
854 VkDeviceMemory
* pMem
)
859 VkResult
anv_GetMultiDeviceCompatibility(
860 VkPhysicalDevice physicalDevice0
,
861 VkPhysicalDevice physicalDevice1
,
862 VkPhysicalDeviceCompatibilityInfo
* pInfo
)
864 return VK_UNSUPPORTED
;
867 VkResult
anv_OpenSharedMemory(
869 const VkMemoryOpenInfo
* pOpenInfo
,
870 VkDeviceMemory
* pMem
)
872 return VK_UNSUPPORTED
;
875 VkResult
anv_OpenSharedSemaphore(
877 const VkSemaphoreOpenInfo
* pOpenInfo
,
878 VkSemaphore
* pSemaphore
)
880 return VK_UNSUPPORTED
;
883 VkResult
anv_OpenPeerMemory(
885 const VkPeerMemoryOpenInfo
* pOpenInfo
,
886 VkDeviceMemory
* pMem
)
888 return VK_UNSUPPORTED
;
891 VkResult
anv_OpenPeerImage(
893 const VkPeerImageOpenInfo
* pOpenInfo
,
895 VkDeviceMemory
* pMem
)
897 return VK_UNSUPPORTED
;
901 anv_instance_destructor(struct anv_device
* device
,
904 return vkDestroyInstance(object
);
908 anv_noop_destructor(struct anv_device
* device
,
915 anv_device_destructor(struct anv_device
* device
,
918 return vkDestroyDevice(object
);
922 anv_cmd_buffer_destructor(struct anv_device
* device
,
925 struct anv_cmd_buffer
*cmd_buffer
= (struct anv_cmd_buffer
*) object
;
927 anv_state_stream_finish(&cmd_buffer
->surface_state_stream
);
928 anv_state_stream_finish(&cmd_buffer
->dynamic_state_stream
);
929 anv_state_stream_finish(&cmd_buffer
->binding_table_state_stream
);
930 anv_batch_finish(&cmd_buffer
->batch
, device
);
931 anv_device_free(device
, cmd_buffer
->exec2_objects
);
932 anv_device_free(device
, cmd_buffer
->exec2_bos
);
933 anv_device_free(device
, cmd_buffer
);
939 anv_pipeline_destructor(struct anv_device
* device
,
942 struct anv_pipeline
*pipeline
= (struct anv_pipeline
*) object
;
944 return anv_pipeline_destroy(pipeline
);
948 anv_free_destructor(struct anv_device
* device
,
951 anv_device_free(device
, (void *) object
);
957 anv_fence_destructor(struct anv_device
* device
,
960 struct anv_fence
*fence
= (struct anv_fence
*) object
;
962 anv_gem_munmap(fence
->bo
.map
, fence
->bo
.size
);
963 anv_gem_close(device
, fence
->bo
.gem_handle
);
964 anv_device_free(device
, fence
);
970 anv_query_pool_destructor(struct anv_device
* device
,
973 struct anv_query_pool
*pool
= (struct anv_query_pool
*) object
;
975 anv_gem_munmap(pool
->bo
.map
, pool
->bo
.size
);
976 anv_gem_close(device
, pool
->bo
.gem_handle
);
977 anv_device_free(device
, pool
);
982 static VkResult (*anv_object_destructors
[])(struct anv_device
*device
,
984 [VK_OBJECT_TYPE_INSTANCE
] = anv_instance_destructor
,
985 [VK_OBJECT_TYPE_PHYSICAL_DEVICE
] = anv_noop_destructor
,
986 [VK_OBJECT_TYPE_DEVICE
] = anv_device_destructor
,
987 [VK_OBJECT_TYPE_QUEUE
] = anv_noop_destructor
,
988 [VK_OBJECT_TYPE_COMMAND_BUFFER
] = anv_cmd_buffer_destructor
,
989 [VK_OBJECT_TYPE_PIPELINE
] = anv_pipeline_destructor
,
990 [VK_OBJECT_TYPE_SHADER
] = anv_free_destructor
,
991 [VK_OBJECT_TYPE_BUFFER
] = anv_free_destructor
,
992 [VK_OBJECT_TYPE_IMAGE
] = anv_free_destructor
,
993 [VK_OBJECT_TYPE_RENDER_PASS
] = anv_free_destructor
,
994 [VK_OBJECT_TYPE_FENCE
] = anv_fence_destructor
,
995 [VK_OBJECT_TYPE_QUERY_POOL
] = anv_query_pool_destructor
998 VkResult
anv_DestroyObject(
1000 VkObjectType objType
,
1003 struct anv_device
*device
= (struct anv_device
*) _device
;
1005 assert(objType
< ARRAY_SIZE(anv_object_destructors
) &&
1006 anv_object_destructors
[objType
] != NULL
);
1008 return anv_object_destructors
[objType
](device
, object
);
1012 fill_memory_requirements(
1013 VkObjectType objType
,
1015 VkMemoryRequirements
* memory_requirements
)
1017 struct anv_buffer
*buffer
;
1018 struct anv_image
*image
;
1020 memory_requirements
->memPropsAllowed
=
1021 VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT
|
1022 VK_MEMORY_PROPERTY_HOST_DEVICE_COHERENT_BIT
|
1023 /* VK_MEMORY_PROPERTY_HOST_UNCACHED_BIT | */
1024 VK_MEMORY_PROPERTY_HOST_WRITE_COMBINED_BIT
|
1025 VK_MEMORY_PROPERTY_PREFER_HOST_LOCAL
|
1026 VK_MEMORY_PROPERTY_SHAREABLE_BIT
;
1028 memory_requirements
->memPropsRequired
= 0;
1031 case VK_OBJECT_TYPE_BUFFER
:
1032 buffer
= (struct anv_buffer
*) object
;
1033 memory_requirements
->size
= buffer
->size
;
1034 memory_requirements
->alignment
= 16;
1036 case VK_OBJECT_TYPE_IMAGE
:
1037 image
= (struct anv_image
*) object
;
1038 memory_requirements
->size
= image
->size
;
1039 memory_requirements
->alignment
= image
->alignment
;
1042 memory_requirements
->size
= 0;
1048 get_allocation_count(VkObjectType objType
)
1051 case VK_OBJECT_TYPE_BUFFER
:
1052 case VK_OBJECT_TYPE_IMAGE
:
1059 VkResult
anv_GetObjectInfo(
1061 VkObjectType objType
,
1063 VkObjectInfoType infoType
,
1067 VkMemoryRequirements memory_requirements
;
1071 case VK_OBJECT_INFO_TYPE_MEMORY_REQUIREMENTS
:
1072 *pDataSize
= sizeof(memory_requirements
);
1076 fill_memory_requirements(objType
, object
, pData
);
1079 case VK_OBJECT_INFO_TYPE_MEMORY_ALLOCATION_COUNT
:
1080 *pDataSize
= sizeof(count
);
1085 *count
= get_allocation_count(objType
);
1089 return VK_UNSUPPORTED
;
1094 VkResult
anv_QueueBindObjectMemory(
1096 VkObjectType objType
,
1098 uint32_t allocationIdx
,
1099 VkDeviceMemory _mem
,
1100 VkDeviceSize memOffset
)
1102 struct anv_buffer
*buffer
;
1103 struct anv_image
*image
;
1104 struct anv_device_memory
*mem
= (struct anv_device_memory
*) _mem
;
1107 case VK_OBJECT_TYPE_BUFFER
:
1108 buffer
= (struct anv_buffer
*) object
;
1109 buffer
->bo
= &mem
->bo
;
1110 buffer
->offset
= memOffset
;
1112 case VK_OBJECT_TYPE_IMAGE
:
1113 image
= (struct anv_image
*) object
;
1114 image
->bo
= &mem
->bo
;
1115 image
->offset
= memOffset
;
1124 VkResult
anv_QueueBindObjectMemoryRange(
1126 VkObjectType objType
,
1128 uint32_t allocationIdx
,
1129 VkDeviceSize rangeOffset
,
1130 VkDeviceSize rangeSize
,
1132 VkDeviceSize memOffset
)
1134 stub_return(VK_UNSUPPORTED
);
1137 VkResult
anv_QueueBindImageMemoryRange(
1140 uint32_t allocationIdx
,
1141 const VkImageMemoryBindInfo
* pBindInfo
,
1143 VkDeviceSize memOffset
)
1145 stub_return(VK_UNSUPPORTED
);
1148 VkResult
anv_CreateFence(
1150 const VkFenceCreateInfo
* pCreateInfo
,
1153 struct anv_device
*device
= (struct anv_device
*) _device
;
1154 struct anv_fence
*fence
;
1155 struct anv_batch batch
;
1158 const uint32_t fence_size
= 128;
1160 assert(pCreateInfo
->sType
== VK_STRUCTURE_TYPE_FENCE_CREATE_INFO
);
1162 fence
= anv_device_alloc(device
, sizeof(*fence
), 8,
1163 VK_SYSTEM_ALLOC_TYPE_API_OBJECT
);
1165 return vk_error(VK_ERROR_OUT_OF_HOST_MEMORY
);
1167 result
= anv_bo_init_new(&fence
->bo
, device
, fence_size
);
1168 if (result
!= VK_SUCCESS
)
1172 anv_gem_mmap(device
, fence
->bo
.gem_handle
, 0, fence
->bo
.size
);
1173 batch
.next
= fence
->bo
.map
;
1174 anv_batch_emit(&batch
, GEN8_MI_BATCH_BUFFER_END
);
1175 anv_batch_emit(&batch
, GEN8_MI_NOOP
);
1177 fence
->exec2_objects
[0].handle
= fence
->bo
.gem_handle
;
1178 fence
->exec2_objects
[0].relocation_count
= 0;
1179 fence
->exec2_objects
[0].relocs_ptr
= 0;
1180 fence
->exec2_objects
[0].alignment
= 0;
1181 fence
->exec2_objects
[0].offset
= fence
->bo
.offset
;
1182 fence
->exec2_objects
[0].flags
= 0;
1183 fence
->exec2_objects
[0].rsvd1
= 0;
1184 fence
->exec2_objects
[0].rsvd2
= 0;
1186 fence
->execbuf
.buffers_ptr
= (uintptr_t) fence
->exec2_objects
;
1187 fence
->execbuf
.buffer_count
= 1;
1188 fence
->execbuf
.batch_start_offset
= 0;
1189 fence
->execbuf
.batch_len
= batch
.next
- fence
->bo
.map
;
1190 fence
->execbuf
.cliprects_ptr
= 0;
1191 fence
->execbuf
.num_cliprects
= 0;
1192 fence
->execbuf
.DR1
= 0;
1193 fence
->execbuf
.DR4
= 0;
1195 fence
->execbuf
.flags
=
1196 I915_EXEC_HANDLE_LUT
| I915_EXEC_NO_RELOC
| I915_EXEC_RENDER
;
1197 fence
->execbuf
.rsvd1
= device
->context_id
;
1198 fence
->execbuf
.rsvd2
= 0;
1200 *pFence
= (VkQueryPool
) fence
;
1205 anv_device_free(device
, fence
);
1210 VkResult
anv_ResetFences(
1212 uint32_t fenceCount
,
1215 struct anv_fence
**fences
= (struct anv_fence
**) pFences
;
1217 for (uint32_t i
; i
< fenceCount
; i
++)
1218 fences
[i
]->ready
= false;
1223 VkResult
anv_GetFenceStatus(
1227 struct anv_device
*device
= (struct anv_device
*) _device
;
1228 struct anv_fence
*fence
= (struct anv_fence
*) _fence
;
1235 ret
= anv_gem_wait(device
, fence
->bo
.gem_handle
, &t
);
1237 fence
->ready
= true;
1241 return VK_NOT_READY
;
1244 VkResult
anv_WaitForFences(
1246 uint32_t fenceCount
,
1247 const VkFence
* pFences
,
1251 struct anv_device
*device
= (struct anv_device
*) _device
;
1252 struct anv_fence
**fences
= (struct anv_fence
**) pFences
;
1253 int64_t t
= timeout
;
1256 /* FIXME: handle !waitAll */
1258 for (uint32_t i
= 0; i
< fenceCount
; i
++) {
1259 ret
= anv_gem_wait(device
, fences
[i
]->bo
.gem_handle
, &t
);
1260 if (ret
== -1 && errno
== ETIME
)
1263 return vk_error(VK_ERROR_UNKNOWN
);
1269 // Queue semaphore functions
1271 VkResult
anv_CreateSemaphore(
1273 const VkSemaphoreCreateInfo
* pCreateInfo
,
1274 VkSemaphore
* pSemaphore
)
1276 stub_return(VK_UNSUPPORTED
);
1279 VkResult
anv_QueueSignalSemaphore(
1281 VkSemaphore semaphore
)
1283 stub_return(VK_UNSUPPORTED
);
1286 VkResult
anv_QueueWaitSemaphore(
1288 VkSemaphore semaphore
)
1290 stub_return(VK_UNSUPPORTED
);
1295 VkResult
anv_CreateEvent(
1297 const VkEventCreateInfo
* pCreateInfo
,
1300 stub_return(VK_UNSUPPORTED
);
1303 VkResult
anv_GetEventStatus(
1307 stub_return(VK_UNSUPPORTED
);
1310 VkResult
anv_SetEvent(
1314 stub_return(VK_UNSUPPORTED
);
1317 VkResult
anv_ResetEvent(
1321 stub_return(VK_UNSUPPORTED
);
1326 VkResult
anv_CreateQueryPool(
1328 const VkQueryPoolCreateInfo
* pCreateInfo
,
1329 VkQueryPool
* pQueryPool
)
1331 struct anv_device
*device
= (struct anv_device
*) _device
;
1332 struct anv_query_pool
*pool
;
1336 assert(pCreateInfo
->sType
== VK_STRUCTURE_TYPE_QUERY_POOL_CREATE_INFO
);
1338 switch (pCreateInfo
->queryType
) {
1339 case VK_QUERY_TYPE_OCCLUSION
:
1341 case VK_QUERY_TYPE_PIPELINE_STATISTICS
:
1342 return VK_UNSUPPORTED
;
1347 pool
= anv_device_alloc(device
, sizeof(*pool
), 8,
1348 VK_SYSTEM_ALLOC_TYPE_API_OBJECT
);
1350 return vk_error(VK_ERROR_OUT_OF_HOST_MEMORY
);
1352 pool
->type
= pCreateInfo
->queryType
;
1353 size
= pCreateInfo
->slots
* sizeof(struct anv_query_pool_slot
);
1354 result
= anv_bo_init_new(&pool
->bo
, device
, size
);
1355 if (result
!= VK_SUCCESS
)
1358 pool
->bo
.map
= anv_gem_mmap(device
, pool
->bo
.gem_handle
, 0, size
);
1360 *pQueryPool
= (VkQueryPool
) pool
;
1365 anv_device_free(device
, pool
);
1370 VkResult
anv_GetQueryPoolResults(
1372 VkQueryPool queryPool
,
1373 uint32_t startQuery
,
1374 uint32_t queryCount
,
1377 VkQueryResultFlags flags
)
1379 struct anv_device
*device
= (struct anv_device
*) _device
;
1380 struct anv_query_pool
*pool
= (struct anv_query_pool
*) queryPool
;
1381 struct anv_query_pool_slot
*slot
= pool
->bo
.map
;
1382 int64_t timeout
= INT64_MAX
;
1383 uint32_t *dst32
= pData
;
1384 uint64_t *dst64
= pData
;
1388 if (flags
& VK_QUERY_RESULT_WITH_AVAILABILITY_BIT
) {
1389 /* Where is the availabilty info supposed to go? */
1390 anv_finishme("VK_QUERY_RESULT_WITH_AVAILABILITY_BIT");
1391 return VK_UNSUPPORTED
;
1394 assert(pool
->type
== VK_QUERY_TYPE_OCCLUSION
);
1396 if (flags
& VK_QUERY_RESULT_64_BIT
)
1397 *pDataSize
= queryCount
* sizeof(uint64_t);
1399 *pDataSize
= queryCount
* sizeof(uint32_t);
1404 if (flags
& VK_QUERY_RESULT_WAIT_BIT
) {
1405 ret
= anv_gem_wait(device
, pool
->bo
.gem_handle
, &timeout
);
1407 return vk_error(VK_ERROR_UNKNOWN
);
1410 for (uint32_t i
= 0; i
< queryCount
; i
++) {
1411 result
= slot
[startQuery
+ i
].end
- slot
[startQuery
+ i
].begin
;
1412 if (flags
& VK_QUERY_RESULT_64_BIT
) {
1415 if (result
> UINT32_MAX
)
1416 result
= UINT32_MAX
;
1426 VkResult
anv_CreateBuffer(
1428 const VkBufferCreateInfo
* pCreateInfo
,
1431 struct anv_device
*device
= (struct anv_device
*) _device
;
1432 struct anv_buffer
*buffer
;
1434 assert(pCreateInfo
->sType
== VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO
);
1436 buffer
= anv_device_alloc(device
, sizeof(*buffer
), 8,
1437 VK_SYSTEM_ALLOC_TYPE_API_OBJECT
);
1439 return vk_error(VK_ERROR_OUT_OF_HOST_MEMORY
);
1441 buffer
->size
= pCreateInfo
->size
;
1445 *pBuffer
= (VkBuffer
) buffer
;
1450 // Buffer view functions
1452 VkResult
anv_CreateBufferView(
1454 const VkBufferViewCreateInfo
* pCreateInfo
,
1455 VkBufferView
* pView
)
1457 struct anv_device
*device
= (struct anv_device
*) _device
;
1458 struct anv_buffer
*buffer
= (struct anv_buffer
*) pCreateInfo
->buffer
;
1459 struct anv_surface_view
*view
;
1460 const struct anv_format
*format
;
1462 assert(pCreateInfo
->sType
== VK_STRUCTURE_TYPE_BUFFER_VIEW_CREATE_INFO
);
1464 view
= anv_device_alloc(device
, sizeof(*view
), 8,
1465 VK_SYSTEM_ALLOC_TYPE_API_OBJECT
);
1467 return vk_error(VK_ERROR_OUT_OF_HOST_MEMORY
);
1469 view
->bo
= buffer
->bo
;
1470 view
->offset
= buffer
->offset
+ pCreateInfo
->offset
;
1471 view
->surface_state
=
1472 anv_state_pool_alloc(&device
->surface_state_pool
, 64, 64);
1473 view
->format
= pCreateInfo
->format
;
1475 format
= anv_format_for_vk_format(pCreateInfo
->format
);
1476 /* This assumes RGBA float format. */
1477 uint32_t stride
= 4;
1478 uint32_t num_elements
= pCreateInfo
->range
/ stride
;
1479 struct GEN8_RENDER_SURFACE_STATE surface_state
= {
1480 .SurfaceType
= SURFTYPE_BUFFER
,
1481 .SurfaceArray
= false,
1482 .SurfaceFormat
= format
->format
,
1483 .SurfaceVerticalAlignment
= VALIGN4
,
1484 .SurfaceHorizontalAlignment
= HALIGN4
,
1486 .VerticalLineStride
= 0,
1487 .VerticalLineStrideOffset
= 0,
1488 .SamplerL2BypassModeDisable
= true,
1489 .RenderCacheReadWriteMode
= WriteOnlyCache
,
1490 .MemoryObjectControlState
= 0, /* FIXME: MOCS */
1493 .Height
= (num_elements
>> 7) & 0x3fff,
1494 .Width
= num_elements
& 0x7f,
1495 .Depth
= (num_elements
>> 21) & 0x3f,
1496 .SurfacePitch
= stride
- 1,
1497 .MinimumArrayElement
= 0,
1498 .NumberofMultisamples
= MULTISAMPLECOUNT_1
,
1503 .AuxiliarySurfaceMode
= AUX_NONE
,
1505 .GreenClearColor
= 0,
1506 .BlueClearColor
= 0,
1507 .AlphaClearColor
= 0,
1508 .ShaderChannelSelectRed
= SCS_RED
,
1509 .ShaderChannelSelectGreen
= SCS_GREEN
,
1510 .ShaderChannelSelectBlue
= SCS_BLUE
,
1511 .ShaderChannelSelectAlpha
= SCS_ALPHA
,
1512 .ResourceMinLOD
= 0,
1513 /* FIXME: We assume that the image must be bound at this time. */
1514 .SurfaceBaseAddress
= { NULL
, view
->offset
},
1517 GEN8_RENDER_SURFACE_STATE_pack(NULL
, view
->surface_state
.map
, &surface_state
);
1519 *pView
= (VkImageView
) view
;
1524 // Sampler functions
1526 VkResult
anv_CreateSampler(
1528 const VkSamplerCreateInfo
* pCreateInfo
,
1529 VkSampler
* pSampler
)
1531 struct anv_device
*device
= (struct anv_device
*) _device
;
1532 struct anv_sampler
*sampler
;
1534 assert(pCreateInfo
->sType
== VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO
);
1536 sampler
= anv_device_alloc(device
, sizeof(*sampler
), 8,
1537 VK_SYSTEM_ALLOC_TYPE_API_OBJECT
);
1539 return vk_error(VK_ERROR_OUT_OF_HOST_MEMORY
);
1541 static const uint32_t vk_to_gen_tex_filter
[] = {
1542 [VK_TEX_FILTER_NEAREST
] = MAPFILTER_NEAREST
,
1543 [VK_TEX_FILTER_LINEAR
] = MAPFILTER_LINEAR
1546 static const uint32_t vk_to_gen_mipmap_mode
[] = {
1547 [VK_TEX_MIPMAP_MODE_BASE
] = MIPFILTER_NONE
,
1548 [VK_TEX_MIPMAP_MODE_NEAREST
] = MIPFILTER_NEAREST
,
1549 [VK_TEX_MIPMAP_MODE_LINEAR
] = MIPFILTER_LINEAR
1552 static const uint32_t vk_to_gen_tex_address
[] = {
1553 [VK_TEX_ADDRESS_WRAP
] = TCM_WRAP
,
1554 [VK_TEX_ADDRESS_MIRROR
] = TCM_MIRROR
,
1555 [VK_TEX_ADDRESS_CLAMP
] = TCM_CLAMP
,
1556 [VK_TEX_ADDRESS_MIRROR_ONCE
] = TCM_MIRROR_ONCE
,
1557 [VK_TEX_ADDRESS_CLAMP_BORDER
] = TCM_CLAMP_BORDER
,
1560 static const uint32_t vk_to_gen_compare_op
[] = {
1561 [VK_COMPARE_OP_NEVER
] = PREFILTEROPNEVER
,
1562 [VK_COMPARE_OP_LESS
] = PREFILTEROPLESS
,
1563 [VK_COMPARE_OP_EQUAL
] = PREFILTEROPEQUAL
,
1564 [VK_COMPARE_OP_LESS_EQUAL
] = PREFILTEROPLEQUAL
,
1565 [VK_COMPARE_OP_GREATER
] = PREFILTEROPGREATER
,
1566 [VK_COMPARE_OP_NOT_EQUAL
] = PREFILTEROPNOTEQUAL
,
1567 [VK_COMPARE_OP_GREATER_EQUAL
] = PREFILTEROPGEQUAL
,
1568 [VK_COMPARE_OP_ALWAYS
] = PREFILTEROPALWAYS
,
1571 if (pCreateInfo
->maxAnisotropy
> 0)
1572 anv_finishme("missing support for anisotropic filtering");
1574 struct GEN8_SAMPLER_STATE sampler_state
= {
1575 .SamplerDisable
= false,
1576 .TextureBorderColorMode
= DX10OGL
,
1577 .LODPreClampMode
= 0,
1579 .MipModeFilter
= vk_to_gen_mipmap_mode
[pCreateInfo
->mipMode
],
1580 .MagModeFilter
= vk_to_gen_tex_filter
[pCreateInfo
->magFilter
],
1581 .MinModeFilter
= vk_to_gen_tex_filter
[pCreateInfo
->minFilter
],
1582 .TextureLODBias
= pCreateInfo
->mipLodBias
* 256,
1583 .AnisotropicAlgorithm
= EWAApproximation
,
1584 .MinLOD
= pCreateInfo
->minLod
* 256,
1585 .MaxLOD
= pCreateInfo
->maxLod
* 256,
1586 .ChromaKeyEnable
= 0,
1587 .ChromaKeyIndex
= 0,
1589 .ShadowFunction
= vk_to_gen_compare_op
[pCreateInfo
->compareOp
],
1590 .CubeSurfaceControlMode
= 0,
1591 .IndirectStatePointer
= 0,
1592 .LODClampMagnificationMode
= MIPNONE
,
1593 .MaximumAnisotropy
= 0,
1594 .RAddressMinFilterRoundingEnable
= 0,
1595 .RAddressMagFilterRoundingEnable
= 0,
1596 .VAddressMinFilterRoundingEnable
= 0,
1597 .VAddressMagFilterRoundingEnable
= 0,
1598 .UAddressMinFilterRoundingEnable
= 0,
1599 .UAddressMagFilterRoundingEnable
= 0,
1600 .TrilinearFilterQuality
= 0,
1601 .NonnormalizedCoordinateEnable
= 0,
1602 .TCXAddressControlMode
= vk_to_gen_tex_address
[pCreateInfo
->addressU
],
1603 .TCYAddressControlMode
= vk_to_gen_tex_address
[pCreateInfo
->addressV
],
1604 .TCZAddressControlMode
= vk_to_gen_tex_address
[pCreateInfo
->addressW
],
1607 GEN8_SAMPLER_STATE_pack(NULL
, sampler
->state
, &sampler_state
);
1609 *pSampler
= (VkSampler
) sampler
;
1614 // Descriptor set functions
1616 VkResult
anv_CreateDescriptorSetLayout(
1618 const VkDescriptorSetLayoutCreateInfo
* pCreateInfo
,
1619 VkDescriptorSetLayout
* pSetLayout
)
1621 struct anv_device
*device
= (struct anv_device
*) _device
;
1622 struct anv_descriptor_set_layout
*set_layout
;
1624 assert(pCreateInfo
->sType
== VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO
);
1626 uint32_t sampler_count
[VK_NUM_SHADER_STAGE
] = { 0, };
1627 uint32_t surface_count
[VK_NUM_SHADER_STAGE
] = { 0, };
1628 uint32_t num_dynamic_buffers
= 0;
1632 for (uint32_t i
= 0; i
< pCreateInfo
->count
; i
++) {
1633 switch (pCreateInfo
->pBinding
[i
].descriptorType
) {
1634 case VK_DESCRIPTOR_TYPE_SAMPLER
:
1635 for_each_bit(s
, pCreateInfo
->pBinding
[i
].stageFlags
)
1636 sampler_count
[s
] += pCreateInfo
->pBinding
[i
].count
;
1639 case VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER
:
1640 for_each_bit(s
, pCreateInfo
->pBinding
[i
].stageFlags
)
1641 sampler_count
[s
] += pCreateInfo
->pBinding
[i
].count
;
1645 case VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE
:
1646 case VK_DESCRIPTOR_TYPE_STORAGE_IMAGE
:
1647 case VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER
:
1648 case VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER
:
1649 case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER
:
1650 case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER
:
1651 case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC
:
1652 case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC
:
1653 for_each_bit(s
, pCreateInfo
->pBinding
[i
].stageFlags
)
1654 surface_count
[s
] += pCreateInfo
->pBinding
[i
].count
;
1660 count
+= pCreateInfo
->pBinding
[i
].count
;
1663 for (uint32_t i
= 0; i
< pCreateInfo
->count
; i
++) {
1664 switch (pCreateInfo
->pBinding
[i
].descriptorType
) {
1665 case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC
:
1666 case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC
:
1667 num_dynamic_buffers
++;
1674 uint32_t sampler_total
= 0;
1675 uint32_t surface_total
= 0;
1676 for (uint32_t s
= 0; s
< VK_NUM_SHADER_STAGE
; s
++) {
1677 sampler_total
+= sampler_count
[s
];
1678 surface_total
+= surface_count
[s
];
1681 size_t size
= sizeof(*set_layout
) +
1682 (sampler_total
+ surface_total
) * sizeof(uint32_t);
1683 set_layout
= anv_device_alloc(device
, size
, 8,
1684 VK_SYSTEM_ALLOC_TYPE_API_OBJECT
);
1686 return vk_error(VK_ERROR_OUT_OF_HOST_MEMORY
);
1688 set_layout
->num_dynamic_buffers
= num_dynamic_buffers
;
1689 set_layout
->count
= count
;
1691 uint32_t *p
= set_layout
->entries
;
1692 uint32_t *sampler
[VK_NUM_SHADER_STAGE
];
1693 uint32_t *surface
[VK_NUM_SHADER_STAGE
];
1694 for (uint32_t s
= 0; s
< VK_NUM_SHADER_STAGE
; s
++) {
1695 set_layout
->stage
[s
].surface_count
= surface_count
[s
];
1696 set_layout
->stage
[s
].surface_start
= surface
[s
] = p
;
1697 p
+= surface_count
[s
];
1698 set_layout
->stage
[s
].sampler_count
= sampler_count
[s
];
1699 set_layout
->stage
[s
].sampler_start
= sampler
[s
] = p
;
1700 p
+= sampler_count
[s
];
1703 uint32_t descriptor
= 0;
1704 for (uint32_t i
= 0; i
< pCreateInfo
->count
; i
++) {
1705 switch (pCreateInfo
->pBinding
[i
].descriptorType
) {
1706 case VK_DESCRIPTOR_TYPE_SAMPLER
:
1707 for_each_bit(s
, pCreateInfo
->pBinding
[i
].stageFlags
)
1708 for (uint32_t j
= 0; j
< pCreateInfo
->pBinding
[i
].count
; j
++)
1709 *(sampler
[s
])++ = descriptor
+ j
;
1712 case VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER
:
1713 for_each_bit(s
, pCreateInfo
->pBinding
[i
].stageFlags
)
1714 for (uint32_t j
= 0; j
< pCreateInfo
->pBinding
[i
].count
; j
++)
1715 *(sampler
[s
])++ = descriptor
+ j
;
1719 case VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE
:
1720 case VK_DESCRIPTOR_TYPE_STORAGE_IMAGE
:
1721 case VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER
:
1722 case VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER
:
1723 case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER
:
1724 case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER
:
1725 case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC
:
1726 case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC
:
1727 for_each_bit(s
, pCreateInfo
->pBinding
[i
].stageFlags
)
1728 for (uint32_t j
= 0; j
< pCreateInfo
->pBinding
[i
].count
; j
++) {
1729 *(surface
[s
])++ = descriptor
+ j
;
1735 descriptor
+= pCreateInfo
->pBinding
[i
].count
;
1738 *pSetLayout
= (VkDescriptorSetLayout
) set_layout
;
1743 VkResult
anv_BeginDescriptorPoolUpdate(
1745 VkDescriptorUpdateMode updateMode
)
1750 VkResult
anv_EndDescriptorPoolUpdate(
1757 VkResult
anv_CreateDescriptorPool(
1759 VkDescriptorPoolUsage poolUsage
,
1761 const VkDescriptorPoolCreateInfo
* pCreateInfo
,
1762 VkDescriptorPool
* pDescriptorPool
)
1764 *pDescriptorPool
= 1;
1769 VkResult
anv_ResetDescriptorPool(
1771 VkDescriptorPool descriptorPool
)
1776 VkResult
anv_AllocDescriptorSets(
1778 VkDescriptorPool descriptorPool
,
1779 VkDescriptorSetUsage setUsage
,
1781 const VkDescriptorSetLayout
* pSetLayouts
,
1782 VkDescriptorSet
* pDescriptorSets
,
1785 struct anv_device
*device
= (struct anv_device
*) _device
;
1786 const struct anv_descriptor_set_layout
*layout
;
1787 struct anv_descriptor_set
*set
;
1790 for (uint32_t i
= 0; i
< count
; i
++) {
1791 layout
= (struct anv_descriptor_set_layout
*) pSetLayouts
[i
];
1792 size
= sizeof(*set
) + layout
->count
* sizeof(set
->descriptors
[0]);
1793 set
= anv_device_alloc(device
, size
, 8,
1794 VK_SYSTEM_ALLOC_TYPE_API_OBJECT
);
1797 return vk_error(VK_ERROR_OUT_OF_HOST_MEMORY
);
1800 pDescriptorSets
[i
] = (VkDescriptorSet
) set
;
1808 void anv_ClearDescriptorSets(
1810 VkDescriptorPool descriptorPool
,
1812 const VkDescriptorSet
* pDescriptorSets
)
1816 void anv_UpdateDescriptors(
1818 VkDescriptorSet descriptorSet
,
1819 uint32_t updateCount
,
1820 const void** ppUpdateArray
)
1822 struct anv_descriptor_set
*set
= (struct anv_descriptor_set
*) descriptorSet
;
1823 VkUpdateSamplers
*update_samplers
;
1824 VkUpdateSamplerTextures
*update_sampler_textures
;
1825 VkUpdateImages
*update_images
;
1826 VkUpdateBuffers
*update_buffers
;
1827 VkUpdateAsCopy
*update_as_copy
;
1829 for (uint32_t i
= 0; i
< updateCount
; i
++) {
1830 const struct anv_common
*common
= ppUpdateArray
[i
];
1832 switch (common
->sType
) {
1833 case VK_STRUCTURE_TYPE_UPDATE_SAMPLERS
:
1834 update_samplers
= (VkUpdateSamplers
*) common
;
1836 for (uint32_t j
= 0; j
< update_samplers
->count
; j
++) {
1837 set
->descriptors
[update_samplers
->binding
+ j
].sampler
=
1838 (struct anv_sampler
*) update_samplers
->pSamplers
[j
];
1842 case VK_STRUCTURE_TYPE_UPDATE_SAMPLER_TEXTURES
:
1843 /* FIXME: Shouldn't this be *_UPDATE_SAMPLER_IMAGES? */
1844 update_sampler_textures
= (VkUpdateSamplerTextures
*) common
;
1846 for (uint32_t j
= 0; j
< update_sampler_textures
->count
; j
++) {
1847 set
->descriptors
[update_sampler_textures
->binding
+ j
].view
=
1848 (struct anv_surface_view
*)
1849 update_sampler_textures
->pSamplerImageViews
[j
].pImageView
->view
;
1850 set
->descriptors
[update_sampler_textures
->binding
+ j
].sampler
=
1851 (struct anv_sampler
*)
1852 update_sampler_textures
->pSamplerImageViews
[j
].sampler
;
1856 case VK_STRUCTURE_TYPE_UPDATE_IMAGES
:
1857 update_images
= (VkUpdateImages
*) common
;
1859 for (uint32_t j
= 0; j
< update_images
->count
; j
++) {
1860 set
->descriptors
[update_images
->binding
+ j
].view
=
1861 (struct anv_surface_view
*) update_images
->pImageViews
[j
].view
;
1865 case VK_STRUCTURE_TYPE_UPDATE_BUFFERS
:
1866 update_buffers
= (VkUpdateBuffers
*) common
;
1868 for (uint32_t j
= 0; j
< update_buffers
->count
; j
++) {
1869 set
->descriptors
[update_buffers
->binding
+ j
].view
=
1870 (struct anv_surface_view
*) update_buffers
->pBufferViews
[j
].view
;
1872 /* FIXME: descriptor arrays? */
1875 case VK_STRUCTURE_TYPE_UPDATE_AS_COPY
:
1876 update_as_copy
= (VkUpdateAsCopy
*) common
;
1877 (void) update_as_copy
;
1886 // State object functions
1888 static inline int64_t
1889 clamp_int64(int64_t x
, int64_t min
, int64_t max
)
1899 VkResult
anv_CreateDynamicViewportState(
1901 const VkDynamicVpStateCreateInfo
* pCreateInfo
,
1902 VkDynamicVpState
* pState
)
1904 struct anv_device
*device
= (struct anv_device
*) _device
;
1905 struct anv_dynamic_vp_state
*state
;
1907 assert(pCreateInfo
->sType
== VK_STRUCTURE_TYPE_DYNAMIC_VP_STATE_CREATE_INFO
);
1909 state
= anv_device_alloc(device
, sizeof(*state
), 8,
1910 VK_SYSTEM_ALLOC_TYPE_API_OBJECT
);
1912 return vk_error(VK_ERROR_OUT_OF_HOST_MEMORY
);
1914 unsigned count
= pCreateInfo
->viewportAndScissorCount
;
1915 state
->sf_clip_vp
= anv_state_pool_alloc(&device
->dynamic_state_pool
,
1917 state
->cc_vp
= anv_state_pool_alloc(&device
->dynamic_state_pool
,
1919 state
->scissor
= anv_state_pool_alloc(&device
->dynamic_state_pool
,
1922 for (uint32_t i
= 0; i
< pCreateInfo
->viewportAndScissorCount
; i
++) {
1923 const VkViewport
*vp
= &pCreateInfo
->pViewports
[i
];
1924 const VkRect
*s
= &pCreateInfo
->pScissors
[i
];
1926 struct GEN8_SF_CLIP_VIEWPORT sf_clip_viewport
= {
1927 .ViewportMatrixElementm00
= vp
->width
/ 2,
1928 .ViewportMatrixElementm11
= vp
->height
/ 2,
1929 .ViewportMatrixElementm22
= (vp
->maxDepth
- vp
->minDepth
) / 2,
1930 .ViewportMatrixElementm30
= vp
->originX
+ vp
->width
/ 2,
1931 .ViewportMatrixElementm31
= vp
->originY
+ vp
->height
/ 2,
1932 .ViewportMatrixElementm32
= (vp
->maxDepth
+ vp
->minDepth
) / 2,
1933 .XMinClipGuardband
= -1.0f
,
1934 .XMaxClipGuardband
= 1.0f
,
1935 .YMinClipGuardband
= -1.0f
,
1936 .YMaxClipGuardband
= 1.0f
,
1937 .XMinViewPort
= vp
->originX
,
1938 .XMaxViewPort
= vp
->originX
+ vp
->width
- 1,
1939 .YMinViewPort
= vp
->originY
,
1940 .YMaxViewPort
= vp
->originY
+ vp
->height
- 1,
1943 struct GEN8_CC_VIEWPORT cc_viewport
= {
1944 .MinimumDepth
= vp
->minDepth
,
1945 .MaximumDepth
= vp
->maxDepth
1948 /* Since xmax and ymax are inclusive, we have to have xmax < xmin or
1949 * ymax < ymin for empty clips. In case clip x, y, width height are all
1950 * 0, the clamps below produce 0 for xmin, ymin, xmax, ymax, which isn't
1951 * what we want. Just special case empty clips and produce a canonical
1953 static const struct GEN8_SCISSOR_RECT empty_scissor
= {
1954 .ScissorRectangleYMin
= 1,
1955 .ScissorRectangleXMin
= 1,
1956 .ScissorRectangleYMax
= 0,
1957 .ScissorRectangleXMax
= 0
1960 const int max
= 0xffff;
1961 struct GEN8_SCISSOR_RECT scissor
= {
1962 /* Do this math using int64_t so overflow gets clamped correctly. */
1963 .ScissorRectangleYMin
= clamp_int64(s
->offset
.y
, 0, max
),
1964 .ScissorRectangleXMin
= clamp_int64(s
->offset
.x
, 0, max
),
1965 .ScissorRectangleYMax
= clamp_int64((uint64_t) s
->offset
.y
+ s
->extent
.height
- 1, 0, max
),
1966 .ScissorRectangleXMax
= clamp_int64((uint64_t) s
->offset
.x
+ s
->extent
.width
- 1, 0, max
)
1969 GEN8_SF_CLIP_VIEWPORT_pack(NULL
, state
->sf_clip_vp
.map
+ i
* 64, &sf_clip_viewport
);
1970 GEN8_CC_VIEWPORT_pack(NULL
, state
->cc_vp
.map
+ i
* 32, &cc_viewport
);
1972 if (s
->extent
.width
<= 0 || s
->extent
.height
<= 0) {
1973 GEN8_SCISSOR_RECT_pack(NULL
, state
->scissor
.map
+ i
* 32, &empty_scissor
);
1975 GEN8_SCISSOR_RECT_pack(NULL
, state
->scissor
.map
+ i
* 32, &scissor
);
1979 *pState
= (VkDynamicVpState
) state
;
1984 VkResult
anv_CreateDynamicRasterState(
1986 const VkDynamicRsStateCreateInfo
* pCreateInfo
,
1987 VkDynamicRsState
* pState
)
1989 struct anv_device
*device
= (struct anv_device
*) _device
;
1990 struct anv_dynamic_rs_state
*state
;
1992 assert(pCreateInfo
->sType
== VK_STRUCTURE_TYPE_DYNAMIC_RS_STATE_CREATE_INFO
);
1994 state
= anv_device_alloc(device
, sizeof(*state
), 8,
1995 VK_SYSTEM_ALLOC_TYPE_API_OBJECT
);
1997 return vk_error(VK_ERROR_OUT_OF_HOST_MEMORY
);
2001 * float depthBiasClamp;
2002 * float slopeScaledDepthBias;
2003 * float pointFadeThreshold;
2004 * // optional (GL45) - Size of point fade threshold
2007 struct GEN8_3DSTATE_SF sf
= {
2008 GEN8_3DSTATE_SF_header
,
2009 .LineWidth
= pCreateInfo
->lineWidth
,
2010 .PointWidth
= pCreateInfo
->pointSize
,
2013 GEN8_3DSTATE_SF_pack(NULL
, state
->state_sf
, &sf
);
2015 *pState
= (VkDynamicRsState
) state
;
2020 VkResult
anv_CreateDynamicColorBlendState(
2022 const VkDynamicCbStateCreateInfo
* pCreateInfo
,
2023 VkDynamicCbState
* pState
)
2025 struct anv_device
*device
= (struct anv_device
*) _device
;
2026 struct anv_dynamic_cb_state
*state
;
2028 assert(pCreateInfo
->sType
== VK_STRUCTURE_TYPE_DYNAMIC_CB_STATE_CREATE_INFO
);
2030 state
= anv_device_alloc(device
, sizeof(*state
), 8,
2031 VK_SYSTEM_ALLOC_TYPE_API_OBJECT
);
2033 return vk_error(VK_ERROR_OUT_OF_HOST_MEMORY
);
2035 *pState
= (VkDynamicCbState
) state
;
2040 VkResult
anv_CreateDynamicDepthStencilState(
2042 const VkDynamicDsStateCreateInfo
* pCreateInfo
,
2043 VkDynamicDsState
* pState
)
2045 stub_return(VK_UNSUPPORTED
);
2048 // Command buffer functions
2050 VkResult
anv_CreateCommandBuffer(
2052 const VkCmdBufferCreateInfo
* pCreateInfo
,
2053 VkCmdBuffer
* pCmdBuffer
)
2055 struct anv_device
*device
= (struct anv_device
*) _device
;
2056 struct anv_cmd_buffer
*cmd_buffer
;
2059 cmd_buffer
= anv_device_alloc(device
, sizeof(*cmd_buffer
), 8,
2060 VK_SYSTEM_ALLOC_TYPE_API_OBJECT
);
2061 if (cmd_buffer
== NULL
)
2062 return vk_error(VK_ERROR_OUT_OF_HOST_MEMORY
);
2064 cmd_buffer
->device
= device
;
2065 cmd_buffer
->rs_state
= NULL
;
2066 cmd_buffer
->vp_state
= NULL
;
2067 memset(&cmd_buffer
->default_bindings
, 0, sizeof(cmd_buffer
->default_bindings
));
2068 cmd_buffer
->bindings
= &cmd_buffer
->default_bindings
;
2070 result
= anv_batch_init(&cmd_buffer
->batch
, device
);
2071 if (result
!= VK_SUCCESS
)
2074 cmd_buffer
->exec2_objects
=
2075 anv_device_alloc(device
, 8192 * sizeof(cmd_buffer
->exec2_objects
[0]), 8,
2076 VK_SYSTEM_ALLOC_TYPE_API_OBJECT
);
2077 if (cmd_buffer
->exec2_objects
== NULL
) {
2078 result
= vk_error(VK_ERROR_OUT_OF_HOST_MEMORY
);
2082 cmd_buffer
->exec2_bos
=
2083 anv_device_alloc(device
, 8192 * sizeof(cmd_buffer
->exec2_bos
[0]), 8,
2084 VK_SYSTEM_ALLOC_TYPE_API_OBJECT
);
2085 if (cmd_buffer
->exec2_bos
== NULL
) {
2086 result
= vk_error(VK_ERROR_OUT_OF_HOST_MEMORY
);
2087 goto fail_exec2_objects
;
2090 anv_state_stream_init(&cmd_buffer
->binding_table_state_stream
,
2091 &device
->binding_table_block_pool
);
2092 anv_state_stream_init(&cmd_buffer
->surface_state_stream
,
2093 &device
->surface_state_block_pool
);
2094 anv_state_stream_init(&cmd_buffer
->dynamic_state_stream
,
2095 &device
->dynamic_state_block_pool
);
2097 cmd_buffer
->dirty
= 0;
2098 cmd_buffer
->vb_dirty
= 0;
2100 *pCmdBuffer
= (VkCmdBuffer
) cmd_buffer
;
2105 anv_device_free(device
, cmd_buffer
->exec2_objects
);
2107 anv_batch_finish(&cmd_buffer
->batch
, device
);
2109 anv_device_free(device
, cmd_buffer
);
2114 VkResult
anv_BeginCommandBuffer(
2115 VkCmdBuffer cmdBuffer
,
2116 const VkCmdBufferBeginInfo
* pBeginInfo
)
2118 struct anv_cmd_buffer
*cmd_buffer
= (struct anv_cmd_buffer
*) cmdBuffer
;
2119 struct anv_device
*device
= cmd_buffer
->device
;
2121 anv_batch_emit(&cmd_buffer
->batch
, GEN8_PIPELINE_SELECT
,
2122 .PipelineSelection
= _3D
);
2123 anv_batch_emit(&cmd_buffer
->batch
, GEN8_STATE_SIP
);
2125 anv_batch_emit(&cmd_buffer
->batch
, GEN8_STATE_BASE_ADDRESS
,
2126 .GeneralStateBaseAddress
= { NULL
, 0 },
2127 .GeneralStateBaseAddressModifyEnable
= true,
2128 .GeneralStateBufferSize
= 0xfffff,
2129 .GeneralStateBufferSizeModifyEnable
= true,
2131 .SurfaceStateBaseAddress
= { &device
->surface_state_block_pool
.bo
, 0 },
2132 .SurfaceStateMemoryObjectControlState
= 0, /* FIXME: MOCS */
2133 .SurfaceStateBaseAddressModifyEnable
= true,
2135 .DynamicStateBaseAddress
= { &device
->dynamic_state_block_pool
.bo
, 0 },
2136 .DynamicStateBaseAddressModifyEnable
= true,
2137 .DynamicStateBufferSize
= 0xfffff,
2138 .DynamicStateBufferSizeModifyEnable
= true,
2140 .IndirectObjectBaseAddress
= { NULL
, 0 },
2141 .IndirectObjectBaseAddressModifyEnable
= true,
2142 .IndirectObjectBufferSize
= 0xfffff,
2143 .IndirectObjectBufferSizeModifyEnable
= true,
2145 .InstructionBaseAddress
= { &device
->instruction_block_pool
.bo
, 0 },
2146 .InstructionBaseAddressModifyEnable
= true,
2147 .InstructionBufferSize
= 0xfffff,
2148 .InstructionBuffersizeModifyEnable
= true);
2150 anv_batch_emit(&cmd_buffer
->batch
, GEN8_3DSTATE_VF_STATISTICS
,
2151 .StatisticsEnable
= true);
2152 anv_batch_emit(&cmd_buffer
->batch
, GEN8_3DSTATE_HS
, .Enable
= false);
2153 anv_batch_emit(&cmd_buffer
->batch
, GEN8_3DSTATE_TE
, .TEEnable
= false);
2154 anv_batch_emit(&cmd_buffer
->batch
, GEN8_3DSTATE_DS
, .FunctionEnable
= false);
2155 anv_batch_emit(&cmd_buffer
->batch
, GEN8_3DSTATE_STREAMOUT
, .SOFunctionEnable
= false);
2157 anv_batch_emit(&cmd_buffer
->batch
, GEN8_3DSTATE_PUSH_CONSTANT_ALLOC_VS
,
2158 .ConstantBufferOffset
= 0,
2159 .ConstantBufferSize
= 4);
2160 anv_batch_emit(&cmd_buffer
->batch
, GEN8_3DSTATE_PUSH_CONSTANT_ALLOC_GS
,
2161 .ConstantBufferOffset
= 4,
2162 .ConstantBufferSize
= 4);
2163 anv_batch_emit(&cmd_buffer
->batch
, GEN8_3DSTATE_PUSH_CONSTANT_ALLOC_PS
,
2164 .ConstantBufferOffset
= 8,
2165 .ConstantBufferSize
= 4);
2167 anv_batch_emit(&cmd_buffer
->batch
, GEN8_3DSTATE_WM_CHROMAKEY
,
2168 .ChromaKeyKillEnable
= false);
2169 anv_batch_emit(&cmd_buffer
->batch
, GEN8_3DSTATE_SBE_SWIZ
);
2170 anv_batch_emit(&cmd_buffer
->batch
, GEN8_3DSTATE_AA_LINE_PARAMETERS
);
2172 /* Hardcoded state: */
2173 anv_batch_emit(&cmd_buffer
->batch
, GEN8_3DSTATE_DEPTH_BUFFER
,
2174 .SurfaceType
= SURFTYPE_2D
,
2177 .SurfaceFormat
= D16_UNORM
,
2178 .SurfaceBaseAddress
= { NULL
, 0 },
2179 .HierarchicalDepthBufferEnable
= 0);
2181 anv_batch_emit(&cmd_buffer
->batch
, GEN8_3DSTATE_WM_DEPTH_STENCIL
,
2182 .DepthTestEnable
= false,
2183 .DepthBufferWriteEnable
= false);
2189 anv_cmd_buffer_add_bo(struct anv_cmd_buffer
*cmd_buffer
,
2190 struct anv_bo
*bo
, struct anv_reloc_list
*list
)
2192 struct drm_i915_gem_exec_object2
*obj
;
2194 bo
->index
= cmd_buffer
->bo_count
;
2195 obj
= &cmd_buffer
->exec2_objects
[bo
->index
];
2196 cmd_buffer
->exec2_bos
[bo
->index
] = bo
;
2197 cmd_buffer
->bo_count
++;
2199 obj
->handle
= bo
->gem_handle
;
2200 obj
->relocation_count
= 0;
2201 obj
->relocs_ptr
= 0;
2203 obj
->offset
= bo
->offset
;
2209 obj
->relocation_count
= list
->num_relocs
;
2210 obj
->relocs_ptr
= (uintptr_t) list
->relocs
;
2215 anv_cmd_buffer_add_validate_bos(struct anv_cmd_buffer
*cmd_buffer
,
2216 struct anv_reloc_list
*list
)
2218 struct anv_bo
*bo
, *batch_bo
;
2220 batch_bo
= &cmd_buffer
->batch
.bo
;
2221 for (size_t i
= 0; i
< list
->num_relocs
; i
++) {
2222 bo
= list
->reloc_bos
[i
];
2223 /* Skip any relocations targeting the batch bo. We need to make sure
2224 * it's the last in the list so we'll add it manually later.
2228 if (bo
->index
< cmd_buffer
->bo_count
&& cmd_buffer
->exec2_bos
[bo
->index
] == bo
)
2231 anv_cmd_buffer_add_bo(cmd_buffer
, bo
, NULL
);
2236 anv_cmd_buffer_process_relocs(struct anv_cmd_buffer
*cmd_buffer
,
2237 struct anv_reloc_list
*list
)
2241 /* If the kernel supports I915_EXEC_NO_RELOC, it will compare offset in
2242 * struct drm_i915_gem_exec_object2 against the bos current offset and if
2243 * all bos haven't moved it will skip relocation processing alltogether.
2244 * If I915_EXEC_NO_RELOC is not supported, the kernel ignores the incoming
2245 * value of offset so we can set it either way. For that to work we need
2246 * to make sure all relocs use the same presumed offset.
2249 for (size_t i
= 0; i
< list
->num_relocs
; i
++) {
2250 bo
= list
->reloc_bos
[i
];
2251 if (bo
->offset
!= list
->relocs
[i
].presumed_offset
)
2252 cmd_buffer
->need_reloc
= true;
2254 list
->relocs
[i
].target_handle
= bo
->index
;
2258 VkResult
anv_EndCommandBuffer(
2259 VkCmdBuffer cmdBuffer
)
2261 struct anv_cmd_buffer
*cmd_buffer
= (struct anv_cmd_buffer
*) cmdBuffer
;
2262 struct anv_device
*device
= cmd_buffer
->device
;
2263 struct anv_batch
*batch
= &cmd_buffer
->batch
;
2265 anv_batch_emit(batch
, GEN8_MI_BATCH_BUFFER_END
);
2267 /* Round batch up to an even number of dwords. */
2268 if ((batch
->next
- batch
->bo
.map
) & 4)
2269 anv_batch_emit(batch
, GEN8_MI_NOOP
);
2271 cmd_buffer
->bo_count
= 0;
2272 cmd_buffer
->need_reloc
= false;
2274 /* Lock for access to bo->index. */
2275 pthread_mutex_lock(&device
->mutex
);
2277 /* Add block pool bos first so we can add them with their relocs. */
2278 anv_cmd_buffer_add_bo(cmd_buffer
, &device
->surface_state_block_pool
.bo
,
2279 &batch
->surf_relocs
);
2281 anv_cmd_buffer_add_validate_bos(cmd_buffer
, &batch
->surf_relocs
);
2282 anv_cmd_buffer_add_validate_bos(cmd_buffer
, &batch
->cmd_relocs
);
2283 anv_cmd_buffer_add_bo(cmd_buffer
, &batch
->bo
, &batch
->cmd_relocs
);
2284 anv_cmd_buffer_process_relocs(cmd_buffer
, &batch
->surf_relocs
);
2285 anv_cmd_buffer_process_relocs(cmd_buffer
, &batch
->cmd_relocs
);
2287 cmd_buffer
->execbuf
.buffers_ptr
= (uintptr_t) cmd_buffer
->exec2_objects
;
2288 cmd_buffer
->execbuf
.buffer_count
= cmd_buffer
->bo_count
;
2289 cmd_buffer
->execbuf
.batch_start_offset
= 0;
2290 cmd_buffer
->execbuf
.batch_len
= batch
->next
- batch
->bo
.map
;
2291 cmd_buffer
->execbuf
.cliprects_ptr
= 0;
2292 cmd_buffer
->execbuf
.num_cliprects
= 0;
2293 cmd_buffer
->execbuf
.DR1
= 0;
2294 cmd_buffer
->execbuf
.DR4
= 0;
2296 cmd_buffer
->execbuf
.flags
= I915_EXEC_HANDLE_LUT
;
2297 if (!cmd_buffer
->need_reloc
)
2298 cmd_buffer
->execbuf
.flags
|= I915_EXEC_NO_RELOC
;
2299 cmd_buffer
->execbuf
.flags
|= I915_EXEC_RENDER
;
2300 cmd_buffer
->execbuf
.rsvd1
= device
->context_id
;
2301 cmd_buffer
->execbuf
.rsvd2
= 0;
2303 pthread_mutex_unlock(&device
->mutex
);
2308 VkResult
anv_ResetCommandBuffer(
2309 VkCmdBuffer cmdBuffer
)
2311 struct anv_cmd_buffer
*cmd_buffer
= (struct anv_cmd_buffer
*) cmdBuffer
;
2313 anv_batch_reset(&cmd_buffer
->batch
);
2318 // Command buffer building functions
2320 void anv_CmdBindPipeline(
2321 VkCmdBuffer cmdBuffer
,
2322 VkPipelineBindPoint pipelineBindPoint
,
2323 VkPipeline _pipeline
)
2325 struct anv_cmd_buffer
*cmd_buffer
= (struct anv_cmd_buffer
*) cmdBuffer
;
2327 cmd_buffer
->pipeline
= (struct anv_pipeline
*) _pipeline
;
2328 cmd_buffer
->dirty
|= ANV_CMD_BUFFER_PIPELINE_DIRTY
;
2331 void anv_CmdBindDynamicStateObject(
2332 VkCmdBuffer cmdBuffer
,
2333 VkStateBindPoint stateBindPoint
,
2334 VkDynamicStateObject dynamicState
)
2336 struct anv_cmd_buffer
*cmd_buffer
= (struct anv_cmd_buffer
*) cmdBuffer
;
2337 struct anv_dynamic_vp_state
*vp_state
;
2339 switch (stateBindPoint
) {
2340 case VK_STATE_BIND_POINT_VIEWPORT
:
2341 vp_state
= (struct anv_dynamic_vp_state
*) dynamicState
;
2342 /* We emit state immediately, but set cmd_buffer->vp_state to indicate
2343 * that vp state has been set in this command buffer. */
2344 cmd_buffer
->vp_state
= vp_state
;
2345 anv_batch_emit(&cmd_buffer
->batch
, GEN8_3DSTATE_SCISSOR_STATE_POINTERS
,
2346 .ScissorRectPointer
= vp_state
->scissor
.offset
);
2347 anv_batch_emit(&cmd_buffer
->batch
, GEN8_3DSTATE_VIEWPORT_STATE_POINTERS_CC
,
2348 .CCViewportPointer
= vp_state
->cc_vp
.offset
);
2349 anv_batch_emit(&cmd_buffer
->batch
, GEN8_3DSTATE_VIEWPORT_STATE_POINTERS_SF_CLIP
,
2350 .SFClipViewportPointer
= vp_state
->sf_clip_vp
.offset
);
2352 case VK_STATE_BIND_POINT_RASTER
:
2353 cmd_buffer
->rs_state
= (struct anv_dynamic_rs_state
*) dynamicState
;
2354 cmd_buffer
->dirty
|= ANV_CMD_BUFFER_RS_DIRTY
;
2356 case VK_STATE_BIND_POINT_COLOR_BLEND
:
2357 case VK_STATE_BIND_POINT_DEPTH_STENCIL
:
2364 void anv_CmdBindDescriptorSets(
2365 VkCmdBuffer cmdBuffer
,
2366 VkPipelineBindPoint pipelineBindPoint
,
2369 const VkDescriptorSet
* pDescriptorSets
,
2370 uint32_t dynamicOffsetCount
,
2371 const uint32_t* pDynamicOffsets
)
2373 struct anv_cmd_buffer
*cmd_buffer
= (struct anv_cmd_buffer
*) cmdBuffer
;
2374 struct anv_pipeline_layout
*layout
= cmd_buffer
->pipeline
->layout
;
2375 struct anv_bindings
*bindings
= cmd_buffer
->bindings
;
2377 uint32_t offset
= 0;
2378 for (uint32_t i
= 0; i
< setCount
; i
++) {
2379 struct anv_descriptor_set
*set
=
2380 (struct anv_descriptor_set
*) pDescriptorSets
[i
];
2381 struct anv_descriptor_set_layout
*set_layout
= layout
->set
[firstSet
+ i
].layout
;
2383 for (uint32_t s
= 0; s
< VK_NUM_SHADER_STAGE
; s
++) {
2384 uint32_t *surface_to_desc
= set_layout
->stage
[s
].surface_start
;
2385 uint32_t *sampler_to_desc
= set_layout
->stage
[s
].sampler_start
;
2386 uint32_t bias
= s
== VK_SHADER_STAGE_FRAGMENT
? MAX_RTS
: 0;
2389 start
= bias
+ layout
->set
[firstSet
+ i
].surface_start
[s
];
2390 for (uint32_t b
= 0; b
< set_layout
->stage
[s
].surface_count
; b
++) {
2391 struct anv_surface_view
*view
= set
->descriptors
[surface_to_desc
[b
]].view
;
2393 bindings
->descriptors
[s
].surfaces
[start
+ b
] =
2394 view
->surface_state
.offset
;
2395 bindings
->descriptors
[s
].relocs
[start
+ b
].bo
= view
->bo
;
2396 bindings
->descriptors
[s
].relocs
[start
+ b
].offset
= view
->offset
;
2399 start
= layout
->set
[firstSet
+ i
].sampler_start
[s
];
2400 for (uint32_t b
= 0; b
< set_layout
->stage
[s
].sampler_count
; b
++) {
2401 struct anv_sampler
*sampler
= set
->descriptors
[sampler_to_desc
[b
]].sampler
;
2403 memcpy(&bindings
->descriptors
[s
].samplers
[start
+ b
],
2404 sampler
->state
, sizeof(sampler
->state
));
2408 offset
+= layout
->set
[firstSet
+ i
].layout
->num_dynamic_buffers
;
2411 cmd_buffer
->dirty
|= ANV_CMD_BUFFER_DESCRIPTOR_SET_DIRTY
;
2414 void anv_CmdBindIndexBuffer(
2415 VkCmdBuffer cmdBuffer
,
2417 VkDeviceSize offset
,
2418 VkIndexType indexType
)
2420 struct anv_cmd_buffer
*cmd_buffer
= (struct anv_cmd_buffer
*) cmdBuffer
;
2421 struct anv_buffer
*buffer
= (struct anv_buffer
*) _buffer
;
2423 static const uint32_t vk_to_gen_index_type
[] = {
2424 [VK_INDEX_TYPE_UINT8
] = INDEX_BYTE
,
2425 [VK_INDEX_TYPE_UINT16
] = INDEX_WORD
,
2426 [VK_INDEX_TYPE_UINT32
] = INDEX_DWORD
,
2429 anv_batch_emit(&cmd_buffer
->batch
, GEN8_3DSTATE_INDEX_BUFFER
,
2430 .IndexFormat
= vk_to_gen_index_type
[indexType
],
2431 .MemoryObjectControlState
= 0,
2432 .BufferStartingAddress
= { buffer
->bo
, buffer
->offset
+ offset
},
2433 .BufferSize
= buffer
->size
- offset
);
2436 void anv_CmdBindVertexBuffers(
2437 VkCmdBuffer cmdBuffer
,
2438 uint32_t startBinding
,
2439 uint32_t bindingCount
,
2440 const VkBuffer
* pBuffers
,
2441 const VkDeviceSize
* pOffsets
)
2443 struct anv_cmd_buffer
*cmd_buffer
= (struct anv_cmd_buffer
*) cmdBuffer
;
2444 struct anv_bindings
*bindings
= cmd_buffer
->bindings
;
2446 /* We have to defer setting up vertex buffer since we need the buffer
2447 * stride from the pipeline. */
2449 for (uint32_t i
= 0; i
< bindingCount
; i
++) {
2450 bindings
->vb
[startBinding
+ i
].buffer
= (struct anv_buffer
*) pBuffers
[i
];
2451 bindings
->vb
[startBinding
+ i
].offset
= pOffsets
[i
];
2452 cmd_buffer
->vb_dirty
|= 1 << (startBinding
+ i
);
2457 flush_descriptor_sets(struct anv_cmd_buffer
*cmd_buffer
)
2459 struct anv_pipeline_layout
*layout
= cmd_buffer
->pipeline
->layout
;
2460 struct anv_bindings
*bindings
= cmd_buffer
->bindings
;
2461 uint32_t layers
= cmd_buffer
->framebuffer
->layers
;
2463 for (uint32_t s
= 0; s
< VK_NUM_SHADER_STAGE
; s
++) {
2466 if (s
== VK_SHADER_STAGE_FRAGMENT
) {
2468 layers
= cmd_buffer
->framebuffer
->layers
;
2474 /* This is a little awkward: layout can be NULL but we still have to
2475 * allocate and set a binding table for the PS stage for render
2477 uint32_t surface_count
= layout
? layout
->stage
[s
].surface_count
: 0;
2479 if (layers
+ surface_count
> 0) {
2480 struct anv_state state
;
2483 size
= (bias
+ surface_count
) * sizeof(uint32_t);
2484 state
= anv_state_stream_alloc(&cmd_buffer
->binding_table_state_stream
,
2486 memcpy(state
.map
, bindings
->descriptors
[s
].surfaces
, size
);
2488 for (uint32_t i
= 0; i
< layers
; i
++)
2489 anv_reloc_list_add(&cmd_buffer
->batch
.surf_relocs
,
2490 bindings
->descriptors
[s
].surfaces
[i
] + 8 * sizeof(int32_t),
2491 bindings
->descriptors
[s
].relocs
[i
].bo
,
2492 bindings
->descriptors
[s
].relocs
[i
].offset
);
2494 for (uint32_t i
= 0; i
< surface_count
; i
++)
2495 anv_reloc_list_add(&cmd_buffer
->batch
.surf_relocs
,
2496 bindings
->descriptors
[s
].surfaces
[bias
+ i
] + 8 * sizeof(int32_t),
2497 bindings
->descriptors
[s
].relocs
[bias
+ i
].bo
,
2498 bindings
->descriptors
[s
].relocs
[bias
+ i
].offset
);
2500 static const uint32_t binding_table_opcodes
[] = {
2501 [VK_SHADER_STAGE_VERTEX
] = 38,
2502 [VK_SHADER_STAGE_TESS_CONTROL
] = 39,
2503 [VK_SHADER_STAGE_TESS_EVALUATION
] = 40,
2504 [VK_SHADER_STAGE_GEOMETRY
] = 41,
2505 [VK_SHADER_STAGE_FRAGMENT
] = 42,
2506 [VK_SHADER_STAGE_COMPUTE
] = 0,
2509 anv_batch_emit(&cmd_buffer
->batch
,
2510 GEN8_3DSTATE_BINDING_TABLE_POINTERS_VS
,
2511 ._3DCommandSubOpcode
= binding_table_opcodes
[s
],
2512 .PointertoVSBindingTable
= state
.offset
);
2515 if (layout
&& layout
->stage
[s
].sampler_count
> 0) {
2516 struct anv_state state
;
2519 size
= layout
->stage
[s
].sampler_count
* 16;
2520 state
= anv_state_stream_alloc(&cmd_buffer
->dynamic_state_stream
, size
, 32);
2521 memcpy(state
.map
, bindings
->descriptors
[s
].samplers
, size
);
2523 static const uint32_t sampler_state_opcodes
[] = {
2524 [VK_SHADER_STAGE_VERTEX
] = 43,
2525 [VK_SHADER_STAGE_TESS_CONTROL
] = 44, /* HS */
2526 [VK_SHADER_STAGE_TESS_EVALUATION
] = 45, /* DS */
2527 [VK_SHADER_STAGE_GEOMETRY
] = 46,
2528 [VK_SHADER_STAGE_FRAGMENT
] = 47,
2529 [VK_SHADER_STAGE_COMPUTE
] = 0,
2532 anv_batch_emit(&cmd_buffer
->batch
,
2533 GEN8_3DSTATE_SAMPLER_STATE_POINTERS_VS
,
2534 ._3DCommandSubOpcode
= sampler_state_opcodes
[s
],
2535 .PointertoVSSamplerState
= state
.offset
);
2541 anv_cmd_buffer_flush_state(struct anv_cmd_buffer
*cmd_buffer
)
2543 struct anv_pipeline
*pipeline
= cmd_buffer
->pipeline
;
2544 struct anv_bindings
*bindings
= cmd_buffer
->bindings
;
2545 const uint32_t num_buffers
= __builtin_popcount(cmd_buffer
->vb_dirty
);
2546 const uint32_t num_dwords
= 1 + num_buffers
* 4;
2549 if (cmd_buffer
->vb_dirty
) {
2550 p
= anv_batch_emitn(&cmd_buffer
->batch
, num_dwords
,
2551 GEN8_3DSTATE_VERTEX_BUFFERS
);
2553 for_each_bit(vb
, cmd_buffer
->vb_dirty
) {
2554 struct anv_buffer
*buffer
= bindings
->vb
[vb
].buffer
;
2555 uint32_t offset
= bindings
->vb
[vb
].offset
;
2557 struct GEN8_VERTEX_BUFFER_STATE state
= {
2558 .VertexBufferIndex
= vb
,
2559 .MemoryObjectControlState
= 0,
2560 .AddressModifyEnable
= true,
2561 .BufferPitch
= pipeline
->binding_stride
[vb
],
2562 .BufferStartingAddress
= { buffer
->bo
, buffer
->offset
+ offset
},
2563 .BufferSize
= buffer
->size
- offset
2566 GEN8_VERTEX_BUFFER_STATE_pack(&cmd_buffer
->batch
, &p
[1 + i
* 4], &state
);
2571 if (cmd_buffer
->dirty
& ANV_CMD_BUFFER_PIPELINE_DIRTY
)
2572 anv_batch_emit_batch(&cmd_buffer
->batch
, &pipeline
->batch
);
2574 if (cmd_buffer
->dirty
& ANV_CMD_BUFFER_DESCRIPTOR_SET_DIRTY
)
2575 flush_descriptor_sets(cmd_buffer
);
2577 if (cmd_buffer
->dirty
& (ANV_CMD_BUFFER_PIPELINE_DIRTY
| ANV_CMD_BUFFER_RS_DIRTY
))
2578 anv_batch_emit_merge(&cmd_buffer
->batch
,
2579 cmd_buffer
->rs_state
->state_sf
, pipeline
->state_sf
);
2581 cmd_buffer
->vb_dirty
= 0;
2582 cmd_buffer
->dirty
= 0;
2586 VkCmdBuffer cmdBuffer
,
2587 uint32_t firstVertex
,
2588 uint32_t vertexCount
,
2589 uint32_t firstInstance
,
2590 uint32_t instanceCount
)
2592 struct anv_cmd_buffer
*cmd_buffer
= (struct anv_cmd_buffer
*) cmdBuffer
;
2594 anv_cmd_buffer_flush_state(cmd_buffer
);
2596 anv_batch_emit(&cmd_buffer
->batch
, GEN8_3DPRIMITIVE
,
2597 .VertexAccessType
= SEQUENTIAL
,
2598 .VertexCountPerInstance
= vertexCount
,
2599 .StartVertexLocation
= firstVertex
,
2600 .InstanceCount
= instanceCount
,
2601 .StartInstanceLocation
= firstInstance
,
2602 .BaseVertexLocation
= 0);
2605 void anv_CmdDrawIndexed(
2606 VkCmdBuffer cmdBuffer
,
2607 uint32_t firstIndex
,
2608 uint32_t indexCount
,
2609 int32_t vertexOffset
,
2610 uint32_t firstInstance
,
2611 uint32_t instanceCount
)
2613 struct anv_cmd_buffer
*cmd_buffer
= (struct anv_cmd_buffer
*) cmdBuffer
;
2615 anv_cmd_buffer_flush_state(cmd_buffer
);
2617 anv_batch_emit(&cmd_buffer
->batch
, GEN8_3DPRIMITIVE
,
2618 .VertexAccessType
= RANDOM
,
2619 .VertexCountPerInstance
= indexCount
,
2620 .StartVertexLocation
= firstIndex
,
2621 .InstanceCount
= instanceCount
,
2622 .StartInstanceLocation
= firstInstance
,
2623 .BaseVertexLocation
= 0);
2627 anv_batch_lrm(struct anv_batch
*batch
,
2628 uint32_t reg
, struct anv_bo
*bo
, uint32_t offset
)
2630 anv_batch_emit(batch
, GEN8_MI_LOAD_REGISTER_MEM
,
2631 .RegisterAddress
= reg
,
2632 .MemoryAddress
= { bo
, offset
});
2636 anv_batch_lri(struct anv_batch
*batch
, uint32_t reg
, uint32_t imm
)
2638 anv_batch_emit(batch
, GEN8_MI_LOAD_REGISTER_IMM
,
2639 .RegisterOffset
= reg
,
2643 /* Auto-Draw / Indirect Registers */
2644 #define GEN7_3DPRIM_END_OFFSET 0x2420
2645 #define GEN7_3DPRIM_START_VERTEX 0x2430
2646 #define GEN7_3DPRIM_VERTEX_COUNT 0x2434
2647 #define GEN7_3DPRIM_INSTANCE_COUNT 0x2438
2648 #define GEN7_3DPRIM_START_INSTANCE 0x243C
2649 #define GEN7_3DPRIM_BASE_VERTEX 0x2440
2651 void anv_CmdDrawIndirect(
2652 VkCmdBuffer cmdBuffer
,
2654 VkDeviceSize offset
,
2658 struct anv_cmd_buffer
*cmd_buffer
= (struct anv_cmd_buffer
*) cmdBuffer
;
2659 struct anv_buffer
*buffer
= (struct anv_buffer
*) _buffer
;
2660 struct anv_bo
*bo
= buffer
->bo
;
2661 uint32_t bo_offset
= buffer
->offset
+ offset
;
2663 anv_cmd_buffer_flush_state(cmd_buffer
);
2665 anv_batch_lrm(&cmd_buffer
->batch
, GEN7_3DPRIM_VERTEX_COUNT
, bo
, bo_offset
);
2666 anv_batch_lrm(&cmd_buffer
->batch
, GEN7_3DPRIM_INSTANCE_COUNT
, bo
, bo_offset
+ 4);
2667 anv_batch_lrm(&cmd_buffer
->batch
, GEN7_3DPRIM_START_VERTEX
, bo
, bo_offset
+ 8);
2668 anv_batch_lrm(&cmd_buffer
->batch
, GEN7_3DPRIM_START_INSTANCE
, bo
, bo_offset
+ 12);
2669 anv_batch_lri(&cmd_buffer
->batch
, GEN7_3DPRIM_BASE_VERTEX
, 0);
2671 anv_batch_emit(&cmd_buffer
->batch
, GEN8_3DPRIMITIVE
,
2672 .IndirectParameterEnable
= true,
2673 .VertexAccessType
= SEQUENTIAL
);
2676 void anv_CmdDrawIndexedIndirect(
2677 VkCmdBuffer cmdBuffer
,
2679 VkDeviceSize offset
,
2683 struct anv_cmd_buffer
*cmd_buffer
= (struct anv_cmd_buffer
*) cmdBuffer
;
2684 struct anv_buffer
*buffer
= (struct anv_buffer
*) _buffer
;
2685 struct anv_bo
*bo
= buffer
->bo
;
2686 uint32_t bo_offset
= buffer
->offset
+ offset
;
2688 anv_cmd_buffer_flush_state(cmd_buffer
);
2690 anv_batch_lrm(&cmd_buffer
->batch
, GEN7_3DPRIM_VERTEX_COUNT
, bo
, bo_offset
);
2691 anv_batch_lrm(&cmd_buffer
->batch
, GEN7_3DPRIM_INSTANCE_COUNT
, bo
, bo_offset
+ 4);
2692 anv_batch_lrm(&cmd_buffer
->batch
, GEN7_3DPRIM_START_VERTEX
, bo
, bo_offset
+ 8);
2693 anv_batch_lrm(&cmd_buffer
->batch
, GEN7_3DPRIM_BASE_VERTEX
, bo
, bo_offset
+ 12);
2694 anv_batch_lrm(&cmd_buffer
->batch
, GEN7_3DPRIM_START_INSTANCE
, bo
, bo_offset
+ 16);
2696 anv_batch_emit(&cmd_buffer
->batch
, GEN8_3DPRIMITIVE
,
2697 .IndirectParameterEnable
= true,
2698 .VertexAccessType
= RANDOM
);
2701 void anv_CmdDispatch(
2702 VkCmdBuffer cmdBuffer
,
2710 void anv_CmdDispatchIndirect(
2711 VkCmdBuffer cmdBuffer
,
2713 VkDeviceSize offset
)
2718 void anv_CmdSetEvent(
2719 VkCmdBuffer cmdBuffer
,
2721 VkPipeEvent pipeEvent
)
2726 void anv_CmdResetEvent(
2727 VkCmdBuffer cmdBuffer
,
2729 VkPipeEvent pipeEvent
)
2734 void anv_CmdWaitEvents(
2735 VkCmdBuffer cmdBuffer
,
2736 VkWaitEvent waitEvent
,
2737 uint32_t eventCount
,
2738 const VkEvent
* pEvents
,
2739 uint32_t memBarrierCount
,
2740 const void** ppMemBarriers
)
2745 void anv_CmdPipelineBarrier(
2746 VkCmdBuffer cmdBuffer
,
2747 VkWaitEvent waitEvent
,
2748 uint32_t pipeEventCount
,
2749 const VkPipeEvent
* pPipeEvents
,
2750 uint32_t memBarrierCount
,
2751 const void** ppMemBarriers
)
2757 anv_batch_emit_ps_depth_count(struct anv_batch
*batch
,
2758 struct anv_bo
*bo
, uint32_t offset
)
2760 anv_batch_emit(batch
, GEN8_PIPE_CONTROL
,
2761 .DestinationAddressType
= DAT_PPGTT
,
2762 .PostSyncOperation
= WritePSDepthCount
,
2763 .Address
= { bo
, offset
}); /* FIXME: This is only lower 32 bits */
2766 void anv_CmdBeginQuery(
2767 VkCmdBuffer cmdBuffer
,
2768 VkQueryPool queryPool
,
2770 VkQueryControlFlags flags
)
2772 struct anv_cmd_buffer
*cmd_buffer
= (struct anv_cmd_buffer
*) cmdBuffer
;
2773 struct anv_query_pool
*pool
= (struct anv_query_pool
*) queryPool
;
2775 switch (pool
->type
) {
2776 case VK_QUERY_TYPE_OCCLUSION
:
2777 anv_batch_emit_ps_depth_count(&cmd_buffer
->batch
, &pool
->bo
,
2778 slot
* sizeof(struct anv_query_pool_slot
));
2781 case VK_QUERY_TYPE_PIPELINE_STATISTICS
:
2787 void anv_CmdEndQuery(
2788 VkCmdBuffer cmdBuffer
,
2789 VkQueryPool queryPool
,
2792 struct anv_cmd_buffer
*cmd_buffer
= (struct anv_cmd_buffer
*) cmdBuffer
;
2793 struct anv_query_pool
*pool
= (struct anv_query_pool
*) queryPool
;
2795 switch (pool
->type
) {
2796 case VK_QUERY_TYPE_OCCLUSION
:
2797 anv_batch_emit_ps_depth_count(&cmd_buffer
->batch
, &pool
->bo
,
2798 slot
* sizeof(struct anv_query_pool_slot
) + 8);
2801 case VK_QUERY_TYPE_PIPELINE_STATISTICS
:
2807 void anv_CmdResetQueryPool(
2808 VkCmdBuffer cmdBuffer
,
2809 VkQueryPool queryPool
,
2810 uint32_t startQuery
,
2811 uint32_t queryCount
)
2816 #define TIMESTAMP 0x2358
2818 void anv_CmdWriteTimestamp(
2819 VkCmdBuffer cmdBuffer
,
2820 VkTimestampType timestampType
,
2821 VkBuffer destBuffer
,
2822 VkDeviceSize destOffset
)
2824 struct anv_cmd_buffer
*cmd_buffer
= (struct anv_cmd_buffer
*) cmdBuffer
;
2825 struct anv_buffer
*buffer
= (struct anv_buffer
*) destBuffer
;
2826 struct anv_bo
*bo
= buffer
->bo
;
2828 switch (timestampType
) {
2829 case VK_TIMESTAMP_TYPE_TOP
:
2830 anv_batch_emit(&cmd_buffer
->batch
, GEN8_MI_STORE_REGISTER_MEM
,
2831 .RegisterAddress
= TIMESTAMP
,
2832 .MemoryAddress
= { bo
, buffer
->offset
+ destOffset
});
2833 anv_batch_emit(&cmd_buffer
->batch
, GEN8_MI_STORE_REGISTER_MEM
,
2834 .RegisterAddress
= TIMESTAMP
+ 4,
2835 .MemoryAddress
= { bo
, buffer
->offset
+ destOffset
+ 4 });
2838 case VK_TIMESTAMP_TYPE_BOTTOM
:
2839 anv_batch_emit(&cmd_buffer
->batch
, GEN8_PIPE_CONTROL
,
2840 .DestinationAddressType
= DAT_PPGTT
,
2841 .PostSyncOperation
= WriteTimestamp
,
2842 .Address
= /* FIXME: This is only lower 32 bits */
2843 { bo
, buffer
->offset
+ destOffset
});
2851 #define alu_opcode(v) __gen_field((v), 20, 31)
2852 #define alu_operand1(v) __gen_field((v), 10, 19)
2853 #define alu_operand2(v) __gen_field((v), 0, 9)
2854 #define alu(opcode, operand1, operand2) \
2855 alu_opcode(opcode) | alu_operand1(operand1) | alu_operand2(operand2)
2857 #define OPCODE_NOOP 0x000
2858 #define OPCODE_LOAD 0x080
2859 #define OPCODE_LOADINV 0x480
2860 #define OPCODE_LOAD0 0x081
2861 #define OPCODE_LOAD1 0x481
2862 #define OPCODE_ADD 0x100
2863 #define OPCODE_SUB 0x101
2864 #define OPCODE_AND 0x102
2865 #define OPCODE_OR 0x103
2866 #define OPCODE_XOR 0x104
2867 #define OPCODE_STORE 0x180
2868 #define OPCODE_STOREINV 0x580
2870 #define OPERAND_R0 0x00
2871 #define OPERAND_R1 0x01
2872 #define OPERAND_R2 0x02
2873 #define OPERAND_R3 0x03
2874 #define OPERAND_R4 0x04
2875 #define OPERAND_SRCA 0x20
2876 #define OPERAND_SRCB 0x21
2877 #define OPERAND_ACCU 0x31
2878 #define OPERAND_ZF 0x32
2879 #define OPERAND_CF 0x33
2881 #define CS_GPR(n) (0x2600 + (n) * 8)
2884 emit_load_alu_reg_u64(struct anv_batch
*batch
, uint32_t reg
,
2885 struct anv_bo
*bo
, uint32_t offset
)
2887 anv_batch_emit(batch
, GEN8_MI_LOAD_REGISTER_MEM
,
2888 .RegisterAddress
= reg
,
2889 .MemoryAddress
= { bo
, offset
});
2890 anv_batch_emit(batch
, GEN8_MI_LOAD_REGISTER_MEM
,
2891 .RegisterAddress
= reg
+ 4,
2892 .MemoryAddress
= { bo
, offset
+ 4 });
2895 void anv_CmdCopyQueryPoolResults(
2896 VkCmdBuffer cmdBuffer
,
2897 VkQueryPool queryPool
,
2898 uint32_t startQuery
,
2899 uint32_t queryCount
,
2900 VkBuffer destBuffer
,
2901 VkDeviceSize destOffset
,
2902 VkDeviceSize destStride
,
2903 VkQueryResultFlags flags
)
2905 struct anv_cmd_buffer
*cmd_buffer
= (struct anv_cmd_buffer
*) cmdBuffer
;
2906 struct anv_query_pool
*pool
= (struct anv_query_pool
*) queryPool
;
2907 struct anv_buffer
*buffer
= (struct anv_buffer
*) destBuffer
;
2908 uint32_t slot_offset
, dst_offset
;
2910 if (flags
& VK_QUERY_RESULT_WITH_AVAILABILITY_BIT
) {
2911 /* Where is the availabilty info supposed to go? */
2912 anv_finishme("VK_QUERY_RESULT_WITH_AVAILABILITY_BIT");
2916 assert(pool
->type
== VK_QUERY_TYPE_OCCLUSION
);
2918 /* FIXME: If we're not waiting, should we just do this on the CPU? */
2919 if (flags
& VK_QUERY_RESULT_WAIT_BIT
)
2920 anv_batch_emit(&cmd_buffer
->batch
, GEN8_PIPE_CONTROL
,
2921 .CommandStreamerStallEnable
= true);
2923 dst_offset
= buffer
->offset
+ destOffset
;
2924 for (uint32_t i
= 0; i
< queryCount
; i
++) {
2926 slot_offset
= (startQuery
+ i
) * sizeof(struct anv_query_pool_slot
);
2928 emit_load_alu_reg_u64(&cmd_buffer
->batch
, CS_GPR(0), &pool
->bo
, slot_offset
);
2929 emit_load_alu_reg_u64(&cmd_buffer
->batch
, CS_GPR(1), &pool
->bo
, slot_offset
+ 8);
2931 /* FIXME: We need to clamp the result for 32 bit. */
2933 uint32_t *dw
= anv_batch_emitn(&cmd_buffer
->batch
, 5, GEN8_MI_MATH
);
2934 dw
[1] = alu(OPCODE_LOAD
, OPERAND_SRCA
, OPERAND_R1
);
2935 dw
[2] = alu(OPCODE_LOAD
, OPERAND_SRCB
, OPERAND_R0
);
2936 dw
[3] = alu(OPCODE_SUB
, 0, 0);
2937 dw
[4] = alu(OPCODE_STORE
, OPERAND_R2
, OPERAND_ACCU
);
2939 anv_batch_emit(&cmd_buffer
->batch
, GEN8_MI_STORE_REGISTER_MEM
,
2940 .RegisterAddress
= CS_GPR(2),
2941 /* FIXME: This is only lower 32 bits */
2942 .MemoryAddress
= { buffer
->bo
, dst_offset
});
2944 if (flags
& VK_QUERY_RESULT_64_BIT
)
2945 anv_batch_emit(&cmd_buffer
->batch
, GEN8_MI_STORE_REGISTER_MEM
,
2946 .RegisterAddress
= CS_GPR(2) + 4,
2947 /* FIXME: This is only lower 32 bits */
2948 .MemoryAddress
= { buffer
->bo
, dst_offset
+ 4 });
2950 dst_offset
+= destStride
;
2954 void anv_CmdInitAtomicCounters(
2955 VkCmdBuffer cmdBuffer
,
2956 VkPipelineBindPoint pipelineBindPoint
,
2957 uint32_t startCounter
,
2958 uint32_t counterCount
,
2959 const uint32_t* pData
)
2964 void anv_CmdLoadAtomicCounters(
2965 VkCmdBuffer cmdBuffer
,
2966 VkPipelineBindPoint pipelineBindPoint
,
2967 uint32_t startCounter
,
2968 uint32_t counterCount
,
2970 VkDeviceSize srcOffset
)
2975 void anv_CmdSaveAtomicCounters(
2976 VkCmdBuffer cmdBuffer
,
2977 VkPipelineBindPoint pipelineBindPoint
,
2978 uint32_t startCounter
,
2979 uint32_t counterCount
,
2980 VkBuffer destBuffer
,
2981 VkDeviceSize destOffset
)
2986 VkResult
anv_CreateFramebuffer(
2988 const VkFramebufferCreateInfo
* pCreateInfo
,
2989 VkFramebuffer
* pFramebuffer
)
2991 struct anv_device
*device
= (struct anv_device
*) _device
;
2992 struct anv_framebuffer
*framebuffer
;
2994 assert(pCreateInfo
->sType
== VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO
);
2996 framebuffer
= anv_device_alloc(device
, sizeof(*framebuffer
), 8,
2997 VK_SYSTEM_ALLOC_TYPE_API_OBJECT
);
2998 if (framebuffer
== NULL
)
2999 return vk_error(VK_ERROR_OUT_OF_HOST_MEMORY
);
3001 framebuffer
->color_attachment_count
= pCreateInfo
->colorAttachmentCount
;
3002 for (uint32_t i
= 0; i
< pCreateInfo
->colorAttachmentCount
; i
++) {
3003 framebuffer
->color_attachments
[i
] =
3004 (struct anv_surface_view
*) pCreateInfo
->pColorAttachments
[i
].view
;
3007 if (pCreateInfo
->pDepthStencilAttachment
) {
3008 framebuffer
->depth_stencil
=
3009 (struct anv_depth_stencil_view
*) pCreateInfo
->pDepthStencilAttachment
->view
;
3012 framebuffer
->sample_count
= pCreateInfo
->sampleCount
;
3013 framebuffer
->width
= pCreateInfo
->width
;
3014 framebuffer
->height
= pCreateInfo
->height
;
3015 framebuffer
->layers
= pCreateInfo
->layers
;
3017 vkCreateDynamicViewportState((VkDevice
) device
,
3018 &(VkDynamicVpStateCreateInfo
) {
3019 .sType
= VK_STRUCTURE_TYPE_DYNAMIC_VP_STATE_CREATE_INFO
,
3020 .viewportAndScissorCount
= 2,
3021 .pViewports
= (VkViewport
[]) {
3025 .width
= pCreateInfo
->width
,
3026 .height
= pCreateInfo
->height
,
3031 .pScissors
= (VkRect
[]) {
3033 { pCreateInfo
->width
, pCreateInfo
->height
} },
3036 &framebuffer
->vp_state
);
3038 *pFramebuffer
= (VkFramebuffer
) framebuffer
;
3043 VkResult
anv_CreateRenderPass(
3045 const VkRenderPassCreateInfo
* pCreateInfo
,
3046 VkRenderPass
* pRenderPass
)
3048 struct anv_device
*device
= (struct anv_device
*) _device
;
3049 struct anv_render_pass
*pass
;
3052 assert(pCreateInfo
->sType
== VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO
);
3054 size
= sizeof(*pass
) +
3055 pCreateInfo
->layers
* sizeof(struct anv_render_pass_layer
);
3056 pass
= anv_device_alloc(device
, size
, 8,
3057 VK_SYSTEM_ALLOC_TYPE_API_OBJECT
);
3059 return vk_error(VK_ERROR_OUT_OF_HOST_MEMORY
);
3061 pass
->render_area
= pCreateInfo
->renderArea
;
3063 pass
->num_layers
= pCreateInfo
->layers
;
3065 pass
->num_clear_layers
= 0;
3066 for (uint32_t i
= 0; i
< pCreateInfo
->layers
; i
++) {
3067 pass
->layers
[i
].color_load_op
= pCreateInfo
->pColorLoadOps
[i
];
3068 pass
->layers
[i
].clear_color
= pCreateInfo
->pColorLoadClearValues
[i
];
3069 if (pass
->layers
[i
].color_load_op
== VK_ATTACHMENT_LOAD_OP_CLEAR
)
3070 pass
->num_clear_layers
++;
3073 *pRenderPass
= (VkRenderPass
) pass
;
3079 anv_cmd_buffer_fill_render_targets(struct anv_cmd_buffer
*cmd_buffer
)
3081 struct anv_framebuffer
*framebuffer
= cmd_buffer
->framebuffer
;
3082 struct anv_bindings
*bindings
= cmd_buffer
->bindings
;
3084 for (uint32_t i
= 0; i
< framebuffer
->color_attachment_count
; i
++) {
3085 struct anv_surface_view
*view
= framebuffer
->color_attachments
[i
];
3087 bindings
->descriptors
[VK_SHADER_STAGE_FRAGMENT
].surfaces
[i
] = view
->surface_state
.offset
;
3088 bindings
->descriptors
[VK_SHADER_STAGE_FRAGMENT
].relocs
[i
].bo
= view
->bo
;
3089 bindings
->descriptors
[VK_SHADER_STAGE_FRAGMENT
].relocs
[i
].offset
= view
->offset
;
3091 cmd_buffer
->dirty
|= ANV_CMD_BUFFER_DESCRIPTOR_SET_DIRTY
;
3094 void anv_CmdBeginRenderPass(
3095 VkCmdBuffer cmdBuffer
,
3096 const VkRenderPassBegin
* pRenderPassBegin
)
3098 struct anv_cmd_buffer
*cmd_buffer
= (struct anv_cmd_buffer
*) cmdBuffer
;
3099 struct anv_render_pass
*pass
= (struct anv_render_pass
*) pRenderPassBegin
->renderPass
;
3100 struct anv_framebuffer
*framebuffer
=
3101 (struct anv_framebuffer
*) pRenderPassBegin
->framebuffer
;
3103 cmd_buffer
->framebuffer
= framebuffer
;
3105 anv_batch_emit(&cmd_buffer
->batch
, GEN8_3DSTATE_DRAWING_RECTANGLE
,
3106 .ClippedDrawingRectangleYMin
= pass
->render_area
.offset
.y
,
3107 .ClippedDrawingRectangleXMin
= pass
->render_area
.offset
.x
,
3108 .ClippedDrawingRectangleYMax
=
3109 pass
->render_area
.offset
.y
+ pass
->render_area
.extent
.height
- 1,
3110 .ClippedDrawingRectangleXMax
=
3111 pass
->render_area
.offset
.x
+ pass
->render_area
.extent
.width
- 1,
3112 .DrawingRectangleOriginY
= 0,
3113 .DrawingRectangleOriginX
= 0);
3115 anv_cmd_buffer_fill_render_targets(cmd_buffer
);
3117 anv_cmd_buffer_clear(cmd_buffer
, pass
);
3120 void anv_CmdEndRenderPass(
3121 VkCmdBuffer cmdBuffer
,
3122 VkRenderPass renderPass
)
3124 /* Emit a flushing pipe control at the end of a pass. This is kind of a
3125 * hack but it ensures that render targets always actually get written.
3126 * Eventually, we should do flushing based on image format transitions
3127 * or something of that nature.
3129 struct anv_cmd_buffer
*cmd_buffer
= (struct anv_cmd_buffer
*)cmdBuffer
;
3130 anv_batch_emit(&cmd_buffer
->batch
, GEN8_PIPE_CONTROL
,
3131 .PostSyncOperation
= NoWrite
,
3132 .RenderTargetCacheFlushEnable
= true,
3133 .InstructionCacheInvalidateEnable
= true,
3134 .DepthCacheFlushEnable
= true,
3135 .VFCacheInvalidationEnable
= true,
3136 .TextureCacheInvalidationEnable
= true,
3137 .CommandStreamerStallEnable
= true);