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");
146 if (result
!= VK_SUCCESS
)
149 instance
->physicalDeviceCount
++;
150 *pInstance
= (VkInstance
) instance
;
155 VkResult
anv_DestroyInstance(
156 VkInstance _instance
)
158 struct anv_instance
*instance
= (struct anv_instance
*) _instance
;
160 instance
->pfnFree(instance
->pAllocUserData
, instance
);
165 VkResult
anv_EnumeratePhysicalDevices(
166 VkInstance _instance
,
167 uint32_t* pPhysicalDeviceCount
,
168 VkPhysicalDevice
* pPhysicalDevices
)
170 struct anv_instance
*instance
= (struct anv_instance
*) _instance
;
172 if (*pPhysicalDeviceCount
>= 1)
173 pPhysicalDevices
[0] = (VkPhysicalDevice
) &instance
->physicalDevice
;
174 *pPhysicalDeviceCount
= instance
->physicalDeviceCount
;
179 VkResult
anv_GetPhysicalDeviceInfo(
180 VkPhysicalDevice physicalDevice
,
181 VkPhysicalDeviceInfoType infoType
,
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;
193 switch ((uint32_t) infoType
) {
194 case VK_PHYSICAL_DEVICE_INFO_TYPE_PROPERTIES
:
197 *pDataSize
= sizeof(*properties
);
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;
217 case VK_PHYSICAL_DEVICE_INFO_TYPE_PERFORMANCE
:
220 *pDataSize
= sizeof(*performance
);
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;
231 case VK_PHYSICAL_DEVICE_INFO_TYPE_QUEUE_PROPERTIES
:
232 queue_properties
= pData
;
234 *pDataSize
= sizeof(*queue_properties
);
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;
245 case VK_PHYSICAL_DEVICE_INFO_TYPE_MEMORY_PROPERTIES
:
246 memory_properties
= pData
;
248 *pDataSize
= sizeof(*memory_properties
);
252 memory_properties
->supportsMigration
= false;
253 memory_properties
->supportsPinning
= false;
256 case VK_PHYSICAL_DEVICE_INFO_TYPE_DISPLAY_PROPERTIES_WSI
:
257 anv_finishme("VK_PHYSICAL_DEVICE_INFO_TYPE_DISPLAY_PROPERTIES_WSI");
259 *pDataSize
= sizeof(*display_properties
);
263 display_properties
= pData
;
264 display_properties
->display
= 0;
265 display_properties
->physicalResolution
= (VkExtent2D
) { 0, 0 };
268 case VK_PHYSICAL_DEVICE_INFO_TYPE_QUEUE_PRESENT_PROPERTIES_WSI
:
269 anv_finishme("VK_PHYSICAL_DEVICE_INFO_TYPE_QUEUE_PRESENT_PROPERTIES_WSI");
274 return VK_UNSUPPORTED
;
279 void * vkGetProcAddr(
280 VkPhysicalDevice physicalDevice
,
283 return anv_lookup_entrypoint(pName
);
287 parse_debug_flags(struct anv_device
*device
)
289 const char *debug
, *p
, *end
;
291 debug
= getenv("INTEL_DEBUG");
292 device
->dump_aub
= false;
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;
306 VkResult
anv_CreateDevice(
307 VkPhysicalDevice _physicalDevice
,
308 const VkDeviceCreateInfo
* pCreateInfo
,
311 struct anv_physical_device
*physicalDevice
=
312 (struct anv_physical_device
*) _physicalDevice
;
313 struct anv_instance
*instance
= physicalDevice
->instance
;
314 struct anv_device
*device
;
316 assert(pCreateInfo
->sType
== VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO
);
318 device
= instance
->pfnAlloc(instance
->pAllocUserData
,
320 VK_SYSTEM_ALLOC_TYPE_API_OBJECT
);
322 return vk_error(VK_ERROR_OUT_OF_HOST_MEMORY
);
324 device
->no_hw
= physicalDevice
->no_hw
;
325 parse_debug_flags(device
);
327 device
->instance
= physicalDevice
->instance
;
328 device
->fd
= open("/dev/dri/renderD128", O_RDWR
| O_CLOEXEC
);
329 if (device
->fd
== -1)
332 device
->context_id
= anv_gem_create_context(device
);
333 if (device
->context_id
== -1)
336 anv_block_pool_init(&device
->dynamic_state_block_pool
, device
, 2048);
338 anv_state_pool_init(&device
->dynamic_state_pool
,
339 &device
->dynamic_state_block_pool
);
341 anv_block_pool_init(&device
->instruction_block_pool
, device
, 2048);
342 anv_block_pool_init(&device
->surface_state_block_pool
, device
, 2048);
345 /* Binding table pointers are only 16 bits so we have to make sure that
346 * they get allocated at the beginning of the surface state BO. To
347 * handle this, we create a separate block pool that works out of the
348 * first 64 KB of the surface state BO.
350 anv_block_pool_init_slave(&device
->binding_table_block_pool
,
351 &device
->surface_state_block_pool
, 32);
353 anv_state_pool_init(&device
->surface_state_pool
,
354 &device
->surface_state_block_pool
);
356 device
->compiler
= anv_compiler_create(device
->fd
);
357 device
->aub_writer
= NULL
;
359 device
->info
= *physicalDevice
->info
;
361 pthread_mutex_init(&device
->mutex
, NULL
);
363 anv_device_init_meta(device
);
365 *pDevice
= (VkDevice
) device
;
372 anv_device_free(device
, device
);
374 return vk_error(VK_ERROR_UNAVAILABLE
);
377 VkResult
anv_DestroyDevice(
380 struct anv_device
*device
= (struct anv_device
*) _device
;
382 anv_compiler_destroy(device
->compiler
);
384 anv_block_pool_finish(&device
->dynamic_state_block_pool
);
385 anv_block_pool_finish(&device
->instruction_block_pool
);
386 anv_block_pool_finish(&device
->surface_state_block_pool
);
390 if (device
->aub_writer
)
391 anv_aub_writer_destroy(device
->aub_writer
);
393 anv_device_free(device
, device
);
398 VkResult
anv_GetGlobalExtensionInfo(
399 VkExtensionInfoType infoType
,
400 uint32_t extensionIndex
,
404 static const VkExtensionProperties extensions
[] = {
406 .extName
= "VK_WSI_LunarG",
410 uint32_t count
= ARRAY_SIZE(extensions
);
413 case VK_EXTENSION_INFO_TYPE_COUNT
:
414 memcpy(pData
, &count
, sizeof(count
));
415 *pDataSize
= sizeof(count
);
418 case VK_EXTENSION_INFO_TYPE_PROPERTIES
:
419 if (extensionIndex
>= count
)
420 return vk_error(VK_ERROR_INVALID_EXTENSION
);
422 memcpy(pData
, &extensions
[extensionIndex
], sizeof(extensions
[0]));
423 *pDataSize
= sizeof(extensions
[0]);
427 return VK_UNSUPPORTED
;
431 VkResult
anv_GetPhysicalDeviceExtensionInfo(
432 VkPhysicalDevice physicalDevice
,
433 VkExtensionInfoType infoType
,
434 uint32_t extensionIndex
,
441 case VK_EXTENSION_INFO_TYPE_COUNT
:
450 case VK_EXTENSION_INFO_TYPE_PROPERTIES
:
451 return vk_error(VK_ERROR_INVALID_EXTENSION
);
454 return VK_UNSUPPORTED
;
458 VkResult
anv_EnumerateLayers(
459 VkPhysicalDevice physicalDevice
,
460 size_t maxStringSize
,
462 char* const* pOutLayers
,
470 VkResult
anv_GetDeviceQueue(
472 uint32_t queueNodeIndex
,
476 struct anv_device
*device
= (struct anv_device
*) _device
;
477 struct anv_queue
*queue
;
479 /* FIXME: Should allocate these at device create time. */
481 queue
= anv_device_alloc(device
, sizeof(*queue
), 8,
482 VK_SYSTEM_ALLOC_TYPE_API_OBJECT
);
484 return vk_error(VK_ERROR_OUT_OF_HOST_MEMORY
);
486 queue
->device
= device
;
487 queue
->pool
= &device
->surface_state_pool
;
489 queue
->completed_serial
= anv_state_pool_alloc(queue
->pool
, 4, 4);
490 *(uint32_t *)queue
->completed_serial
.map
= 0;
491 queue
->next_serial
= 1;
493 *pQueue
= (VkQueue
) queue
;
498 static const uint32_t BATCH_SIZE
= 8192;
501 anv_batch_init(struct anv_batch
*batch
, struct anv_device
*device
)
505 result
= anv_bo_init_new(&batch
->bo
, device
, BATCH_SIZE
);
506 if (result
!= VK_SUCCESS
)
510 anv_gem_mmap(device
, batch
->bo
.gem_handle
, 0, BATCH_SIZE
);
511 if (batch
->bo
.map
== NULL
) {
512 result
= vk_error(VK_ERROR_MEMORY_MAP_FAILED
);
516 batch
->cmd_relocs
.num_relocs
= 0;
517 batch
->next
= batch
->bo
.map
;
522 anv_gem_close(device
, batch
->bo
.gem_handle
);
529 anv_batch_finish(struct anv_batch
*batch
, struct anv_device
*device
)
531 anv_gem_munmap(batch
->bo
.map
, BATCH_SIZE
);
532 anv_gem_close(device
, batch
->bo
.gem_handle
);
536 anv_batch_reset(struct anv_batch
*batch
)
538 batch
->next
= batch
->bo
.map
;
539 batch
->cmd_relocs
.num_relocs
= 0;
543 anv_batch_emit_dwords(struct anv_batch
*batch
, int num_dwords
)
545 void *p
= batch
->next
;
547 batch
->next
+= num_dwords
* 4;
553 anv_reloc_list_append(struct anv_reloc_list
*list
,
554 struct anv_reloc_list
*other
, uint32_t offset
)
558 count
= list
->num_relocs
;
559 memcpy(&list
->relocs
[count
], &other
->relocs
[0],
560 other
->num_relocs
* sizeof(other
->relocs
[0]));
561 memcpy(&list
->reloc_bos
[count
], &other
->reloc_bos
[0],
562 other
->num_relocs
* sizeof(other
->reloc_bos
[0]));
563 for (i
= 0; i
< other
->num_relocs
; i
++)
564 list
->relocs
[i
+ count
].offset
+= offset
;
566 count
+= other
->num_relocs
;
570 anv_reloc_list_add(struct anv_reloc_list
*list
,
572 struct anv_bo
*target_bo
, uint32_t delta
)
574 struct drm_i915_gem_relocation_entry
*entry
;
577 assert(list
->num_relocs
< ANV_BATCH_MAX_RELOCS
);
579 /* XXX: Can we use I915_EXEC_HANDLE_LUT? */
580 index
= list
->num_relocs
++;
581 list
->reloc_bos
[index
] = target_bo
;
582 entry
= &list
->relocs
[index
];
583 entry
->target_handle
= target_bo
->gem_handle
;
584 entry
->delta
= delta
;
585 entry
->offset
= offset
;
586 entry
->presumed_offset
= target_bo
->offset
;
587 entry
->read_domains
= 0;
588 entry
->write_domain
= 0;
590 return target_bo
->offset
+ delta
;
594 anv_batch_emit_batch(struct anv_batch
*batch
, struct anv_batch
*other
)
596 uint32_t size
, offset
;
598 size
= other
->next
- other
->bo
.map
;
599 memcpy(batch
->next
, other
->bo
.map
, size
);
601 offset
= batch
->next
- batch
->bo
.map
;
602 anv_reloc_list_append(&batch
->cmd_relocs
, &other
->cmd_relocs
, offset
);
608 anv_batch_emit_reloc(struct anv_batch
*batch
,
609 void *location
, struct anv_bo
*bo
, uint32_t delta
)
611 return anv_reloc_list_add(&batch
->cmd_relocs
,
612 location
- batch
->bo
.map
, bo
, delta
);
615 VkResult
anv_QueueSubmit(
617 uint32_t cmdBufferCount
,
618 const VkCmdBuffer
* pCmdBuffers
,
621 struct anv_queue
*queue
= (struct anv_queue
*) _queue
;
622 struct anv_device
*device
= queue
->device
;
623 struct anv_fence
*fence
= (struct anv_fence
*) _fence
;
626 for (uint32_t i
= 0; i
< cmdBufferCount
; i
++) {
627 struct anv_cmd_buffer
*cmd_buffer
=
628 (struct anv_cmd_buffer
*) pCmdBuffers
[i
];
630 if (device
->dump_aub
)
631 anv_cmd_buffer_dump(cmd_buffer
);
633 if (!device
->no_hw
) {
634 ret
= anv_gem_execbuffer(device
, &cmd_buffer
->execbuf
);
636 return vk_error(VK_ERROR_UNKNOWN
);
639 ret
= anv_gem_execbuffer(device
, &fence
->execbuf
);
641 return vk_error(VK_ERROR_UNKNOWN
);
644 for (uint32_t i
= 0; i
< cmd_buffer
->bo_count
; i
++)
645 cmd_buffer
->exec2_bos
[i
]->offset
= cmd_buffer
->exec2_objects
[i
].offset
;
647 *(uint32_t *)queue
->completed_serial
.map
= cmd_buffer
->serial
;
654 VkResult
anv_QueueAddMemReferences(
657 const VkDeviceMemory
* pMems
)
662 VkResult
anv_QueueRemoveMemReferences(
665 const VkDeviceMemory
* pMems
)
670 VkResult
anv_QueueWaitIdle(
673 struct anv_queue
*queue
= (struct anv_queue
*) _queue
;
675 return vkDeviceWaitIdle((VkDevice
) queue
->device
);
678 VkResult
anv_DeviceWaitIdle(
681 struct anv_device
*device
= (struct anv_device
*) _device
;
682 struct anv_state state
;
683 struct anv_batch batch
;
684 struct drm_i915_gem_execbuffer2 execbuf
;
685 struct drm_i915_gem_exec_object2 exec2_objects
[1];
686 struct anv_bo
*bo
= NULL
;
691 state
= anv_state_pool_alloc(&device
->dynamic_state_pool
, 32, 32);
692 bo
= &device
->dynamic_state_pool
.block_pool
->bo
;
693 batch
.next
= state
.map
;
694 anv_batch_emit(&batch
, GEN8_MI_BATCH_BUFFER_END
);
695 anv_batch_emit(&batch
, GEN8_MI_NOOP
);
697 exec2_objects
[0].handle
= bo
->gem_handle
;
698 exec2_objects
[0].relocation_count
= 0;
699 exec2_objects
[0].relocs_ptr
= 0;
700 exec2_objects
[0].alignment
= 0;
701 exec2_objects
[0].offset
= bo
->offset
;
702 exec2_objects
[0].flags
= 0;
703 exec2_objects
[0].rsvd1
= 0;
704 exec2_objects
[0].rsvd2
= 0;
706 execbuf
.buffers_ptr
= (uintptr_t) exec2_objects
;
707 execbuf
.buffer_count
= 1;
708 execbuf
.batch_start_offset
= state
.offset
;
709 execbuf
.batch_len
= batch
.next
- state
.map
;
710 execbuf
.cliprects_ptr
= 0;
711 execbuf
.num_cliprects
= 0;
716 I915_EXEC_HANDLE_LUT
| I915_EXEC_NO_RELOC
| I915_EXEC_RENDER
;
717 execbuf
.rsvd1
= device
->context_id
;
720 if (!device
->no_hw
) {
721 ret
= anv_gem_execbuffer(device
, &execbuf
);
723 result
= vk_error(VK_ERROR_UNKNOWN
);
728 ret
= anv_gem_wait(device
, bo
->gem_handle
, &timeout
);
730 result
= vk_error(VK_ERROR_UNKNOWN
);
735 anv_state_pool_free(&device
->dynamic_state_pool
, state
);
740 anv_state_pool_free(&device
->dynamic_state_pool
, state
);
746 anv_device_alloc(struct anv_device
* device
,
749 VkSystemAllocType allocType
)
751 return device
->instance
->pfnAlloc(device
->instance
->pAllocUserData
,
758 anv_device_free(struct anv_device
* device
,
761 return device
->instance
->pfnFree(device
->instance
->pAllocUserData
,
766 anv_bo_init_new(struct anv_bo
*bo
, struct anv_device
*device
, uint64_t size
)
768 bo
->gem_handle
= anv_gem_create(device
, size
);
770 return vk_error(VK_ERROR_OUT_OF_DEVICE_MEMORY
);
780 VkResult
anv_AllocMemory(
782 const VkMemoryAllocInfo
* pAllocInfo
,
783 VkDeviceMemory
* pMem
)
785 struct anv_device
*device
= (struct anv_device
*) _device
;
786 struct anv_device_memory
*mem
;
789 assert(pAllocInfo
->sType
== VK_STRUCTURE_TYPE_MEMORY_ALLOC_INFO
);
791 mem
= anv_device_alloc(device
, sizeof(*mem
), 8,
792 VK_SYSTEM_ALLOC_TYPE_API_OBJECT
);
794 return vk_error(VK_ERROR_OUT_OF_HOST_MEMORY
);
796 result
= anv_bo_init_new(&mem
->bo
, device
, pAllocInfo
->allocationSize
);
797 if (result
!= VK_SUCCESS
)
800 *pMem
= (VkDeviceMemory
) mem
;
805 anv_device_free(device
, mem
);
810 VkResult
anv_FreeMemory(
814 struct anv_device
*device
= (struct anv_device
*) _device
;
815 struct anv_device_memory
*mem
= (struct anv_device_memory
*) _mem
;
818 anv_gem_munmap(mem
->bo
.map
, mem
->bo
.size
);
820 if (mem
->bo
.gem_handle
!= 0)
821 anv_gem_close(device
, mem
->bo
.gem_handle
);
823 anv_device_free(device
, mem
);
828 VkResult
anv_SetMemoryPriority(
831 VkMemoryPriority priority
)
836 VkResult
anv_MapMemory(
841 VkMemoryMapFlags flags
,
844 struct anv_device
*device
= (struct anv_device
*) _device
;
845 struct anv_device_memory
*mem
= (struct anv_device_memory
*) _mem
;
847 /* FIXME: Is this supposed to be thread safe? Since vkUnmapMemory() only
848 * takes a VkDeviceMemory pointer, it seems like only one map of the memory
849 * at a time is valid. We could just mmap up front and return an offset
850 * pointer here, but that may exhaust virtual memory on 32 bit
853 mem
->map
= anv_gem_mmap(device
, mem
->bo
.gem_handle
, offset
, size
);
854 mem
->map_size
= size
;
861 VkResult
anv_UnmapMemory(
865 struct anv_device_memory
*mem
= (struct anv_device_memory
*) _mem
;
867 anv_gem_munmap(mem
->map
, mem
->map_size
);
872 VkResult
anv_FlushMappedMemory(
878 /* clflush here for !llc platforms */
883 VkResult
anv_PinSystemMemory(
887 VkDeviceMemory
* pMem
)
892 VkResult
anv_GetMultiDeviceCompatibility(
893 VkPhysicalDevice physicalDevice0
,
894 VkPhysicalDevice physicalDevice1
,
895 VkPhysicalDeviceCompatibilityInfo
* pInfo
)
897 return VK_UNSUPPORTED
;
900 VkResult
anv_OpenSharedMemory(
902 const VkMemoryOpenInfo
* pOpenInfo
,
903 VkDeviceMemory
* pMem
)
905 return VK_UNSUPPORTED
;
908 VkResult
anv_OpenSharedSemaphore(
910 const VkSemaphoreOpenInfo
* pOpenInfo
,
911 VkSemaphore
* pSemaphore
)
913 return VK_UNSUPPORTED
;
916 VkResult
anv_OpenPeerMemory(
918 const VkPeerMemoryOpenInfo
* pOpenInfo
,
919 VkDeviceMemory
* pMem
)
921 return VK_UNSUPPORTED
;
924 VkResult
anv_OpenPeerImage(
926 const VkPeerImageOpenInfo
* pOpenInfo
,
928 VkDeviceMemory
* pMem
)
930 return VK_UNSUPPORTED
;
934 anv_instance_destructor(struct anv_device
* device
,
937 return vkDestroyInstance(object
);
941 anv_noop_destructor(struct anv_device
* device
,
948 anv_device_destructor(struct anv_device
* device
,
951 return vkDestroyDevice(object
);
955 anv_cmd_buffer_destructor(struct anv_device
* device
,
958 struct anv_cmd_buffer
*cmd_buffer
= (struct anv_cmd_buffer
*) object
;
960 anv_gem_munmap(cmd_buffer
->surface_bo
.map
, BATCH_SIZE
);
961 anv_gem_close(device
, cmd_buffer
->surface_bo
.gem_handle
);
962 anv_state_stream_finish(&cmd_buffer
->surface_state_stream
);
963 anv_state_stream_finish(&cmd_buffer
->dynamic_state_stream
);
964 anv_state_stream_finish(&cmd_buffer
->binding_table_state_stream
);
965 anv_batch_finish(&cmd_buffer
->batch
, device
);
966 anv_device_free(device
, cmd_buffer
->exec2_objects
);
967 anv_device_free(device
, cmd_buffer
->exec2_bos
);
968 anv_device_free(device
, cmd_buffer
);
974 anv_pipeline_destructor(struct anv_device
* device
,
977 struct anv_pipeline
*pipeline
= (struct anv_pipeline
*) object
;
979 return anv_pipeline_destroy(pipeline
);
983 anv_free_destructor(struct anv_device
* device
,
986 anv_device_free(device
, (void *) object
);
992 anv_fence_destructor(struct anv_device
* device
,
995 struct anv_fence
*fence
= (struct anv_fence
*) object
;
997 anv_gem_munmap(fence
->bo
.map
, fence
->bo
.size
);
998 anv_gem_close(device
, fence
->bo
.gem_handle
);
999 anv_device_free(device
, fence
);
1005 anv_query_pool_destructor(struct anv_device
* device
,
1008 struct anv_query_pool
*pool
= (struct anv_query_pool
*) object
;
1010 anv_gem_munmap(pool
->bo
.map
, pool
->bo
.size
);
1011 anv_gem_close(device
, pool
->bo
.gem_handle
);
1012 anv_device_free(device
, pool
);
1017 static VkResult (*anv_object_destructors
[])(struct anv_device
*device
,
1018 VkObject object
) = {
1019 [VK_OBJECT_TYPE_INSTANCE
] = anv_instance_destructor
,
1020 [VK_OBJECT_TYPE_PHYSICAL_DEVICE
] = anv_noop_destructor
,
1021 [VK_OBJECT_TYPE_DEVICE
] = anv_device_destructor
,
1022 [VK_OBJECT_TYPE_QUEUE
] = anv_noop_destructor
,
1023 [VK_OBJECT_TYPE_COMMAND_BUFFER
] = anv_cmd_buffer_destructor
,
1024 [VK_OBJECT_TYPE_PIPELINE
] = anv_pipeline_destructor
,
1025 [VK_OBJECT_TYPE_SHADER
] = anv_free_destructor
,
1026 [VK_OBJECT_TYPE_BUFFER
] = anv_free_destructor
,
1027 [VK_OBJECT_TYPE_IMAGE
] = anv_free_destructor
,
1028 [VK_OBJECT_TYPE_RENDER_PASS
] = anv_free_destructor
,
1029 [VK_OBJECT_TYPE_FENCE
] = anv_fence_destructor
,
1030 [VK_OBJECT_TYPE_QUERY_POOL
] = anv_query_pool_destructor
1033 VkResult
anv_DestroyObject(
1035 VkObjectType objType
,
1038 struct anv_device
*device
= (struct anv_device
*) _device
;
1040 assert(objType
< ARRAY_SIZE(anv_object_destructors
) &&
1041 anv_object_destructors
[objType
] != NULL
);
1043 return anv_object_destructors
[objType
](device
, object
);
1047 fill_memory_requirements(
1048 VkObjectType objType
,
1050 VkMemoryRequirements
* memory_requirements
)
1052 struct anv_buffer
*buffer
;
1053 struct anv_image
*image
;
1055 memory_requirements
->memPropsAllowed
=
1056 VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT
|
1057 VK_MEMORY_PROPERTY_HOST_DEVICE_COHERENT_BIT
|
1058 /* VK_MEMORY_PROPERTY_HOST_UNCACHED_BIT | */
1059 VK_MEMORY_PROPERTY_HOST_WRITE_COMBINED_BIT
|
1060 VK_MEMORY_PROPERTY_PREFER_HOST_LOCAL
|
1061 VK_MEMORY_PROPERTY_SHAREABLE_BIT
;
1063 memory_requirements
->memPropsRequired
= 0;
1066 case VK_OBJECT_TYPE_BUFFER
:
1067 buffer
= (struct anv_buffer
*) object
;
1068 memory_requirements
->size
= buffer
->size
;
1069 memory_requirements
->alignment
= 16;
1071 case VK_OBJECT_TYPE_IMAGE
:
1072 image
= (struct anv_image
*) object
;
1073 memory_requirements
->size
= image
->size
;
1074 memory_requirements
->alignment
= image
->alignment
;
1077 memory_requirements
->size
= 0;
1083 get_allocation_count(VkObjectType objType
)
1086 case VK_OBJECT_TYPE_BUFFER
:
1087 case VK_OBJECT_TYPE_IMAGE
:
1094 VkResult
anv_GetObjectInfo(
1096 VkObjectType objType
,
1098 VkObjectInfoType infoType
,
1102 VkMemoryRequirements memory_requirements
;
1106 case VK_OBJECT_INFO_TYPE_MEMORY_REQUIREMENTS
:
1107 *pDataSize
= sizeof(memory_requirements
);
1111 fill_memory_requirements(objType
, object
, pData
);
1114 case VK_OBJECT_INFO_TYPE_MEMORY_ALLOCATION_COUNT
:
1115 *pDataSize
= sizeof(count
);
1120 *count
= get_allocation_count(objType
);
1124 return VK_UNSUPPORTED
;
1129 VkResult
anv_QueueBindObjectMemory(
1131 VkObjectType objType
,
1133 uint32_t allocationIdx
,
1134 VkDeviceMemory _mem
,
1135 VkDeviceSize memOffset
)
1137 struct anv_buffer
*buffer
;
1138 struct anv_image
*image
;
1139 struct anv_device_memory
*mem
= (struct anv_device_memory
*) _mem
;
1142 case VK_OBJECT_TYPE_BUFFER
:
1143 buffer
= (struct anv_buffer
*) object
;
1144 buffer
->bo
= &mem
->bo
;
1145 buffer
->offset
= memOffset
;
1147 case VK_OBJECT_TYPE_IMAGE
:
1148 image
= (struct anv_image
*) object
;
1149 image
->bo
= &mem
->bo
;
1150 image
->offset
= memOffset
;
1159 VkResult
anv_QueueBindObjectMemoryRange(
1161 VkObjectType objType
,
1163 uint32_t allocationIdx
,
1164 VkDeviceSize rangeOffset
,
1165 VkDeviceSize rangeSize
,
1167 VkDeviceSize memOffset
)
1169 stub_return(VK_UNSUPPORTED
);
1172 VkResult
anv_QueueBindImageMemoryRange(
1175 uint32_t allocationIdx
,
1176 const VkImageMemoryBindInfo
* pBindInfo
,
1178 VkDeviceSize memOffset
)
1180 stub_return(VK_UNSUPPORTED
);
1183 VkResult
anv_CreateFence(
1185 const VkFenceCreateInfo
* pCreateInfo
,
1188 struct anv_device
*device
= (struct anv_device
*) _device
;
1189 struct anv_fence
*fence
;
1190 struct anv_batch batch
;
1193 const uint32_t fence_size
= 128;
1195 assert(pCreateInfo
->sType
== VK_STRUCTURE_TYPE_FENCE_CREATE_INFO
);
1197 fence
= anv_device_alloc(device
, sizeof(*fence
), 8,
1198 VK_SYSTEM_ALLOC_TYPE_API_OBJECT
);
1200 return vk_error(VK_ERROR_OUT_OF_HOST_MEMORY
);
1202 result
= anv_bo_init_new(&fence
->bo
, device
, fence_size
);
1203 if (result
!= VK_SUCCESS
)
1207 anv_gem_mmap(device
, fence
->bo
.gem_handle
, 0, fence
->bo
.size
);
1208 batch
.next
= fence
->bo
.map
;
1209 anv_batch_emit(&batch
, GEN8_MI_BATCH_BUFFER_END
);
1210 anv_batch_emit(&batch
, GEN8_MI_NOOP
);
1212 fence
->exec2_objects
[0].handle
= fence
->bo
.gem_handle
;
1213 fence
->exec2_objects
[0].relocation_count
= 0;
1214 fence
->exec2_objects
[0].relocs_ptr
= 0;
1215 fence
->exec2_objects
[0].alignment
= 0;
1216 fence
->exec2_objects
[0].offset
= fence
->bo
.offset
;
1217 fence
->exec2_objects
[0].flags
= 0;
1218 fence
->exec2_objects
[0].rsvd1
= 0;
1219 fence
->exec2_objects
[0].rsvd2
= 0;
1221 fence
->execbuf
.buffers_ptr
= (uintptr_t) fence
->exec2_objects
;
1222 fence
->execbuf
.buffer_count
= 1;
1223 fence
->execbuf
.batch_start_offset
= 0;
1224 fence
->execbuf
.batch_len
= batch
.next
- fence
->bo
.map
;
1225 fence
->execbuf
.cliprects_ptr
= 0;
1226 fence
->execbuf
.num_cliprects
= 0;
1227 fence
->execbuf
.DR1
= 0;
1228 fence
->execbuf
.DR4
= 0;
1230 fence
->execbuf
.flags
=
1231 I915_EXEC_HANDLE_LUT
| I915_EXEC_NO_RELOC
| I915_EXEC_RENDER
;
1232 fence
->execbuf
.rsvd1
= device
->context_id
;
1233 fence
->execbuf
.rsvd2
= 0;
1235 *pFence
= (VkQueryPool
) fence
;
1240 anv_device_free(device
, fence
);
1245 VkResult
anv_ResetFences(
1247 uint32_t fenceCount
,
1250 struct anv_fence
**fences
= (struct anv_fence
**) pFences
;
1252 for (uint32_t i
; i
< fenceCount
; i
++)
1253 fences
[i
]->ready
= false;
1258 VkResult
anv_GetFenceStatus(
1262 struct anv_device
*device
= (struct anv_device
*) _device
;
1263 struct anv_fence
*fence
= (struct anv_fence
*) _fence
;
1270 ret
= anv_gem_wait(device
, fence
->bo
.gem_handle
, &t
);
1272 fence
->ready
= true;
1276 return VK_NOT_READY
;
1279 VkResult
anv_WaitForFences(
1281 uint32_t fenceCount
,
1282 const VkFence
* pFences
,
1286 struct anv_device
*device
= (struct anv_device
*) _device
;
1287 struct anv_fence
**fences
= (struct anv_fence
**) pFences
;
1288 int64_t t
= timeout
;
1291 /* FIXME: handle !waitAll */
1293 for (uint32_t i
= 0; i
< fenceCount
; i
++) {
1294 ret
= anv_gem_wait(device
, fences
[i
]->bo
.gem_handle
, &t
);
1295 if (ret
== -1 && errno
== ETIME
)
1298 return vk_error(VK_ERROR_UNKNOWN
);
1304 // Queue semaphore functions
1306 VkResult
anv_CreateSemaphore(
1308 const VkSemaphoreCreateInfo
* pCreateInfo
,
1309 VkSemaphore
* pSemaphore
)
1311 stub_return(VK_UNSUPPORTED
);
1314 VkResult
anv_QueueSignalSemaphore(
1316 VkSemaphore semaphore
)
1318 stub_return(VK_UNSUPPORTED
);
1321 VkResult
anv_QueueWaitSemaphore(
1323 VkSemaphore semaphore
)
1325 stub_return(VK_UNSUPPORTED
);
1330 VkResult
anv_CreateEvent(
1332 const VkEventCreateInfo
* pCreateInfo
,
1335 stub_return(VK_UNSUPPORTED
);
1338 VkResult
anv_GetEventStatus(
1342 stub_return(VK_UNSUPPORTED
);
1345 VkResult
anv_SetEvent(
1349 stub_return(VK_UNSUPPORTED
);
1352 VkResult
anv_ResetEvent(
1356 stub_return(VK_UNSUPPORTED
);
1361 VkResult
anv_CreateQueryPool(
1363 const VkQueryPoolCreateInfo
* pCreateInfo
,
1364 VkQueryPool
* pQueryPool
)
1366 struct anv_device
*device
= (struct anv_device
*) _device
;
1367 struct anv_query_pool
*pool
;
1371 assert(pCreateInfo
->sType
== VK_STRUCTURE_TYPE_QUERY_POOL_CREATE_INFO
);
1373 switch (pCreateInfo
->queryType
) {
1374 case VK_QUERY_TYPE_OCCLUSION
:
1376 case VK_QUERY_TYPE_PIPELINE_STATISTICS
:
1377 return VK_UNSUPPORTED
;
1382 pool
= anv_device_alloc(device
, sizeof(*pool
), 8,
1383 VK_SYSTEM_ALLOC_TYPE_API_OBJECT
);
1385 return vk_error(VK_ERROR_OUT_OF_HOST_MEMORY
);
1387 pool
->type
= pCreateInfo
->queryType
;
1388 size
= pCreateInfo
->slots
* sizeof(struct anv_query_pool_slot
);
1389 result
= anv_bo_init_new(&pool
->bo
, device
, size
);
1390 if (result
!= VK_SUCCESS
)
1393 pool
->bo
.map
= anv_gem_mmap(device
, pool
->bo
.gem_handle
, 0, size
);
1395 *pQueryPool
= (VkQueryPool
) pool
;
1400 anv_device_free(device
, pool
);
1405 VkResult
anv_GetQueryPoolResults(
1407 VkQueryPool queryPool
,
1408 uint32_t startQuery
,
1409 uint32_t queryCount
,
1412 VkQueryResultFlags flags
)
1414 struct anv_device
*device
= (struct anv_device
*) _device
;
1415 struct anv_query_pool
*pool
= (struct anv_query_pool
*) queryPool
;
1416 struct anv_query_pool_slot
*slot
= pool
->bo
.map
;
1417 int64_t timeout
= INT64_MAX
;
1418 uint32_t *dst32
= pData
;
1419 uint64_t *dst64
= pData
;
1423 if (flags
& VK_QUERY_RESULT_WITH_AVAILABILITY_BIT
) {
1424 /* Where is the availabilty info supposed to go? */
1425 anv_finishme("VK_QUERY_RESULT_WITH_AVAILABILITY_BIT");
1426 return VK_UNSUPPORTED
;
1429 assert(pool
->type
== VK_QUERY_TYPE_OCCLUSION
);
1431 if (flags
& VK_QUERY_RESULT_64_BIT
)
1432 *pDataSize
= queryCount
* sizeof(uint64_t);
1434 *pDataSize
= queryCount
* sizeof(uint32_t);
1439 if (flags
& VK_QUERY_RESULT_WAIT_BIT
) {
1440 ret
= anv_gem_wait(device
, pool
->bo
.gem_handle
, &timeout
);
1442 return vk_error(VK_ERROR_UNKNOWN
);
1445 for (uint32_t i
= 0; i
< queryCount
; i
++) {
1446 result
= slot
[startQuery
+ i
].end
- slot
[startQuery
+ i
].begin
;
1447 if (flags
& VK_QUERY_RESULT_64_BIT
) {
1450 if (result
> UINT32_MAX
)
1451 result
= UINT32_MAX
;
1461 VkResult
anv_CreateBuffer(
1463 const VkBufferCreateInfo
* pCreateInfo
,
1466 struct anv_device
*device
= (struct anv_device
*) _device
;
1467 struct anv_buffer
*buffer
;
1469 assert(pCreateInfo
->sType
== VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO
);
1471 buffer
= anv_device_alloc(device
, sizeof(*buffer
), 8,
1472 VK_SYSTEM_ALLOC_TYPE_API_OBJECT
);
1474 return vk_error(VK_ERROR_OUT_OF_HOST_MEMORY
);
1476 buffer
->size
= pCreateInfo
->size
;
1480 *pBuffer
= (VkBuffer
) buffer
;
1485 // Buffer view functions
1487 VkResult
anv_CreateBufferView(
1489 const VkBufferViewCreateInfo
* pCreateInfo
,
1490 VkBufferView
* pView
)
1492 struct anv_device
*device
= (struct anv_device
*) _device
;
1493 struct anv_buffer
*buffer
= (struct anv_buffer
*) pCreateInfo
->buffer
;
1494 struct anv_surface_view
*view
;
1495 const struct anv_format
*format
;
1497 assert(pCreateInfo
->sType
== VK_STRUCTURE_TYPE_BUFFER_VIEW_CREATE_INFO
);
1499 view
= anv_device_alloc(device
, sizeof(*view
), 8,
1500 VK_SYSTEM_ALLOC_TYPE_API_OBJECT
);
1502 return vk_error(VK_ERROR_OUT_OF_HOST_MEMORY
);
1504 view
->bo
= buffer
->bo
;
1505 view
->offset
= buffer
->offset
+ pCreateInfo
->offset
;
1506 view
->surface_state
=
1507 anv_state_pool_alloc(&device
->surface_state_pool
, 64, 64);
1508 view
->format
= pCreateInfo
->format
;
1510 format
= anv_format_for_vk_format(pCreateInfo
->format
);
1511 /* This assumes RGBA float format. */
1512 uint32_t stride
= 4;
1513 uint32_t num_elements
= pCreateInfo
->range
/ stride
;
1514 struct GEN8_RENDER_SURFACE_STATE surface_state
= {
1515 .SurfaceType
= SURFTYPE_BUFFER
,
1516 .SurfaceArray
= false,
1517 .SurfaceFormat
= format
->format
,
1518 .SurfaceVerticalAlignment
= VALIGN4
,
1519 .SurfaceHorizontalAlignment
= HALIGN4
,
1521 .VerticalLineStride
= 0,
1522 .VerticalLineStrideOffset
= 0,
1523 .SamplerL2BypassModeDisable
= true,
1524 .RenderCacheReadWriteMode
= WriteOnlyCache
,
1525 .MemoryObjectControlState
= 0, /* FIXME: MOCS */
1528 .Height
= (num_elements
>> 7) & 0x3fff,
1529 .Width
= num_elements
& 0x7f,
1530 .Depth
= (num_elements
>> 21) & 0x3f,
1531 .SurfacePitch
= stride
- 1,
1532 .MinimumArrayElement
= 0,
1533 .NumberofMultisamples
= MULTISAMPLECOUNT_1
,
1538 .AuxiliarySurfaceMode
= AUX_NONE
,
1540 .GreenClearColor
= 0,
1541 .BlueClearColor
= 0,
1542 .AlphaClearColor
= 0,
1543 .ShaderChannelSelectRed
= SCS_RED
,
1544 .ShaderChannelSelectGreen
= SCS_GREEN
,
1545 .ShaderChannelSelectBlue
= SCS_BLUE
,
1546 .ShaderChannelSelectAlpha
= SCS_ALPHA
,
1547 .ResourceMinLOD
= 0,
1548 /* FIXME: We assume that the image must be bound at this time. */
1549 .SurfaceBaseAddress
= { NULL
, view
->offset
},
1552 GEN8_RENDER_SURFACE_STATE_pack(NULL
, view
->surface_state
.map
, &surface_state
);
1554 *pView
= (VkImageView
) view
;
1559 // Sampler functions
1561 VkResult
anv_CreateSampler(
1563 const VkSamplerCreateInfo
* pCreateInfo
,
1564 VkSampler
* pSampler
)
1566 struct anv_device
*device
= (struct anv_device
*) _device
;
1567 struct anv_sampler
*sampler
;
1569 assert(pCreateInfo
->sType
== VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO
);
1571 sampler
= anv_device_alloc(device
, sizeof(*sampler
), 8,
1572 VK_SYSTEM_ALLOC_TYPE_API_OBJECT
);
1574 return vk_error(VK_ERROR_OUT_OF_HOST_MEMORY
);
1576 static const uint32_t vk_to_gen_tex_filter
[] = {
1577 [VK_TEX_FILTER_NEAREST
] = MAPFILTER_NEAREST
,
1578 [VK_TEX_FILTER_LINEAR
] = MAPFILTER_LINEAR
1581 static const uint32_t vk_to_gen_mipmap_mode
[] = {
1582 [VK_TEX_MIPMAP_MODE_BASE
] = MIPFILTER_NONE
,
1583 [VK_TEX_MIPMAP_MODE_NEAREST
] = MIPFILTER_NEAREST
,
1584 [VK_TEX_MIPMAP_MODE_LINEAR
] = MIPFILTER_LINEAR
1587 static const uint32_t vk_to_gen_tex_address
[] = {
1588 [VK_TEX_ADDRESS_WRAP
] = TCM_WRAP
,
1589 [VK_TEX_ADDRESS_MIRROR
] = TCM_MIRROR
,
1590 [VK_TEX_ADDRESS_CLAMP
] = TCM_CLAMP
,
1591 [VK_TEX_ADDRESS_MIRROR_ONCE
] = TCM_MIRROR_ONCE
,
1592 [VK_TEX_ADDRESS_CLAMP_BORDER
] = TCM_CLAMP_BORDER
,
1595 static const uint32_t vk_to_gen_compare_op
[] = {
1596 [VK_COMPARE_OP_NEVER
] = PREFILTEROPNEVER
,
1597 [VK_COMPARE_OP_LESS
] = PREFILTEROPLESS
,
1598 [VK_COMPARE_OP_EQUAL
] = PREFILTEROPEQUAL
,
1599 [VK_COMPARE_OP_LESS_EQUAL
] = PREFILTEROPLEQUAL
,
1600 [VK_COMPARE_OP_GREATER
] = PREFILTEROPGREATER
,
1601 [VK_COMPARE_OP_NOT_EQUAL
] = PREFILTEROPNOTEQUAL
,
1602 [VK_COMPARE_OP_GREATER_EQUAL
] = PREFILTEROPGEQUAL
,
1603 [VK_COMPARE_OP_ALWAYS
] = PREFILTEROPALWAYS
,
1606 if (pCreateInfo
->maxAnisotropy
> 0)
1607 anv_finishme("missing support for anisotropic filtering");
1609 struct GEN8_SAMPLER_STATE sampler_state
= {
1610 .SamplerDisable
= false,
1611 .TextureBorderColorMode
= DX10OGL
,
1612 .LODPreClampMode
= 0,
1614 .MipModeFilter
= vk_to_gen_mipmap_mode
[pCreateInfo
->mipMode
],
1615 .MagModeFilter
= vk_to_gen_tex_filter
[pCreateInfo
->magFilter
],
1616 .MinModeFilter
= vk_to_gen_tex_filter
[pCreateInfo
->minFilter
],
1617 .TextureLODBias
= pCreateInfo
->mipLodBias
* 256,
1618 .AnisotropicAlgorithm
= EWAApproximation
,
1619 .MinLOD
= pCreateInfo
->minLod
* 256,
1620 .MaxLOD
= pCreateInfo
->maxLod
* 256,
1621 .ChromaKeyEnable
= 0,
1622 .ChromaKeyIndex
= 0,
1624 .ShadowFunction
= vk_to_gen_compare_op
[pCreateInfo
->compareOp
],
1625 .CubeSurfaceControlMode
= 0,
1626 .IndirectStatePointer
= 0,
1627 .LODClampMagnificationMode
= MIPNONE
,
1628 .MaximumAnisotropy
= 0,
1629 .RAddressMinFilterRoundingEnable
= 0,
1630 .RAddressMagFilterRoundingEnable
= 0,
1631 .VAddressMinFilterRoundingEnable
= 0,
1632 .VAddressMagFilterRoundingEnable
= 0,
1633 .UAddressMinFilterRoundingEnable
= 0,
1634 .UAddressMagFilterRoundingEnable
= 0,
1635 .TrilinearFilterQuality
= 0,
1636 .NonnormalizedCoordinateEnable
= 0,
1637 .TCXAddressControlMode
= vk_to_gen_tex_address
[pCreateInfo
->addressU
],
1638 .TCYAddressControlMode
= vk_to_gen_tex_address
[pCreateInfo
->addressV
],
1639 .TCZAddressControlMode
= vk_to_gen_tex_address
[pCreateInfo
->addressW
],
1642 GEN8_SAMPLER_STATE_pack(NULL
, sampler
->state
, &sampler_state
);
1644 *pSampler
= (VkSampler
) sampler
;
1649 // Descriptor set functions
1651 VkResult
anv_CreateDescriptorSetLayout(
1653 const VkDescriptorSetLayoutCreateInfo
* pCreateInfo
,
1654 VkDescriptorSetLayout
* pSetLayout
)
1656 struct anv_device
*device
= (struct anv_device
*) _device
;
1657 struct anv_descriptor_set_layout
*set_layout
;
1659 assert(pCreateInfo
->sType
== VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO
);
1661 uint32_t sampler_count
[VK_NUM_SHADER_STAGE
] = { 0, };
1662 uint32_t surface_count
[VK_NUM_SHADER_STAGE
] = { 0, };
1663 uint32_t num_dynamic_buffers
= 0;
1667 for (uint32_t i
= 0; i
< pCreateInfo
->count
; i
++) {
1668 switch (pCreateInfo
->pBinding
[i
].descriptorType
) {
1669 case VK_DESCRIPTOR_TYPE_SAMPLER
:
1670 for_each_bit(s
, pCreateInfo
->pBinding
[i
].stageFlags
)
1671 sampler_count
[s
] += pCreateInfo
->pBinding
[i
].count
;
1674 case VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER
:
1675 for_each_bit(s
, pCreateInfo
->pBinding
[i
].stageFlags
)
1676 sampler_count
[s
] += pCreateInfo
->pBinding
[i
].count
;
1680 case VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE
:
1681 case VK_DESCRIPTOR_TYPE_STORAGE_IMAGE
:
1682 case VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER
:
1683 case VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER
:
1684 case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER
:
1685 case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER
:
1686 case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC
:
1687 case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC
:
1688 for_each_bit(s
, pCreateInfo
->pBinding
[i
].stageFlags
)
1689 surface_count
[s
] += pCreateInfo
->pBinding
[i
].count
;
1695 count
+= pCreateInfo
->pBinding
[i
].count
;
1698 for (uint32_t i
= 0; i
< pCreateInfo
->count
; i
++) {
1699 switch (pCreateInfo
->pBinding
[i
].descriptorType
) {
1700 case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC
:
1701 case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC
:
1702 num_dynamic_buffers
++;
1709 uint32_t sampler_total
= 0;
1710 uint32_t surface_total
= 0;
1711 for (uint32_t s
= 0; s
< VK_NUM_SHADER_STAGE
; s
++) {
1712 sampler_total
+= sampler_count
[s
];
1713 surface_total
+= surface_count
[s
];
1716 size_t size
= sizeof(*set_layout
) +
1717 (sampler_total
+ surface_total
) * sizeof(uint32_t);
1718 set_layout
= anv_device_alloc(device
, size
, 8,
1719 VK_SYSTEM_ALLOC_TYPE_API_OBJECT
);
1721 return vk_error(VK_ERROR_OUT_OF_HOST_MEMORY
);
1723 set_layout
->num_dynamic_buffers
= num_dynamic_buffers
;
1724 set_layout
->count
= count
;
1726 uint32_t *p
= set_layout
->entries
;
1727 uint32_t *sampler
[VK_NUM_SHADER_STAGE
];
1728 uint32_t *surface
[VK_NUM_SHADER_STAGE
];
1729 for (uint32_t s
= 0; s
< VK_NUM_SHADER_STAGE
; s
++) {
1730 set_layout
->stage
[s
].surface_count
= surface_count
[s
];
1731 set_layout
->stage
[s
].surface_start
= surface
[s
] = p
;
1732 p
+= surface_count
[s
];
1733 set_layout
->stage
[s
].sampler_count
= sampler_count
[s
];
1734 set_layout
->stage
[s
].sampler_start
= sampler
[s
] = p
;
1735 p
+= sampler_count
[s
];
1738 uint32_t descriptor
= 0;
1739 for (uint32_t i
= 0; i
< pCreateInfo
->count
; i
++) {
1740 switch (pCreateInfo
->pBinding
[i
].descriptorType
) {
1741 case VK_DESCRIPTOR_TYPE_SAMPLER
:
1742 for_each_bit(s
, pCreateInfo
->pBinding
[i
].stageFlags
)
1743 for (uint32_t j
= 0; j
< pCreateInfo
->pBinding
[i
].count
; j
++)
1744 *(sampler
[s
])++ = descriptor
+ j
;
1747 case VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER
:
1748 for_each_bit(s
, pCreateInfo
->pBinding
[i
].stageFlags
)
1749 for (uint32_t j
= 0; j
< pCreateInfo
->pBinding
[i
].count
; j
++)
1750 *(sampler
[s
])++ = descriptor
+ j
;
1754 case VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE
:
1755 case VK_DESCRIPTOR_TYPE_STORAGE_IMAGE
:
1756 case VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER
:
1757 case VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER
:
1758 case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER
:
1759 case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER
:
1760 case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC
:
1761 case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC
:
1762 for_each_bit(s
, pCreateInfo
->pBinding
[i
].stageFlags
)
1763 for (uint32_t j
= 0; j
< pCreateInfo
->pBinding
[i
].count
; j
++) {
1764 *(surface
[s
])++ = descriptor
+ j
;
1770 descriptor
+= pCreateInfo
->pBinding
[i
].count
;
1773 *pSetLayout
= (VkDescriptorSetLayout
) set_layout
;
1778 VkResult
anv_BeginDescriptorPoolUpdate(
1780 VkDescriptorUpdateMode updateMode
)
1785 VkResult
anv_EndDescriptorPoolUpdate(
1792 VkResult
anv_CreateDescriptorPool(
1794 VkDescriptorPoolUsage poolUsage
,
1796 const VkDescriptorPoolCreateInfo
* pCreateInfo
,
1797 VkDescriptorPool
* pDescriptorPool
)
1799 *pDescriptorPool
= 1;
1804 VkResult
anv_ResetDescriptorPool(
1806 VkDescriptorPool descriptorPool
)
1811 VkResult
anv_AllocDescriptorSets(
1813 VkDescriptorPool descriptorPool
,
1814 VkDescriptorSetUsage setUsage
,
1816 const VkDescriptorSetLayout
* pSetLayouts
,
1817 VkDescriptorSet
* pDescriptorSets
,
1820 struct anv_device
*device
= (struct anv_device
*) _device
;
1821 const struct anv_descriptor_set_layout
*layout
;
1822 struct anv_descriptor_set
*set
;
1825 for (uint32_t i
= 0; i
< count
; i
++) {
1826 layout
= (struct anv_descriptor_set_layout
*) pSetLayouts
[i
];
1827 size
= sizeof(*set
) + layout
->count
* sizeof(set
->descriptors
[0]);
1828 set
= anv_device_alloc(device
, size
, 8,
1829 VK_SYSTEM_ALLOC_TYPE_API_OBJECT
);
1832 return vk_error(VK_ERROR_OUT_OF_HOST_MEMORY
);
1835 pDescriptorSets
[i
] = (VkDescriptorSet
) set
;
1843 void anv_ClearDescriptorSets(
1845 VkDescriptorPool descriptorPool
,
1847 const VkDescriptorSet
* pDescriptorSets
)
1851 void anv_UpdateDescriptors(
1853 VkDescriptorSet descriptorSet
,
1854 uint32_t updateCount
,
1855 const void** ppUpdateArray
)
1857 struct anv_descriptor_set
*set
= (struct anv_descriptor_set
*) descriptorSet
;
1858 VkUpdateSamplers
*update_samplers
;
1859 VkUpdateSamplerTextures
*update_sampler_textures
;
1860 VkUpdateImages
*update_images
;
1861 VkUpdateBuffers
*update_buffers
;
1862 VkUpdateAsCopy
*update_as_copy
;
1864 for (uint32_t i
= 0; i
< updateCount
; i
++) {
1865 const struct anv_common
*common
= ppUpdateArray
[i
];
1867 switch (common
->sType
) {
1868 case VK_STRUCTURE_TYPE_UPDATE_SAMPLERS
:
1869 update_samplers
= (VkUpdateSamplers
*) common
;
1871 for (uint32_t j
= 0; j
< update_samplers
->count
; j
++) {
1872 set
->descriptors
[update_samplers
->binding
+ j
].sampler
=
1873 (struct anv_sampler
*) update_samplers
->pSamplers
[j
];
1877 case VK_STRUCTURE_TYPE_UPDATE_SAMPLER_TEXTURES
:
1878 /* FIXME: Shouldn't this be *_UPDATE_SAMPLER_IMAGES? */
1879 update_sampler_textures
= (VkUpdateSamplerTextures
*) common
;
1881 for (uint32_t j
= 0; j
< update_sampler_textures
->count
; j
++) {
1882 set
->descriptors
[update_sampler_textures
->binding
+ j
].view
=
1883 (struct anv_surface_view
*)
1884 update_sampler_textures
->pSamplerImageViews
[j
].pImageView
->view
;
1885 set
->descriptors
[update_sampler_textures
->binding
+ j
].sampler
=
1886 (struct anv_sampler
*)
1887 update_sampler_textures
->pSamplerImageViews
[j
].sampler
;
1891 case VK_STRUCTURE_TYPE_UPDATE_IMAGES
:
1892 update_images
= (VkUpdateImages
*) common
;
1894 for (uint32_t j
= 0; j
< update_images
->count
; j
++) {
1895 set
->descriptors
[update_images
->binding
+ j
].view
=
1896 (struct anv_surface_view
*) update_images
->pImageViews
[j
].view
;
1900 case VK_STRUCTURE_TYPE_UPDATE_BUFFERS
:
1901 update_buffers
= (VkUpdateBuffers
*) common
;
1903 for (uint32_t j
= 0; j
< update_buffers
->count
; j
++) {
1904 set
->descriptors
[update_buffers
->binding
+ j
].view
=
1905 (struct anv_surface_view
*) update_buffers
->pBufferViews
[j
].view
;
1907 /* FIXME: descriptor arrays? */
1910 case VK_STRUCTURE_TYPE_UPDATE_AS_COPY
:
1911 update_as_copy
= (VkUpdateAsCopy
*) common
;
1912 (void) update_as_copy
;
1921 // State object functions
1923 static inline int64_t
1924 clamp_int64(int64_t x
, int64_t min
, int64_t max
)
1934 VkResult
anv_CreateDynamicViewportState(
1936 const VkDynamicVpStateCreateInfo
* pCreateInfo
,
1937 VkDynamicVpState
* pState
)
1939 struct anv_device
*device
= (struct anv_device
*) _device
;
1940 struct anv_dynamic_vp_state
*state
;
1942 assert(pCreateInfo
->sType
== VK_STRUCTURE_TYPE_DYNAMIC_VP_STATE_CREATE_INFO
);
1944 state
= anv_device_alloc(device
, sizeof(*state
), 8,
1945 VK_SYSTEM_ALLOC_TYPE_API_OBJECT
);
1947 return vk_error(VK_ERROR_OUT_OF_HOST_MEMORY
);
1949 unsigned count
= pCreateInfo
->viewportAndScissorCount
;
1950 state
->sf_clip_vp
= anv_state_pool_alloc(&device
->dynamic_state_pool
,
1952 state
->cc_vp
= anv_state_pool_alloc(&device
->dynamic_state_pool
,
1954 state
->scissor
= anv_state_pool_alloc(&device
->dynamic_state_pool
,
1957 for (uint32_t i
= 0; i
< pCreateInfo
->viewportAndScissorCount
; i
++) {
1958 const VkViewport
*vp
= &pCreateInfo
->pViewports
[i
];
1959 const VkRect
*s
= &pCreateInfo
->pScissors
[i
];
1961 struct GEN8_SF_CLIP_VIEWPORT sf_clip_viewport
= {
1962 .ViewportMatrixElementm00
= vp
->width
/ 2,
1963 .ViewportMatrixElementm11
= vp
->height
/ 2,
1964 .ViewportMatrixElementm22
= (vp
->maxDepth
- vp
->minDepth
) / 2,
1965 .ViewportMatrixElementm30
= vp
->originX
+ vp
->width
/ 2,
1966 .ViewportMatrixElementm31
= vp
->originY
+ vp
->height
/ 2,
1967 .ViewportMatrixElementm32
= (vp
->maxDepth
+ vp
->minDepth
) / 2,
1968 .XMinClipGuardband
= -1.0f
,
1969 .XMaxClipGuardband
= 1.0f
,
1970 .YMinClipGuardband
= -1.0f
,
1971 .YMaxClipGuardband
= 1.0f
,
1972 .XMinViewPort
= vp
->originX
,
1973 .XMaxViewPort
= vp
->originX
+ vp
->width
- 1,
1974 .YMinViewPort
= vp
->originY
,
1975 .YMaxViewPort
= vp
->originY
+ vp
->height
- 1,
1978 struct GEN8_CC_VIEWPORT cc_viewport
= {
1979 .MinimumDepth
= vp
->minDepth
,
1980 .MaximumDepth
= vp
->maxDepth
1983 /* Since xmax and ymax are inclusive, we have to have xmax < xmin or
1984 * ymax < ymin for empty clips. In case clip x, y, width height are all
1985 * 0, the clamps below produce 0 for xmin, ymin, xmax, ymax, which isn't
1986 * what we want. Just special case empty clips and produce a canonical
1988 static const struct GEN8_SCISSOR_RECT empty_scissor
= {
1989 .ScissorRectangleYMin
= 1,
1990 .ScissorRectangleXMin
= 1,
1991 .ScissorRectangleYMax
= 0,
1992 .ScissorRectangleXMax
= 0
1995 const int max
= 0xffff;
1996 struct GEN8_SCISSOR_RECT scissor
= {
1997 /* Do this math using int64_t so overflow gets clamped correctly. */
1998 .ScissorRectangleYMin
= clamp_int64(s
->offset
.y
, 0, max
),
1999 .ScissorRectangleXMin
= clamp_int64(s
->offset
.x
, 0, max
),
2000 .ScissorRectangleYMax
= clamp_int64((uint64_t) s
->offset
.y
+ s
->extent
.height
- 1, 0, max
),
2001 .ScissorRectangleXMax
= clamp_int64((uint64_t) s
->offset
.x
+ s
->extent
.width
- 1, 0, max
)
2004 GEN8_SF_CLIP_VIEWPORT_pack(NULL
, state
->sf_clip_vp
.map
+ i
* 64, &sf_clip_viewport
);
2005 GEN8_CC_VIEWPORT_pack(NULL
, state
->cc_vp
.map
+ i
* 32, &cc_viewport
);
2007 if (s
->extent
.width
<= 0 || s
->extent
.height
<= 0) {
2008 GEN8_SCISSOR_RECT_pack(NULL
, state
->scissor
.map
+ i
* 32, &empty_scissor
);
2010 GEN8_SCISSOR_RECT_pack(NULL
, state
->scissor
.map
+ i
* 32, &scissor
);
2014 *pState
= (VkDynamicVpState
) state
;
2019 VkResult
anv_CreateDynamicRasterState(
2021 const VkDynamicRsStateCreateInfo
* pCreateInfo
,
2022 VkDynamicRsState
* pState
)
2024 struct anv_device
*device
= (struct anv_device
*) _device
;
2025 struct anv_dynamic_rs_state
*state
;
2027 assert(pCreateInfo
->sType
== VK_STRUCTURE_TYPE_DYNAMIC_RS_STATE_CREATE_INFO
);
2029 state
= anv_device_alloc(device
, sizeof(*state
), 8,
2030 VK_SYSTEM_ALLOC_TYPE_API_OBJECT
);
2032 return vk_error(VK_ERROR_OUT_OF_HOST_MEMORY
);
2036 * float depthBiasClamp;
2037 * float slopeScaledDepthBias;
2038 * float pointFadeThreshold;
2039 * // optional (GL45) - Size of point fade threshold
2042 struct GEN8_3DSTATE_SF sf
= {
2043 GEN8_3DSTATE_SF_header
,
2044 .LineWidth
= pCreateInfo
->lineWidth
,
2045 .PointWidth
= pCreateInfo
->pointSize
,
2048 GEN8_3DSTATE_SF_pack(NULL
, state
->state_sf
, &sf
);
2050 *pState
= (VkDynamicRsState
) state
;
2055 VkResult
anv_CreateDynamicColorBlendState(
2057 const VkDynamicCbStateCreateInfo
* pCreateInfo
,
2058 VkDynamicCbState
* pState
)
2060 struct anv_device
*device
= (struct anv_device
*) _device
;
2061 struct anv_dynamic_cb_state
*state
;
2063 assert(pCreateInfo
->sType
== VK_STRUCTURE_TYPE_DYNAMIC_CB_STATE_CREATE_INFO
);
2065 state
= anv_device_alloc(device
, sizeof(*state
), 8,
2066 VK_SYSTEM_ALLOC_TYPE_API_OBJECT
);
2068 return vk_error(VK_ERROR_OUT_OF_HOST_MEMORY
);
2070 *pState
= (VkDynamicCbState
) state
;
2075 VkResult
anv_CreateDynamicDepthStencilState(
2077 const VkDynamicDsStateCreateInfo
* pCreateInfo
,
2078 VkDynamicDsState
* pState
)
2080 stub_return(VK_UNSUPPORTED
);
2083 // Command buffer functions
2085 VkResult
anv_CreateCommandBuffer(
2087 const VkCmdBufferCreateInfo
* pCreateInfo
,
2088 VkCmdBuffer
* pCmdBuffer
)
2090 struct anv_device
*device
= (struct anv_device
*) _device
;
2091 struct anv_cmd_buffer
*cmd_buffer
;
2094 cmd_buffer
= anv_device_alloc(device
, sizeof(*cmd_buffer
), 8,
2095 VK_SYSTEM_ALLOC_TYPE_API_OBJECT
);
2096 if (cmd_buffer
== NULL
)
2097 return vk_error(VK_ERROR_OUT_OF_HOST_MEMORY
);
2099 cmd_buffer
->device
= device
;
2100 cmd_buffer
->rs_state
= NULL
;
2101 cmd_buffer
->vp_state
= NULL
;
2102 memset(&cmd_buffer
->default_bindings
, 0, sizeof(cmd_buffer
->default_bindings
));
2103 cmd_buffer
->bindings
= &cmd_buffer
->default_bindings
;
2105 result
= anv_batch_init(&cmd_buffer
->batch
, device
);
2106 if (result
!= VK_SUCCESS
)
2109 result
= anv_bo_init_new(&cmd_buffer
->surface_bo
, device
, BATCH_SIZE
);
2110 if (result
!= VK_SUCCESS
)
2113 cmd_buffer
->surface_bo
.map
=
2114 anv_gem_mmap(device
, cmd_buffer
->surface_bo
.gem_handle
, 0, BATCH_SIZE
);
2115 if (cmd_buffer
->surface_bo
.map
== NULL
) {
2116 result
= vk_error(VK_ERROR_MEMORY_MAP_FAILED
);
2117 goto fail_surface_bo
;
2120 /* Start surface_next at 1 so surface offset 0 is invalid. */
2121 cmd_buffer
->surface_next
= 1;
2122 cmd_buffer
->surface_relocs
.num_relocs
= 0;
2124 cmd_buffer
->exec2_objects
=
2125 anv_device_alloc(device
, 8192 * sizeof(cmd_buffer
->exec2_objects
[0]), 8,
2126 VK_SYSTEM_ALLOC_TYPE_API_OBJECT
);
2127 if (cmd_buffer
->exec2_objects
== NULL
) {
2128 result
= vk_error(VK_ERROR_OUT_OF_HOST_MEMORY
);
2129 goto fail_surface_map
;
2132 cmd_buffer
->exec2_bos
=
2133 anv_device_alloc(device
, 8192 * sizeof(cmd_buffer
->exec2_bos
[0]), 8,
2134 VK_SYSTEM_ALLOC_TYPE_API_OBJECT
);
2135 if (cmd_buffer
->exec2_bos
== NULL
) {
2136 result
= vk_error(VK_ERROR_OUT_OF_HOST_MEMORY
);
2137 goto fail_exec2_objects
;
2140 anv_state_stream_init(&cmd_buffer
->binding_table_state_stream
,
2141 &device
->binding_table_block_pool
);
2142 anv_state_stream_init(&cmd_buffer
->surface_state_stream
,
2143 &device
->surface_state_block_pool
);
2144 anv_state_stream_init(&cmd_buffer
->dynamic_state_stream
,
2145 &device
->dynamic_state_block_pool
);
2147 cmd_buffer
->dirty
= 0;
2148 cmd_buffer
->vb_dirty
= 0;
2150 *pCmdBuffer
= (VkCmdBuffer
) cmd_buffer
;
2155 anv_device_free(device
, cmd_buffer
->exec2_objects
);
2157 anv_gem_munmap(cmd_buffer
->surface_bo
.map
, BATCH_SIZE
);
2159 anv_gem_close(device
, cmd_buffer
->surface_bo
.gem_handle
);
2161 anv_batch_finish(&cmd_buffer
->batch
, device
);
2163 anv_device_free(device
, cmd_buffer
);
2168 VkResult
anv_BeginCommandBuffer(
2169 VkCmdBuffer cmdBuffer
,
2170 const VkCmdBufferBeginInfo
* pBeginInfo
)
2172 struct anv_cmd_buffer
*cmd_buffer
= (struct anv_cmd_buffer
*) cmdBuffer
;
2173 struct anv_device
*device
= cmd_buffer
->device
;
2175 anv_batch_emit(&cmd_buffer
->batch
, GEN8_PIPELINE_SELECT
,
2176 .PipelineSelection
= _3D
);
2177 anv_batch_emit(&cmd_buffer
->batch
, GEN8_STATE_SIP
);
2179 anv_batch_emit(&cmd_buffer
->batch
, GEN8_STATE_BASE_ADDRESS
,
2180 .GeneralStateBaseAddress
= { NULL
, 0 },
2181 .GeneralStateBaseAddressModifyEnable
= true,
2182 .GeneralStateBufferSize
= 0xfffff,
2183 .GeneralStateBufferSizeModifyEnable
= true,
2185 .SurfaceStateBaseAddress
= { &cmd_buffer
->surface_bo
, 0 },
2186 .SurfaceStateMemoryObjectControlState
= 0, /* FIXME: MOCS */
2187 .SurfaceStateBaseAddressModifyEnable
= true,
2189 .DynamicStateBaseAddress
= { &device
->dynamic_state_block_pool
.bo
, 0 },
2190 .DynamicStateBaseAddressModifyEnable
= true,
2191 .DynamicStateBufferSize
= 0xfffff,
2192 .DynamicStateBufferSizeModifyEnable
= true,
2194 .IndirectObjectBaseAddress
= { NULL
, 0 },
2195 .IndirectObjectBaseAddressModifyEnable
= true,
2196 .IndirectObjectBufferSize
= 0xfffff,
2197 .IndirectObjectBufferSizeModifyEnable
= true,
2199 .InstructionBaseAddress
= { &device
->instruction_block_pool
.bo
, 0 },
2200 .InstructionBaseAddressModifyEnable
= true,
2201 .InstructionBufferSize
= 0xfffff,
2202 .InstructionBuffersizeModifyEnable
= true);
2204 anv_batch_emit(&cmd_buffer
->batch
, GEN8_3DSTATE_VF_STATISTICS
,
2205 .StatisticsEnable
= true);
2206 anv_batch_emit(&cmd_buffer
->batch
, GEN8_3DSTATE_HS
, .Enable
= false);
2207 anv_batch_emit(&cmd_buffer
->batch
, GEN8_3DSTATE_TE
, .TEEnable
= false);
2208 anv_batch_emit(&cmd_buffer
->batch
, GEN8_3DSTATE_DS
, .FunctionEnable
= false);
2209 anv_batch_emit(&cmd_buffer
->batch
, GEN8_3DSTATE_STREAMOUT
, .SOFunctionEnable
= false);
2211 anv_batch_emit(&cmd_buffer
->batch
, GEN8_3DSTATE_PUSH_CONSTANT_ALLOC_VS
,
2212 .ConstantBufferOffset
= 0,
2213 .ConstantBufferSize
= 4);
2214 anv_batch_emit(&cmd_buffer
->batch
, GEN8_3DSTATE_PUSH_CONSTANT_ALLOC_GS
,
2215 .ConstantBufferOffset
= 4,
2216 .ConstantBufferSize
= 4);
2217 anv_batch_emit(&cmd_buffer
->batch
, GEN8_3DSTATE_PUSH_CONSTANT_ALLOC_PS
,
2218 .ConstantBufferOffset
= 8,
2219 .ConstantBufferSize
= 4);
2221 anv_batch_emit(&cmd_buffer
->batch
, GEN8_3DSTATE_WM_CHROMAKEY
,
2222 .ChromaKeyKillEnable
= false);
2223 anv_batch_emit(&cmd_buffer
->batch
, GEN8_3DSTATE_SBE_SWIZ
);
2224 anv_batch_emit(&cmd_buffer
->batch
, GEN8_3DSTATE_AA_LINE_PARAMETERS
);
2226 /* Hardcoded state: */
2227 anv_batch_emit(&cmd_buffer
->batch
, GEN8_3DSTATE_DEPTH_BUFFER
,
2228 .SurfaceType
= SURFTYPE_2D
,
2231 .SurfaceFormat
= D16_UNORM
,
2232 .SurfaceBaseAddress
= { NULL
, 0 },
2233 .HierarchicalDepthBufferEnable
= 0);
2235 anv_batch_emit(&cmd_buffer
->batch
, GEN8_3DSTATE_WM_DEPTH_STENCIL
,
2236 .DepthTestEnable
= false,
2237 .DepthBufferWriteEnable
= false);
2243 anv_cmd_buffer_add_bo(struct anv_cmd_buffer
*cmd_buffer
,
2244 struct anv_bo
*bo
, struct anv_reloc_list
*list
)
2246 struct drm_i915_gem_exec_object2
*obj
;
2248 bo
->index
= cmd_buffer
->bo_count
;
2249 obj
= &cmd_buffer
->exec2_objects
[bo
->index
];
2250 cmd_buffer
->exec2_bos
[bo
->index
] = bo
;
2251 cmd_buffer
->bo_count
++;
2253 obj
->handle
= bo
->gem_handle
;
2254 obj
->relocation_count
= 0;
2255 obj
->relocs_ptr
= 0;
2257 obj
->offset
= bo
->offset
;
2263 obj
->relocation_count
= list
->num_relocs
;
2264 obj
->relocs_ptr
= (uintptr_t) list
->relocs
;
2269 anv_cmd_buffer_add_validate_bos(struct anv_cmd_buffer
*cmd_buffer
,
2270 struct anv_reloc_list
*list
)
2272 struct anv_bo
*bo
, *batch_bo
;
2274 batch_bo
= &cmd_buffer
->batch
.bo
;
2275 for (size_t i
= 0; i
< list
->num_relocs
; i
++) {
2276 bo
= list
->reloc_bos
[i
];
2277 /* Skip any relocations targeting the batch bo. We need to make sure
2278 * it's the last in the list so we'll add it manually later.
2282 if (bo
->index
< cmd_buffer
->bo_count
&& cmd_buffer
->exec2_bos
[bo
->index
] == bo
)
2285 anv_cmd_buffer_add_bo(cmd_buffer
, bo
, NULL
);
2290 anv_cmd_buffer_process_relocs(struct anv_cmd_buffer
*cmd_buffer
,
2291 struct anv_reloc_list
*list
)
2295 /* If the kernel supports I915_EXEC_NO_RELOC, it will compare offset in
2296 * struct drm_i915_gem_exec_object2 against the bos current offset and if
2297 * all bos haven't moved it will skip relocation processing alltogether.
2298 * If I915_EXEC_NO_RELOC is not supported, the kernel ignores the incoming
2299 * value of offset so we can set it either way. For that to work we need
2300 * to make sure all relocs use the same presumed offset.
2303 for (size_t i
= 0; i
< list
->num_relocs
; i
++) {
2304 bo
= list
->reloc_bos
[i
];
2305 if (bo
->offset
!= list
->relocs
[i
].presumed_offset
)
2306 cmd_buffer
->need_reloc
= true;
2308 list
->relocs
[i
].target_handle
= bo
->index
;
2312 VkResult
anv_EndCommandBuffer(
2313 VkCmdBuffer cmdBuffer
)
2315 struct anv_cmd_buffer
*cmd_buffer
= (struct anv_cmd_buffer
*) cmdBuffer
;
2316 struct anv_device
*device
= cmd_buffer
->device
;
2317 struct anv_batch
*batch
= &cmd_buffer
->batch
;
2319 anv_batch_emit(batch
, GEN8_MI_BATCH_BUFFER_END
);
2321 /* Round batch up to an even number of dwords. */
2322 if ((batch
->next
- batch
->bo
.map
) & 4)
2323 anv_batch_emit(batch
, GEN8_MI_NOOP
);
2325 cmd_buffer
->bo_count
= 0;
2326 cmd_buffer
->need_reloc
= false;
2328 /* Lock for access to bo->index. */
2329 pthread_mutex_lock(&device
->mutex
);
2331 /* Add block pool bos first so we can add them with their relocs. */
2332 anv_cmd_buffer_add_bo(cmd_buffer
, &cmd_buffer
->surface_bo
,
2333 &cmd_buffer
->surface_relocs
);
2335 anv_cmd_buffer_add_validate_bos(cmd_buffer
, &cmd_buffer
->surface_relocs
);
2336 anv_cmd_buffer_add_validate_bos(cmd_buffer
, &batch
->cmd_relocs
);
2337 anv_cmd_buffer_add_bo(cmd_buffer
, &batch
->bo
, &batch
->cmd_relocs
);
2338 anv_cmd_buffer_process_relocs(cmd_buffer
, &cmd_buffer
->surface_relocs
);
2339 anv_cmd_buffer_process_relocs(cmd_buffer
, &batch
->cmd_relocs
);
2341 cmd_buffer
->execbuf
.buffers_ptr
= (uintptr_t) cmd_buffer
->exec2_objects
;
2342 cmd_buffer
->execbuf
.buffer_count
= cmd_buffer
->bo_count
;
2343 cmd_buffer
->execbuf
.batch_start_offset
= 0;
2344 cmd_buffer
->execbuf
.batch_len
= batch
->next
- batch
->bo
.map
;
2345 cmd_buffer
->execbuf
.cliprects_ptr
= 0;
2346 cmd_buffer
->execbuf
.num_cliprects
= 0;
2347 cmd_buffer
->execbuf
.DR1
= 0;
2348 cmd_buffer
->execbuf
.DR4
= 0;
2350 cmd_buffer
->execbuf
.flags
= I915_EXEC_HANDLE_LUT
;
2351 if (!cmd_buffer
->need_reloc
)
2352 cmd_buffer
->execbuf
.flags
|= I915_EXEC_NO_RELOC
;
2353 cmd_buffer
->execbuf
.flags
|= I915_EXEC_RENDER
;
2354 cmd_buffer
->execbuf
.rsvd1
= device
->context_id
;
2355 cmd_buffer
->execbuf
.rsvd2
= 0;
2357 pthread_mutex_unlock(&device
->mutex
);
2362 VkResult
anv_ResetCommandBuffer(
2363 VkCmdBuffer cmdBuffer
)
2365 struct anv_cmd_buffer
*cmd_buffer
= (struct anv_cmd_buffer
*) cmdBuffer
;
2367 anv_batch_reset(&cmd_buffer
->batch
);
2368 cmd_buffer
->surface_next
= 0;
2369 cmd_buffer
->surface_relocs
.num_relocs
= 0;
2374 // Command buffer building functions
2376 void anv_CmdBindPipeline(
2377 VkCmdBuffer cmdBuffer
,
2378 VkPipelineBindPoint pipelineBindPoint
,
2379 VkPipeline _pipeline
)
2381 struct anv_cmd_buffer
*cmd_buffer
= (struct anv_cmd_buffer
*) cmdBuffer
;
2383 cmd_buffer
->pipeline
= (struct anv_pipeline
*) _pipeline
;
2384 cmd_buffer
->dirty
|= ANV_CMD_BUFFER_PIPELINE_DIRTY
;
2387 void anv_CmdBindDynamicStateObject(
2388 VkCmdBuffer cmdBuffer
,
2389 VkStateBindPoint stateBindPoint
,
2390 VkDynamicStateObject dynamicState
)
2392 struct anv_cmd_buffer
*cmd_buffer
= (struct anv_cmd_buffer
*) cmdBuffer
;
2393 struct anv_dynamic_vp_state
*vp_state
;
2395 switch (stateBindPoint
) {
2396 case VK_STATE_BIND_POINT_VIEWPORT
:
2397 vp_state
= (struct anv_dynamic_vp_state
*) dynamicState
;
2398 /* We emit state immediately, but set cmd_buffer->vp_state to indicate
2399 * that vp state has been set in this command buffer. */
2400 cmd_buffer
->vp_state
= vp_state
;
2401 anv_batch_emit(&cmd_buffer
->batch
, GEN8_3DSTATE_SCISSOR_STATE_POINTERS
,
2402 .ScissorRectPointer
= vp_state
->scissor
.offset
);
2403 anv_batch_emit(&cmd_buffer
->batch
, GEN8_3DSTATE_VIEWPORT_STATE_POINTERS_CC
,
2404 .CCViewportPointer
= vp_state
->cc_vp
.offset
);
2405 anv_batch_emit(&cmd_buffer
->batch
, GEN8_3DSTATE_VIEWPORT_STATE_POINTERS_SF_CLIP
,
2406 .SFClipViewportPointer
= vp_state
->sf_clip_vp
.offset
);
2408 case VK_STATE_BIND_POINT_RASTER
:
2409 cmd_buffer
->rs_state
= (struct anv_dynamic_rs_state
*) dynamicState
;
2410 cmd_buffer
->dirty
|= ANV_CMD_BUFFER_RS_DIRTY
;
2412 case VK_STATE_BIND_POINT_COLOR_BLEND
:
2413 case VK_STATE_BIND_POINT_DEPTH_STENCIL
:
2420 static struct anv_state
2421 anv_cmd_buffer_alloc_surface_state(struct anv_cmd_buffer
*cmd_buffer
,
2422 uint32_t size
, uint32_t alignment
)
2424 struct anv_state state
;
2426 state
.offset
= ALIGN_U32(cmd_buffer
->surface_next
, alignment
);
2427 state
.map
= cmd_buffer
->surface_bo
.map
+ state
.offset
;
2428 state
.alloc_size
= size
;
2429 cmd_buffer
->surface_next
= state
.offset
+ size
;
2431 assert(state
.offset
+ size
< cmd_buffer
->surface_bo
.size
);
2436 void anv_CmdBindDescriptorSets(
2437 VkCmdBuffer cmdBuffer
,
2438 VkPipelineBindPoint pipelineBindPoint
,
2441 const VkDescriptorSet
* pDescriptorSets
,
2442 uint32_t dynamicOffsetCount
,
2443 const uint32_t* pDynamicOffsets
)
2445 struct anv_cmd_buffer
*cmd_buffer
= (struct anv_cmd_buffer
*) cmdBuffer
;
2446 struct anv_pipeline_layout
*layout
= cmd_buffer
->pipeline
->layout
;
2447 struct anv_bindings
*bindings
= cmd_buffer
->bindings
;
2449 uint32_t offset
= 0;
2450 for (uint32_t i
= 0; i
< setCount
; i
++) {
2451 struct anv_descriptor_set
*set
=
2452 (struct anv_descriptor_set
*) pDescriptorSets
[i
];
2453 struct anv_descriptor_set_layout
*set_layout
= layout
->set
[firstSet
+ i
].layout
;
2455 for (uint32_t s
= 0; s
< VK_NUM_SHADER_STAGE
; s
++) {
2456 uint32_t *surface_to_desc
= set_layout
->stage
[s
].surface_start
;
2457 uint32_t *sampler_to_desc
= set_layout
->stage
[s
].sampler_start
;
2458 uint32_t bias
= s
== VK_SHADER_STAGE_FRAGMENT
? MAX_RTS
: 0;
2461 start
= bias
+ layout
->set
[firstSet
+ i
].surface_start
[s
];
2462 for (uint32_t b
= 0; b
< set_layout
->stage
[s
].surface_count
; b
++) {
2463 struct anv_surface_view
*view
= set
->descriptors
[surface_to_desc
[b
]].view
;
2465 struct anv_state state
=
2466 anv_cmd_buffer_alloc_surface_state(cmd_buffer
, 64, 64);
2467 memcpy(state
.map
, view
->surface_state
.map
, 64);
2469 bindings
->descriptors
[s
].surfaces
[start
+ b
] = state
.offset
;
2470 bindings
->descriptors
[s
].relocs
[start
+ b
].bo
= view
->bo
;
2471 bindings
->descriptors
[s
].relocs
[start
+ b
].offset
= view
->offset
;
2474 start
= layout
->set
[firstSet
+ i
].sampler_start
[s
];
2475 for (uint32_t b
= 0; b
< set_layout
->stage
[s
].sampler_count
; b
++) {
2476 struct anv_sampler
*sampler
= set
->descriptors
[sampler_to_desc
[b
]].sampler
;
2478 memcpy(&bindings
->descriptors
[s
].samplers
[start
+ b
],
2479 sampler
->state
, sizeof(sampler
->state
));
2483 offset
+= layout
->set
[firstSet
+ i
].layout
->num_dynamic_buffers
;
2486 cmd_buffer
->dirty
|= ANV_CMD_BUFFER_DESCRIPTOR_SET_DIRTY
;
2489 void anv_CmdBindIndexBuffer(
2490 VkCmdBuffer cmdBuffer
,
2492 VkDeviceSize offset
,
2493 VkIndexType indexType
)
2495 struct anv_cmd_buffer
*cmd_buffer
= (struct anv_cmd_buffer
*) cmdBuffer
;
2496 struct anv_buffer
*buffer
= (struct anv_buffer
*) _buffer
;
2498 static const uint32_t vk_to_gen_index_type
[] = {
2499 [VK_INDEX_TYPE_UINT8
] = INDEX_BYTE
,
2500 [VK_INDEX_TYPE_UINT16
] = INDEX_WORD
,
2501 [VK_INDEX_TYPE_UINT32
] = INDEX_DWORD
,
2504 anv_batch_emit(&cmd_buffer
->batch
, GEN8_3DSTATE_INDEX_BUFFER
,
2505 .IndexFormat
= vk_to_gen_index_type
[indexType
],
2506 .MemoryObjectControlState
= 0,
2507 .BufferStartingAddress
= { buffer
->bo
, buffer
->offset
+ offset
},
2508 .BufferSize
= buffer
->size
- offset
);
2511 void anv_CmdBindVertexBuffers(
2512 VkCmdBuffer cmdBuffer
,
2513 uint32_t startBinding
,
2514 uint32_t bindingCount
,
2515 const VkBuffer
* pBuffers
,
2516 const VkDeviceSize
* pOffsets
)
2518 struct anv_cmd_buffer
*cmd_buffer
= (struct anv_cmd_buffer
*) cmdBuffer
;
2519 struct anv_bindings
*bindings
= cmd_buffer
->bindings
;
2521 /* We have to defer setting up vertex buffer since we need the buffer
2522 * stride from the pipeline. */
2524 for (uint32_t i
= 0; i
< bindingCount
; i
++) {
2525 bindings
->vb
[startBinding
+ i
].buffer
= (struct anv_buffer
*) pBuffers
[i
];
2526 bindings
->vb
[startBinding
+ i
].offset
= pOffsets
[i
];
2527 cmd_buffer
->vb_dirty
|= 1 << (startBinding
+ i
);
2532 flush_descriptor_sets(struct anv_cmd_buffer
*cmd_buffer
)
2534 struct anv_pipeline_layout
*layout
= cmd_buffer
->pipeline
->layout
;
2535 struct anv_bindings
*bindings
= cmd_buffer
->bindings
;
2536 uint32_t layers
= cmd_buffer
->framebuffer
->layers
;
2538 for (uint32_t s
= 0; s
< VK_NUM_SHADER_STAGE
; s
++) {
2541 if (s
== VK_SHADER_STAGE_FRAGMENT
) {
2543 layers
= cmd_buffer
->framebuffer
->layers
;
2549 /* This is a little awkward: layout can be NULL but we still have to
2550 * allocate and set a binding table for the PS stage for render
2552 uint32_t surface_count
= layout
? layout
->stage
[s
].surface_count
: 0;
2554 if (layers
+ surface_count
> 0) {
2555 struct anv_state state
;
2560 size
= (bias
+ surface_count
) * sizeof(uint32_t);
2561 state
= anv_cmd_buffer_alloc_surface_state(cmd_buffer
, size
, 32);
2562 memcpy(state
.map
, bindings
->descriptors
[s
].surfaces
, size
);
2564 for (uint32_t i
= 0; i
< layers
; i
++) {
2565 offset
= bindings
->descriptors
[s
].surfaces
[i
] + 8 * sizeof(int32_t);
2566 address
= cmd_buffer
->surface_bo
.map
+ offset
;
2569 anv_reloc_list_add(&cmd_buffer
->surface_relocs
, offset
,
2570 bindings
->descriptors
[s
].relocs
[i
].bo
,
2571 bindings
->descriptors
[s
].relocs
[i
].offset
);
2574 for (uint32_t i
= 0; i
< surface_count
; i
++) {
2575 offset
= bindings
->descriptors
[s
].surfaces
[i
] + 8 * sizeof(int32_t);
2576 address
= cmd_buffer
->surface_bo
.map
+ offset
;
2579 anv_reloc_list_add(&cmd_buffer
->surface_relocs
, offset
,
2580 bindings
->descriptors
[s
].relocs
[bias
+ i
].bo
,
2581 bindings
->descriptors
[s
].relocs
[bias
+ i
].offset
);
2584 static const uint32_t binding_table_opcodes
[] = {
2585 [VK_SHADER_STAGE_VERTEX
] = 38,
2586 [VK_SHADER_STAGE_TESS_CONTROL
] = 39,
2587 [VK_SHADER_STAGE_TESS_EVALUATION
] = 40,
2588 [VK_SHADER_STAGE_GEOMETRY
] = 41,
2589 [VK_SHADER_STAGE_FRAGMENT
] = 42,
2590 [VK_SHADER_STAGE_COMPUTE
] = 0,
2593 anv_batch_emit(&cmd_buffer
->batch
,
2594 GEN8_3DSTATE_BINDING_TABLE_POINTERS_VS
,
2595 ._3DCommandSubOpcode
= binding_table_opcodes
[s
],
2596 .PointertoVSBindingTable
= state
.offset
);
2599 if (layout
&& layout
->stage
[s
].sampler_count
> 0) {
2600 struct anv_state state
;
2603 size
= layout
->stage
[s
].sampler_count
* 16;
2604 state
= anv_cmd_buffer_alloc_surface_state(cmd_buffer
, size
, 32);
2605 memcpy(state
.map
, bindings
->descriptors
[s
].samplers
, size
);
2607 static const uint32_t sampler_state_opcodes
[] = {
2608 [VK_SHADER_STAGE_VERTEX
] = 43,
2609 [VK_SHADER_STAGE_TESS_CONTROL
] = 44, /* HS */
2610 [VK_SHADER_STAGE_TESS_EVALUATION
] = 45, /* DS */
2611 [VK_SHADER_STAGE_GEOMETRY
] = 46,
2612 [VK_SHADER_STAGE_FRAGMENT
] = 47,
2613 [VK_SHADER_STAGE_COMPUTE
] = 0,
2616 anv_batch_emit(&cmd_buffer
->batch
,
2617 GEN8_3DSTATE_SAMPLER_STATE_POINTERS_VS
,
2618 ._3DCommandSubOpcode
= sampler_state_opcodes
[s
],
2619 .PointertoVSSamplerState
= state
.offset
);
2625 anv_cmd_buffer_flush_state(struct anv_cmd_buffer
*cmd_buffer
)
2627 struct anv_pipeline
*pipeline
= cmd_buffer
->pipeline
;
2628 struct anv_bindings
*bindings
= cmd_buffer
->bindings
;
2629 const uint32_t num_buffers
= __builtin_popcount(cmd_buffer
->vb_dirty
);
2630 const uint32_t num_dwords
= 1 + num_buffers
* 4;
2633 if (cmd_buffer
->vb_dirty
) {
2634 p
= anv_batch_emitn(&cmd_buffer
->batch
, num_dwords
,
2635 GEN8_3DSTATE_VERTEX_BUFFERS
);
2637 for_each_bit(vb
, cmd_buffer
->vb_dirty
) {
2638 struct anv_buffer
*buffer
= bindings
->vb
[vb
].buffer
;
2639 uint32_t offset
= bindings
->vb
[vb
].offset
;
2641 struct GEN8_VERTEX_BUFFER_STATE state
= {
2642 .VertexBufferIndex
= vb
,
2643 .MemoryObjectControlState
= 0,
2644 .AddressModifyEnable
= true,
2645 .BufferPitch
= pipeline
->binding_stride
[vb
],
2646 .BufferStartingAddress
= { buffer
->bo
, buffer
->offset
+ offset
},
2647 .BufferSize
= buffer
->size
- offset
2650 GEN8_VERTEX_BUFFER_STATE_pack(&cmd_buffer
->batch
, &p
[1 + i
* 4], &state
);
2655 if (cmd_buffer
->dirty
& ANV_CMD_BUFFER_PIPELINE_DIRTY
)
2656 anv_batch_emit_batch(&cmd_buffer
->batch
, &pipeline
->batch
);
2658 if (cmd_buffer
->dirty
& ANV_CMD_BUFFER_DESCRIPTOR_SET_DIRTY
)
2659 flush_descriptor_sets(cmd_buffer
);
2661 if (cmd_buffer
->dirty
& (ANV_CMD_BUFFER_PIPELINE_DIRTY
| ANV_CMD_BUFFER_RS_DIRTY
))
2662 anv_batch_emit_merge(&cmd_buffer
->batch
,
2663 cmd_buffer
->rs_state
->state_sf
, pipeline
->state_sf
);
2665 cmd_buffer
->vb_dirty
= 0;
2666 cmd_buffer
->dirty
= 0;
2670 VkCmdBuffer cmdBuffer
,
2671 uint32_t firstVertex
,
2672 uint32_t vertexCount
,
2673 uint32_t firstInstance
,
2674 uint32_t instanceCount
)
2676 struct anv_cmd_buffer
*cmd_buffer
= (struct anv_cmd_buffer
*) cmdBuffer
;
2678 anv_cmd_buffer_flush_state(cmd_buffer
);
2680 anv_batch_emit(&cmd_buffer
->batch
, GEN8_3DPRIMITIVE
,
2681 .VertexAccessType
= SEQUENTIAL
,
2682 .VertexCountPerInstance
= vertexCount
,
2683 .StartVertexLocation
= firstVertex
,
2684 .InstanceCount
= instanceCount
,
2685 .StartInstanceLocation
= firstInstance
,
2686 .BaseVertexLocation
= 0);
2689 void anv_CmdDrawIndexed(
2690 VkCmdBuffer cmdBuffer
,
2691 uint32_t firstIndex
,
2692 uint32_t indexCount
,
2693 int32_t vertexOffset
,
2694 uint32_t firstInstance
,
2695 uint32_t instanceCount
)
2697 struct anv_cmd_buffer
*cmd_buffer
= (struct anv_cmd_buffer
*) cmdBuffer
;
2699 anv_cmd_buffer_flush_state(cmd_buffer
);
2701 anv_batch_emit(&cmd_buffer
->batch
, GEN8_3DPRIMITIVE
,
2702 .VertexAccessType
= RANDOM
,
2703 .VertexCountPerInstance
= indexCount
,
2704 .StartVertexLocation
= firstIndex
,
2705 .InstanceCount
= instanceCount
,
2706 .StartInstanceLocation
= firstInstance
,
2707 .BaseVertexLocation
= 0);
2711 anv_batch_lrm(struct anv_batch
*batch
,
2712 uint32_t reg
, struct anv_bo
*bo
, uint32_t offset
)
2714 anv_batch_emit(batch
, GEN8_MI_LOAD_REGISTER_MEM
,
2715 .RegisterAddress
= reg
,
2716 .MemoryAddress
= { bo
, offset
});
2720 anv_batch_lri(struct anv_batch
*batch
, uint32_t reg
, uint32_t imm
)
2722 anv_batch_emit(batch
, GEN8_MI_LOAD_REGISTER_IMM
,
2723 .RegisterOffset
= reg
,
2727 /* Auto-Draw / Indirect Registers */
2728 #define GEN7_3DPRIM_END_OFFSET 0x2420
2729 #define GEN7_3DPRIM_START_VERTEX 0x2430
2730 #define GEN7_3DPRIM_VERTEX_COUNT 0x2434
2731 #define GEN7_3DPRIM_INSTANCE_COUNT 0x2438
2732 #define GEN7_3DPRIM_START_INSTANCE 0x243C
2733 #define GEN7_3DPRIM_BASE_VERTEX 0x2440
2735 void anv_CmdDrawIndirect(
2736 VkCmdBuffer cmdBuffer
,
2738 VkDeviceSize offset
,
2742 struct anv_cmd_buffer
*cmd_buffer
= (struct anv_cmd_buffer
*) cmdBuffer
;
2743 struct anv_buffer
*buffer
= (struct anv_buffer
*) _buffer
;
2744 struct anv_bo
*bo
= buffer
->bo
;
2745 uint32_t bo_offset
= buffer
->offset
+ offset
;
2747 anv_cmd_buffer_flush_state(cmd_buffer
);
2749 anv_batch_lrm(&cmd_buffer
->batch
, GEN7_3DPRIM_VERTEX_COUNT
, bo
, bo_offset
);
2750 anv_batch_lrm(&cmd_buffer
->batch
, GEN7_3DPRIM_INSTANCE_COUNT
, bo
, bo_offset
+ 4);
2751 anv_batch_lrm(&cmd_buffer
->batch
, GEN7_3DPRIM_START_VERTEX
, bo
, bo_offset
+ 8);
2752 anv_batch_lrm(&cmd_buffer
->batch
, GEN7_3DPRIM_START_INSTANCE
, bo
, bo_offset
+ 12);
2753 anv_batch_lri(&cmd_buffer
->batch
, GEN7_3DPRIM_BASE_VERTEX
, 0);
2755 anv_batch_emit(&cmd_buffer
->batch
, GEN8_3DPRIMITIVE
,
2756 .IndirectParameterEnable
= true,
2757 .VertexAccessType
= SEQUENTIAL
);
2760 void anv_CmdDrawIndexedIndirect(
2761 VkCmdBuffer cmdBuffer
,
2763 VkDeviceSize offset
,
2767 struct anv_cmd_buffer
*cmd_buffer
= (struct anv_cmd_buffer
*) cmdBuffer
;
2768 struct anv_buffer
*buffer
= (struct anv_buffer
*) _buffer
;
2769 struct anv_bo
*bo
= buffer
->bo
;
2770 uint32_t bo_offset
= buffer
->offset
+ offset
;
2772 anv_cmd_buffer_flush_state(cmd_buffer
);
2774 anv_batch_lrm(&cmd_buffer
->batch
, GEN7_3DPRIM_VERTEX_COUNT
, bo
, bo_offset
);
2775 anv_batch_lrm(&cmd_buffer
->batch
, GEN7_3DPRIM_INSTANCE_COUNT
, bo
, bo_offset
+ 4);
2776 anv_batch_lrm(&cmd_buffer
->batch
, GEN7_3DPRIM_START_VERTEX
, bo
, bo_offset
+ 8);
2777 anv_batch_lrm(&cmd_buffer
->batch
, GEN7_3DPRIM_BASE_VERTEX
, bo
, bo_offset
+ 12);
2778 anv_batch_lrm(&cmd_buffer
->batch
, GEN7_3DPRIM_START_INSTANCE
, bo
, bo_offset
+ 16);
2780 anv_batch_emit(&cmd_buffer
->batch
, GEN8_3DPRIMITIVE
,
2781 .IndirectParameterEnable
= true,
2782 .VertexAccessType
= RANDOM
);
2785 void anv_CmdDispatch(
2786 VkCmdBuffer cmdBuffer
,
2794 void anv_CmdDispatchIndirect(
2795 VkCmdBuffer cmdBuffer
,
2797 VkDeviceSize offset
)
2802 void anv_CmdSetEvent(
2803 VkCmdBuffer cmdBuffer
,
2805 VkPipeEvent pipeEvent
)
2810 void anv_CmdResetEvent(
2811 VkCmdBuffer cmdBuffer
,
2813 VkPipeEvent pipeEvent
)
2818 void anv_CmdWaitEvents(
2819 VkCmdBuffer cmdBuffer
,
2820 VkWaitEvent waitEvent
,
2821 uint32_t eventCount
,
2822 const VkEvent
* pEvents
,
2823 uint32_t memBarrierCount
,
2824 const void** ppMemBarriers
)
2829 void anv_CmdPipelineBarrier(
2830 VkCmdBuffer cmdBuffer
,
2831 VkWaitEvent waitEvent
,
2832 uint32_t pipeEventCount
,
2833 const VkPipeEvent
* pPipeEvents
,
2834 uint32_t memBarrierCount
,
2835 const void** ppMemBarriers
)
2841 anv_batch_emit_ps_depth_count(struct anv_batch
*batch
,
2842 struct anv_bo
*bo
, uint32_t offset
)
2844 anv_batch_emit(batch
, GEN8_PIPE_CONTROL
,
2845 .DestinationAddressType
= DAT_PPGTT
,
2846 .PostSyncOperation
= WritePSDepthCount
,
2847 .Address
= { bo
, offset
}); /* FIXME: This is only lower 32 bits */
2850 void anv_CmdBeginQuery(
2851 VkCmdBuffer cmdBuffer
,
2852 VkQueryPool queryPool
,
2854 VkQueryControlFlags flags
)
2856 struct anv_cmd_buffer
*cmd_buffer
= (struct anv_cmd_buffer
*) cmdBuffer
;
2857 struct anv_query_pool
*pool
= (struct anv_query_pool
*) queryPool
;
2859 switch (pool
->type
) {
2860 case VK_QUERY_TYPE_OCCLUSION
:
2861 anv_batch_emit_ps_depth_count(&cmd_buffer
->batch
, &pool
->bo
,
2862 slot
* sizeof(struct anv_query_pool_slot
));
2865 case VK_QUERY_TYPE_PIPELINE_STATISTICS
:
2871 void anv_CmdEndQuery(
2872 VkCmdBuffer cmdBuffer
,
2873 VkQueryPool queryPool
,
2876 struct anv_cmd_buffer
*cmd_buffer
= (struct anv_cmd_buffer
*) cmdBuffer
;
2877 struct anv_query_pool
*pool
= (struct anv_query_pool
*) queryPool
;
2879 switch (pool
->type
) {
2880 case VK_QUERY_TYPE_OCCLUSION
:
2881 anv_batch_emit_ps_depth_count(&cmd_buffer
->batch
, &pool
->bo
,
2882 slot
* sizeof(struct anv_query_pool_slot
) + 8);
2885 case VK_QUERY_TYPE_PIPELINE_STATISTICS
:
2891 void anv_CmdResetQueryPool(
2892 VkCmdBuffer cmdBuffer
,
2893 VkQueryPool queryPool
,
2894 uint32_t startQuery
,
2895 uint32_t queryCount
)
2900 #define TIMESTAMP 0x2358
2902 void anv_CmdWriteTimestamp(
2903 VkCmdBuffer cmdBuffer
,
2904 VkTimestampType timestampType
,
2905 VkBuffer destBuffer
,
2906 VkDeviceSize destOffset
)
2908 struct anv_cmd_buffer
*cmd_buffer
= (struct anv_cmd_buffer
*) cmdBuffer
;
2909 struct anv_buffer
*buffer
= (struct anv_buffer
*) destBuffer
;
2910 struct anv_bo
*bo
= buffer
->bo
;
2912 switch (timestampType
) {
2913 case VK_TIMESTAMP_TYPE_TOP
:
2914 anv_batch_emit(&cmd_buffer
->batch
, GEN8_MI_STORE_REGISTER_MEM
,
2915 .RegisterAddress
= TIMESTAMP
,
2916 .MemoryAddress
= { bo
, buffer
->offset
+ destOffset
});
2917 anv_batch_emit(&cmd_buffer
->batch
, GEN8_MI_STORE_REGISTER_MEM
,
2918 .RegisterAddress
= TIMESTAMP
+ 4,
2919 .MemoryAddress
= { bo
, buffer
->offset
+ destOffset
+ 4 });
2922 case VK_TIMESTAMP_TYPE_BOTTOM
:
2923 anv_batch_emit(&cmd_buffer
->batch
, GEN8_PIPE_CONTROL
,
2924 .DestinationAddressType
= DAT_PPGTT
,
2925 .PostSyncOperation
= WriteTimestamp
,
2926 .Address
= /* FIXME: This is only lower 32 bits */
2927 { bo
, buffer
->offset
+ destOffset
});
2935 #define alu_opcode(v) __gen_field((v), 20, 31)
2936 #define alu_operand1(v) __gen_field((v), 10, 19)
2937 #define alu_operand2(v) __gen_field((v), 0, 9)
2938 #define alu(opcode, operand1, operand2) \
2939 alu_opcode(opcode) | alu_operand1(operand1) | alu_operand2(operand2)
2941 #define OPCODE_NOOP 0x000
2942 #define OPCODE_LOAD 0x080
2943 #define OPCODE_LOADINV 0x480
2944 #define OPCODE_LOAD0 0x081
2945 #define OPCODE_LOAD1 0x481
2946 #define OPCODE_ADD 0x100
2947 #define OPCODE_SUB 0x101
2948 #define OPCODE_AND 0x102
2949 #define OPCODE_OR 0x103
2950 #define OPCODE_XOR 0x104
2951 #define OPCODE_STORE 0x180
2952 #define OPCODE_STOREINV 0x580
2954 #define OPERAND_R0 0x00
2955 #define OPERAND_R1 0x01
2956 #define OPERAND_R2 0x02
2957 #define OPERAND_R3 0x03
2958 #define OPERAND_R4 0x04
2959 #define OPERAND_SRCA 0x20
2960 #define OPERAND_SRCB 0x21
2961 #define OPERAND_ACCU 0x31
2962 #define OPERAND_ZF 0x32
2963 #define OPERAND_CF 0x33
2965 #define CS_GPR(n) (0x2600 + (n) * 8)
2968 emit_load_alu_reg_u64(struct anv_batch
*batch
, uint32_t reg
,
2969 struct anv_bo
*bo
, uint32_t offset
)
2971 anv_batch_emit(batch
, GEN8_MI_LOAD_REGISTER_MEM
,
2972 .RegisterAddress
= reg
,
2973 .MemoryAddress
= { bo
, offset
});
2974 anv_batch_emit(batch
, GEN8_MI_LOAD_REGISTER_MEM
,
2975 .RegisterAddress
= reg
+ 4,
2976 .MemoryAddress
= { bo
, offset
+ 4 });
2979 void anv_CmdCopyQueryPoolResults(
2980 VkCmdBuffer cmdBuffer
,
2981 VkQueryPool queryPool
,
2982 uint32_t startQuery
,
2983 uint32_t queryCount
,
2984 VkBuffer destBuffer
,
2985 VkDeviceSize destOffset
,
2986 VkDeviceSize destStride
,
2987 VkQueryResultFlags flags
)
2989 struct anv_cmd_buffer
*cmd_buffer
= (struct anv_cmd_buffer
*) cmdBuffer
;
2990 struct anv_query_pool
*pool
= (struct anv_query_pool
*) queryPool
;
2991 struct anv_buffer
*buffer
= (struct anv_buffer
*) destBuffer
;
2992 uint32_t slot_offset
, dst_offset
;
2994 if (flags
& VK_QUERY_RESULT_WITH_AVAILABILITY_BIT
) {
2995 /* Where is the availabilty info supposed to go? */
2996 anv_finishme("VK_QUERY_RESULT_WITH_AVAILABILITY_BIT");
3000 assert(pool
->type
== VK_QUERY_TYPE_OCCLUSION
);
3002 /* FIXME: If we're not waiting, should we just do this on the CPU? */
3003 if (flags
& VK_QUERY_RESULT_WAIT_BIT
)
3004 anv_batch_emit(&cmd_buffer
->batch
, GEN8_PIPE_CONTROL
,
3005 .CommandStreamerStallEnable
= true);
3007 dst_offset
= buffer
->offset
+ destOffset
;
3008 for (uint32_t i
= 0; i
< queryCount
; i
++) {
3010 slot_offset
= (startQuery
+ i
) * sizeof(struct anv_query_pool_slot
);
3012 emit_load_alu_reg_u64(&cmd_buffer
->batch
, CS_GPR(0), &pool
->bo
, slot_offset
);
3013 emit_load_alu_reg_u64(&cmd_buffer
->batch
, CS_GPR(1), &pool
->bo
, slot_offset
+ 8);
3015 /* FIXME: We need to clamp the result for 32 bit. */
3017 uint32_t *dw
= anv_batch_emitn(&cmd_buffer
->batch
, 5, GEN8_MI_MATH
);
3018 dw
[1] = alu(OPCODE_LOAD
, OPERAND_SRCA
, OPERAND_R1
);
3019 dw
[2] = alu(OPCODE_LOAD
, OPERAND_SRCB
, OPERAND_R0
);
3020 dw
[3] = alu(OPCODE_SUB
, 0, 0);
3021 dw
[4] = alu(OPCODE_STORE
, OPERAND_R2
, OPERAND_ACCU
);
3023 anv_batch_emit(&cmd_buffer
->batch
, GEN8_MI_STORE_REGISTER_MEM
,
3024 .RegisterAddress
= CS_GPR(2),
3025 /* FIXME: This is only lower 32 bits */
3026 .MemoryAddress
= { buffer
->bo
, dst_offset
});
3028 if (flags
& VK_QUERY_RESULT_64_BIT
)
3029 anv_batch_emit(&cmd_buffer
->batch
, GEN8_MI_STORE_REGISTER_MEM
,
3030 .RegisterAddress
= CS_GPR(2) + 4,
3031 /* FIXME: This is only lower 32 bits */
3032 .MemoryAddress
= { buffer
->bo
, dst_offset
+ 4 });
3034 dst_offset
+= destStride
;
3038 void anv_CmdInitAtomicCounters(
3039 VkCmdBuffer cmdBuffer
,
3040 VkPipelineBindPoint pipelineBindPoint
,
3041 uint32_t startCounter
,
3042 uint32_t counterCount
,
3043 const uint32_t* pData
)
3048 void anv_CmdLoadAtomicCounters(
3049 VkCmdBuffer cmdBuffer
,
3050 VkPipelineBindPoint pipelineBindPoint
,
3051 uint32_t startCounter
,
3052 uint32_t counterCount
,
3054 VkDeviceSize srcOffset
)
3059 void anv_CmdSaveAtomicCounters(
3060 VkCmdBuffer cmdBuffer
,
3061 VkPipelineBindPoint pipelineBindPoint
,
3062 uint32_t startCounter
,
3063 uint32_t counterCount
,
3064 VkBuffer destBuffer
,
3065 VkDeviceSize destOffset
)
3070 VkResult
anv_CreateFramebuffer(
3072 const VkFramebufferCreateInfo
* pCreateInfo
,
3073 VkFramebuffer
* pFramebuffer
)
3075 struct anv_device
*device
= (struct anv_device
*) _device
;
3076 struct anv_framebuffer
*framebuffer
;
3078 assert(pCreateInfo
->sType
== VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO
);
3080 framebuffer
= anv_device_alloc(device
, sizeof(*framebuffer
), 8,
3081 VK_SYSTEM_ALLOC_TYPE_API_OBJECT
);
3082 if (framebuffer
== NULL
)
3083 return vk_error(VK_ERROR_OUT_OF_HOST_MEMORY
);
3085 framebuffer
->color_attachment_count
= pCreateInfo
->colorAttachmentCount
;
3086 for (uint32_t i
= 0; i
< pCreateInfo
->colorAttachmentCount
; i
++) {
3087 framebuffer
->color_attachments
[i
] =
3088 (struct anv_surface_view
*) pCreateInfo
->pColorAttachments
[i
].view
;
3091 if (pCreateInfo
->pDepthStencilAttachment
) {
3092 framebuffer
->depth_stencil
=
3093 (struct anv_depth_stencil_view
*) pCreateInfo
->pDepthStencilAttachment
->view
;
3096 framebuffer
->sample_count
= pCreateInfo
->sampleCount
;
3097 framebuffer
->width
= pCreateInfo
->width
;
3098 framebuffer
->height
= pCreateInfo
->height
;
3099 framebuffer
->layers
= pCreateInfo
->layers
;
3101 vkCreateDynamicViewportState((VkDevice
) device
,
3102 &(VkDynamicVpStateCreateInfo
) {
3103 .sType
= VK_STRUCTURE_TYPE_DYNAMIC_VP_STATE_CREATE_INFO
,
3104 .viewportAndScissorCount
= 2,
3105 .pViewports
= (VkViewport
[]) {
3109 .width
= pCreateInfo
->width
,
3110 .height
= pCreateInfo
->height
,
3115 .pScissors
= (VkRect
[]) {
3117 { pCreateInfo
->width
, pCreateInfo
->height
} },
3120 &framebuffer
->vp_state
);
3122 *pFramebuffer
= (VkFramebuffer
) framebuffer
;
3127 VkResult
anv_CreateRenderPass(
3129 const VkRenderPassCreateInfo
* pCreateInfo
,
3130 VkRenderPass
* pRenderPass
)
3132 struct anv_device
*device
= (struct anv_device
*) _device
;
3133 struct anv_render_pass
*pass
;
3136 assert(pCreateInfo
->sType
== VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO
);
3138 size
= sizeof(*pass
) +
3139 pCreateInfo
->layers
* sizeof(struct anv_render_pass_layer
);
3140 pass
= anv_device_alloc(device
, size
, 8,
3141 VK_SYSTEM_ALLOC_TYPE_API_OBJECT
);
3143 return vk_error(VK_ERROR_OUT_OF_HOST_MEMORY
);
3145 pass
->render_area
= pCreateInfo
->renderArea
;
3147 pass
->num_layers
= pCreateInfo
->layers
;
3149 pass
->num_clear_layers
= 0;
3150 for (uint32_t i
= 0; i
< pCreateInfo
->layers
; i
++) {
3151 pass
->layers
[i
].color_load_op
= pCreateInfo
->pColorLoadOps
[i
];
3152 pass
->layers
[i
].clear_color
= pCreateInfo
->pColorLoadClearValues
[i
];
3153 if (pass
->layers
[i
].color_load_op
== VK_ATTACHMENT_LOAD_OP_CLEAR
)
3154 pass
->num_clear_layers
++;
3157 *pRenderPass
= (VkRenderPass
) pass
;
3163 anv_cmd_buffer_fill_render_targets(struct anv_cmd_buffer
*cmd_buffer
)
3165 struct anv_framebuffer
*framebuffer
= cmd_buffer
->framebuffer
;
3166 struct anv_bindings
*bindings
= cmd_buffer
->bindings
;
3168 for (uint32_t i
= 0; i
< framebuffer
->color_attachment_count
; i
++) {
3169 struct anv_surface_view
*view
= framebuffer
->color_attachments
[i
];
3171 struct anv_state state
=
3172 anv_cmd_buffer_alloc_surface_state(cmd_buffer
, 64, 64);
3173 memcpy(state
.map
, view
->surface_state
.map
, 64);
3175 bindings
->descriptors
[VK_SHADER_STAGE_FRAGMENT
].surfaces
[i
] = state
.offset
;
3176 bindings
->descriptors
[VK_SHADER_STAGE_FRAGMENT
].relocs
[i
].bo
= view
->bo
;
3177 bindings
->descriptors
[VK_SHADER_STAGE_FRAGMENT
].relocs
[i
].offset
= view
->offset
;
3179 cmd_buffer
->dirty
|= ANV_CMD_BUFFER_DESCRIPTOR_SET_DIRTY
;
3182 void anv_CmdBeginRenderPass(
3183 VkCmdBuffer cmdBuffer
,
3184 const VkRenderPassBegin
* pRenderPassBegin
)
3186 struct anv_cmd_buffer
*cmd_buffer
= (struct anv_cmd_buffer
*) cmdBuffer
;
3187 struct anv_render_pass
*pass
= (struct anv_render_pass
*) pRenderPassBegin
->renderPass
;
3188 struct anv_framebuffer
*framebuffer
=
3189 (struct anv_framebuffer
*) pRenderPassBegin
->framebuffer
;
3191 cmd_buffer
->framebuffer
= framebuffer
;
3193 anv_batch_emit(&cmd_buffer
->batch
, GEN8_3DSTATE_DRAWING_RECTANGLE
,
3194 .ClippedDrawingRectangleYMin
= pass
->render_area
.offset
.y
,
3195 .ClippedDrawingRectangleXMin
= pass
->render_area
.offset
.x
,
3196 .ClippedDrawingRectangleYMax
=
3197 pass
->render_area
.offset
.y
+ pass
->render_area
.extent
.height
- 1,
3198 .ClippedDrawingRectangleXMax
=
3199 pass
->render_area
.offset
.x
+ pass
->render_area
.extent
.width
- 1,
3200 .DrawingRectangleOriginY
= 0,
3201 .DrawingRectangleOriginX
= 0);
3203 anv_cmd_buffer_fill_render_targets(cmd_buffer
);
3205 anv_cmd_buffer_clear(cmd_buffer
, pass
);
3208 void anv_CmdEndRenderPass(
3209 VkCmdBuffer cmdBuffer
,
3210 VkRenderPass renderPass
)
3212 /* Emit a flushing pipe control at the end of a pass. This is kind of a
3213 * hack but it ensures that render targets always actually get written.
3214 * Eventually, we should do flushing based on image format transitions
3215 * or something of that nature.
3217 struct anv_cmd_buffer
*cmd_buffer
= (struct anv_cmd_buffer
*)cmdBuffer
;
3218 anv_batch_emit(&cmd_buffer
->batch
, GEN8_PIPE_CONTROL
,
3219 .PostSyncOperation
= NoWrite
,
3220 .RenderTargetCacheFlushEnable
= true,
3221 .InstructionCacheInvalidateEnable
= true,
3222 .DepthCacheFlushEnable
= true,
3223 .VFCacheInvalidationEnable
= true,
3224 .TextureCacheInvalidationEnable
= true,
3225 .CommandStreamerStallEnable
= true);
3228 void vkCmdDbgMarkerBegin(
3229 VkCmdBuffer cmdBuffer
,
3230 const char* pMarker
)
3231 __attribute__ ((visibility ("default")));
3233 void vkCmdDbgMarkerEnd(
3234 VkCmdBuffer cmdBuffer
)
3235 __attribute__ ((visibility ("default")));
3237 VkResult
vkDbgSetObjectTag(
3242 __attribute__ ((visibility ("default")));
3245 void vkCmdDbgMarkerBegin(
3246 VkCmdBuffer cmdBuffer
,
3247 const char* pMarker
)
3251 void vkCmdDbgMarkerEnd(
3252 VkCmdBuffer cmdBuffer
)
3256 VkResult
vkDbgSetObjectTag(