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;
307 anv_device_init_border_colors(struct anv_device
*device
)
309 float float_border_colors
[][4] = {
310 [VK_BORDER_COLOR_OPAQUE_WHITE
] = { 1.0, 1.0, 1.0, 1.0 },
311 [VK_BORDER_COLOR_TRANSPARENT_BLACK
] = { 0.0, 0.0, 0.0, 0.0 },
312 [VK_BORDER_COLOR_OPAQUE_BLACK
] = { 0.0, 0.0, 0.0, 1.0 }
315 uint32_t uint32_border_colors
[][4] = {
316 [VK_BORDER_COLOR_OPAQUE_WHITE
] = { 1, 1, 1, 1 },
317 [VK_BORDER_COLOR_TRANSPARENT_BLACK
] = { 0, 0, 0, 0 },
318 [VK_BORDER_COLOR_OPAQUE_BLACK
] = { 0, 0, 0, 1 }
321 device
->float_border_colors
=
322 anv_state_pool_alloc(&device
->dynamic_state_pool
,
323 sizeof(float_border_colors
), 32);
324 memcpy(device
->float_border_colors
.map
,
325 float_border_colors
, sizeof(float_border_colors
));
327 device
->uint32_border_colors
=
328 anv_state_pool_alloc(&device
->dynamic_state_pool
,
329 sizeof(uint32_border_colors
), 32);
330 memcpy(device
->uint32_border_colors
.map
,
331 uint32_border_colors
, sizeof(uint32_border_colors
));
335 static const uint32_t BATCH_SIZE
= 8192;
337 VkResult
anv_CreateDevice(
338 VkPhysicalDevice _physicalDevice
,
339 const VkDeviceCreateInfo
* pCreateInfo
,
342 struct anv_physical_device
*physicalDevice
=
343 (struct anv_physical_device
*) _physicalDevice
;
344 struct anv_instance
*instance
= physicalDevice
->instance
;
345 struct anv_device
*device
;
347 assert(pCreateInfo
->sType
== VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO
);
349 device
= instance
->pfnAlloc(instance
->pAllocUserData
,
351 VK_SYSTEM_ALLOC_TYPE_API_OBJECT
);
353 return vk_error(VK_ERROR_OUT_OF_HOST_MEMORY
);
355 device
->no_hw
= physicalDevice
->no_hw
;
356 parse_debug_flags(device
);
358 device
->instance
= physicalDevice
->instance
;
359 device
->fd
= open("/dev/dri/renderD128", O_RDWR
| O_CLOEXEC
);
360 if (device
->fd
== -1)
363 device
->context_id
= anv_gem_create_context(device
);
364 if (device
->context_id
== -1)
367 anv_bo_pool_init(&device
->batch_bo_pool
, device
, BATCH_SIZE
);
369 anv_block_pool_init(&device
->dynamic_state_block_pool
, device
, 2048);
371 anv_state_pool_init(&device
->dynamic_state_pool
,
372 &device
->dynamic_state_block_pool
);
374 anv_block_pool_init(&device
->instruction_block_pool
, device
, 2048);
375 anv_block_pool_init(&device
->surface_state_block_pool
, device
, 2048);
377 anv_state_pool_init(&device
->surface_state_pool
,
378 &device
->surface_state_block_pool
);
380 device
->info
= *physicalDevice
->info
;
382 device
->compiler
= anv_compiler_create(device
);
383 device
->aub_writer
= NULL
;
385 pthread_mutex_init(&device
->mutex
, NULL
);
387 anv_device_init_meta(device
);
389 anv_device_init_border_colors(device
);
391 *pDevice
= (VkDevice
) device
;
398 anv_device_free(device
, device
);
400 return vk_error(VK_ERROR_UNAVAILABLE
);
403 VkResult
anv_DestroyDevice(
406 struct anv_device
*device
= (struct anv_device
*) _device
;
408 /* FIXME: We should make device destruction actually safe. */
409 return VK_UNSUPPORTED
;
411 anv_compiler_destroy(device
->compiler
);
414 anv_bo_pool_finish(&device
->batch_bo_pool
);
415 anv_block_pool_finish(&device
->dynamic_state_block_pool
);
416 anv_block_pool_finish(&device
->instruction_block_pool
);
417 anv_block_pool_finish(&device
->surface_state_block_pool
);
421 if (device
->aub_writer
)
422 anv_aub_writer_destroy(device
->aub_writer
);
424 anv_device_free(device
, device
);
429 VkResult
anv_GetGlobalExtensionInfo(
430 VkExtensionInfoType infoType
,
431 uint32_t extensionIndex
,
435 static const VkExtensionProperties extensions
[] = {
437 .extName
= "VK_WSI_LunarG",
441 uint32_t count
= ARRAY_SIZE(extensions
);
444 case VK_EXTENSION_INFO_TYPE_COUNT
:
445 memcpy(pData
, &count
, sizeof(count
));
446 *pDataSize
= sizeof(count
);
449 case VK_EXTENSION_INFO_TYPE_PROPERTIES
:
450 if (extensionIndex
>= count
)
451 return vk_error(VK_ERROR_INVALID_EXTENSION
);
453 memcpy(pData
, &extensions
[extensionIndex
], sizeof(extensions
[0]));
454 *pDataSize
= sizeof(extensions
[0]);
458 return VK_UNSUPPORTED
;
462 VkResult
anv_GetPhysicalDeviceExtensionInfo(
463 VkPhysicalDevice physicalDevice
,
464 VkExtensionInfoType infoType
,
465 uint32_t extensionIndex
,
472 case VK_EXTENSION_INFO_TYPE_COUNT
:
481 case VK_EXTENSION_INFO_TYPE_PROPERTIES
:
482 return vk_error(VK_ERROR_INVALID_EXTENSION
);
485 return VK_UNSUPPORTED
;
489 VkResult
anv_EnumerateLayers(
490 VkPhysicalDevice physicalDevice
,
491 size_t maxStringSize
,
493 char* const* pOutLayers
,
501 VkResult
anv_GetDeviceQueue(
503 uint32_t queueNodeIndex
,
507 struct anv_device
*device
= (struct anv_device
*) _device
;
508 struct anv_queue
*queue
;
510 /* FIXME: Should allocate these at device create time. */
512 queue
= anv_device_alloc(device
, sizeof(*queue
), 8,
513 VK_SYSTEM_ALLOC_TYPE_API_OBJECT
);
515 return vk_error(VK_ERROR_OUT_OF_HOST_MEMORY
);
517 queue
->device
= device
;
518 queue
->pool
= &device
->surface_state_pool
;
520 queue
->completed_serial
= anv_state_pool_alloc(queue
->pool
, 4, 4);
521 *(uint32_t *)queue
->completed_serial
.map
= 0;
522 queue
->next_serial
= 1;
524 *pQueue
= (VkQueue
) queue
;
530 anv_reloc_list_init(struct anv_reloc_list
*list
, struct anv_device
*device
)
532 list
->num_relocs
= 0;
533 list
->array_length
= 256;
535 anv_device_alloc(device
, list
->array_length
* sizeof(*list
->relocs
), 8,
536 VK_SYSTEM_ALLOC_TYPE_INTERNAL
);
538 if (list
->relocs
== NULL
)
539 return vk_error(VK_ERROR_OUT_OF_HOST_MEMORY
);
542 anv_device_alloc(device
, list
->array_length
* sizeof(*list
->reloc_bos
), 8,
543 VK_SYSTEM_ALLOC_TYPE_INTERNAL
);
545 if (list
->relocs
== NULL
) {
546 anv_device_free(device
, list
->relocs
);
547 return vk_error(VK_ERROR_OUT_OF_HOST_MEMORY
);
554 anv_reloc_list_finish(struct anv_reloc_list
*list
, struct anv_device
*device
)
556 anv_device_free(device
, list
->relocs
);
557 anv_device_free(device
, list
->reloc_bos
);
561 anv_reloc_list_grow(struct anv_reloc_list
*list
, struct anv_device
*device
,
562 size_t num_additional_relocs
)
564 if (list
->num_relocs
+ num_additional_relocs
<= list
->array_length
)
567 size_t new_length
= list
->array_length
* 2;
568 while (new_length
< list
->num_relocs
+ num_additional_relocs
)
571 struct drm_i915_gem_relocation_entry
*new_relocs
=
572 anv_device_alloc(device
, new_length
* sizeof(*list
->relocs
), 8,
573 VK_SYSTEM_ALLOC_TYPE_INTERNAL
);
574 if (new_relocs
== NULL
)
575 return vk_error(VK_ERROR_OUT_OF_HOST_MEMORY
);
577 struct anv_bo
**new_reloc_bos
=
578 anv_device_alloc(device
, new_length
* sizeof(*list
->reloc_bos
), 8,
579 VK_SYSTEM_ALLOC_TYPE_INTERNAL
);
580 if (new_relocs
== NULL
) {
581 anv_device_free(device
, new_relocs
);
582 return vk_error(VK_ERROR_OUT_OF_HOST_MEMORY
);
585 memcpy(new_relocs
, list
->relocs
, list
->num_relocs
* sizeof(*list
->relocs
));
586 memcpy(new_reloc_bos
, list
->reloc_bos
,
587 list
->num_relocs
* sizeof(*list
->reloc_bos
));
589 anv_device_free(device
, list
->relocs
);
590 anv_device_free(device
, list
->reloc_bos
);
592 list
->relocs
= new_relocs
;
593 list
->reloc_bos
= new_reloc_bos
;
599 anv_batch_bo_create(struct anv_device
*device
, struct anv_batch_bo
**bbo_out
)
603 struct anv_batch_bo
*bbo
=
604 anv_device_alloc(device
, sizeof(*bbo
), 8, VK_SYSTEM_ALLOC_TYPE_INTERNAL
);
606 return vk_error(VK_ERROR_OUT_OF_HOST_MEMORY
);
609 bbo
->prev_batch_bo
= NULL
;
611 result
= anv_bo_pool_alloc(&device
->batch_bo_pool
, &bbo
->bo
);
612 if (result
!= VK_SUCCESS
) {
613 anv_device_free(device
, bbo
);
623 anv_batch_bo_start(struct anv_batch_bo
*bbo
, struct anv_batch
*batch
,
624 size_t batch_padding
)
626 batch
->next
= batch
->start
= bbo
->bo
.map
;
627 batch
->end
= bbo
->bo
.map
+ bbo
->bo
.size
- batch_padding
;
628 bbo
->first_reloc
= batch
->relocs
.num_relocs
;
632 anv_batch_bo_finish(struct anv_batch_bo
*bbo
, struct anv_batch
*batch
)
634 assert(batch
->start
== bbo
->bo
.map
);
635 bbo
->length
= batch
->next
- batch
->start
;
636 bbo
->num_relocs
= batch
->relocs
.num_relocs
- bbo
->first_reloc
;
640 anv_batch_bo_destroy(struct anv_batch_bo
*bbo
, struct anv_device
*device
)
642 anv_bo_pool_free(&device
->batch_bo_pool
, &bbo
->bo
);
643 anv_device_free(device
, bbo
);
647 anv_batch_emit_dwords(struct anv_batch
*batch
, int num_dwords
)
649 if (batch
->next
+ num_dwords
* 4 > batch
->end
)
650 batch
->extend_cb(batch
, batch
->user_data
);
652 void *p
= batch
->next
;
654 batch
->next
+= num_dwords
* 4;
655 assert(batch
->next
<= batch
->end
);
661 anv_reloc_list_append(struct anv_reloc_list
*list
, struct anv_device
*device
,
662 struct anv_reloc_list
*other
, uint32_t offset
)
664 anv_reloc_list_grow(list
, device
, other
->num_relocs
);
665 /* TODO: Handle failure */
667 memcpy(&list
->relocs
[list
->num_relocs
], &other
->relocs
[0],
668 other
->num_relocs
* sizeof(other
->relocs
[0]));
669 memcpy(&list
->reloc_bos
[list
->num_relocs
], &other
->reloc_bos
[0],
670 other
->num_relocs
* sizeof(other
->reloc_bos
[0]));
672 for (uint32_t i
= 0; i
< other
->num_relocs
; i
++)
673 list
->relocs
[i
+ list
->num_relocs
].offset
+= offset
;
675 list
->num_relocs
+= other
->num_relocs
;
679 anv_reloc_list_add(struct anv_reloc_list
*list
, struct anv_device
*device
,
680 uint32_t offset
, struct anv_bo
*target_bo
, uint32_t delta
)
682 struct drm_i915_gem_relocation_entry
*entry
;
685 anv_reloc_list_grow(list
, device
, 1);
686 /* TODO: Handle failure */
688 /* XXX: Can we use I915_EXEC_HANDLE_LUT? */
689 index
= list
->num_relocs
++;
690 list
->reloc_bos
[index
] = target_bo
;
691 entry
= &list
->relocs
[index
];
692 entry
->target_handle
= target_bo
->gem_handle
;
693 entry
->delta
= delta
;
694 entry
->offset
= offset
;
695 entry
->presumed_offset
= target_bo
->offset
;
696 entry
->read_domains
= 0;
697 entry
->write_domain
= 0;
699 return target_bo
->offset
+ delta
;
703 anv_batch_emit_batch(struct anv_batch
*batch
, struct anv_batch
*other
)
705 uint32_t size
, offset
;
707 size
= other
->next
- other
->start
;
708 assert(size
% 4 == 0);
710 if (batch
->next
+ size
> batch
->end
)
711 batch
->extend_cb(batch
, batch
->user_data
);
713 assert(batch
->next
+ size
<= batch
->end
);
715 memcpy(batch
->next
, other
->start
, size
);
717 offset
= batch
->next
- batch
->start
;
718 anv_reloc_list_append(&batch
->relocs
, batch
->device
,
719 &other
->relocs
, offset
);
725 anv_batch_emit_reloc(struct anv_batch
*batch
,
726 void *location
, struct anv_bo
*bo
, uint32_t delta
)
728 return anv_reloc_list_add(&batch
->relocs
, batch
->device
,
729 location
- batch
->start
, bo
, delta
);
732 VkResult
anv_QueueSubmit(
734 uint32_t cmdBufferCount
,
735 const VkCmdBuffer
* pCmdBuffers
,
738 struct anv_queue
*queue
= (struct anv_queue
*) _queue
;
739 struct anv_device
*device
= queue
->device
;
740 struct anv_fence
*fence
= (struct anv_fence
*) _fence
;
743 for (uint32_t i
= 0; i
< cmdBufferCount
; i
++) {
744 struct anv_cmd_buffer
*cmd_buffer
=
745 (struct anv_cmd_buffer
*) pCmdBuffers
[i
];
747 if (device
->dump_aub
)
748 anv_cmd_buffer_dump(cmd_buffer
);
750 if (!device
->no_hw
) {
751 ret
= anv_gem_execbuffer(device
, &cmd_buffer
->execbuf
);
753 return vk_error(VK_ERROR_UNKNOWN
);
756 ret
= anv_gem_execbuffer(device
, &fence
->execbuf
);
758 return vk_error(VK_ERROR_UNKNOWN
);
761 for (uint32_t i
= 0; i
< cmd_buffer
->bo_count
; i
++)
762 cmd_buffer
->exec2_bos
[i
]->offset
= cmd_buffer
->exec2_objects
[i
].offset
;
764 *(uint32_t *)queue
->completed_serial
.map
= cmd_buffer
->serial
;
771 VkResult
anv_QueueAddMemReferences(
774 const VkDeviceMemory
* pMems
)
779 VkResult
anv_QueueRemoveMemReferences(
782 const VkDeviceMemory
* pMems
)
787 VkResult
anv_QueueWaitIdle(
790 struct anv_queue
*queue
= (struct anv_queue
*) _queue
;
792 return vkDeviceWaitIdle((VkDevice
) queue
->device
);
795 VkResult
anv_DeviceWaitIdle(
798 struct anv_device
*device
= (struct anv_device
*) _device
;
799 struct anv_state state
;
800 struct anv_batch batch
;
801 struct drm_i915_gem_execbuffer2 execbuf
;
802 struct drm_i915_gem_exec_object2 exec2_objects
[1];
803 struct anv_bo
*bo
= NULL
;
808 state
= anv_state_pool_alloc(&device
->dynamic_state_pool
, 32, 32);
809 bo
= &device
->dynamic_state_pool
.block_pool
->bo
;
810 batch
.start
= batch
.next
= state
.map
;
811 batch
.end
= state
.map
+ 32;
812 anv_batch_emit(&batch
, GEN8_MI_BATCH_BUFFER_END
);
813 anv_batch_emit(&batch
, GEN8_MI_NOOP
);
815 exec2_objects
[0].handle
= bo
->gem_handle
;
816 exec2_objects
[0].relocation_count
= 0;
817 exec2_objects
[0].relocs_ptr
= 0;
818 exec2_objects
[0].alignment
= 0;
819 exec2_objects
[0].offset
= bo
->offset
;
820 exec2_objects
[0].flags
= 0;
821 exec2_objects
[0].rsvd1
= 0;
822 exec2_objects
[0].rsvd2
= 0;
824 execbuf
.buffers_ptr
= (uintptr_t) exec2_objects
;
825 execbuf
.buffer_count
= 1;
826 execbuf
.batch_start_offset
= state
.offset
;
827 execbuf
.batch_len
= batch
.next
- state
.map
;
828 execbuf
.cliprects_ptr
= 0;
829 execbuf
.num_cliprects
= 0;
834 I915_EXEC_HANDLE_LUT
| I915_EXEC_NO_RELOC
| I915_EXEC_RENDER
;
835 execbuf
.rsvd1
= device
->context_id
;
838 if (!device
->no_hw
) {
839 ret
= anv_gem_execbuffer(device
, &execbuf
);
841 result
= vk_error(VK_ERROR_UNKNOWN
);
846 ret
= anv_gem_wait(device
, bo
->gem_handle
, &timeout
);
848 result
= vk_error(VK_ERROR_UNKNOWN
);
853 anv_state_pool_free(&device
->dynamic_state_pool
, state
);
858 anv_state_pool_free(&device
->dynamic_state_pool
, state
);
864 anv_device_alloc(struct anv_device
* device
,
867 VkSystemAllocType allocType
)
869 return device
->instance
->pfnAlloc(device
->instance
->pAllocUserData
,
876 anv_device_free(struct anv_device
* device
,
879 return device
->instance
->pfnFree(device
->instance
->pAllocUserData
,
884 anv_bo_init_new(struct anv_bo
*bo
, struct anv_device
*device
, uint64_t size
)
886 bo
->gem_handle
= anv_gem_create(device
, size
);
888 return vk_error(VK_ERROR_OUT_OF_DEVICE_MEMORY
);
898 VkResult
anv_AllocMemory(
900 const VkMemoryAllocInfo
* pAllocInfo
,
901 VkDeviceMemory
* pMem
)
903 struct anv_device
*device
= (struct anv_device
*) _device
;
904 struct anv_device_memory
*mem
;
907 assert(pAllocInfo
->sType
== VK_STRUCTURE_TYPE_MEMORY_ALLOC_INFO
);
909 mem
= anv_device_alloc(device
, sizeof(*mem
), 8,
910 VK_SYSTEM_ALLOC_TYPE_API_OBJECT
);
912 return vk_error(VK_ERROR_OUT_OF_HOST_MEMORY
);
914 result
= anv_bo_init_new(&mem
->bo
, device
, pAllocInfo
->allocationSize
);
915 if (result
!= VK_SUCCESS
)
918 *pMem
= (VkDeviceMemory
) mem
;
923 anv_device_free(device
, mem
);
928 VkResult
anv_FreeMemory(
932 struct anv_device
*device
= (struct anv_device
*) _device
;
933 struct anv_device_memory
*mem
= (struct anv_device_memory
*) _mem
;
936 anv_gem_munmap(mem
->bo
.map
, mem
->bo
.size
);
938 if (mem
->bo
.gem_handle
!= 0)
939 anv_gem_close(device
, mem
->bo
.gem_handle
);
941 anv_device_free(device
, mem
);
946 VkResult
anv_SetMemoryPriority(
949 VkMemoryPriority priority
)
954 VkResult
anv_MapMemory(
959 VkMemoryMapFlags flags
,
962 struct anv_device
*device
= (struct anv_device
*) _device
;
963 struct anv_device_memory
*mem
= (struct anv_device_memory
*) _mem
;
965 /* FIXME: Is this supposed to be thread safe? Since vkUnmapMemory() only
966 * takes a VkDeviceMemory pointer, it seems like only one map of the memory
967 * at a time is valid. We could just mmap up front and return an offset
968 * pointer here, but that may exhaust virtual memory on 32 bit
971 mem
->map
= anv_gem_mmap(device
, mem
->bo
.gem_handle
, offset
, size
);
972 mem
->map_size
= size
;
979 VkResult
anv_UnmapMemory(
983 struct anv_device_memory
*mem
= (struct anv_device_memory
*) _mem
;
985 anv_gem_munmap(mem
->map
, mem
->map_size
);
990 VkResult
anv_FlushMappedMemory(
996 /* clflush here for !llc platforms */
1001 VkResult
anv_PinSystemMemory(
1003 const void* pSysMem
,
1005 VkDeviceMemory
* pMem
)
1010 VkResult
anv_GetMultiDeviceCompatibility(
1011 VkPhysicalDevice physicalDevice0
,
1012 VkPhysicalDevice physicalDevice1
,
1013 VkPhysicalDeviceCompatibilityInfo
* pInfo
)
1015 return VK_UNSUPPORTED
;
1018 VkResult
anv_OpenSharedMemory(
1020 const VkMemoryOpenInfo
* pOpenInfo
,
1021 VkDeviceMemory
* pMem
)
1023 return VK_UNSUPPORTED
;
1026 VkResult
anv_OpenSharedSemaphore(
1028 const VkSemaphoreOpenInfo
* pOpenInfo
,
1029 VkSemaphore
* pSemaphore
)
1031 return VK_UNSUPPORTED
;
1034 VkResult
anv_OpenPeerMemory(
1036 const VkPeerMemoryOpenInfo
* pOpenInfo
,
1037 VkDeviceMemory
* pMem
)
1039 return VK_UNSUPPORTED
;
1042 VkResult
anv_OpenPeerImage(
1044 const VkPeerImageOpenInfo
* pOpenInfo
,
1046 VkDeviceMemory
* pMem
)
1048 return VK_UNSUPPORTED
;
1051 VkResult
anv_DestroyObject(
1053 VkObjectType objType
,
1056 struct anv_device
*device
= (struct anv_device
*) _device
;
1057 struct anv_object
*object
= (struct anv_object
*) _object
;
1060 case VK_OBJECT_TYPE_INSTANCE
:
1061 return anv_DestroyInstance((VkInstance
) _object
);
1063 case VK_OBJECT_TYPE_PHYSICAL_DEVICE
:
1064 /* We don't want to actually destroy physical devices */
1067 case VK_OBJECT_TYPE_DEVICE
:
1068 assert(_device
== (VkDevice
) _object
);
1069 return anv_DestroyDevice((VkDevice
) _object
);
1071 case VK_OBJECT_TYPE_QUEUE
:
1075 case VK_OBJECT_TYPE_DEVICE_MEMORY
:
1076 return anv_FreeMemory(_device
, (VkDeviceMemory
) _object
);
1078 case VK_OBJECT_TYPE_DESCRIPTOR_POOL
:
1079 /* These are just dummys anyway, so we don't need to destroy them */
1082 case VK_OBJECT_TYPE_BUFFER
:
1083 case VK_OBJECT_TYPE_IMAGE
:
1084 case VK_OBJECT_TYPE_DEPTH_STENCIL_VIEW
:
1085 case VK_OBJECT_TYPE_SHADER
:
1086 case VK_OBJECT_TYPE_PIPELINE_LAYOUT
:
1087 case VK_OBJECT_TYPE_SAMPLER
:
1088 case VK_OBJECT_TYPE_DESCRIPTOR_SET
:
1089 case VK_OBJECT_TYPE_DESCRIPTOR_SET_LAYOUT
:
1090 case VK_OBJECT_TYPE_DYNAMIC_RS_STATE
:
1091 case VK_OBJECT_TYPE_DYNAMIC_CB_STATE
:
1092 case VK_OBJECT_TYPE_DYNAMIC_DS_STATE
:
1093 case VK_OBJECT_TYPE_RENDER_PASS
:
1094 /* These are trivially destroyable */
1095 anv_device_free(device
, (void *) _object
);
1098 case VK_OBJECT_TYPE_COMMAND_BUFFER
:
1099 case VK_OBJECT_TYPE_PIPELINE
:
1100 case VK_OBJECT_TYPE_DYNAMIC_VP_STATE
:
1101 case VK_OBJECT_TYPE_FENCE
:
1102 case VK_OBJECT_TYPE_QUERY_POOL
:
1103 case VK_OBJECT_TYPE_FRAMEBUFFER
:
1104 case VK_OBJECT_TYPE_BUFFER_VIEW
:
1105 case VK_OBJECT_TYPE_IMAGE_VIEW
:
1106 case VK_OBJECT_TYPE_COLOR_ATTACHMENT_VIEW
:
1107 (object
->destructor
)(device
, object
, objType
);
1110 case VK_OBJECT_TYPE_SEMAPHORE
:
1111 case VK_OBJECT_TYPE_EVENT
:
1112 stub_return(VK_UNSUPPORTED
);
1115 unreachable("Invalid object type");
1120 fill_memory_requirements(
1121 VkObjectType objType
,
1123 VkMemoryRequirements
* memory_requirements
)
1125 struct anv_buffer
*buffer
;
1126 struct anv_image
*image
;
1128 memory_requirements
->memPropsAllowed
=
1129 VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT
|
1130 VK_MEMORY_PROPERTY_HOST_DEVICE_COHERENT_BIT
|
1131 /* VK_MEMORY_PROPERTY_HOST_UNCACHED_BIT | */
1132 VK_MEMORY_PROPERTY_HOST_WRITE_COMBINED_BIT
|
1133 VK_MEMORY_PROPERTY_PREFER_HOST_LOCAL
|
1134 VK_MEMORY_PROPERTY_SHAREABLE_BIT
;
1136 memory_requirements
->memPropsRequired
= 0;
1139 case VK_OBJECT_TYPE_BUFFER
:
1140 buffer
= (struct anv_buffer
*) object
;
1141 memory_requirements
->size
= buffer
->size
;
1142 memory_requirements
->alignment
= 16;
1144 case VK_OBJECT_TYPE_IMAGE
:
1145 image
= (struct anv_image
*) object
;
1146 memory_requirements
->size
= image
->size
;
1147 memory_requirements
->alignment
= image
->alignment
;
1150 memory_requirements
->size
= 0;
1156 get_allocation_count(VkObjectType objType
)
1159 case VK_OBJECT_TYPE_BUFFER
:
1160 case VK_OBJECT_TYPE_IMAGE
:
1167 VkResult
anv_GetObjectInfo(
1169 VkObjectType objType
,
1171 VkObjectInfoType infoType
,
1175 VkMemoryRequirements memory_requirements
;
1179 case VK_OBJECT_INFO_TYPE_MEMORY_REQUIREMENTS
:
1180 *pDataSize
= sizeof(memory_requirements
);
1184 fill_memory_requirements(objType
, object
, pData
);
1187 case VK_OBJECT_INFO_TYPE_MEMORY_ALLOCATION_COUNT
:
1188 *pDataSize
= sizeof(count
);
1193 *count
= get_allocation_count(objType
);
1197 return VK_UNSUPPORTED
;
1202 VkResult
anv_QueueBindObjectMemory(
1204 VkObjectType objType
,
1206 uint32_t allocationIdx
,
1207 VkDeviceMemory _mem
,
1208 VkDeviceSize memOffset
)
1210 struct anv_buffer
*buffer
;
1211 struct anv_image
*image
;
1212 struct anv_device_memory
*mem
= (struct anv_device_memory
*) _mem
;
1215 case VK_OBJECT_TYPE_BUFFER
:
1216 buffer
= (struct anv_buffer
*) object
;
1217 buffer
->bo
= &mem
->bo
;
1218 buffer
->offset
= memOffset
;
1220 case VK_OBJECT_TYPE_IMAGE
:
1221 image
= (struct anv_image
*) object
;
1222 image
->bo
= &mem
->bo
;
1223 image
->offset
= memOffset
;
1232 VkResult
anv_QueueBindObjectMemoryRange(
1234 VkObjectType objType
,
1236 uint32_t allocationIdx
,
1237 VkDeviceSize rangeOffset
,
1238 VkDeviceSize rangeSize
,
1240 VkDeviceSize memOffset
)
1242 stub_return(VK_UNSUPPORTED
);
1245 VkResult
anv_QueueBindImageMemoryRange(
1248 uint32_t allocationIdx
,
1249 const VkImageMemoryBindInfo
* pBindInfo
,
1251 VkDeviceSize memOffset
)
1253 stub_return(VK_UNSUPPORTED
);
1257 anv_fence_destroy(struct anv_device
*device
,
1258 struct anv_object
*object
,
1259 VkObjectType obj_type
)
1261 struct anv_fence
*fence
= (struct anv_fence
*) object
;
1263 assert(obj_type
== VK_OBJECT_TYPE_FENCE
);
1265 anv_gem_munmap(fence
->bo
.map
, fence
->bo
.size
);
1266 anv_gem_close(device
, fence
->bo
.gem_handle
);
1267 anv_device_free(device
, fence
);
1270 VkResult
anv_CreateFence(
1272 const VkFenceCreateInfo
* pCreateInfo
,
1275 struct anv_device
*device
= (struct anv_device
*) _device
;
1276 struct anv_fence
*fence
;
1277 struct anv_batch batch
;
1280 const uint32_t fence_size
= 128;
1282 assert(pCreateInfo
->sType
== VK_STRUCTURE_TYPE_FENCE_CREATE_INFO
);
1284 fence
= anv_device_alloc(device
, sizeof(*fence
), 8,
1285 VK_SYSTEM_ALLOC_TYPE_API_OBJECT
);
1287 return vk_error(VK_ERROR_OUT_OF_HOST_MEMORY
);
1289 result
= anv_bo_init_new(&fence
->bo
, device
, fence_size
);
1290 if (result
!= VK_SUCCESS
)
1293 fence
->base
.destructor
= anv_fence_destroy
;
1296 anv_gem_mmap(device
, fence
->bo
.gem_handle
, 0, fence
->bo
.size
);
1297 batch
.next
= batch
.start
= fence
->bo
.map
;
1298 batch
.end
= fence
->bo
.map
+ fence
->bo
.size
;
1299 anv_batch_emit(&batch
, GEN8_MI_BATCH_BUFFER_END
);
1300 anv_batch_emit(&batch
, GEN8_MI_NOOP
);
1302 fence
->exec2_objects
[0].handle
= fence
->bo
.gem_handle
;
1303 fence
->exec2_objects
[0].relocation_count
= 0;
1304 fence
->exec2_objects
[0].relocs_ptr
= 0;
1305 fence
->exec2_objects
[0].alignment
= 0;
1306 fence
->exec2_objects
[0].offset
= fence
->bo
.offset
;
1307 fence
->exec2_objects
[0].flags
= 0;
1308 fence
->exec2_objects
[0].rsvd1
= 0;
1309 fence
->exec2_objects
[0].rsvd2
= 0;
1311 fence
->execbuf
.buffers_ptr
= (uintptr_t) fence
->exec2_objects
;
1312 fence
->execbuf
.buffer_count
= 1;
1313 fence
->execbuf
.batch_start_offset
= 0;
1314 fence
->execbuf
.batch_len
= batch
.next
- fence
->bo
.map
;
1315 fence
->execbuf
.cliprects_ptr
= 0;
1316 fence
->execbuf
.num_cliprects
= 0;
1317 fence
->execbuf
.DR1
= 0;
1318 fence
->execbuf
.DR4
= 0;
1320 fence
->execbuf
.flags
=
1321 I915_EXEC_HANDLE_LUT
| I915_EXEC_NO_RELOC
| I915_EXEC_RENDER
;
1322 fence
->execbuf
.rsvd1
= device
->context_id
;
1323 fence
->execbuf
.rsvd2
= 0;
1325 *pFence
= (VkFence
) fence
;
1330 anv_device_free(device
, fence
);
1335 VkResult
anv_ResetFences(
1337 uint32_t fenceCount
,
1340 struct anv_fence
**fences
= (struct anv_fence
**) pFences
;
1342 for (uint32_t i
= 0; i
< fenceCount
; i
++)
1343 fences
[i
]->ready
= false;
1348 VkResult
anv_GetFenceStatus(
1352 struct anv_device
*device
= (struct anv_device
*) _device
;
1353 struct anv_fence
*fence
= (struct anv_fence
*) _fence
;
1360 ret
= anv_gem_wait(device
, fence
->bo
.gem_handle
, &t
);
1362 fence
->ready
= true;
1366 return VK_NOT_READY
;
1369 VkResult
anv_WaitForFences(
1371 uint32_t fenceCount
,
1372 const VkFence
* pFences
,
1376 struct anv_device
*device
= (struct anv_device
*) _device
;
1377 struct anv_fence
**fences
= (struct anv_fence
**) pFences
;
1378 int64_t t
= timeout
;
1381 /* FIXME: handle !waitAll */
1383 for (uint32_t i
= 0; i
< fenceCount
; i
++) {
1384 ret
= anv_gem_wait(device
, fences
[i
]->bo
.gem_handle
, &t
);
1385 if (ret
== -1 && errno
== ETIME
)
1388 return vk_error(VK_ERROR_UNKNOWN
);
1394 // Queue semaphore functions
1396 VkResult
anv_CreateSemaphore(
1398 const VkSemaphoreCreateInfo
* pCreateInfo
,
1399 VkSemaphore
* pSemaphore
)
1401 stub_return(VK_UNSUPPORTED
);
1404 VkResult
anv_QueueSignalSemaphore(
1406 VkSemaphore semaphore
)
1408 stub_return(VK_UNSUPPORTED
);
1411 VkResult
anv_QueueWaitSemaphore(
1413 VkSemaphore semaphore
)
1415 stub_return(VK_UNSUPPORTED
);
1420 VkResult
anv_CreateEvent(
1422 const VkEventCreateInfo
* pCreateInfo
,
1425 stub_return(VK_UNSUPPORTED
);
1428 VkResult
anv_GetEventStatus(
1432 stub_return(VK_UNSUPPORTED
);
1435 VkResult
anv_SetEvent(
1439 stub_return(VK_UNSUPPORTED
);
1442 VkResult
anv_ResetEvent(
1446 stub_return(VK_UNSUPPORTED
);
1451 VkResult
anv_CreateBuffer(
1453 const VkBufferCreateInfo
* pCreateInfo
,
1456 struct anv_device
*device
= (struct anv_device
*) _device
;
1457 struct anv_buffer
*buffer
;
1459 assert(pCreateInfo
->sType
== VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO
);
1461 buffer
= anv_device_alloc(device
, sizeof(*buffer
), 8,
1462 VK_SYSTEM_ALLOC_TYPE_API_OBJECT
);
1464 return vk_error(VK_ERROR_OUT_OF_HOST_MEMORY
);
1466 buffer
->size
= pCreateInfo
->size
;
1470 *pBuffer
= (VkBuffer
) buffer
;
1475 // Buffer view functions
1478 fill_buffer_surface_state(void *state
, VkFormat format
,
1479 uint32_t offset
, uint32_t range
)
1481 const struct anv_format
*info
;
1483 info
= anv_format_for_vk_format(format
);
1484 /* This assumes RGBA float format. */
1485 uint32_t stride
= 4;
1486 uint32_t num_elements
= range
/ stride
;
1488 struct GEN8_RENDER_SURFACE_STATE surface_state
= {
1489 .SurfaceType
= SURFTYPE_BUFFER
,
1490 .SurfaceArray
= false,
1491 .SurfaceFormat
= info
->format
,
1492 .SurfaceVerticalAlignment
= VALIGN4
,
1493 .SurfaceHorizontalAlignment
= HALIGN4
,
1495 .VerticalLineStride
= 0,
1496 .VerticalLineStrideOffset
= 0,
1497 .SamplerL2BypassModeDisable
= true,
1498 .RenderCacheReadWriteMode
= WriteOnlyCache
,
1499 .MemoryObjectControlState
= GEN8_MOCS
,
1502 .Height
= (num_elements
>> 7) & 0x3fff,
1503 .Width
= num_elements
& 0x7f,
1504 .Depth
= (num_elements
>> 21) & 0x3f,
1505 .SurfacePitch
= stride
- 1,
1506 .MinimumArrayElement
= 0,
1507 .NumberofMultisamples
= MULTISAMPLECOUNT_1
,
1512 .AuxiliarySurfaceMode
= AUX_NONE
,
1514 .GreenClearColor
= 0,
1515 .BlueClearColor
= 0,
1516 .AlphaClearColor
= 0,
1517 .ShaderChannelSelectRed
= SCS_RED
,
1518 .ShaderChannelSelectGreen
= SCS_GREEN
,
1519 .ShaderChannelSelectBlue
= SCS_BLUE
,
1520 .ShaderChannelSelectAlpha
= SCS_ALPHA
,
1521 .ResourceMinLOD
= 0,
1522 /* FIXME: We assume that the image must be bound at this time. */
1523 .SurfaceBaseAddress
= { NULL
, offset
},
1526 GEN8_RENDER_SURFACE_STATE_pack(NULL
, state
, &surface_state
);
1529 VkResult
anv_CreateBufferView(
1531 const VkBufferViewCreateInfo
* pCreateInfo
,
1532 VkBufferView
* pView
)
1534 struct anv_device
*device
= (struct anv_device
*) _device
;
1535 struct anv_buffer
*buffer
= (struct anv_buffer
*) pCreateInfo
->buffer
;
1536 struct anv_surface_view
*view
;
1538 assert(pCreateInfo
->sType
== VK_STRUCTURE_TYPE_BUFFER_VIEW_CREATE_INFO
);
1540 view
= anv_device_alloc(device
, sizeof(*view
), 8,
1541 VK_SYSTEM_ALLOC_TYPE_API_OBJECT
);
1543 return vk_error(VK_ERROR_OUT_OF_HOST_MEMORY
);
1545 view
->base
.destructor
= anv_surface_view_destroy
;
1547 view
->bo
= buffer
->bo
;
1548 view
->offset
= buffer
->offset
+ pCreateInfo
->offset
;
1549 view
->surface_state
=
1550 anv_state_pool_alloc(&device
->surface_state_pool
, 64, 64);
1551 view
->format
= pCreateInfo
->format
;
1552 view
->range
= pCreateInfo
->range
;
1554 fill_buffer_surface_state(view
->surface_state
.map
,
1555 pCreateInfo
->format
, view
->offset
, pCreateInfo
->range
);
1557 *pView
= (VkBufferView
) view
;
1562 // Sampler functions
1564 VkResult
anv_CreateSampler(
1566 const VkSamplerCreateInfo
* pCreateInfo
,
1567 VkSampler
* pSampler
)
1569 struct anv_device
*device
= (struct anv_device
*) _device
;
1570 struct anv_sampler
*sampler
;
1571 uint32_t mag_filter
, min_filter
, max_anisotropy
;
1573 assert(pCreateInfo
->sType
== VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO
);
1575 sampler
= anv_device_alloc(device
, sizeof(*sampler
), 8,
1576 VK_SYSTEM_ALLOC_TYPE_API_OBJECT
);
1578 return vk_error(VK_ERROR_OUT_OF_HOST_MEMORY
);
1580 static const uint32_t vk_to_gen_tex_filter
[] = {
1581 [VK_TEX_FILTER_NEAREST
] = MAPFILTER_NEAREST
,
1582 [VK_TEX_FILTER_LINEAR
] = MAPFILTER_LINEAR
1585 static const uint32_t vk_to_gen_mipmap_mode
[] = {
1586 [VK_TEX_MIPMAP_MODE_BASE
] = MIPFILTER_NONE
,
1587 [VK_TEX_MIPMAP_MODE_NEAREST
] = MIPFILTER_NEAREST
,
1588 [VK_TEX_MIPMAP_MODE_LINEAR
] = MIPFILTER_LINEAR
1591 static const uint32_t vk_to_gen_tex_address
[] = {
1592 [VK_TEX_ADDRESS_WRAP
] = TCM_WRAP
,
1593 [VK_TEX_ADDRESS_MIRROR
] = TCM_MIRROR
,
1594 [VK_TEX_ADDRESS_CLAMP
] = TCM_CLAMP
,
1595 [VK_TEX_ADDRESS_MIRROR_ONCE
] = TCM_MIRROR_ONCE
,
1596 [VK_TEX_ADDRESS_CLAMP_BORDER
] = TCM_CLAMP_BORDER
,
1599 static const uint32_t vk_to_gen_compare_op
[] = {
1600 [VK_COMPARE_OP_NEVER
] = PREFILTEROPNEVER
,
1601 [VK_COMPARE_OP_LESS
] = PREFILTEROPLESS
,
1602 [VK_COMPARE_OP_EQUAL
] = PREFILTEROPEQUAL
,
1603 [VK_COMPARE_OP_LESS_EQUAL
] = PREFILTEROPLEQUAL
,
1604 [VK_COMPARE_OP_GREATER
] = PREFILTEROPGREATER
,
1605 [VK_COMPARE_OP_NOT_EQUAL
] = PREFILTEROPNOTEQUAL
,
1606 [VK_COMPARE_OP_GREATER_EQUAL
] = PREFILTEROPGEQUAL
,
1607 [VK_COMPARE_OP_ALWAYS
] = PREFILTEROPALWAYS
,
1610 if (pCreateInfo
->maxAnisotropy
> 1) {
1611 mag_filter
= MAPFILTER_ANISOTROPIC
;
1612 min_filter
= MAPFILTER_ANISOTROPIC
;
1613 max_anisotropy
= (pCreateInfo
->maxAnisotropy
- 2) / 2;
1615 mag_filter
= vk_to_gen_tex_filter
[pCreateInfo
->magFilter
];
1616 min_filter
= vk_to_gen_tex_filter
[pCreateInfo
->minFilter
];
1617 max_anisotropy
= RATIO21
;
1620 struct GEN8_SAMPLER_STATE sampler_state
= {
1621 .SamplerDisable
= false,
1622 .TextureBorderColorMode
= DX10OGL
,
1623 .LODPreClampMode
= 0,
1625 .MipModeFilter
= vk_to_gen_mipmap_mode
[pCreateInfo
->mipMode
],
1626 .MagModeFilter
= mag_filter
,
1627 .MinModeFilter
= min_filter
,
1628 .TextureLODBias
= pCreateInfo
->mipLodBias
* 256,
1629 .AnisotropicAlgorithm
= EWAApproximation
,
1630 .MinLOD
= pCreateInfo
->minLod
* 256,
1631 .MaxLOD
= pCreateInfo
->maxLod
* 256,
1632 .ChromaKeyEnable
= 0,
1633 .ChromaKeyIndex
= 0,
1635 .ShadowFunction
= vk_to_gen_compare_op
[pCreateInfo
->compareOp
],
1636 .CubeSurfaceControlMode
= 0,
1638 .IndirectStatePointer
=
1639 device
->float_border_colors
.offset
+
1640 pCreateInfo
->borderColor
* sizeof(float) * 4,
1642 .LODClampMagnificationMode
= MIPNONE
,
1643 .MaximumAnisotropy
= max_anisotropy
,
1644 .RAddressMinFilterRoundingEnable
= 0,
1645 .RAddressMagFilterRoundingEnable
= 0,
1646 .VAddressMinFilterRoundingEnable
= 0,
1647 .VAddressMagFilterRoundingEnable
= 0,
1648 .UAddressMinFilterRoundingEnable
= 0,
1649 .UAddressMagFilterRoundingEnable
= 0,
1650 .TrilinearFilterQuality
= 0,
1651 .NonnormalizedCoordinateEnable
= 0,
1652 .TCXAddressControlMode
= vk_to_gen_tex_address
[pCreateInfo
->addressU
],
1653 .TCYAddressControlMode
= vk_to_gen_tex_address
[pCreateInfo
->addressV
],
1654 .TCZAddressControlMode
= vk_to_gen_tex_address
[pCreateInfo
->addressW
],
1657 GEN8_SAMPLER_STATE_pack(NULL
, sampler
->state
, &sampler_state
);
1659 *pSampler
= (VkSampler
) sampler
;
1664 // Descriptor set functions
1666 VkResult
anv_CreateDescriptorSetLayout(
1668 const VkDescriptorSetLayoutCreateInfo
* pCreateInfo
,
1669 VkDescriptorSetLayout
* pSetLayout
)
1671 struct anv_device
*device
= (struct anv_device
*) _device
;
1672 struct anv_descriptor_set_layout
*set_layout
;
1674 assert(pCreateInfo
->sType
== VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO
);
1676 uint32_t sampler_count
[VK_NUM_SHADER_STAGE
] = { 0, };
1677 uint32_t surface_count
[VK_NUM_SHADER_STAGE
] = { 0, };
1678 uint32_t num_dynamic_buffers
= 0;
1680 uint32_t stages
= 0;
1683 for (uint32_t i
= 0; i
< pCreateInfo
->count
; i
++) {
1684 switch (pCreateInfo
->pBinding
[i
].descriptorType
) {
1685 case VK_DESCRIPTOR_TYPE_SAMPLER
:
1686 case VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER
:
1687 for_each_bit(s
, pCreateInfo
->pBinding
[i
].stageFlags
)
1688 sampler_count
[s
] += pCreateInfo
->pBinding
[i
].count
;
1694 switch (pCreateInfo
->pBinding
[i
].descriptorType
) {
1695 case VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER
:
1696 case VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE
:
1697 case VK_DESCRIPTOR_TYPE_STORAGE_IMAGE
:
1698 case VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER
:
1699 case VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER
:
1700 case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER
:
1701 case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER
:
1702 case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC
:
1703 case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC
:
1704 for_each_bit(s
, pCreateInfo
->pBinding
[i
].stageFlags
)
1705 surface_count
[s
] += pCreateInfo
->pBinding
[i
].count
;
1711 switch (pCreateInfo
->pBinding
[i
].descriptorType
) {
1712 case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC
:
1713 case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC
:
1714 num_dynamic_buffers
+= pCreateInfo
->pBinding
[i
].count
;
1720 stages
|= pCreateInfo
->pBinding
[i
].stageFlags
;
1721 count
+= pCreateInfo
->pBinding
[i
].count
;
1724 uint32_t sampler_total
= 0;
1725 uint32_t surface_total
= 0;
1726 for (uint32_t s
= 0; s
< VK_NUM_SHADER_STAGE
; s
++) {
1727 sampler_total
+= sampler_count
[s
];
1728 surface_total
+= surface_count
[s
];
1731 size_t size
= sizeof(*set_layout
) +
1732 (sampler_total
+ surface_total
) * sizeof(set_layout
->entries
[0]);
1733 set_layout
= anv_device_alloc(device
, size
, 8,
1734 VK_SYSTEM_ALLOC_TYPE_API_OBJECT
);
1736 return vk_error(VK_ERROR_OUT_OF_HOST_MEMORY
);
1738 set_layout
->num_dynamic_buffers
= num_dynamic_buffers
;
1739 set_layout
->count
= count
;
1740 set_layout
->shader_stages
= stages
;
1742 struct anv_descriptor_slot
*p
= set_layout
->entries
;
1743 struct anv_descriptor_slot
*sampler
[VK_NUM_SHADER_STAGE
];
1744 struct anv_descriptor_slot
*surface
[VK_NUM_SHADER_STAGE
];
1745 for (uint32_t s
= 0; s
< VK_NUM_SHADER_STAGE
; s
++) {
1746 set_layout
->stage
[s
].surface_count
= surface_count
[s
];
1747 set_layout
->stage
[s
].surface_start
= surface
[s
] = p
;
1748 p
+= surface_count
[s
];
1749 set_layout
->stage
[s
].sampler_count
= sampler_count
[s
];
1750 set_layout
->stage
[s
].sampler_start
= sampler
[s
] = p
;
1751 p
+= sampler_count
[s
];
1754 uint32_t descriptor
= 0;
1755 int8_t dynamic_slot
= 0;
1757 for (uint32_t i
= 0; i
< pCreateInfo
->count
; i
++) {
1758 switch (pCreateInfo
->pBinding
[i
].descriptorType
) {
1759 case VK_DESCRIPTOR_TYPE_SAMPLER
:
1760 case VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER
:
1761 for_each_bit(s
, pCreateInfo
->pBinding
[i
].stageFlags
)
1762 for (uint32_t j
= 0; j
< pCreateInfo
->pBinding
[i
].count
; j
++) {
1763 sampler
[s
]->index
= descriptor
+ j
;
1764 sampler
[s
]->dynamic_slot
= -1;
1772 switch (pCreateInfo
->pBinding
[i
].descriptorType
) {
1773 case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC
:
1774 case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC
:
1782 switch (pCreateInfo
->pBinding
[i
].descriptorType
) {
1783 case VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER
:
1784 case VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE
:
1785 case VK_DESCRIPTOR_TYPE_STORAGE_IMAGE
:
1786 case VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER
:
1787 case VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER
:
1788 case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER
:
1789 case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER
:
1790 case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC
:
1791 case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC
:
1792 for_each_bit(s
, pCreateInfo
->pBinding
[i
].stageFlags
)
1793 for (uint32_t j
= 0; j
< pCreateInfo
->pBinding
[i
].count
; j
++) {
1794 surface
[s
]->index
= descriptor
+ j
;
1796 surface
[s
]->dynamic_slot
= dynamic_slot
+ j
;
1798 surface
[s
]->dynamic_slot
= -1;
1807 dynamic_slot
+= pCreateInfo
->pBinding
[i
].count
;
1809 descriptor
+= pCreateInfo
->pBinding
[i
].count
;
1812 *pSetLayout
= (VkDescriptorSetLayout
) set_layout
;
1817 VkResult
anv_BeginDescriptorPoolUpdate(
1819 VkDescriptorUpdateMode updateMode
)
1824 VkResult
anv_EndDescriptorPoolUpdate(
1831 VkResult
anv_CreateDescriptorPool(
1833 VkDescriptorPoolUsage poolUsage
,
1835 const VkDescriptorPoolCreateInfo
* pCreateInfo
,
1836 VkDescriptorPool
* pDescriptorPool
)
1838 *pDescriptorPool
= 1;
1843 VkResult
anv_ResetDescriptorPool(
1845 VkDescriptorPool descriptorPool
)
1850 VkResult
anv_AllocDescriptorSets(
1852 VkDescriptorPool descriptorPool
,
1853 VkDescriptorSetUsage setUsage
,
1855 const VkDescriptorSetLayout
* pSetLayouts
,
1856 VkDescriptorSet
* pDescriptorSets
,
1859 struct anv_device
*device
= (struct anv_device
*) _device
;
1860 const struct anv_descriptor_set_layout
*layout
;
1861 struct anv_descriptor_set
*set
;
1864 for (uint32_t i
= 0; i
< count
; i
++) {
1865 layout
= (struct anv_descriptor_set_layout
*) pSetLayouts
[i
];
1866 size
= sizeof(*set
) + layout
->count
* sizeof(set
->descriptors
[0]);
1867 set
= anv_device_alloc(device
, size
, 8,
1868 VK_SYSTEM_ALLOC_TYPE_API_OBJECT
);
1871 return vk_error(VK_ERROR_OUT_OF_HOST_MEMORY
);
1874 /* Descriptor sets may not be 100% filled out so we need to memset to
1875 * ensure that we can properly detect and handle holes.
1877 memset(set
, 0, size
);
1879 pDescriptorSets
[i
] = (VkDescriptorSet
) set
;
1887 void anv_ClearDescriptorSets(
1889 VkDescriptorPool descriptorPool
,
1891 const VkDescriptorSet
* pDescriptorSets
)
1895 void anv_UpdateDescriptors(
1897 VkDescriptorSet descriptorSet
,
1898 uint32_t updateCount
,
1899 const void** ppUpdateArray
)
1901 struct anv_descriptor_set
*set
= (struct anv_descriptor_set
*) descriptorSet
;
1902 VkUpdateSamplers
*update_samplers
;
1903 VkUpdateSamplerTextures
*update_sampler_textures
;
1904 VkUpdateImages
*update_images
;
1905 VkUpdateBuffers
*update_buffers
;
1906 VkUpdateAsCopy
*update_as_copy
;
1908 for (uint32_t i
= 0; i
< updateCount
; i
++) {
1909 const struct anv_common
*common
= ppUpdateArray
[i
];
1911 switch (common
->sType
) {
1912 case VK_STRUCTURE_TYPE_UPDATE_SAMPLERS
:
1913 update_samplers
= (VkUpdateSamplers
*) common
;
1915 for (uint32_t j
= 0; j
< update_samplers
->count
; j
++) {
1916 set
->descriptors
[update_samplers
->binding
+ j
].sampler
=
1917 (struct anv_sampler
*) update_samplers
->pSamplers
[j
];
1921 case VK_STRUCTURE_TYPE_UPDATE_SAMPLER_TEXTURES
:
1922 /* FIXME: Shouldn't this be *_UPDATE_SAMPLER_IMAGES? */
1923 update_sampler_textures
= (VkUpdateSamplerTextures
*) common
;
1925 for (uint32_t j
= 0; j
< update_sampler_textures
->count
; j
++) {
1926 set
->descriptors
[update_sampler_textures
->binding
+ j
].view
=
1927 (struct anv_surface_view
*)
1928 update_sampler_textures
->pSamplerImageViews
[j
].pImageView
->view
;
1929 set
->descriptors
[update_sampler_textures
->binding
+ j
].sampler
=
1930 (struct anv_sampler
*)
1931 update_sampler_textures
->pSamplerImageViews
[j
].sampler
;
1935 case VK_STRUCTURE_TYPE_UPDATE_IMAGES
:
1936 update_images
= (VkUpdateImages
*) common
;
1938 for (uint32_t j
= 0; j
< update_images
->count
; j
++) {
1939 set
->descriptors
[update_images
->binding
+ j
].view
=
1940 (struct anv_surface_view
*) update_images
->pImageViews
[j
].view
;
1944 case VK_STRUCTURE_TYPE_UPDATE_BUFFERS
:
1945 update_buffers
= (VkUpdateBuffers
*) common
;
1947 for (uint32_t j
= 0; j
< update_buffers
->count
; j
++) {
1948 set
->descriptors
[update_buffers
->binding
+ j
].view
=
1949 (struct anv_surface_view
*) update_buffers
->pBufferViews
[j
].view
;
1951 /* FIXME: descriptor arrays? */
1954 case VK_STRUCTURE_TYPE_UPDATE_AS_COPY
:
1955 update_as_copy
= (VkUpdateAsCopy
*) common
;
1956 (void) update_as_copy
;
1965 // State object functions
1967 static inline int64_t
1968 clamp_int64(int64_t x
, int64_t min
, int64_t max
)
1979 anv_dynamic_vp_state_destroy(struct anv_device
*device
,
1980 struct anv_object
*object
,
1981 VkObjectType obj_type
)
1983 struct anv_dynamic_vp_state
*state
= (void *)object
;
1985 assert(obj_type
== VK_OBJECT_TYPE_DYNAMIC_VP_STATE
);
1987 anv_state_pool_free(&device
->dynamic_state_pool
, state
->sf_clip_vp
);
1988 anv_state_pool_free(&device
->dynamic_state_pool
, state
->cc_vp
);
1989 anv_state_pool_free(&device
->dynamic_state_pool
, state
->scissor
);
1991 anv_device_free(device
, state
);
1994 VkResult
anv_CreateDynamicViewportState(
1996 const VkDynamicVpStateCreateInfo
* pCreateInfo
,
1997 VkDynamicVpState
* pState
)
1999 struct anv_device
*device
= (struct anv_device
*) _device
;
2000 struct anv_dynamic_vp_state
*state
;
2002 assert(pCreateInfo
->sType
== VK_STRUCTURE_TYPE_DYNAMIC_VP_STATE_CREATE_INFO
);
2004 state
= anv_device_alloc(device
, sizeof(*state
), 8,
2005 VK_SYSTEM_ALLOC_TYPE_API_OBJECT
);
2007 return vk_error(VK_ERROR_OUT_OF_HOST_MEMORY
);
2009 state
->base
.destructor
= anv_dynamic_vp_state_destroy
;
2011 unsigned count
= pCreateInfo
->viewportAndScissorCount
;
2012 state
->sf_clip_vp
= anv_state_pool_alloc(&device
->dynamic_state_pool
,
2014 state
->cc_vp
= anv_state_pool_alloc(&device
->dynamic_state_pool
,
2016 state
->scissor
= anv_state_pool_alloc(&device
->dynamic_state_pool
,
2019 for (uint32_t i
= 0; i
< pCreateInfo
->viewportAndScissorCount
; i
++) {
2020 const VkViewport
*vp
= &pCreateInfo
->pViewports
[i
];
2021 const VkRect
*s
= &pCreateInfo
->pScissors
[i
];
2023 struct GEN8_SF_CLIP_VIEWPORT sf_clip_viewport
= {
2024 .ViewportMatrixElementm00
= vp
->width
/ 2,
2025 .ViewportMatrixElementm11
= vp
->height
/ 2,
2026 .ViewportMatrixElementm22
= (vp
->maxDepth
- vp
->minDepth
) / 2,
2027 .ViewportMatrixElementm30
= vp
->originX
+ vp
->width
/ 2,
2028 .ViewportMatrixElementm31
= vp
->originY
+ vp
->height
/ 2,
2029 .ViewportMatrixElementm32
= (vp
->maxDepth
+ vp
->minDepth
) / 2,
2030 .XMinClipGuardband
= -1.0f
,
2031 .XMaxClipGuardband
= 1.0f
,
2032 .YMinClipGuardband
= -1.0f
,
2033 .YMaxClipGuardband
= 1.0f
,
2034 .XMinViewPort
= vp
->originX
,
2035 .XMaxViewPort
= vp
->originX
+ vp
->width
- 1,
2036 .YMinViewPort
= vp
->originY
,
2037 .YMaxViewPort
= vp
->originY
+ vp
->height
- 1,
2040 struct GEN8_CC_VIEWPORT cc_viewport
= {
2041 .MinimumDepth
= vp
->minDepth
,
2042 .MaximumDepth
= vp
->maxDepth
2045 /* Since xmax and ymax are inclusive, we have to have xmax < xmin or
2046 * ymax < ymin for empty clips. In case clip x, y, width height are all
2047 * 0, the clamps below produce 0 for xmin, ymin, xmax, ymax, which isn't
2048 * what we want. Just special case empty clips and produce a canonical
2050 static const struct GEN8_SCISSOR_RECT empty_scissor
= {
2051 .ScissorRectangleYMin
= 1,
2052 .ScissorRectangleXMin
= 1,
2053 .ScissorRectangleYMax
= 0,
2054 .ScissorRectangleXMax
= 0
2057 const int max
= 0xffff;
2058 struct GEN8_SCISSOR_RECT scissor
= {
2059 /* Do this math using int64_t so overflow gets clamped correctly. */
2060 .ScissorRectangleYMin
= clamp_int64(s
->offset
.y
, 0, max
),
2061 .ScissorRectangleXMin
= clamp_int64(s
->offset
.x
, 0, max
),
2062 .ScissorRectangleYMax
= clamp_int64((uint64_t) s
->offset
.y
+ s
->extent
.height
- 1, 0, max
),
2063 .ScissorRectangleXMax
= clamp_int64((uint64_t) s
->offset
.x
+ s
->extent
.width
- 1, 0, max
)
2066 GEN8_SF_CLIP_VIEWPORT_pack(NULL
, state
->sf_clip_vp
.map
+ i
* 64, &sf_clip_viewport
);
2067 GEN8_CC_VIEWPORT_pack(NULL
, state
->cc_vp
.map
+ i
* 32, &cc_viewport
);
2069 if (s
->extent
.width
<= 0 || s
->extent
.height
<= 0) {
2070 GEN8_SCISSOR_RECT_pack(NULL
, state
->scissor
.map
+ i
* 32, &empty_scissor
);
2072 GEN8_SCISSOR_RECT_pack(NULL
, state
->scissor
.map
+ i
* 32, &scissor
);
2076 *pState
= (VkDynamicVpState
) state
;
2081 VkResult
anv_CreateDynamicRasterState(
2083 const VkDynamicRsStateCreateInfo
* pCreateInfo
,
2084 VkDynamicRsState
* pState
)
2086 struct anv_device
*device
= (struct anv_device
*) _device
;
2087 struct anv_dynamic_rs_state
*state
;
2089 assert(pCreateInfo
->sType
== VK_STRUCTURE_TYPE_DYNAMIC_RS_STATE_CREATE_INFO
);
2091 state
= anv_device_alloc(device
, sizeof(*state
), 8,
2092 VK_SYSTEM_ALLOC_TYPE_API_OBJECT
);
2094 return vk_error(VK_ERROR_OUT_OF_HOST_MEMORY
);
2097 * float pointFadeThreshold;
2098 * // optional (GL45) - Size of point fade threshold
2101 struct GEN8_3DSTATE_SF sf
= {
2102 GEN8_3DSTATE_SF_header
,
2103 .LineWidth
= pCreateInfo
->lineWidth
,
2104 .PointWidth
= pCreateInfo
->pointSize
,
2107 GEN8_3DSTATE_SF_pack(NULL
, state
->state_sf
, &sf
);
2109 bool enable_bias
= pCreateInfo
->depthBias
!= 0.0f
||
2110 pCreateInfo
->slopeScaledDepthBias
!= 0.0f
;
2111 struct GEN8_3DSTATE_RASTER raster
= {
2112 .GlobalDepthOffsetEnableSolid
= enable_bias
,
2113 .GlobalDepthOffsetEnableWireframe
= enable_bias
,
2114 .GlobalDepthOffsetEnablePoint
= enable_bias
,
2115 .GlobalDepthOffsetConstant
= pCreateInfo
->depthBias
,
2116 .GlobalDepthOffsetScale
= pCreateInfo
->slopeScaledDepthBias
,
2117 .GlobalDepthOffsetClamp
= pCreateInfo
->depthBiasClamp
2120 GEN8_3DSTATE_RASTER_pack(NULL
, state
->state_raster
, &raster
);
2122 *pState
= (VkDynamicRsState
) state
;
2127 VkResult
anv_CreateDynamicColorBlendState(
2129 const VkDynamicCbStateCreateInfo
* pCreateInfo
,
2130 VkDynamicCbState
* pState
)
2132 struct anv_device
*device
= (struct anv_device
*) _device
;
2133 struct anv_dynamic_cb_state
*state
;
2135 assert(pCreateInfo
->sType
== VK_STRUCTURE_TYPE_DYNAMIC_CB_STATE_CREATE_INFO
);
2137 state
= anv_device_alloc(device
, sizeof(*state
), 8,
2138 VK_SYSTEM_ALLOC_TYPE_API_OBJECT
);
2140 return vk_error(VK_ERROR_OUT_OF_HOST_MEMORY
);
2142 struct GEN8_COLOR_CALC_STATE color_calc_state
= {
2143 .BlendConstantColorRed
= pCreateInfo
->blendConst
[0],
2144 .BlendConstantColorGreen
= pCreateInfo
->blendConst
[1],
2145 .BlendConstantColorBlue
= pCreateInfo
->blendConst
[2],
2146 .BlendConstantColorAlpha
= pCreateInfo
->blendConst
[3]
2149 GEN8_COLOR_CALC_STATE_pack(NULL
, state
->state_color_calc
, &color_calc_state
);
2151 *pState
= (VkDynamicCbState
) state
;
2156 VkResult
anv_CreateDynamicDepthStencilState(
2158 const VkDynamicDsStateCreateInfo
* pCreateInfo
,
2159 VkDynamicDsState
* pState
)
2161 struct anv_device
*device
= (struct anv_device
*) _device
;
2162 struct anv_dynamic_ds_state
*state
;
2164 assert(pCreateInfo
->sType
== VK_STRUCTURE_TYPE_DYNAMIC_DS_STATE_CREATE_INFO
);
2166 state
= anv_device_alloc(device
, sizeof(*state
), 8,
2167 VK_SYSTEM_ALLOC_TYPE_API_OBJECT
);
2169 return vk_error(VK_ERROR_OUT_OF_HOST_MEMORY
);
2171 struct GEN8_3DSTATE_WM_DEPTH_STENCIL wm_depth_stencil
= {
2172 GEN8_3DSTATE_WM_DEPTH_STENCIL_header
,
2174 /* Is this what we need to do? */
2175 .StencilBufferWriteEnable
= pCreateInfo
->stencilWriteMask
!= 0,
2177 .StencilTestMask
= pCreateInfo
->stencilReadMask
& 0xff,
2178 .StencilWriteMask
= pCreateInfo
->stencilWriteMask
& 0xff,
2180 .BackfaceStencilTestMask
= pCreateInfo
->stencilReadMask
& 0xff,
2181 .BackfaceStencilWriteMask
= pCreateInfo
->stencilWriteMask
& 0xff,
2184 GEN8_3DSTATE_WM_DEPTH_STENCIL_pack(NULL
, state
->state_wm_depth_stencil
,
2187 struct GEN8_COLOR_CALC_STATE color_calc_state
= {
2188 .StencilReferenceValue
= pCreateInfo
->stencilFrontRef
,
2189 .BackFaceStencilReferenceValue
= pCreateInfo
->stencilBackRef
2192 GEN8_COLOR_CALC_STATE_pack(NULL
, state
->state_color_calc
, &color_calc_state
);
2194 *pState
= (VkDynamicDsState
) state
;
2199 // Command buffer functions
2202 anv_cmd_buffer_destroy(struct anv_device
*device
,
2203 struct anv_object
*object
,
2204 VkObjectType obj_type
)
2206 struct anv_cmd_buffer
*cmd_buffer
= (struct anv_cmd_buffer
*) object
;
2208 assert(obj_type
== VK_OBJECT_TYPE_COMMAND_BUFFER
);
2210 /* Destroy all of the batch buffers */
2211 struct anv_batch_bo
*bbo
= cmd_buffer
->last_batch_bo
;
2212 while (bbo
->prev_batch_bo
) {
2213 struct anv_batch_bo
*prev
= bbo
->prev_batch_bo
;
2214 anv_batch_bo_destroy(bbo
, device
);
2217 anv_reloc_list_finish(&cmd_buffer
->batch
.relocs
, device
);
2219 /* Destroy all of the surface state buffers */
2220 bbo
= cmd_buffer
->surface_batch_bo
;
2221 while (bbo
->prev_batch_bo
) {
2222 struct anv_batch_bo
*prev
= bbo
->prev_batch_bo
;
2223 anv_batch_bo_destroy(bbo
, device
);
2226 anv_reloc_list_finish(&cmd_buffer
->surface_relocs
, device
);
2228 anv_state_stream_finish(&cmd_buffer
->surface_state_stream
);
2229 anv_state_stream_finish(&cmd_buffer
->dynamic_state_stream
);
2230 anv_device_free(device
, cmd_buffer
->exec2_objects
);
2231 anv_device_free(device
, cmd_buffer
->exec2_bos
);
2232 anv_device_free(device
, cmd_buffer
);
2236 anv_cmd_buffer_chain_batch(struct anv_batch
*batch
, void *_data
)
2238 struct anv_cmd_buffer
*cmd_buffer
= _data
;
2240 struct anv_batch_bo
*new_bbo
, *old_bbo
= cmd_buffer
->last_batch_bo
;
2242 VkResult result
= anv_batch_bo_create(cmd_buffer
->device
, &new_bbo
);
2243 if (result
!= VK_SUCCESS
)
2246 /* We set the end of the batch a little short so we would be sure we
2247 * have room for the chaining command. Since we're about to emit the
2248 * chaining command, let's set it back where it should go.
2250 batch
->end
+= GEN8_MI_BATCH_BUFFER_START_length
* 4;
2251 assert(batch
->end
== old_bbo
->bo
.map
+ old_bbo
->bo
.size
);
2253 anv_batch_emit(batch
, GEN8_MI_BATCH_BUFFER_START
,
2254 GEN8_MI_BATCH_BUFFER_START_header
,
2255 ._2ndLevelBatchBuffer
= _1stlevelbatch
,
2256 .AddressSpaceIndicator
= ASI_PPGTT
,
2257 .BatchBufferStartAddress
= { &new_bbo
->bo
, 0 },
2260 /* Pad out to a 2-dword aligned boundary with zeros */
2261 if ((uintptr_t)batch
->next
% 8 != 0) {
2262 *(uint32_t *)batch
->next
= 0;
2266 anv_batch_bo_finish(cmd_buffer
->last_batch_bo
, batch
);
2268 new_bbo
->prev_batch_bo
= old_bbo
;
2269 cmd_buffer
->last_batch_bo
= new_bbo
;
2271 anv_batch_bo_start(new_bbo
, batch
, GEN8_MI_BATCH_BUFFER_START_length
* 4);
2276 VkResult
anv_CreateCommandBuffer(
2278 const VkCmdBufferCreateInfo
* pCreateInfo
,
2279 VkCmdBuffer
* pCmdBuffer
)
2281 struct anv_device
*device
= (struct anv_device
*) _device
;
2282 struct anv_cmd_buffer
*cmd_buffer
;
2285 cmd_buffer
= anv_device_alloc(device
, sizeof(*cmd_buffer
), 8,
2286 VK_SYSTEM_ALLOC_TYPE_API_OBJECT
);
2287 if (cmd_buffer
== NULL
)
2288 return vk_error(VK_ERROR_OUT_OF_HOST_MEMORY
);
2290 cmd_buffer
->base
.destructor
= anv_cmd_buffer_destroy
;
2292 cmd_buffer
->device
= device
;
2293 cmd_buffer
->rs_state
= NULL
;
2294 cmd_buffer
->vp_state
= NULL
;
2295 cmd_buffer
->cb_state
= NULL
;
2296 memset(&cmd_buffer
->descriptors
, 0, sizeof(cmd_buffer
->descriptors
));
2298 result
= anv_batch_bo_create(device
, &cmd_buffer
->last_batch_bo
);
2299 if (result
!= VK_SUCCESS
)
2302 result
= anv_reloc_list_init(&cmd_buffer
->batch
.relocs
, device
);
2303 if (result
!= VK_SUCCESS
)
2306 cmd_buffer
->batch
.device
= device
;
2307 cmd_buffer
->batch
.extend_cb
= anv_cmd_buffer_chain_batch
;
2308 cmd_buffer
->batch
.user_data
= cmd_buffer
;
2310 anv_batch_bo_start(cmd_buffer
->last_batch_bo
, &cmd_buffer
->batch
,
2311 GEN8_MI_BATCH_BUFFER_START_length
* 4);
2313 result
= anv_batch_bo_create(device
, &cmd_buffer
->surface_batch_bo
);
2314 if (result
!= VK_SUCCESS
)
2315 goto fail_batch_relocs
;
2316 cmd_buffer
->surface_batch_bo
->first_reloc
= 0;
2318 result
= anv_reloc_list_init(&cmd_buffer
->surface_relocs
, device
);
2319 if (result
!= VK_SUCCESS
)
2320 goto fail_ss_batch_bo
;
2322 /* Start surface_next at 1 so surface offset 0 is invalid. */
2323 cmd_buffer
->surface_next
= 1;
2325 cmd_buffer
->exec2_objects
= NULL
;
2326 cmd_buffer
->exec2_bos
= NULL
;
2327 cmd_buffer
->exec2_array_length
= 0;
2329 anv_state_stream_init(&cmd_buffer
->surface_state_stream
,
2330 &device
->surface_state_block_pool
);
2331 anv_state_stream_init(&cmd_buffer
->dynamic_state_stream
,
2332 &device
->dynamic_state_block_pool
);
2334 cmd_buffer
->dirty
= 0;
2335 cmd_buffer
->vb_dirty
= 0;
2336 cmd_buffer
->descriptors_dirty
= 0;
2337 cmd_buffer
->pipeline
= NULL
;
2338 cmd_buffer
->vp_state
= NULL
;
2339 cmd_buffer
->rs_state
= NULL
;
2340 cmd_buffer
->ds_state
= NULL
;
2342 *pCmdBuffer
= (VkCmdBuffer
) cmd_buffer
;
2347 anv_batch_bo_destroy(cmd_buffer
->surface_batch_bo
, device
);
2349 anv_reloc_list_finish(&cmd_buffer
->batch
.relocs
, device
);
2351 anv_batch_bo_destroy(cmd_buffer
->last_batch_bo
, device
);
2353 anv_device_free(device
, cmd_buffer
);
2359 anv_cmd_buffer_emit_state_base_address(struct anv_cmd_buffer
*cmd_buffer
)
2361 struct anv_device
*device
= cmd_buffer
->device
;
2363 anv_batch_emit(&cmd_buffer
->batch
, GEN8_STATE_BASE_ADDRESS
,
2364 .GeneralStateBaseAddress
= { NULL
, 0 },
2365 .GeneralStateMemoryObjectControlState
= GEN8_MOCS
,
2366 .GeneralStateBaseAddressModifyEnable
= true,
2367 .GeneralStateBufferSize
= 0xfffff,
2368 .GeneralStateBufferSizeModifyEnable
= true,
2370 .SurfaceStateBaseAddress
= { &cmd_buffer
->surface_batch_bo
->bo
, 0 },
2371 .SurfaceStateMemoryObjectControlState
= GEN8_MOCS
,
2372 .SurfaceStateBaseAddressModifyEnable
= true,
2374 .DynamicStateBaseAddress
= { &device
->dynamic_state_block_pool
.bo
, 0 },
2375 .DynamicStateMemoryObjectControlState
= GEN8_MOCS
,
2376 .DynamicStateBaseAddressModifyEnable
= true,
2377 .DynamicStateBufferSize
= 0xfffff,
2378 .DynamicStateBufferSizeModifyEnable
= true,
2380 .IndirectObjectBaseAddress
= { NULL
, 0 },
2381 .IndirectObjectMemoryObjectControlState
= GEN8_MOCS
,
2382 .IndirectObjectBaseAddressModifyEnable
= true,
2383 .IndirectObjectBufferSize
= 0xfffff,
2384 .IndirectObjectBufferSizeModifyEnable
= true,
2386 .InstructionBaseAddress
= { &device
->instruction_block_pool
.bo
, 0 },
2387 .InstructionMemoryObjectControlState
= GEN8_MOCS
,
2388 .InstructionBaseAddressModifyEnable
= true,
2389 .InstructionBufferSize
= 0xfffff,
2390 .InstructionBuffersizeModifyEnable
= true);
2393 VkResult
anv_BeginCommandBuffer(
2394 VkCmdBuffer cmdBuffer
,
2395 const VkCmdBufferBeginInfo
* pBeginInfo
)
2397 struct anv_cmd_buffer
*cmd_buffer
= (struct anv_cmd_buffer
*) cmdBuffer
;
2399 anv_batch_emit(&cmd_buffer
->batch
, GEN8_PIPELINE_SELECT
,
2400 .PipelineSelection
= _3D
);
2401 anv_batch_emit(&cmd_buffer
->batch
, GEN8_STATE_SIP
);
2403 anv_cmd_buffer_emit_state_base_address(cmd_buffer
);
2405 anv_batch_emit(&cmd_buffer
->batch
, GEN8_3DSTATE_VF_STATISTICS
,
2406 .StatisticsEnable
= true);
2407 anv_batch_emit(&cmd_buffer
->batch
, GEN8_3DSTATE_HS
, .Enable
= false);
2408 anv_batch_emit(&cmd_buffer
->batch
, GEN8_3DSTATE_TE
, .TEEnable
= false);
2409 anv_batch_emit(&cmd_buffer
->batch
, GEN8_3DSTATE_DS
, .FunctionEnable
= false);
2410 anv_batch_emit(&cmd_buffer
->batch
, GEN8_3DSTATE_STREAMOUT
, .SOFunctionEnable
= false);
2412 anv_batch_emit(&cmd_buffer
->batch
, GEN8_3DSTATE_PUSH_CONSTANT_ALLOC_VS
,
2413 .ConstantBufferOffset
= 0,
2414 .ConstantBufferSize
= 4);
2415 anv_batch_emit(&cmd_buffer
->batch
, GEN8_3DSTATE_PUSH_CONSTANT_ALLOC_GS
,
2416 .ConstantBufferOffset
= 4,
2417 .ConstantBufferSize
= 4);
2418 anv_batch_emit(&cmd_buffer
->batch
, GEN8_3DSTATE_PUSH_CONSTANT_ALLOC_PS
,
2419 .ConstantBufferOffset
= 8,
2420 .ConstantBufferSize
= 4);
2422 anv_batch_emit(&cmd_buffer
->batch
, GEN8_3DSTATE_WM_CHROMAKEY
,
2423 .ChromaKeyKillEnable
= false);
2424 anv_batch_emit(&cmd_buffer
->batch
, GEN8_3DSTATE_SBE_SWIZ
);
2425 anv_batch_emit(&cmd_buffer
->batch
, GEN8_3DSTATE_AA_LINE_PARAMETERS
);
2431 anv_cmd_buffer_add_bo(struct anv_cmd_buffer
*cmd_buffer
,
2433 struct drm_i915_gem_relocation_entry
*relocs
,
2436 struct drm_i915_gem_exec_object2
*obj
;
2438 if (bo
->index
< cmd_buffer
->bo_count
&&
2439 cmd_buffer
->exec2_bos
[bo
->index
] == bo
)
2442 if (cmd_buffer
->bo_count
>= cmd_buffer
->exec2_array_length
) {
2443 uint32_t new_len
= cmd_buffer
->exec2_objects
?
2444 cmd_buffer
->exec2_array_length
* 2 : 64;
2446 struct drm_i915_gem_exec_object2
*new_objects
=
2447 anv_device_alloc(cmd_buffer
->device
, new_len
* sizeof(*new_objects
),
2448 8, VK_SYSTEM_ALLOC_TYPE_INTERNAL
);
2449 if (new_objects
== NULL
)
2450 return vk_error(VK_ERROR_OUT_OF_HOST_MEMORY
);
2452 struct anv_bo
**new_bos
=
2453 anv_device_alloc(cmd_buffer
->device
, new_len
* sizeof(*new_bos
),
2454 8, VK_SYSTEM_ALLOC_TYPE_INTERNAL
);
2455 if (new_objects
== NULL
) {
2456 anv_device_free(cmd_buffer
->device
, new_objects
);
2457 return vk_error(VK_ERROR_OUT_OF_HOST_MEMORY
);
2460 if (cmd_buffer
->exec2_objects
) {
2461 memcpy(new_objects
, cmd_buffer
->exec2_objects
,
2462 cmd_buffer
->bo_count
* sizeof(*new_objects
));
2463 memcpy(new_bos
, cmd_buffer
->exec2_bos
,
2464 cmd_buffer
->bo_count
* sizeof(*new_bos
));
2467 cmd_buffer
->exec2_objects
= new_objects
;
2468 cmd_buffer
->exec2_bos
= new_bos
;
2469 cmd_buffer
->exec2_array_length
= new_len
;
2472 assert(cmd_buffer
->bo_count
< cmd_buffer
->exec2_array_length
);
2474 bo
->index
= cmd_buffer
->bo_count
++;
2475 obj
= &cmd_buffer
->exec2_objects
[bo
->index
];
2476 cmd_buffer
->exec2_bos
[bo
->index
] = bo
;
2478 obj
->handle
= bo
->gem_handle
;
2479 obj
->relocation_count
= 0;
2480 obj
->relocs_ptr
= 0;
2482 obj
->offset
= bo
->offset
;
2488 obj
->relocation_count
= num_relocs
;
2489 obj
->relocs_ptr
= (uintptr_t) relocs
;
2496 anv_cmd_buffer_add_validate_bos(struct anv_cmd_buffer
*cmd_buffer
,
2497 struct anv_reloc_list
*list
)
2499 for (size_t i
= 0; i
< list
->num_relocs
; i
++)
2500 anv_cmd_buffer_add_bo(cmd_buffer
, list
->reloc_bos
[i
], NULL
, 0);
2504 anv_cmd_buffer_process_relocs(struct anv_cmd_buffer
*cmd_buffer
,
2505 struct anv_reloc_list
*list
)
2509 /* If the kernel supports I915_EXEC_NO_RELOC, it will compare offset in
2510 * struct drm_i915_gem_exec_object2 against the bos current offset and if
2511 * all bos haven't moved it will skip relocation processing alltogether.
2512 * If I915_EXEC_NO_RELOC is not supported, the kernel ignores the incoming
2513 * value of offset so we can set it either way. For that to work we need
2514 * to make sure all relocs use the same presumed offset.
2517 for (size_t i
= 0; i
< list
->num_relocs
; i
++) {
2518 bo
= list
->reloc_bos
[i
];
2519 if (bo
->offset
!= list
->relocs
[i
].presumed_offset
)
2520 cmd_buffer
->need_reloc
= true;
2522 list
->relocs
[i
].target_handle
= bo
->index
;
2526 VkResult
anv_EndCommandBuffer(
2527 VkCmdBuffer cmdBuffer
)
2529 struct anv_cmd_buffer
*cmd_buffer
= (struct anv_cmd_buffer
*) cmdBuffer
;
2530 struct anv_device
*device
= cmd_buffer
->device
;
2531 struct anv_batch
*batch
= &cmd_buffer
->batch
;
2533 anv_batch_emit(batch
, GEN8_MI_BATCH_BUFFER_END
);
2535 /* Round batch up to an even number of dwords. */
2536 if ((batch
->next
- batch
->start
) & 4)
2537 anv_batch_emit(batch
, GEN8_MI_NOOP
);
2539 anv_batch_bo_finish(cmd_buffer
->last_batch_bo
, &cmd_buffer
->batch
);
2540 cmd_buffer
->surface_batch_bo
->num_relocs
=
2541 cmd_buffer
->surface_relocs
.num_relocs
- cmd_buffer
->surface_batch_bo
->first_reloc
;
2542 cmd_buffer
->surface_batch_bo
->length
= cmd_buffer
->surface_next
;
2544 cmd_buffer
->bo_count
= 0;
2545 cmd_buffer
->need_reloc
= false;
2547 /* Lock for access to bo->index. */
2548 pthread_mutex_lock(&device
->mutex
);
2550 /* Add surface state bos first so we can add them with their relocs. */
2551 for (struct anv_batch_bo
*bbo
= cmd_buffer
->surface_batch_bo
;
2552 bbo
!= NULL
; bbo
= bbo
->prev_batch_bo
) {
2553 anv_cmd_buffer_add_bo(cmd_buffer
, &bbo
->bo
,
2554 &cmd_buffer
->surface_relocs
.relocs
[bbo
->first_reloc
],
2558 /* Add all of the BOs referenced by surface state */
2559 anv_cmd_buffer_add_validate_bos(cmd_buffer
, &cmd_buffer
->surface_relocs
);
2561 /* Add all but the first batch BO */
2562 struct anv_batch_bo
*batch_bo
= cmd_buffer
->last_batch_bo
;
2563 while (batch_bo
->prev_batch_bo
) {
2564 anv_cmd_buffer_add_bo(cmd_buffer
, &batch_bo
->bo
,
2565 &batch
->relocs
.relocs
[batch_bo
->first_reloc
],
2566 batch_bo
->num_relocs
);
2567 batch_bo
= batch_bo
->prev_batch_bo
;
2570 /* Add everything referenced by the batches */
2571 anv_cmd_buffer_add_validate_bos(cmd_buffer
, &batch
->relocs
);
2573 /* Add the first batch bo last */
2574 assert(batch_bo
->prev_batch_bo
== NULL
&& batch_bo
->first_reloc
== 0);
2575 anv_cmd_buffer_add_bo(cmd_buffer
, &batch_bo
->bo
,
2576 &batch
->relocs
.relocs
[batch_bo
->first_reloc
],
2577 batch_bo
->num_relocs
);
2578 assert(batch_bo
->bo
.index
== cmd_buffer
->bo_count
- 1);
2580 anv_cmd_buffer_process_relocs(cmd_buffer
, &cmd_buffer
->surface_relocs
);
2581 anv_cmd_buffer_process_relocs(cmd_buffer
, &batch
->relocs
);
2583 cmd_buffer
->execbuf
.buffers_ptr
= (uintptr_t) cmd_buffer
->exec2_objects
;
2584 cmd_buffer
->execbuf
.buffer_count
= cmd_buffer
->bo_count
;
2585 cmd_buffer
->execbuf
.batch_start_offset
= 0;
2586 cmd_buffer
->execbuf
.batch_len
= batch
->next
- batch
->start
;
2587 cmd_buffer
->execbuf
.cliprects_ptr
= 0;
2588 cmd_buffer
->execbuf
.num_cliprects
= 0;
2589 cmd_buffer
->execbuf
.DR1
= 0;
2590 cmd_buffer
->execbuf
.DR4
= 0;
2592 cmd_buffer
->execbuf
.flags
= I915_EXEC_HANDLE_LUT
;
2593 if (!cmd_buffer
->need_reloc
)
2594 cmd_buffer
->execbuf
.flags
|= I915_EXEC_NO_RELOC
;
2595 cmd_buffer
->execbuf
.flags
|= I915_EXEC_RENDER
;
2596 cmd_buffer
->execbuf
.rsvd1
= device
->context_id
;
2597 cmd_buffer
->execbuf
.rsvd2
= 0;
2599 pthread_mutex_unlock(&device
->mutex
);
2604 VkResult
anv_ResetCommandBuffer(
2605 VkCmdBuffer cmdBuffer
)
2607 struct anv_cmd_buffer
*cmd_buffer
= (struct anv_cmd_buffer
*) cmdBuffer
;
2609 /* Delete all but the first batch bo */
2610 while (cmd_buffer
->last_batch_bo
->prev_batch_bo
) {
2611 struct anv_batch_bo
*prev
= cmd_buffer
->last_batch_bo
->prev_batch_bo
;
2612 anv_batch_bo_destroy(cmd_buffer
->last_batch_bo
, cmd_buffer
->device
);
2613 cmd_buffer
->last_batch_bo
= prev
;
2615 assert(cmd_buffer
->last_batch_bo
->prev_batch_bo
== NULL
);
2617 cmd_buffer
->batch
.relocs
.num_relocs
= 0;
2618 anv_batch_bo_start(cmd_buffer
->last_batch_bo
, &cmd_buffer
->batch
,
2619 GEN8_MI_BATCH_BUFFER_START_length
* 4);
2621 /* Delete all but the first batch bo */
2622 while (cmd_buffer
->surface_batch_bo
->prev_batch_bo
) {
2623 struct anv_batch_bo
*prev
= cmd_buffer
->surface_batch_bo
->prev_batch_bo
;
2624 anv_batch_bo_destroy(cmd_buffer
->surface_batch_bo
, cmd_buffer
->device
);
2625 cmd_buffer
->surface_batch_bo
= prev
;
2627 assert(cmd_buffer
->surface_batch_bo
->prev_batch_bo
== NULL
);
2629 cmd_buffer
->surface_next
= 1;
2630 cmd_buffer
->surface_relocs
.num_relocs
= 0;
2635 // Command buffer building functions
2637 void anv_CmdBindPipeline(
2638 VkCmdBuffer cmdBuffer
,
2639 VkPipelineBindPoint pipelineBindPoint
,
2640 VkPipeline _pipeline
)
2642 struct anv_cmd_buffer
*cmd_buffer
= (struct anv_cmd_buffer
*) cmdBuffer
;
2643 struct anv_pipeline
*pipeline
= (struct anv_pipeline
*) _pipeline
;
2645 cmd_buffer
->pipeline
= pipeline
;
2646 cmd_buffer
->vb_dirty
|= pipeline
->vb_used
;
2647 cmd_buffer
->dirty
|= ANV_CMD_BUFFER_PIPELINE_DIRTY
;
2650 void anv_CmdBindDynamicStateObject(
2651 VkCmdBuffer cmdBuffer
,
2652 VkStateBindPoint stateBindPoint
,
2653 VkDynamicStateObject dynamicState
)
2655 struct anv_cmd_buffer
*cmd_buffer
= (struct anv_cmd_buffer
*) cmdBuffer
;
2656 struct anv_dynamic_vp_state
*vp_state
;
2658 switch (stateBindPoint
) {
2659 case VK_STATE_BIND_POINT_VIEWPORT
:
2660 vp_state
= (struct anv_dynamic_vp_state
*) dynamicState
;
2661 /* We emit state immediately, but set cmd_buffer->vp_state to indicate
2662 * that vp state has been set in this command buffer. */
2663 cmd_buffer
->vp_state
= vp_state
;
2664 anv_batch_emit(&cmd_buffer
->batch
, GEN8_3DSTATE_SCISSOR_STATE_POINTERS
,
2665 .ScissorRectPointer
= vp_state
->scissor
.offset
);
2666 anv_batch_emit(&cmd_buffer
->batch
, GEN8_3DSTATE_VIEWPORT_STATE_POINTERS_CC
,
2667 .CCViewportPointer
= vp_state
->cc_vp
.offset
);
2668 anv_batch_emit(&cmd_buffer
->batch
, GEN8_3DSTATE_VIEWPORT_STATE_POINTERS_SF_CLIP
,
2669 .SFClipViewportPointer
= vp_state
->sf_clip_vp
.offset
);
2671 case VK_STATE_BIND_POINT_RASTER
:
2672 cmd_buffer
->rs_state
= (struct anv_dynamic_rs_state
*) dynamicState
;
2673 cmd_buffer
->dirty
|= ANV_CMD_BUFFER_RS_DIRTY
;
2675 case VK_STATE_BIND_POINT_COLOR_BLEND
:
2676 cmd_buffer
->cb_state
= (struct anv_dynamic_cb_state
*) dynamicState
;
2677 cmd_buffer
->dirty
|= ANV_CMD_BUFFER_CB_DIRTY
;
2679 case VK_STATE_BIND_POINT_DEPTH_STENCIL
:
2680 cmd_buffer
->ds_state
= (struct anv_dynamic_ds_state
*) dynamicState
;
2681 cmd_buffer
->dirty
|= ANV_CMD_BUFFER_DS_DIRTY
;
2688 static struct anv_state
2689 anv_cmd_buffer_alloc_surface_state(struct anv_cmd_buffer
*cmd_buffer
,
2690 uint32_t size
, uint32_t alignment
)
2692 struct anv_state state
;
2694 state
.offset
= ALIGN_U32(cmd_buffer
->surface_next
, alignment
);
2695 if (state
.offset
+ size
> cmd_buffer
->surface_batch_bo
->bo
.size
)
2696 return (struct anv_state
) { 0 };
2698 state
.map
= cmd_buffer
->surface_batch_bo
->bo
.map
+ state
.offset
;
2699 state
.alloc_size
= size
;
2700 cmd_buffer
->surface_next
= state
.offset
+ size
;
2702 assert(state
.offset
+ size
<= cmd_buffer
->surface_batch_bo
->bo
.size
);
2708 anv_cmd_buffer_new_surface_state_bo(struct anv_cmd_buffer
*cmd_buffer
)
2710 struct anv_batch_bo
*new_bbo
, *old_bbo
= cmd_buffer
->surface_batch_bo
;
2712 /* Finish off the old buffer */
2713 old_bbo
->num_relocs
=
2714 cmd_buffer
->surface_relocs
.num_relocs
- old_bbo
->first_reloc
;
2715 old_bbo
->length
= cmd_buffer
->surface_next
;
2717 VkResult result
= anv_batch_bo_create(cmd_buffer
->device
, &new_bbo
);
2718 if (result
!= VK_SUCCESS
)
2721 new_bbo
->first_reloc
= cmd_buffer
->surface_relocs
.num_relocs
;
2722 cmd_buffer
->surface_next
= 1;
2724 new_bbo
->prev_batch_bo
= old_bbo
;
2725 cmd_buffer
->surface_batch_bo
= new_bbo
;
2727 /* Re-emit state base addresses so we get the new surface state base
2728 * address before we start emitting binding tables etc.
2730 anv_cmd_buffer_emit_state_base_address(cmd_buffer
);
2732 /* It seems like just changing the state base addresses isn't enough.
2733 * Invalidating the cache seems to be enough to cause things to
2734 * propagate. However, I'm not 100% sure what we're supposed to do.
2736 anv_batch_emit(&cmd_buffer
->batch
, GEN8_PIPE_CONTROL
,
2737 .TextureCacheInvalidationEnable
= true);
2742 void anv_CmdBindDescriptorSets(
2743 VkCmdBuffer cmdBuffer
,
2744 VkPipelineBindPoint pipelineBindPoint
,
2747 const VkDescriptorSet
* pDescriptorSets
,
2748 uint32_t dynamicOffsetCount
,
2749 const uint32_t* pDynamicOffsets
)
2751 struct anv_cmd_buffer
*cmd_buffer
= (struct anv_cmd_buffer
*) cmdBuffer
;
2752 struct anv_pipeline_layout
*layout
= cmd_buffer
->pipeline
->layout
;
2753 struct anv_descriptor_set
*set
;
2754 struct anv_descriptor_set_layout
*set_layout
;
2756 assert(firstSet
+ setCount
< MAX_SETS
);
2758 uint32_t dynamic_slot
= 0;
2759 for (uint32_t i
= 0; i
< setCount
; i
++) {
2760 set
= (struct anv_descriptor_set
*) pDescriptorSets
[i
];
2761 set_layout
= layout
->set
[firstSet
+ i
].layout
;
2763 cmd_buffer
->descriptors
[firstSet
+ i
].set
= set
;
2765 assert(set_layout
->num_dynamic_buffers
<
2766 ARRAY_SIZE(cmd_buffer
->descriptors
[0].dynamic_offsets
));
2767 memcpy(cmd_buffer
->descriptors
[firstSet
+ i
].dynamic_offsets
,
2768 pDynamicOffsets
+ dynamic_slot
,
2769 set_layout
->num_dynamic_buffers
* sizeof(*pDynamicOffsets
));
2771 cmd_buffer
->descriptors_dirty
|= set_layout
->shader_stages
;
2773 dynamic_slot
+= set_layout
->num_dynamic_buffers
;
2777 void anv_CmdBindIndexBuffer(
2778 VkCmdBuffer cmdBuffer
,
2780 VkDeviceSize offset
,
2781 VkIndexType indexType
)
2783 struct anv_cmd_buffer
*cmd_buffer
= (struct anv_cmd_buffer
*) cmdBuffer
;
2784 struct anv_buffer
*buffer
= (struct anv_buffer
*) _buffer
;
2786 static const uint32_t vk_to_gen_index_type
[] = {
2787 [VK_INDEX_TYPE_UINT8
] = INDEX_BYTE
,
2788 [VK_INDEX_TYPE_UINT16
] = INDEX_WORD
,
2789 [VK_INDEX_TYPE_UINT32
] = INDEX_DWORD
,
2792 anv_batch_emit(&cmd_buffer
->batch
, GEN8_3DSTATE_INDEX_BUFFER
,
2793 .IndexFormat
= vk_to_gen_index_type
[indexType
],
2794 .MemoryObjectControlState
= GEN8_MOCS
,
2795 .BufferStartingAddress
= { buffer
->bo
, buffer
->offset
+ offset
},
2796 .BufferSize
= buffer
->size
- offset
);
2799 void anv_CmdBindVertexBuffers(
2800 VkCmdBuffer cmdBuffer
,
2801 uint32_t startBinding
,
2802 uint32_t bindingCount
,
2803 const VkBuffer
* pBuffers
,
2804 const VkDeviceSize
* pOffsets
)
2806 struct anv_cmd_buffer
*cmd_buffer
= (struct anv_cmd_buffer
*) cmdBuffer
;
2807 struct anv_vertex_binding
*vb
= cmd_buffer
->vertex_bindings
;
2809 /* We have to defer setting up vertex buffer since we need the buffer
2810 * stride from the pipeline. */
2812 assert(startBinding
+ bindingCount
< MAX_VBS
);
2813 for (uint32_t i
= 0; i
< bindingCount
; i
++) {
2814 vb
[startBinding
+ i
].buffer
= (struct anv_buffer
*) pBuffers
[i
];
2815 vb
[startBinding
+ i
].offset
= pOffsets
[i
];
2816 cmd_buffer
->vb_dirty
|= 1 << (startBinding
+ i
);
2821 cmd_buffer_emit_binding_table(struct anv_cmd_buffer
*cmd_buffer
,
2824 struct anv_pipeline_layout
*layout
= cmd_buffer
->pipeline
->layout
;
2825 uint32_t color_attachments
, bias
, size
;
2826 struct anv_state bt_state
;
2828 if (stage
== VK_SHADER_STAGE_FRAGMENT
) {
2830 color_attachments
= cmd_buffer
->framebuffer
->color_attachment_count
;
2833 color_attachments
= 0;
2836 /* This is a little awkward: layout can be NULL but we still have to
2837 * allocate and set a binding table for the PS stage for render
2839 uint32_t surface_count
= layout
? layout
->stage
[stage
].surface_count
: 0;
2841 if (color_attachments
+ surface_count
== 0)
2844 size
= (bias
+ surface_count
) * sizeof(uint32_t);
2845 bt_state
= anv_cmd_buffer_alloc_surface_state(cmd_buffer
, size
, 32);
2846 uint32_t *bt_map
= bt_state
.map
;
2848 if (bt_state
.map
== NULL
)
2849 return VK_ERROR_OUT_OF_DEVICE_MEMORY
;
2851 static const uint32_t binding_table_opcodes
[] = {
2852 [VK_SHADER_STAGE_VERTEX
] = 38,
2853 [VK_SHADER_STAGE_TESS_CONTROL
] = 39,
2854 [VK_SHADER_STAGE_TESS_EVALUATION
] = 40,
2855 [VK_SHADER_STAGE_GEOMETRY
] = 41,
2856 [VK_SHADER_STAGE_FRAGMENT
] = 42,
2857 [VK_SHADER_STAGE_COMPUTE
] = 0,
2860 anv_batch_emit(&cmd_buffer
->batch
,
2861 GEN8_3DSTATE_BINDING_TABLE_POINTERS_VS
,
2862 ._3DCommandSubOpcode
= binding_table_opcodes
[stage
],
2863 .PointertoVSBindingTable
= bt_state
.offset
);
2865 for (uint32_t ca
= 0; ca
< color_attachments
; ca
++) {
2866 const struct anv_surface_view
*view
=
2867 cmd_buffer
->framebuffer
->color_attachments
[ca
];
2869 struct anv_state state
=
2870 anv_cmd_buffer_alloc_surface_state(cmd_buffer
, 64, 64);
2872 if (state
.map
== NULL
)
2873 return VK_ERROR_OUT_OF_DEVICE_MEMORY
;
2875 memcpy(state
.map
, view
->surface_state
.map
, 64);
2877 /* The address goes in dwords 8 and 9 of the SURFACE_STATE */
2878 *(uint64_t *)(state
.map
+ 8 * 4) =
2879 anv_reloc_list_add(&cmd_buffer
->surface_relocs
,
2881 state
.offset
+ 8 * 4,
2882 view
->bo
, view
->offset
);
2884 bt_map
[ca
] = state
.offset
;
2890 for (uint32_t set
= 0; set
< layout
->num_sets
; set
++) {
2891 struct anv_descriptor_set_binding
*d
= &cmd_buffer
->descriptors
[set
];
2892 struct anv_descriptor_set_layout
*set_layout
= layout
->set
[set
].layout
;
2893 struct anv_descriptor_slot
*surface_slots
=
2894 set_layout
->stage
[stage
].surface_start
;
2896 uint32_t start
= bias
+ layout
->set
[set
].surface_start
[stage
];
2898 for (uint32_t b
= 0; b
< set_layout
->stage
[stage
].surface_count
; b
++) {
2899 struct anv_surface_view
*view
=
2900 d
->set
->descriptors
[surface_slots
[b
].index
].view
;
2905 struct anv_state state
=
2906 anv_cmd_buffer_alloc_surface_state(cmd_buffer
, 64, 64);
2908 if (state
.map
== NULL
)
2909 return VK_ERROR_OUT_OF_DEVICE_MEMORY
;
2912 if (surface_slots
[b
].dynamic_slot
>= 0) {
2913 uint32_t dynamic_offset
=
2914 d
->dynamic_offsets
[surface_slots
[b
].dynamic_slot
];
2916 offset
= view
->offset
+ dynamic_offset
;
2917 fill_buffer_surface_state(state
.map
, view
->format
, offset
,
2918 view
->range
- dynamic_offset
);
2920 offset
= view
->offset
;
2921 memcpy(state
.map
, view
->surface_state
.map
, 64);
2924 /* The address goes in dwords 8 and 9 of the SURFACE_STATE */
2925 *(uint64_t *)(state
.map
+ 8 * 4) =
2926 anv_reloc_list_add(&cmd_buffer
->surface_relocs
,
2928 state
.offset
+ 8 * 4,
2931 bt_map
[start
+ b
] = state
.offset
;
2939 cmd_buffer_emit_samplers(struct anv_cmd_buffer
*cmd_buffer
, unsigned stage
)
2941 struct anv_pipeline_layout
*layout
= cmd_buffer
->pipeline
->layout
;
2942 struct anv_state state
;
2947 uint32_t sampler_count
= layout
->stage
[stage
].sampler_count
;
2949 if (sampler_count
== 0)
2952 uint32_t size
= sampler_count
* 16;
2953 state
= anv_state_stream_alloc(&cmd_buffer
->dynamic_state_stream
, size
, 32);
2955 if (state
.map
== NULL
)
2956 return VK_ERROR_OUT_OF_DEVICE_MEMORY
;
2958 static const uint32_t sampler_state_opcodes
[] = {
2959 [VK_SHADER_STAGE_VERTEX
] = 43,
2960 [VK_SHADER_STAGE_TESS_CONTROL
] = 44, /* HS */
2961 [VK_SHADER_STAGE_TESS_EVALUATION
] = 45, /* DS */
2962 [VK_SHADER_STAGE_GEOMETRY
] = 46,
2963 [VK_SHADER_STAGE_FRAGMENT
] = 47,
2964 [VK_SHADER_STAGE_COMPUTE
] = 0,
2967 anv_batch_emit(&cmd_buffer
->batch
,
2968 GEN8_3DSTATE_SAMPLER_STATE_POINTERS_VS
,
2969 ._3DCommandSubOpcode
= sampler_state_opcodes
[stage
],
2970 .PointertoVSSamplerState
= state
.offset
);
2972 for (uint32_t set
= 0; set
< layout
->num_sets
; set
++) {
2973 struct anv_descriptor_set_binding
*d
= &cmd_buffer
->descriptors
[set
];
2974 struct anv_descriptor_set_layout
*set_layout
= layout
->set
[set
].layout
;
2975 struct anv_descriptor_slot
*sampler_slots
=
2976 set_layout
->stage
[stage
].sampler_start
;
2978 uint32_t start
= layout
->set
[set
].sampler_start
[stage
];
2980 for (uint32_t b
= 0; b
< set_layout
->stage
[stage
].sampler_count
; b
++) {
2981 struct anv_sampler
*sampler
=
2982 d
->set
->descriptors
[sampler_slots
[b
].index
].sampler
;
2987 memcpy(state
.map
+ (start
+ b
) * 16,
2988 sampler
->state
, sizeof(sampler
->state
));
2996 flush_descriptor_sets(struct anv_cmd_buffer
*cmd_buffer
)
2998 uint32_t s
, dirty
= cmd_buffer
->descriptors_dirty
&
2999 cmd_buffer
->pipeline
->active_stages
;
3002 for_each_bit(s
, dirty
) {
3003 result
= cmd_buffer_emit_binding_table(cmd_buffer
, s
);
3004 if (result
!= VK_SUCCESS
)
3007 result
= cmd_buffer_emit_samplers(cmd_buffer
, s
);
3008 if (result
!= VK_SUCCESS
)
3012 if (result
!= VK_SUCCESS
) {
3013 assert(result
== VK_ERROR_OUT_OF_DEVICE_MEMORY
);
3015 result
= anv_cmd_buffer_new_surface_state_bo(cmd_buffer
);
3016 assert(result
== VK_SUCCESS
);
3018 /* Re-emit all active binding tables */
3019 for_each_bit(s
, cmd_buffer
->pipeline
->active_stages
) {
3020 result
= cmd_buffer_emit_binding_table(cmd_buffer
, s
);
3021 result
= cmd_buffer_emit_samplers(cmd_buffer
, s
);
3024 /* It had better succeed this time */
3025 assert(result
== VK_SUCCESS
);
3028 cmd_buffer
->descriptors_dirty
&= ~cmd_buffer
->pipeline
->active_stages
;
3031 static struct anv_state
3032 anv_cmd_buffer_emit_dynamic(struct anv_cmd_buffer
*cmd_buffer
,
3033 uint32_t *a
, uint32_t dwords
, uint32_t alignment
)
3035 struct anv_state state
;
3037 state
= anv_state_stream_alloc(&cmd_buffer
->dynamic_state_stream
,
3038 dwords
* 4, alignment
);
3039 memcpy(state
.map
, a
, dwords
* 4);
3044 static struct anv_state
3045 anv_cmd_buffer_merge_dynamic(struct anv_cmd_buffer
*cmd_buffer
,
3046 uint32_t *a
, uint32_t *b
,
3047 uint32_t dwords
, uint32_t alignment
)
3049 struct anv_state state
;
3052 state
= anv_state_stream_alloc(&cmd_buffer
->dynamic_state_stream
,
3053 dwords
* 4, alignment
);
3055 for (uint32_t i
= 0; i
< dwords
; i
++)
3062 anv_cmd_buffer_flush_state(struct anv_cmd_buffer
*cmd_buffer
)
3064 struct anv_pipeline
*pipeline
= cmd_buffer
->pipeline
;
3067 uint32_t vb_emit
= cmd_buffer
->vb_dirty
& pipeline
->vb_used
;
3070 const uint32_t num_buffers
= __builtin_popcount(vb_emit
);
3071 const uint32_t num_dwords
= 1 + num_buffers
* 4;
3073 p
= anv_batch_emitn(&cmd_buffer
->batch
, num_dwords
,
3074 GEN8_3DSTATE_VERTEX_BUFFERS
);
3076 for_each_bit(vb
, vb_emit
) {
3077 struct anv_buffer
*buffer
= cmd_buffer
->vertex_bindings
[vb
].buffer
;
3078 uint32_t offset
= cmd_buffer
->vertex_bindings
[vb
].offset
;
3080 struct GEN8_VERTEX_BUFFER_STATE state
= {
3081 .VertexBufferIndex
= vb
,
3082 .MemoryObjectControlState
= GEN8_MOCS
,
3083 .AddressModifyEnable
= true,
3084 .BufferPitch
= pipeline
->binding_stride
[vb
],
3085 .BufferStartingAddress
= { buffer
->bo
, buffer
->offset
+ offset
},
3086 .BufferSize
= buffer
->size
- offset
3089 GEN8_VERTEX_BUFFER_STATE_pack(&cmd_buffer
->batch
, &p
[1 + i
* 4], &state
);
3094 if (cmd_buffer
->dirty
& ANV_CMD_BUFFER_PIPELINE_DIRTY
)
3095 anv_batch_emit_batch(&cmd_buffer
->batch
, &pipeline
->batch
);
3097 if (cmd_buffer
->descriptors_dirty
)
3098 flush_descriptor_sets(cmd_buffer
);
3100 if (cmd_buffer
->dirty
& (ANV_CMD_BUFFER_PIPELINE_DIRTY
| ANV_CMD_BUFFER_RS_DIRTY
)) {
3101 anv_batch_emit_merge(&cmd_buffer
->batch
,
3102 cmd_buffer
->rs_state
->state_sf
, pipeline
->state_sf
);
3103 anv_batch_emit_merge(&cmd_buffer
->batch
,
3104 cmd_buffer
->rs_state
->state_raster
, pipeline
->state_raster
);
3107 if (cmd_buffer
->ds_state
&&
3108 (cmd_buffer
->dirty
& (ANV_CMD_BUFFER_PIPELINE_DIRTY
| ANV_CMD_BUFFER_DS_DIRTY
)))
3109 anv_batch_emit_merge(&cmd_buffer
->batch
,
3110 cmd_buffer
->ds_state
->state_wm_depth_stencil
,
3111 pipeline
->state_wm_depth_stencil
);
3113 if (cmd_buffer
->dirty
& (ANV_CMD_BUFFER_CB_DIRTY
| ANV_CMD_BUFFER_DS_DIRTY
)) {
3114 struct anv_state state
;
3115 if (cmd_buffer
->ds_state
== NULL
)
3116 state
= anv_cmd_buffer_emit_dynamic(cmd_buffer
,
3117 cmd_buffer
->cb_state
->state_color_calc
,
3118 GEN8_COLOR_CALC_STATE_length
, 64);
3119 else if (cmd_buffer
->cb_state
== NULL
)
3120 state
= anv_cmd_buffer_emit_dynamic(cmd_buffer
,
3121 cmd_buffer
->ds_state
->state_color_calc
,
3122 GEN8_COLOR_CALC_STATE_length
, 64);
3124 state
= anv_cmd_buffer_merge_dynamic(cmd_buffer
,
3125 cmd_buffer
->ds_state
->state_color_calc
,
3126 cmd_buffer
->cb_state
->state_color_calc
,
3127 GEN8_COLOR_CALC_STATE_length
, 64);
3129 anv_batch_emit(&cmd_buffer
->batch
,
3130 GEN8_3DSTATE_CC_STATE_POINTERS
,
3131 .ColorCalcStatePointer
= state
.offset
,
3132 .ColorCalcStatePointerValid
= true);
3135 cmd_buffer
->vb_dirty
&= ~vb_emit
;
3136 cmd_buffer
->dirty
= 0;
3140 VkCmdBuffer cmdBuffer
,
3141 uint32_t firstVertex
,
3142 uint32_t vertexCount
,
3143 uint32_t firstInstance
,
3144 uint32_t instanceCount
)
3146 struct anv_cmd_buffer
*cmd_buffer
= (struct anv_cmd_buffer
*) cmdBuffer
;
3148 anv_cmd_buffer_flush_state(cmd_buffer
);
3150 anv_batch_emit(&cmd_buffer
->batch
, GEN8_3DPRIMITIVE
,
3151 .VertexAccessType
= SEQUENTIAL
,
3152 .VertexCountPerInstance
= vertexCount
,
3153 .StartVertexLocation
= firstVertex
,
3154 .InstanceCount
= instanceCount
,
3155 .StartInstanceLocation
= firstInstance
,
3156 .BaseVertexLocation
= 0);
3159 void anv_CmdDrawIndexed(
3160 VkCmdBuffer cmdBuffer
,
3161 uint32_t firstIndex
,
3162 uint32_t indexCount
,
3163 int32_t vertexOffset
,
3164 uint32_t firstInstance
,
3165 uint32_t instanceCount
)
3167 struct anv_cmd_buffer
*cmd_buffer
= (struct anv_cmd_buffer
*) cmdBuffer
;
3169 anv_cmd_buffer_flush_state(cmd_buffer
);
3171 anv_batch_emit(&cmd_buffer
->batch
, GEN8_3DPRIMITIVE
,
3172 .VertexAccessType
= RANDOM
,
3173 .VertexCountPerInstance
= indexCount
,
3174 .StartVertexLocation
= firstIndex
,
3175 .InstanceCount
= instanceCount
,
3176 .StartInstanceLocation
= firstInstance
,
3177 .BaseVertexLocation
= vertexOffset
);
3181 anv_batch_lrm(struct anv_batch
*batch
,
3182 uint32_t reg
, struct anv_bo
*bo
, uint32_t offset
)
3184 anv_batch_emit(batch
, GEN8_MI_LOAD_REGISTER_MEM
,
3185 .RegisterAddress
= reg
,
3186 .MemoryAddress
= { bo
, offset
});
3190 anv_batch_lri(struct anv_batch
*batch
, uint32_t reg
, uint32_t imm
)
3192 anv_batch_emit(batch
, GEN8_MI_LOAD_REGISTER_IMM
,
3193 .RegisterOffset
= reg
,
3197 /* Auto-Draw / Indirect Registers */
3198 #define GEN7_3DPRIM_END_OFFSET 0x2420
3199 #define GEN7_3DPRIM_START_VERTEX 0x2430
3200 #define GEN7_3DPRIM_VERTEX_COUNT 0x2434
3201 #define GEN7_3DPRIM_INSTANCE_COUNT 0x2438
3202 #define GEN7_3DPRIM_START_INSTANCE 0x243C
3203 #define GEN7_3DPRIM_BASE_VERTEX 0x2440
3205 void anv_CmdDrawIndirect(
3206 VkCmdBuffer cmdBuffer
,
3208 VkDeviceSize offset
,
3212 struct anv_cmd_buffer
*cmd_buffer
= (struct anv_cmd_buffer
*) cmdBuffer
;
3213 struct anv_buffer
*buffer
= (struct anv_buffer
*) _buffer
;
3214 struct anv_bo
*bo
= buffer
->bo
;
3215 uint32_t bo_offset
= buffer
->offset
+ offset
;
3217 anv_cmd_buffer_flush_state(cmd_buffer
);
3219 anv_batch_lrm(&cmd_buffer
->batch
, GEN7_3DPRIM_VERTEX_COUNT
, bo
, bo_offset
);
3220 anv_batch_lrm(&cmd_buffer
->batch
, GEN7_3DPRIM_INSTANCE_COUNT
, bo
, bo_offset
+ 4);
3221 anv_batch_lrm(&cmd_buffer
->batch
, GEN7_3DPRIM_START_VERTEX
, bo
, bo_offset
+ 8);
3222 anv_batch_lrm(&cmd_buffer
->batch
, GEN7_3DPRIM_START_INSTANCE
, bo
, bo_offset
+ 12);
3223 anv_batch_lri(&cmd_buffer
->batch
, GEN7_3DPRIM_BASE_VERTEX
, 0);
3225 anv_batch_emit(&cmd_buffer
->batch
, GEN8_3DPRIMITIVE
,
3226 .IndirectParameterEnable
= true,
3227 .VertexAccessType
= SEQUENTIAL
);
3230 void anv_CmdDrawIndexedIndirect(
3231 VkCmdBuffer cmdBuffer
,
3233 VkDeviceSize offset
,
3237 struct anv_cmd_buffer
*cmd_buffer
= (struct anv_cmd_buffer
*) cmdBuffer
;
3238 struct anv_buffer
*buffer
= (struct anv_buffer
*) _buffer
;
3239 struct anv_bo
*bo
= buffer
->bo
;
3240 uint32_t bo_offset
= buffer
->offset
+ offset
;
3242 anv_cmd_buffer_flush_state(cmd_buffer
);
3244 anv_batch_lrm(&cmd_buffer
->batch
, GEN7_3DPRIM_VERTEX_COUNT
, bo
, bo_offset
);
3245 anv_batch_lrm(&cmd_buffer
->batch
, GEN7_3DPRIM_INSTANCE_COUNT
, bo
, bo_offset
+ 4);
3246 anv_batch_lrm(&cmd_buffer
->batch
, GEN7_3DPRIM_START_VERTEX
, bo
, bo_offset
+ 8);
3247 anv_batch_lrm(&cmd_buffer
->batch
, GEN7_3DPRIM_BASE_VERTEX
, bo
, bo_offset
+ 12);
3248 anv_batch_lrm(&cmd_buffer
->batch
, GEN7_3DPRIM_START_INSTANCE
, bo
, bo_offset
+ 16);
3250 anv_batch_emit(&cmd_buffer
->batch
, GEN8_3DPRIMITIVE
,
3251 .IndirectParameterEnable
= true,
3252 .VertexAccessType
= RANDOM
);
3255 void anv_CmdDispatch(
3256 VkCmdBuffer cmdBuffer
,
3264 void anv_CmdDispatchIndirect(
3265 VkCmdBuffer cmdBuffer
,
3267 VkDeviceSize offset
)
3272 void anv_CmdSetEvent(
3273 VkCmdBuffer cmdBuffer
,
3275 VkPipeEvent pipeEvent
)
3280 void anv_CmdResetEvent(
3281 VkCmdBuffer cmdBuffer
,
3283 VkPipeEvent pipeEvent
)
3288 void anv_CmdWaitEvents(
3289 VkCmdBuffer cmdBuffer
,
3290 VkWaitEvent waitEvent
,
3291 uint32_t eventCount
,
3292 const VkEvent
* pEvents
,
3293 uint32_t memBarrierCount
,
3294 const void** ppMemBarriers
)
3299 void anv_CmdPipelineBarrier(
3300 VkCmdBuffer cmdBuffer
,
3301 VkWaitEvent waitEvent
,
3302 uint32_t pipeEventCount
,
3303 const VkPipeEvent
* pPipeEvents
,
3304 uint32_t memBarrierCount
,
3305 const void** ppMemBarriers
)
3310 void anv_CmdInitAtomicCounters(
3311 VkCmdBuffer cmdBuffer
,
3312 VkPipelineBindPoint pipelineBindPoint
,
3313 uint32_t startCounter
,
3314 uint32_t counterCount
,
3315 const uint32_t* pData
)
3320 void anv_CmdLoadAtomicCounters(
3321 VkCmdBuffer cmdBuffer
,
3322 VkPipelineBindPoint pipelineBindPoint
,
3323 uint32_t startCounter
,
3324 uint32_t counterCount
,
3326 VkDeviceSize srcOffset
)
3331 void anv_CmdSaveAtomicCounters(
3332 VkCmdBuffer cmdBuffer
,
3333 VkPipelineBindPoint pipelineBindPoint
,
3334 uint32_t startCounter
,
3335 uint32_t counterCount
,
3336 VkBuffer destBuffer
,
3337 VkDeviceSize destOffset
)
3343 anv_framebuffer_destroy(struct anv_device
*device
,
3344 struct anv_object
*object
,
3345 VkObjectType obj_type
)
3347 struct anv_framebuffer
*fb
= (struct anv_framebuffer
*)object
;
3349 assert(obj_type
== VK_OBJECT_TYPE_FRAMEBUFFER
);
3351 anv_DestroyObject((VkDevice
) device
,
3352 VK_OBJECT_TYPE_DYNAMIC_VP_STATE
,
3355 anv_device_free(device
, fb
);
3358 VkResult
anv_CreateFramebuffer(
3360 const VkFramebufferCreateInfo
* pCreateInfo
,
3361 VkFramebuffer
* pFramebuffer
)
3363 struct anv_device
*device
= (struct anv_device
*) _device
;
3364 struct anv_framebuffer
*framebuffer
;
3366 static const struct anv_depth_stencil_view null_view
=
3367 { .depth_format
= D16_UNORM
, .depth_stride
= 0, .stencil_stride
= 0 };
3369 assert(pCreateInfo
->sType
== VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO
);
3371 framebuffer
= anv_device_alloc(device
, sizeof(*framebuffer
), 8,
3372 VK_SYSTEM_ALLOC_TYPE_API_OBJECT
);
3373 if (framebuffer
== NULL
)
3374 return vk_error(VK_ERROR_OUT_OF_HOST_MEMORY
);
3376 framebuffer
->base
.destructor
= anv_framebuffer_destroy
;
3378 framebuffer
->color_attachment_count
= pCreateInfo
->colorAttachmentCount
;
3379 for (uint32_t i
= 0; i
< pCreateInfo
->colorAttachmentCount
; i
++) {
3380 framebuffer
->color_attachments
[i
] =
3381 (struct anv_surface_view
*) pCreateInfo
->pColorAttachments
[i
].view
;
3384 if (pCreateInfo
->pDepthStencilAttachment
) {
3385 framebuffer
->depth_stencil
=
3386 (struct anv_depth_stencil_view
*) pCreateInfo
->pDepthStencilAttachment
->view
;
3388 framebuffer
->depth_stencil
= &null_view
;
3391 framebuffer
->sample_count
= pCreateInfo
->sampleCount
;
3392 framebuffer
->width
= pCreateInfo
->width
;
3393 framebuffer
->height
= pCreateInfo
->height
;
3394 framebuffer
->layers
= pCreateInfo
->layers
;
3396 vkCreateDynamicViewportState((VkDevice
) device
,
3397 &(VkDynamicVpStateCreateInfo
) {
3398 .sType
= VK_STRUCTURE_TYPE_DYNAMIC_VP_STATE_CREATE_INFO
,
3399 .viewportAndScissorCount
= 1,
3400 .pViewports
= (VkViewport
[]) {
3404 .width
= pCreateInfo
->width
,
3405 .height
= pCreateInfo
->height
,
3410 .pScissors
= (VkRect
[]) {
3412 { pCreateInfo
->width
, pCreateInfo
->height
} },
3415 &framebuffer
->vp_state
);
3417 *pFramebuffer
= (VkFramebuffer
) framebuffer
;
3422 VkResult
anv_CreateRenderPass(
3424 const VkRenderPassCreateInfo
* pCreateInfo
,
3425 VkRenderPass
* pRenderPass
)
3427 struct anv_device
*device
= (struct anv_device
*) _device
;
3428 struct anv_render_pass
*pass
;
3431 assert(pCreateInfo
->sType
== VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO
);
3433 size
= sizeof(*pass
) +
3434 pCreateInfo
->layers
* sizeof(struct anv_render_pass_layer
);
3435 pass
= anv_device_alloc(device
, size
, 8,
3436 VK_SYSTEM_ALLOC_TYPE_API_OBJECT
);
3438 return vk_error(VK_ERROR_OUT_OF_HOST_MEMORY
);
3440 pass
->render_area
= pCreateInfo
->renderArea
;
3442 pass
->num_layers
= pCreateInfo
->layers
;
3444 pass
->num_clear_layers
= 0;
3445 for (uint32_t i
= 0; i
< pCreateInfo
->layers
; i
++) {
3446 pass
->layers
[i
].color_load_op
= pCreateInfo
->pColorLoadOps
[i
];
3447 pass
->layers
[i
].clear_color
= pCreateInfo
->pColorLoadClearValues
[i
];
3448 if (pass
->layers
[i
].color_load_op
== VK_ATTACHMENT_LOAD_OP_CLEAR
)
3449 pass
->num_clear_layers
++;
3452 *pRenderPass
= (VkRenderPass
) pass
;
3458 anv_cmd_buffer_emit_depth_stencil(struct anv_cmd_buffer
*cmd_buffer
,
3459 struct anv_render_pass
*pass
)
3461 const struct anv_depth_stencil_view
*view
=
3462 cmd_buffer
->framebuffer
->depth_stencil
;
3464 /* FIXME: Implement the PMA stall W/A */
3466 anv_batch_emit(&cmd_buffer
->batch
, GEN8_3DSTATE_DEPTH_BUFFER
,
3467 .SurfaceType
= SURFTYPE_2D
,
3468 .DepthWriteEnable
= view
->depth_stride
> 0,
3469 .StencilWriteEnable
= view
->stencil_stride
> 0,
3470 .HierarchicalDepthBufferEnable
= false,
3471 .SurfaceFormat
= view
->depth_format
,
3472 .SurfacePitch
= view
->depth_stride
> 0 ? view
->depth_stride
- 1 : 0,
3473 .SurfaceBaseAddress
= { view
->bo
, view
->depth_offset
},
3474 .Height
= pass
->render_area
.extent
.height
- 1,
3475 .Width
= pass
->render_area
.extent
.width
- 1,
3478 .MinimumArrayElement
= 0,
3479 .DepthBufferObjectControlState
= GEN8_MOCS
,
3480 .RenderTargetViewExtent
= 1 - 1,
3481 .SurfaceQPitch
= 0);
3483 /* Disable hierarchial depth buffers. */
3484 anv_batch_emit(&cmd_buffer
->batch
, GEN8_3DSTATE_HIER_DEPTH_BUFFER
);
3486 anv_batch_emit(&cmd_buffer
->batch
, GEN8_3DSTATE_STENCIL_BUFFER
,
3487 .StencilBufferEnable
= view
->stencil_stride
> 0,
3488 .StencilBufferObjectControlState
= GEN8_MOCS
,
3489 .SurfacePitch
= view
->stencil_stride
> 0 ? view
->stencil_stride
- 1 : 0,
3490 .SurfaceBaseAddress
= { view
->bo
, view
->stencil_offset
},
3491 .SurfaceQPitch
= 0);
3493 /* Clear the clear params. */
3494 anv_batch_emit(&cmd_buffer
->batch
, GEN8_3DSTATE_CLEAR_PARAMS
);
3497 void anv_CmdBeginRenderPass(
3498 VkCmdBuffer cmdBuffer
,
3499 const VkRenderPassBegin
* pRenderPassBegin
)
3501 struct anv_cmd_buffer
*cmd_buffer
= (struct anv_cmd_buffer
*) cmdBuffer
;
3502 struct anv_render_pass
*pass
= (struct anv_render_pass
*) pRenderPassBegin
->renderPass
;
3503 struct anv_framebuffer
*framebuffer
=
3504 (struct anv_framebuffer
*) pRenderPassBegin
->framebuffer
;
3506 cmd_buffer
->framebuffer
= framebuffer
;
3508 cmd_buffer
->descriptors_dirty
|= VK_SHADER_STAGE_FRAGMENT_BIT
;
3510 anv_batch_emit(&cmd_buffer
->batch
, GEN8_3DSTATE_DRAWING_RECTANGLE
,
3511 .ClippedDrawingRectangleYMin
= pass
->render_area
.offset
.y
,
3512 .ClippedDrawingRectangleXMin
= pass
->render_area
.offset
.x
,
3513 .ClippedDrawingRectangleYMax
=
3514 pass
->render_area
.offset
.y
+ pass
->render_area
.extent
.height
- 1,
3515 .ClippedDrawingRectangleXMax
=
3516 pass
->render_area
.offset
.x
+ pass
->render_area
.extent
.width
- 1,
3517 .DrawingRectangleOriginY
= 0,
3518 .DrawingRectangleOriginX
= 0);
3520 anv_cmd_buffer_emit_depth_stencil(cmd_buffer
, pass
);
3522 anv_cmd_buffer_clear(cmd_buffer
, pass
);
3525 void anv_CmdEndRenderPass(
3526 VkCmdBuffer cmdBuffer
,
3527 VkRenderPass renderPass
)
3529 /* Emit a flushing pipe control at the end of a pass. This is kind of a
3530 * hack but it ensures that render targets always actually get written.
3531 * Eventually, we should do flushing based on image format transitions
3532 * or something of that nature.
3534 struct anv_cmd_buffer
*cmd_buffer
= (struct anv_cmd_buffer
*)cmdBuffer
;
3535 anv_batch_emit(&cmd_buffer
->batch
, GEN8_PIPE_CONTROL
,
3536 .PostSyncOperation
= NoWrite
,
3537 .RenderTargetCacheFlushEnable
= true,
3538 .InstructionCacheInvalidateEnable
= true,
3539 .DepthCacheFlushEnable
= true,
3540 .VFCacheInvalidationEnable
= true,
3541 .TextureCacheInvalidationEnable
= true,
3542 .CommandStreamerStallEnable
= true);
3545 void vkCmdDbgMarkerBegin(
3546 VkCmdBuffer cmdBuffer
,
3547 const char* pMarker
)
3548 __attribute__ ((visibility ("default")));
3550 void vkCmdDbgMarkerEnd(
3551 VkCmdBuffer cmdBuffer
)
3552 __attribute__ ((visibility ("default")));
3554 VkResult
vkDbgSetObjectTag(
3559 __attribute__ ((visibility ("default")));
3562 void vkCmdDbgMarkerBegin(
3563 VkCmdBuffer cmdBuffer
,
3564 const char* pMarker
)
3568 void vkCmdDbgMarkerEnd(
3569 VkCmdBuffer cmdBuffer
)
3573 VkResult
vkDbgSetObjectTag(