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_queue_init(struct anv_device
*device
, struct anv_queue
*queue
)
309 queue
->device
= device
;
310 queue
->pool
= &device
->surface_state_pool
;
312 queue
->completed_serial
= anv_state_pool_alloc(queue
->pool
, 4, 4);
313 if (queue
->completed_serial
.map
== NULL
)
314 return vk_error(VK_ERROR_OUT_OF_DEVICE_MEMORY
);
316 *(uint32_t *)queue
->completed_serial
.map
= 0;
317 queue
->next_serial
= 1;
323 anv_queue_finish(struct anv_queue
*queue
)
326 /* This gets torn down with the device so we only need to do this if
327 * valgrind is present.
329 anv_state_pool_free(queue
->pool
, queue
->completed_serial
);
334 anv_device_init_border_colors(struct anv_device
*device
)
336 float float_border_colors
[][4] = {
337 [VK_BORDER_COLOR_OPAQUE_WHITE
] = { 1.0, 1.0, 1.0, 1.0 },
338 [VK_BORDER_COLOR_TRANSPARENT_BLACK
] = { 0.0, 0.0, 0.0, 0.0 },
339 [VK_BORDER_COLOR_OPAQUE_BLACK
] = { 0.0, 0.0, 0.0, 1.0 }
342 uint32_t uint32_border_colors
[][4] = {
343 [VK_BORDER_COLOR_OPAQUE_WHITE
] = { 1, 1, 1, 1 },
344 [VK_BORDER_COLOR_TRANSPARENT_BLACK
] = { 0, 0, 0, 0 },
345 [VK_BORDER_COLOR_OPAQUE_BLACK
] = { 0, 0, 0, 1 }
348 device
->float_border_colors
=
349 anv_state_pool_alloc(&device
->dynamic_state_pool
,
350 sizeof(float_border_colors
), 32);
351 memcpy(device
->float_border_colors
.map
,
352 float_border_colors
, sizeof(float_border_colors
));
354 device
->uint32_border_colors
=
355 anv_state_pool_alloc(&device
->dynamic_state_pool
,
356 sizeof(uint32_border_colors
), 32);
357 memcpy(device
->uint32_border_colors
.map
,
358 uint32_border_colors
, sizeof(uint32_border_colors
));
362 static const uint32_t BATCH_SIZE
= 8192;
364 VkResult
anv_CreateDevice(
365 VkPhysicalDevice _physicalDevice
,
366 const VkDeviceCreateInfo
* pCreateInfo
,
369 struct anv_physical_device
*physicalDevice
=
370 (struct anv_physical_device
*) _physicalDevice
;
371 struct anv_instance
*instance
= physicalDevice
->instance
;
372 struct anv_device
*device
;
374 assert(pCreateInfo
->sType
== VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO
);
376 device
= instance
->pfnAlloc(instance
->pAllocUserData
,
378 VK_SYSTEM_ALLOC_TYPE_API_OBJECT
);
380 return vk_error(VK_ERROR_OUT_OF_HOST_MEMORY
);
382 device
->no_hw
= physicalDevice
->no_hw
;
383 parse_debug_flags(device
);
385 device
->instance
= physicalDevice
->instance
;
386 device
->fd
= open("/dev/dri/renderD128", O_RDWR
| O_CLOEXEC
);
387 if (device
->fd
== -1)
390 device
->context_id
= anv_gem_create_context(device
);
391 if (device
->context_id
== -1)
394 anv_bo_pool_init(&device
->batch_bo_pool
, device
, BATCH_SIZE
);
396 anv_block_pool_init(&device
->dynamic_state_block_pool
, device
, 2048);
398 anv_state_pool_init(&device
->dynamic_state_pool
,
399 &device
->dynamic_state_block_pool
);
401 anv_block_pool_init(&device
->instruction_block_pool
, device
, 2048);
402 anv_block_pool_init(&device
->surface_state_block_pool
, device
, 2048);
404 anv_state_pool_init(&device
->surface_state_pool
,
405 &device
->surface_state_block_pool
);
407 anv_block_pool_init(&device
->scratch_block_pool
, device
, 0x10000);
409 device
->info
= *physicalDevice
->info
;
411 device
->compiler
= anv_compiler_create(device
);
412 device
->aub_writer
= NULL
;
414 pthread_mutex_init(&device
->mutex
, NULL
);
416 anv_queue_init(device
, &device
->queue
);
418 anv_device_init_meta(device
);
420 anv_device_init_border_colors(device
);
422 *pDevice
= (VkDevice
) device
;
429 anv_device_free(device
, device
);
431 return vk_error(VK_ERROR_UNAVAILABLE
);
434 VkResult
anv_DestroyDevice(
437 struct anv_device
*device
= (struct anv_device
*) _device
;
439 anv_compiler_destroy(device
->compiler
);
441 anv_queue_finish(&device
->queue
);
443 anv_device_finish_meta(device
);
446 /* We only need to free these to prevent valgrind errors. The backing
447 * BO will go away in a couple of lines so we don't actually leak.
449 anv_state_pool_free(&device
->dynamic_state_pool
,
450 device
->float_border_colors
);
451 anv_state_pool_free(&device
->dynamic_state_pool
,
452 device
->uint32_border_colors
);
455 anv_bo_pool_finish(&device
->batch_bo_pool
);
456 anv_block_pool_finish(&device
->dynamic_state_block_pool
);
457 anv_block_pool_finish(&device
->instruction_block_pool
);
458 anv_block_pool_finish(&device
->surface_state_block_pool
);
462 if (device
->aub_writer
)
463 anv_aub_writer_destroy(device
->aub_writer
);
465 anv_device_free(device
, device
);
470 VkResult
anv_GetGlobalExtensionInfo(
471 VkExtensionInfoType infoType
,
472 uint32_t extensionIndex
,
476 static const VkExtensionProperties extensions
[] = {
478 .extName
= "VK_WSI_LunarG",
482 uint32_t count
= ARRAY_SIZE(extensions
);
485 case VK_EXTENSION_INFO_TYPE_COUNT
:
486 memcpy(pData
, &count
, sizeof(count
));
487 *pDataSize
= sizeof(count
);
490 case VK_EXTENSION_INFO_TYPE_PROPERTIES
:
491 if (extensionIndex
>= count
)
492 return vk_error(VK_ERROR_INVALID_EXTENSION
);
494 memcpy(pData
, &extensions
[extensionIndex
], sizeof(extensions
[0]));
495 *pDataSize
= sizeof(extensions
[0]);
499 return VK_UNSUPPORTED
;
503 VkResult
anv_GetPhysicalDeviceExtensionInfo(
504 VkPhysicalDevice physicalDevice
,
505 VkExtensionInfoType infoType
,
506 uint32_t extensionIndex
,
513 case VK_EXTENSION_INFO_TYPE_COUNT
:
522 case VK_EXTENSION_INFO_TYPE_PROPERTIES
:
523 return vk_error(VK_ERROR_INVALID_EXTENSION
);
526 return VK_UNSUPPORTED
;
530 VkResult
anv_EnumerateLayers(
531 VkPhysicalDevice physicalDevice
,
532 size_t maxStringSize
,
534 char* const* pOutLayers
,
542 VkResult
anv_GetDeviceQueue(
544 uint32_t queueNodeIndex
,
548 struct anv_device
*device
= (struct anv_device
*) _device
;
550 assert(queueIndex
== 0);
552 *pQueue
= (VkQueue
) &device
->queue
;
558 anv_reloc_list_init(struct anv_reloc_list
*list
, struct anv_device
*device
)
560 list
->num_relocs
= 0;
561 list
->array_length
= 256;
563 anv_device_alloc(device
, list
->array_length
* sizeof(*list
->relocs
), 8,
564 VK_SYSTEM_ALLOC_TYPE_INTERNAL
);
566 if (list
->relocs
== NULL
)
567 return vk_error(VK_ERROR_OUT_OF_HOST_MEMORY
);
570 anv_device_alloc(device
, list
->array_length
* sizeof(*list
->reloc_bos
), 8,
571 VK_SYSTEM_ALLOC_TYPE_INTERNAL
);
573 if (list
->relocs
== NULL
) {
574 anv_device_free(device
, list
->relocs
);
575 return vk_error(VK_ERROR_OUT_OF_HOST_MEMORY
);
582 anv_reloc_list_finish(struct anv_reloc_list
*list
, struct anv_device
*device
)
584 anv_device_free(device
, list
->relocs
);
585 anv_device_free(device
, list
->reloc_bos
);
589 anv_reloc_list_grow(struct anv_reloc_list
*list
, struct anv_device
*device
,
590 size_t num_additional_relocs
)
592 if (list
->num_relocs
+ num_additional_relocs
<= list
->array_length
)
595 size_t new_length
= list
->array_length
* 2;
596 while (new_length
< list
->num_relocs
+ num_additional_relocs
)
599 struct drm_i915_gem_relocation_entry
*new_relocs
=
600 anv_device_alloc(device
, new_length
* sizeof(*list
->relocs
), 8,
601 VK_SYSTEM_ALLOC_TYPE_INTERNAL
);
602 if (new_relocs
== NULL
)
603 return vk_error(VK_ERROR_OUT_OF_HOST_MEMORY
);
605 struct anv_bo
**new_reloc_bos
=
606 anv_device_alloc(device
, new_length
* sizeof(*list
->reloc_bos
), 8,
607 VK_SYSTEM_ALLOC_TYPE_INTERNAL
);
608 if (new_relocs
== NULL
) {
609 anv_device_free(device
, new_relocs
);
610 return vk_error(VK_ERROR_OUT_OF_HOST_MEMORY
);
613 memcpy(new_relocs
, list
->relocs
, list
->num_relocs
* sizeof(*list
->relocs
));
614 memcpy(new_reloc_bos
, list
->reloc_bos
,
615 list
->num_relocs
* sizeof(*list
->reloc_bos
));
617 anv_device_free(device
, list
->relocs
);
618 anv_device_free(device
, list
->reloc_bos
);
620 list
->relocs
= new_relocs
;
621 list
->reloc_bos
= new_reloc_bos
;
627 anv_batch_bo_create(struct anv_device
*device
, struct anv_batch_bo
**bbo_out
)
631 struct anv_batch_bo
*bbo
=
632 anv_device_alloc(device
, sizeof(*bbo
), 8, VK_SYSTEM_ALLOC_TYPE_INTERNAL
);
634 return vk_error(VK_ERROR_OUT_OF_HOST_MEMORY
);
637 bbo
->prev_batch_bo
= NULL
;
639 result
= anv_bo_pool_alloc(&device
->batch_bo_pool
, &bbo
->bo
);
640 if (result
!= VK_SUCCESS
) {
641 anv_device_free(device
, bbo
);
651 anv_batch_bo_start(struct anv_batch_bo
*bbo
, struct anv_batch
*batch
,
652 size_t batch_padding
)
654 batch
->next
= batch
->start
= bbo
->bo
.map
;
655 batch
->end
= bbo
->bo
.map
+ bbo
->bo
.size
- batch_padding
;
656 bbo
->first_reloc
= batch
->relocs
.num_relocs
;
660 anv_batch_bo_finish(struct anv_batch_bo
*bbo
, struct anv_batch
*batch
)
662 assert(batch
->start
== bbo
->bo
.map
);
663 bbo
->length
= batch
->next
- batch
->start
;
664 VG(VALGRIND_CHECK_MEM_IS_DEFINED(batch
->start
, bbo
->length
));
665 bbo
->num_relocs
= batch
->relocs
.num_relocs
- bbo
->first_reloc
;
669 anv_batch_bo_destroy(struct anv_batch_bo
*bbo
, struct anv_device
*device
)
671 anv_bo_pool_free(&device
->batch_bo_pool
, &bbo
->bo
);
672 anv_device_free(device
, bbo
);
676 anv_batch_emit_dwords(struct anv_batch
*batch
, int num_dwords
)
678 if (batch
->next
+ num_dwords
* 4 > batch
->end
)
679 batch
->extend_cb(batch
, batch
->user_data
);
681 void *p
= batch
->next
;
683 batch
->next
+= num_dwords
* 4;
684 assert(batch
->next
<= batch
->end
);
690 anv_reloc_list_append(struct anv_reloc_list
*list
, struct anv_device
*device
,
691 struct anv_reloc_list
*other
, uint32_t offset
)
693 anv_reloc_list_grow(list
, device
, other
->num_relocs
);
694 /* TODO: Handle failure */
696 memcpy(&list
->relocs
[list
->num_relocs
], &other
->relocs
[0],
697 other
->num_relocs
* sizeof(other
->relocs
[0]));
698 memcpy(&list
->reloc_bos
[list
->num_relocs
], &other
->reloc_bos
[0],
699 other
->num_relocs
* sizeof(other
->reloc_bos
[0]));
701 for (uint32_t i
= 0; i
< other
->num_relocs
; i
++)
702 list
->relocs
[i
+ list
->num_relocs
].offset
+= offset
;
704 list
->num_relocs
+= other
->num_relocs
;
708 anv_reloc_list_add(struct anv_reloc_list
*list
, struct anv_device
*device
,
709 uint32_t offset
, struct anv_bo
*target_bo
, uint32_t delta
)
711 struct drm_i915_gem_relocation_entry
*entry
;
714 anv_reloc_list_grow(list
, device
, 1);
715 /* TODO: Handle failure */
717 /* XXX: Can we use I915_EXEC_HANDLE_LUT? */
718 index
= list
->num_relocs
++;
719 list
->reloc_bos
[index
] = target_bo
;
720 entry
= &list
->relocs
[index
];
721 entry
->target_handle
= target_bo
->gem_handle
;
722 entry
->delta
= delta
;
723 entry
->offset
= offset
;
724 entry
->presumed_offset
= target_bo
->offset
;
725 entry
->read_domains
= 0;
726 entry
->write_domain
= 0;
728 return target_bo
->offset
+ delta
;
732 anv_batch_emit_batch(struct anv_batch
*batch
, struct anv_batch
*other
)
734 uint32_t size
, offset
;
736 size
= other
->next
- other
->start
;
737 assert(size
% 4 == 0);
739 if (batch
->next
+ size
> batch
->end
)
740 batch
->extend_cb(batch
, batch
->user_data
);
742 assert(batch
->next
+ size
<= batch
->end
);
744 memcpy(batch
->next
, other
->start
, size
);
746 offset
= batch
->next
- batch
->start
;
747 anv_reloc_list_append(&batch
->relocs
, batch
->device
,
748 &other
->relocs
, offset
);
754 anv_batch_emit_reloc(struct anv_batch
*batch
,
755 void *location
, struct anv_bo
*bo
, uint32_t delta
)
757 return anv_reloc_list_add(&batch
->relocs
, batch
->device
,
758 location
- batch
->start
, bo
, delta
);
761 VkResult
anv_QueueSubmit(
763 uint32_t cmdBufferCount
,
764 const VkCmdBuffer
* pCmdBuffers
,
767 struct anv_queue
*queue
= (struct anv_queue
*) _queue
;
768 struct anv_device
*device
= queue
->device
;
769 struct anv_fence
*fence
= (struct anv_fence
*) _fence
;
772 for (uint32_t i
= 0; i
< cmdBufferCount
; i
++) {
773 struct anv_cmd_buffer
*cmd_buffer
=
774 (struct anv_cmd_buffer
*) pCmdBuffers
[i
];
776 if (device
->dump_aub
)
777 anv_cmd_buffer_dump(cmd_buffer
);
779 if (!device
->no_hw
) {
780 ret
= anv_gem_execbuffer(device
, &cmd_buffer
->execbuf
);
782 return vk_error(VK_ERROR_UNKNOWN
);
785 ret
= anv_gem_execbuffer(device
, &fence
->execbuf
);
787 return vk_error(VK_ERROR_UNKNOWN
);
790 for (uint32_t i
= 0; i
< cmd_buffer
->bo_count
; i
++)
791 cmd_buffer
->exec2_bos
[i
]->offset
= cmd_buffer
->exec2_objects
[i
].offset
;
793 *(uint32_t *)queue
->completed_serial
.map
= cmd_buffer
->serial
;
800 VkResult
anv_QueueAddMemReferences(
803 const VkDeviceMemory
* pMems
)
808 VkResult
anv_QueueRemoveMemReferences(
811 const VkDeviceMemory
* pMems
)
816 VkResult
anv_QueueWaitIdle(
819 struct anv_queue
*queue
= (struct anv_queue
*) _queue
;
821 return vkDeviceWaitIdle((VkDevice
) queue
->device
);
824 VkResult
anv_DeviceWaitIdle(
827 struct anv_device
*device
= (struct anv_device
*) _device
;
828 struct anv_state state
;
829 struct anv_batch batch
;
830 struct drm_i915_gem_execbuffer2 execbuf
;
831 struct drm_i915_gem_exec_object2 exec2_objects
[1];
832 struct anv_bo
*bo
= NULL
;
837 state
= anv_state_pool_alloc(&device
->dynamic_state_pool
, 32, 32);
838 bo
= &device
->dynamic_state_pool
.block_pool
->bo
;
839 batch
.start
= batch
.next
= state
.map
;
840 batch
.end
= state
.map
+ 32;
841 anv_batch_emit(&batch
, GEN8_MI_BATCH_BUFFER_END
);
842 anv_batch_emit(&batch
, GEN8_MI_NOOP
);
844 exec2_objects
[0].handle
= bo
->gem_handle
;
845 exec2_objects
[0].relocation_count
= 0;
846 exec2_objects
[0].relocs_ptr
= 0;
847 exec2_objects
[0].alignment
= 0;
848 exec2_objects
[0].offset
= bo
->offset
;
849 exec2_objects
[0].flags
= 0;
850 exec2_objects
[0].rsvd1
= 0;
851 exec2_objects
[0].rsvd2
= 0;
853 execbuf
.buffers_ptr
= (uintptr_t) exec2_objects
;
854 execbuf
.buffer_count
= 1;
855 execbuf
.batch_start_offset
= state
.offset
;
856 execbuf
.batch_len
= batch
.next
- state
.map
;
857 execbuf
.cliprects_ptr
= 0;
858 execbuf
.num_cliprects
= 0;
863 I915_EXEC_HANDLE_LUT
| I915_EXEC_NO_RELOC
| I915_EXEC_RENDER
;
864 execbuf
.rsvd1
= device
->context_id
;
867 if (!device
->no_hw
) {
868 ret
= anv_gem_execbuffer(device
, &execbuf
);
870 result
= vk_error(VK_ERROR_UNKNOWN
);
875 ret
= anv_gem_wait(device
, bo
->gem_handle
, &timeout
);
877 result
= vk_error(VK_ERROR_UNKNOWN
);
882 anv_state_pool_free(&device
->dynamic_state_pool
, state
);
887 anv_state_pool_free(&device
->dynamic_state_pool
, state
);
893 anv_device_alloc(struct anv_device
* device
,
896 VkSystemAllocType allocType
)
898 return device
->instance
->pfnAlloc(device
->instance
->pAllocUserData
,
905 anv_device_free(struct anv_device
* device
,
908 return device
->instance
->pfnFree(device
->instance
->pAllocUserData
,
913 anv_bo_init_new(struct anv_bo
*bo
, struct anv_device
*device
, uint64_t size
)
915 bo
->gem_handle
= anv_gem_create(device
, size
);
917 return vk_error(VK_ERROR_OUT_OF_DEVICE_MEMORY
);
927 VkResult
anv_AllocMemory(
929 const VkMemoryAllocInfo
* pAllocInfo
,
930 VkDeviceMemory
* pMem
)
932 struct anv_device
*device
= (struct anv_device
*) _device
;
933 struct anv_device_memory
*mem
;
936 assert(pAllocInfo
->sType
== VK_STRUCTURE_TYPE_MEMORY_ALLOC_INFO
);
938 mem
= anv_device_alloc(device
, sizeof(*mem
), 8,
939 VK_SYSTEM_ALLOC_TYPE_API_OBJECT
);
941 return vk_error(VK_ERROR_OUT_OF_HOST_MEMORY
);
943 result
= anv_bo_init_new(&mem
->bo
, device
, pAllocInfo
->allocationSize
);
944 if (result
!= VK_SUCCESS
)
947 *pMem
= (VkDeviceMemory
) mem
;
952 anv_device_free(device
, mem
);
957 VkResult
anv_FreeMemory(
961 struct anv_device
*device
= (struct anv_device
*) _device
;
962 struct anv_device_memory
*mem
= (struct anv_device_memory
*) _mem
;
965 anv_gem_munmap(mem
->bo
.map
, mem
->bo
.size
);
967 if (mem
->bo
.gem_handle
!= 0)
968 anv_gem_close(device
, mem
->bo
.gem_handle
);
970 anv_device_free(device
, mem
);
975 VkResult
anv_SetMemoryPriority(
978 VkMemoryPriority priority
)
983 VkResult
anv_MapMemory(
988 VkMemoryMapFlags flags
,
991 struct anv_device
*device
= (struct anv_device
*) _device
;
992 struct anv_device_memory
*mem
= (struct anv_device_memory
*) _mem
;
994 /* FIXME: Is this supposed to be thread safe? Since vkUnmapMemory() only
995 * takes a VkDeviceMemory pointer, it seems like only one map of the memory
996 * at a time is valid. We could just mmap up front and return an offset
997 * pointer here, but that may exhaust virtual memory on 32 bit
1000 mem
->map
= anv_gem_mmap(device
, mem
->bo
.gem_handle
, offset
, size
);
1001 mem
->map_size
= size
;
1008 VkResult
anv_UnmapMemory(
1010 VkDeviceMemory _mem
)
1012 struct anv_device_memory
*mem
= (struct anv_device_memory
*) _mem
;
1014 anv_gem_munmap(mem
->map
, mem
->map_size
);
1019 VkResult
anv_FlushMappedMemory(
1022 VkDeviceSize offset
,
1025 /* clflush here for !llc platforms */
1030 VkResult
anv_PinSystemMemory(
1032 const void* pSysMem
,
1034 VkDeviceMemory
* pMem
)
1039 VkResult
anv_GetMultiDeviceCompatibility(
1040 VkPhysicalDevice physicalDevice0
,
1041 VkPhysicalDevice physicalDevice1
,
1042 VkPhysicalDeviceCompatibilityInfo
* pInfo
)
1044 return VK_UNSUPPORTED
;
1047 VkResult
anv_OpenSharedMemory(
1049 const VkMemoryOpenInfo
* pOpenInfo
,
1050 VkDeviceMemory
* pMem
)
1052 return VK_UNSUPPORTED
;
1055 VkResult
anv_OpenSharedSemaphore(
1057 const VkSemaphoreOpenInfo
* pOpenInfo
,
1058 VkSemaphore
* pSemaphore
)
1060 return VK_UNSUPPORTED
;
1063 VkResult
anv_OpenPeerMemory(
1065 const VkPeerMemoryOpenInfo
* pOpenInfo
,
1066 VkDeviceMemory
* pMem
)
1068 return VK_UNSUPPORTED
;
1071 VkResult
anv_OpenPeerImage(
1073 const VkPeerImageOpenInfo
* pOpenInfo
,
1075 VkDeviceMemory
* pMem
)
1077 return VK_UNSUPPORTED
;
1080 VkResult
anv_DestroyObject(
1082 VkObjectType objType
,
1085 struct anv_device
*device
= (struct anv_device
*) _device
;
1086 struct anv_object
*object
= (struct anv_object
*) _object
;
1089 case VK_OBJECT_TYPE_INSTANCE
:
1090 return anv_DestroyInstance((VkInstance
) _object
);
1092 case VK_OBJECT_TYPE_PHYSICAL_DEVICE
:
1093 /* We don't want to actually destroy physical devices */
1096 case VK_OBJECT_TYPE_DEVICE
:
1097 assert(_device
== (VkDevice
) _object
);
1098 return anv_DestroyDevice((VkDevice
) _object
);
1100 case VK_OBJECT_TYPE_QUEUE
:
1104 case VK_OBJECT_TYPE_DEVICE_MEMORY
:
1105 return anv_FreeMemory(_device
, (VkDeviceMemory
) _object
);
1107 case VK_OBJECT_TYPE_DESCRIPTOR_POOL
:
1108 /* These are just dummys anyway, so we don't need to destroy them */
1111 case VK_OBJECT_TYPE_BUFFER
:
1112 case VK_OBJECT_TYPE_IMAGE
:
1113 case VK_OBJECT_TYPE_DEPTH_STENCIL_VIEW
:
1114 case VK_OBJECT_TYPE_SHADER
:
1115 case VK_OBJECT_TYPE_PIPELINE_LAYOUT
:
1116 case VK_OBJECT_TYPE_SAMPLER
:
1117 case VK_OBJECT_TYPE_DESCRIPTOR_SET
:
1118 case VK_OBJECT_TYPE_DESCRIPTOR_SET_LAYOUT
:
1119 case VK_OBJECT_TYPE_DYNAMIC_RS_STATE
:
1120 case VK_OBJECT_TYPE_DYNAMIC_CB_STATE
:
1121 case VK_OBJECT_TYPE_DYNAMIC_DS_STATE
:
1122 case VK_OBJECT_TYPE_RENDER_PASS
:
1123 /* These are trivially destroyable */
1124 anv_device_free(device
, (void *) _object
);
1127 case VK_OBJECT_TYPE_COMMAND_BUFFER
:
1128 case VK_OBJECT_TYPE_PIPELINE
:
1129 case VK_OBJECT_TYPE_DYNAMIC_VP_STATE
:
1130 case VK_OBJECT_TYPE_FENCE
:
1131 case VK_OBJECT_TYPE_QUERY_POOL
:
1132 case VK_OBJECT_TYPE_FRAMEBUFFER
:
1133 case VK_OBJECT_TYPE_BUFFER_VIEW
:
1134 case VK_OBJECT_TYPE_IMAGE_VIEW
:
1135 case VK_OBJECT_TYPE_COLOR_ATTACHMENT_VIEW
:
1136 (object
->destructor
)(device
, object
, objType
);
1139 case VK_OBJECT_TYPE_SEMAPHORE
:
1140 case VK_OBJECT_TYPE_EVENT
:
1141 stub_return(VK_UNSUPPORTED
);
1144 unreachable("Invalid object type");
1149 fill_memory_requirements(
1150 VkObjectType objType
,
1152 VkMemoryRequirements
* memory_requirements
)
1154 struct anv_buffer
*buffer
;
1155 struct anv_image
*image
;
1157 memory_requirements
->memPropsAllowed
=
1158 VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT
|
1159 VK_MEMORY_PROPERTY_HOST_DEVICE_COHERENT_BIT
|
1160 /* VK_MEMORY_PROPERTY_HOST_UNCACHED_BIT | */
1161 VK_MEMORY_PROPERTY_HOST_WRITE_COMBINED_BIT
|
1162 VK_MEMORY_PROPERTY_PREFER_HOST_LOCAL
|
1163 VK_MEMORY_PROPERTY_SHAREABLE_BIT
;
1165 memory_requirements
->memPropsRequired
= 0;
1168 case VK_OBJECT_TYPE_BUFFER
:
1169 buffer
= (struct anv_buffer
*) object
;
1170 memory_requirements
->size
= buffer
->size
;
1171 memory_requirements
->alignment
= 16;
1173 case VK_OBJECT_TYPE_IMAGE
:
1174 image
= (struct anv_image
*) object
;
1175 memory_requirements
->size
= image
->size
;
1176 memory_requirements
->alignment
= image
->alignment
;
1179 memory_requirements
->size
= 0;
1185 get_allocation_count(VkObjectType objType
)
1188 case VK_OBJECT_TYPE_BUFFER
:
1189 case VK_OBJECT_TYPE_IMAGE
:
1196 VkResult
anv_GetObjectInfo(
1198 VkObjectType objType
,
1200 VkObjectInfoType infoType
,
1204 VkMemoryRequirements memory_requirements
;
1208 case VK_OBJECT_INFO_TYPE_MEMORY_REQUIREMENTS
:
1209 *pDataSize
= sizeof(memory_requirements
);
1213 fill_memory_requirements(objType
, object
, pData
);
1216 case VK_OBJECT_INFO_TYPE_MEMORY_ALLOCATION_COUNT
:
1217 *pDataSize
= sizeof(count
);
1222 *count
= get_allocation_count(objType
);
1226 return vk_error(VK_UNSUPPORTED
);
1231 VkResult
anv_QueueBindObjectMemory(
1233 VkObjectType objType
,
1235 uint32_t allocationIdx
,
1236 VkDeviceMemory _mem
,
1237 VkDeviceSize memOffset
)
1239 struct anv_buffer
*buffer
;
1240 struct anv_image
*image
;
1241 struct anv_device_memory
*mem
= (struct anv_device_memory
*) _mem
;
1244 case VK_OBJECT_TYPE_BUFFER
:
1245 buffer
= (struct anv_buffer
*) object
;
1246 buffer
->bo
= &mem
->bo
;
1247 buffer
->offset
= memOffset
;
1249 case VK_OBJECT_TYPE_IMAGE
:
1250 image
= (struct anv_image
*) object
;
1251 image
->bo
= &mem
->bo
;
1252 image
->offset
= memOffset
;
1261 VkResult
anv_QueueBindObjectMemoryRange(
1263 VkObjectType objType
,
1265 uint32_t allocationIdx
,
1266 VkDeviceSize rangeOffset
,
1267 VkDeviceSize rangeSize
,
1269 VkDeviceSize memOffset
)
1271 stub_return(VK_UNSUPPORTED
);
1274 VkResult
anv_QueueBindImageMemoryRange(
1277 uint32_t allocationIdx
,
1278 const VkImageMemoryBindInfo
* pBindInfo
,
1280 VkDeviceSize memOffset
)
1282 stub_return(VK_UNSUPPORTED
);
1286 anv_fence_destroy(struct anv_device
*device
,
1287 struct anv_object
*object
,
1288 VkObjectType obj_type
)
1290 struct anv_fence
*fence
= (struct anv_fence
*) object
;
1292 assert(obj_type
== VK_OBJECT_TYPE_FENCE
);
1294 anv_gem_munmap(fence
->bo
.map
, fence
->bo
.size
);
1295 anv_gem_close(device
, fence
->bo
.gem_handle
);
1296 anv_device_free(device
, fence
);
1299 VkResult
anv_CreateFence(
1301 const VkFenceCreateInfo
* pCreateInfo
,
1304 struct anv_device
*device
= (struct anv_device
*) _device
;
1305 struct anv_fence
*fence
;
1306 struct anv_batch batch
;
1309 const uint32_t fence_size
= 128;
1311 assert(pCreateInfo
->sType
== VK_STRUCTURE_TYPE_FENCE_CREATE_INFO
);
1313 fence
= anv_device_alloc(device
, sizeof(*fence
), 8,
1314 VK_SYSTEM_ALLOC_TYPE_API_OBJECT
);
1316 return vk_error(VK_ERROR_OUT_OF_HOST_MEMORY
);
1318 result
= anv_bo_init_new(&fence
->bo
, device
, fence_size
);
1319 if (result
!= VK_SUCCESS
)
1322 fence
->base
.destructor
= anv_fence_destroy
;
1325 anv_gem_mmap(device
, fence
->bo
.gem_handle
, 0, fence
->bo
.size
);
1326 batch
.next
= batch
.start
= fence
->bo
.map
;
1327 batch
.end
= fence
->bo
.map
+ fence
->bo
.size
;
1328 anv_batch_emit(&batch
, GEN8_MI_BATCH_BUFFER_END
);
1329 anv_batch_emit(&batch
, GEN8_MI_NOOP
);
1331 fence
->exec2_objects
[0].handle
= fence
->bo
.gem_handle
;
1332 fence
->exec2_objects
[0].relocation_count
= 0;
1333 fence
->exec2_objects
[0].relocs_ptr
= 0;
1334 fence
->exec2_objects
[0].alignment
= 0;
1335 fence
->exec2_objects
[0].offset
= fence
->bo
.offset
;
1336 fence
->exec2_objects
[0].flags
= 0;
1337 fence
->exec2_objects
[0].rsvd1
= 0;
1338 fence
->exec2_objects
[0].rsvd2
= 0;
1340 fence
->execbuf
.buffers_ptr
= (uintptr_t) fence
->exec2_objects
;
1341 fence
->execbuf
.buffer_count
= 1;
1342 fence
->execbuf
.batch_start_offset
= 0;
1343 fence
->execbuf
.batch_len
= batch
.next
- fence
->bo
.map
;
1344 fence
->execbuf
.cliprects_ptr
= 0;
1345 fence
->execbuf
.num_cliprects
= 0;
1346 fence
->execbuf
.DR1
= 0;
1347 fence
->execbuf
.DR4
= 0;
1349 fence
->execbuf
.flags
=
1350 I915_EXEC_HANDLE_LUT
| I915_EXEC_NO_RELOC
| I915_EXEC_RENDER
;
1351 fence
->execbuf
.rsvd1
= device
->context_id
;
1352 fence
->execbuf
.rsvd2
= 0;
1354 *pFence
= (VkFence
) fence
;
1359 anv_device_free(device
, fence
);
1364 VkResult
anv_ResetFences(
1366 uint32_t fenceCount
,
1369 struct anv_fence
**fences
= (struct anv_fence
**) pFences
;
1371 for (uint32_t i
= 0; i
< fenceCount
; i
++)
1372 fences
[i
]->ready
= false;
1377 VkResult
anv_GetFenceStatus(
1381 struct anv_device
*device
= (struct anv_device
*) _device
;
1382 struct anv_fence
*fence
= (struct anv_fence
*) _fence
;
1389 ret
= anv_gem_wait(device
, fence
->bo
.gem_handle
, &t
);
1391 fence
->ready
= true;
1395 return VK_NOT_READY
;
1398 VkResult
anv_WaitForFences(
1400 uint32_t fenceCount
,
1401 const VkFence
* pFences
,
1405 struct anv_device
*device
= (struct anv_device
*) _device
;
1406 struct anv_fence
**fences
= (struct anv_fence
**) pFences
;
1407 int64_t t
= timeout
;
1410 /* FIXME: handle !waitAll */
1412 for (uint32_t i
= 0; i
< fenceCount
; i
++) {
1413 ret
= anv_gem_wait(device
, fences
[i
]->bo
.gem_handle
, &t
);
1414 if (ret
== -1 && errno
== ETIME
)
1417 return vk_error(VK_ERROR_UNKNOWN
);
1423 // Queue semaphore functions
1425 VkResult
anv_CreateSemaphore(
1427 const VkSemaphoreCreateInfo
* pCreateInfo
,
1428 VkSemaphore
* pSemaphore
)
1430 stub_return(VK_UNSUPPORTED
);
1433 VkResult
anv_QueueSignalSemaphore(
1435 VkSemaphore semaphore
)
1437 stub_return(VK_UNSUPPORTED
);
1440 VkResult
anv_QueueWaitSemaphore(
1442 VkSemaphore semaphore
)
1444 stub_return(VK_UNSUPPORTED
);
1449 VkResult
anv_CreateEvent(
1451 const VkEventCreateInfo
* pCreateInfo
,
1454 stub_return(VK_UNSUPPORTED
);
1457 VkResult
anv_GetEventStatus(
1461 stub_return(VK_UNSUPPORTED
);
1464 VkResult
anv_SetEvent(
1468 stub_return(VK_UNSUPPORTED
);
1471 VkResult
anv_ResetEvent(
1475 stub_return(VK_UNSUPPORTED
);
1480 VkResult
anv_CreateBuffer(
1482 const VkBufferCreateInfo
* pCreateInfo
,
1485 struct anv_device
*device
= (struct anv_device
*) _device
;
1486 struct anv_buffer
*buffer
;
1488 assert(pCreateInfo
->sType
== VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO
);
1490 buffer
= anv_device_alloc(device
, sizeof(*buffer
), 8,
1491 VK_SYSTEM_ALLOC_TYPE_API_OBJECT
);
1493 return vk_error(VK_ERROR_OUT_OF_HOST_MEMORY
);
1495 buffer
->size
= pCreateInfo
->size
;
1499 *pBuffer
= (VkBuffer
) buffer
;
1504 // Buffer view functions
1507 fill_buffer_surface_state(void *state
, VkFormat format
,
1508 uint32_t offset
, uint32_t range
)
1510 const struct anv_format
*info
;
1512 info
= anv_format_for_vk_format(format
);
1513 /* This assumes RGBA float format. */
1514 uint32_t stride
= 4;
1515 uint32_t num_elements
= range
/ stride
;
1517 struct GEN8_RENDER_SURFACE_STATE surface_state
= {
1518 .SurfaceType
= SURFTYPE_BUFFER
,
1519 .SurfaceArray
= false,
1520 .SurfaceFormat
= info
->format
,
1521 .SurfaceVerticalAlignment
= VALIGN4
,
1522 .SurfaceHorizontalAlignment
= HALIGN4
,
1524 .VerticalLineStride
= 0,
1525 .VerticalLineStrideOffset
= 0,
1526 .SamplerL2BypassModeDisable
= true,
1527 .RenderCacheReadWriteMode
= WriteOnlyCache
,
1528 .MemoryObjectControlState
= GEN8_MOCS
,
1529 .BaseMipLevel
= 0.0,
1531 .Height
= (num_elements
>> 7) & 0x3fff,
1532 .Width
= num_elements
& 0x7f,
1533 .Depth
= (num_elements
>> 21) & 0x3f,
1534 .SurfacePitch
= stride
- 1,
1535 .MinimumArrayElement
= 0,
1536 .NumberofMultisamples
= MULTISAMPLECOUNT_1
,
1541 .AuxiliarySurfaceMode
= AUX_NONE
,
1543 .GreenClearColor
= 0,
1544 .BlueClearColor
= 0,
1545 .AlphaClearColor
= 0,
1546 .ShaderChannelSelectRed
= SCS_RED
,
1547 .ShaderChannelSelectGreen
= SCS_GREEN
,
1548 .ShaderChannelSelectBlue
= SCS_BLUE
,
1549 .ShaderChannelSelectAlpha
= SCS_ALPHA
,
1550 .ResourceMinLOD
= 0.0,
1551 /* FIXME: We assume that the image must be bound at this time. */
1552 .SurfaceBaseAddress
= { NULL
, offset
},
1555 GEN8_RENDER_SURFACE_STATE_pack(NULL
, state
, &surface_state
);
1558 VkResult
anv_CreateBufferView(
1560 const VkBufferViewCreateInfo
* pCreateInfo
,
1561 VkBufferView
* pView
)
1563 struct anv_device
*device
= (struct anv_device
*) _device
;
1564 struct anv_buffer
*buffer
= (struct anv_buffer
*) pCreateInfo
->buffer
;
1565 struct anv_surface_view
*view
;
1567 assert(pCreateInfo
->sType
== VK_STRUCTURE_TYPE_BUFFER_VIEW_CREATE_INFO
);
1569 view
= anv_device_alloc(device
, sizeof(*view
), 8,
1570 VK_SYSTEM_ALLOC_TYPE_API_OBJECT
);
1572 return vk_error(VK_ERROR_OUT_OF_HOST_MEMORY
);
1574 view
->base
.destructor
= anv_surface_view_destroy
;
1576 view
->bo
= buffer
->bo
;
1577 view
->offset
= buffer
->offset
+ pCreateInfo
->offset
;
1578 view
->surface_state
=
1579 anv_state_pool_alloc(&device
->surface_state_pool
, 64, 64);
1580 view
->format
= pCreateInfo
->format
;
1581 view
->range
= pCreateInfo
->range
;
1583 fill_buffer_surface_state(view
->surface_state
.map
,
1584 pCreateInfo
->format
, view
->offset
, pCreateInfo
->range
);
1586 *pView
= (VkBufferView
) view
;
1591 // Sampler functions
1593 VkResult
anv_CreateSampler(
1595 const VkSamplerCreateInfo
* pCreateInfo
,
1596 VkSampler
* pSampler
)
1598 struct anv_device
*device
= (struct anv_device
*) _device
;
1599 struct anv_sampler
*sampler
;
1600 uint32_t mag_filter
, min_filter
, max_anisotropy
;
1602 assert(pCreateInfo
->sType
== VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO
);
1604 sampler
= anv_device_alloc(device
, sizeof(*sampler
), 8,
1605 VK_SYSTEM_ALLOC_TYPE_API_OBJECT
);
1607 return vk_error(VK_ERROR_OUT_OF_HOST_MEMORY
);
1609 static const uint32_t vk_to_gen_tex_filter
[] = {
1610 [VK_TEX_FILTER_NEAREST
] = MAPFILTER_NEAREST
,
1611 [VK_TEX_FILTER_LINEAR
] = MAPFILTER_LINEAR
1614 static const uint32_t vk_to_gen_mipmap_mode
[] = {
1615 [VK_TEX_MIPMAP_MODE_BASE
] = MIPFILTER_NONE
,
1616 [VK_TEX_MIPMAP_MODE_NEAREST
] = MIPFILTER_NEAREST
,
1617 [VK_TEX_MIPMAP_MODE_LINEAR
] = MIPFILTER_LINEAR
1620 static const uint32_t vk_to_gen_tex_address
[] = {
1621 [VK_TEX_ADDRESS_WRAP
] = TCM_WRAP
,
1622 [VK_TEX_ADDRESS_MIRROR
] = TCM_MIRROR
,
1623 [VK_TEX_ADDRESS_CLAMP
] = TCM_CLAMP
,
1624 [VK_TEX_ADDRESS_MIRROR_ONCE
] = TCM_MIRROR_ONCE
,
1625 [VK_TEX_ADDRESS_CLAMP_BORDER
] = TCM_CLAMP_BORDER
,
1628 static const uint32_t vk_to_gen_compare_op
[] = {
1629 [VK_COMPARE_OP_NEVER
] = PREFILTEROPNEVER
,
1630 [VK_COMPARE_OP_LESS
] = PREFILTEROPLESS
,
1631 [VK_COMPARE_OP_EQUAL
] = PREFILTEROPEQUAL
,
1632 [VK_COMPARE_OP_LESS_EQUAL
] = PREFILTEROPLEQUAL
,
1633 [VK_COMPARE_OP_GREATER
] = PREFILTEROPGREATER
,
1634 [VK_COMPARE_OP_NOT_EQUAL
] = PREFILTEROPNOTEQUAL
,
1635 [VK_COMPARE_OP_GREATER_EQUAL
] = PREFILTEROPGEQUAL
,
1636 [VK_COMPARE_OP_ALWAYS
] = PREFILTEROPALWAYS
,
1639 if (pCreateInfo
->maxAnisotropy
> 1) {
1640 mag_filter
= MAPFILTER_ANISOTROPIC
;
1641 min_filter
= MAPFILTER_ANISOTROPIC
;
1642 max_anisotropy
= (pCreateInfo
->maxAnisotropy
- 2) / 2;
1644 mag_filter
= vk_to_gen_tex_filter
[pCreateInfo
->magFilter
];
1645 min_filter
= vk_to_gen_tex_filter
[pCreateInfo
->minFilter
];
1646 max_anisotropy
= RATIO21
;
1649 struct GEN8_SAMPLER_STATE sampler_state
= {
1650 .SamplerDisable
= false,
1651 .TextureBorderColorMode
= DX10OGL
,
1652 .LODPreClampMode
= 0,
1653 .BaseMipLevel
= 0.0,
1654 .MipModeFilter
= vk_to_gen_mipmap_mode
[pCreateInfo
->mipMode
],
1655 .MagModeFilter
= mag_filter
,
1656 .MinModeFilter
= min_filter
,
1657 .TextureLODBias
= pCreateInfo
->mipLodBias
* 256,
1658 .AnisotropicAlgorithm
= EWAApproximation
,
1659 .MinLOD
= pCreateInfo
->minLod
,
1660 .MaxLOD
= pCreateInfo
->maxLod
,
1661 .ChromaKeyEnable
= 0,
1662 .ChromaKeyIndex
= 0,
1664 .ShadowFunction
= vk_to_gen_compare_op
[pCreateInfo
->compareOp
],
1665 .CubeSurfaceControlMode
= 0,
1667 .IndirectStatePointer
=
1668 device
->float_border_colors
.offset
+
1669 pCreateInfo
->borderColor
* sizeof(float) * 4,
1671 .LODClampMagnificationMode
= MIPNONE
,
1672 .MaximumAnisotropy
= max_anisotropy
,
1673 .RAddressMinFilterRoundingEnable
= 0,
1674 .RAddressMagFilterRoundingEnable
= 0,
1675 .VAddressMinFilterRoundingEnable
= 0,
1676 .VAddressMagFilterRoundingEnable
= 0,
1677 .UAddressMinFilterRoundingEnable
= 0,
1678 .UAddressMagFilterRoundingEnable
= 0,
1679 .TrilinearFilterQuality
= 0,
1680 .NonnormalizedCoordinateEnable
= 0,
1681 .TCXAddressControlMode
= vk_to_gen_tex_address
[pCreateInfo
->addressU
],
1682 .TCYAddressControlMode
= vk_to_gen_tex_address
[pCreateInfo
->addressV
],
1683 .TCZAddressControlMode
= vk_to_gen_tex_address
[pCreateInfo
->addressW
],
1686 GEN8_SAMPLER_STATE_pack(NULL
, sampler
->state
, &sampler_state
);
1688 *pSampler
= (VkSampler
) sampler
;
1693 // Descriptor set functions
1695 VkResult
anv_CreateDescriptorSetLayout(
1697 const VkDescriptorSetLayoutCreateInfo
* pCreateInfo
,
1698 VkDescriptorSetLayout
* pSetLayout
)
1700 struct anv_device
*device
= (struct anv_device
*) _device
;
1701 struct anv_descriptor_set_layout
*set_layout
;
1703 assert(pCreateInfo
->sType
== VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO
);
1705 uint32_t sampler_count
[VK_NUM_SHADER_STAGE
] = { 0, };
1706 uint32_t surface_count
[VK_NUM_SHADER_STAGE
] = { 0, };
1707 uint32_t num_dynamic_buffers
= 0;
1709 uint32_t stages
= 0;
1712 for (uint32_t i
= 0; i
< pCreateInfo
->count
; i
++) {
1713 switch (pCreateInfo
->pBinding
[i
].descriptorType
) {
1714 case VK_DESCRIPTOR_TYPE_SAMPLER
:
1715 case VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER
:
1716 for_each_bit(s
, pCreateInfo
->pBinding
[i
].stageFlags
)
1717 sampler_count
[s
] += pCreateInfo
->pBinding
[i
].count
;
1723 switch (pCreateInfo
->pBinding
[i
].descriptorType
) {
1724 case VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER
:
1725 case VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE
:
1726 case VK_DESCRIPTOR_TYPE_STORAGE_IMAGE
:
1727 case VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER
:
1728 case VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER
:
1729 case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER
:
1730 case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER
:
1731 case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC
:
1732 case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC
:
1733 for_each_bit(s
, pCreateInfo
->pBinding
[i
].stageFlags
)
1734 surface_count
[s
] += pCreateInfo
->pBinding
[i
].count
;
1740 switch (pCreateInfo
->pBinding
[i
].descriptorType
) {
1741 case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC
:
1742 case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC
:
1743 num_dynamic_buffers
+= pCreateInfo
->pBinding
[i
].count
;
1749 stages
|= pCreateInfo
->pBinding
[i
].stageFlags
;
1750 count
+= pCreateInfo
->pBinding
[i
].count
;
1753 uint32_t sampler_total
= 0;
1754 uint32_t surface_total
= 0;
1755 for (uint32_t s
= 0; s
< VK_NUM_SHADER_STAGE
; s
++) {
1756 sampler_total
+= sampler_count
[s
];
1757 surface_total
+= surface_count
[s
];
1760 size_t size
= sizeof(*set_layout
) +
1761 (sampler_total
+ surface_total
) * sizeof(set_layout
->entries
[0]);
1762 set_layout
= anv_device_alloc(device
, size
, 8,
1763 VK_SYSTEM_ALLOC_TYPE_API_OBJECT
);
1765 return vk_error(VK_ERROR_OUT_OF_HOST_MEMORY
);
1767 set_layout
->num_dynamic_buffers
= num_dynamic_buffers
;
1768 set_layout
->count
= count
;
1769 set_layout
->shader_stages
= stages
;
1771 struct anv_descriptor_slot
*p
= set_layout
->entries
;
1772 struct anv_descriptor_slot
*sampler
[VK_NUM_SHADER_STAGE
];
1773 struct anv_descriptor_slot
*surface
[VK_NUM_SHADER_STAGE
];
1774 for (uint32_t s
= 0; s
< VK_NUM_SHADER_STAGE
; s
++) {
1775 set_layout
->stage
[s
].surface_count
= surface_count
[s
];
1776 set_layout
->stage
[s
].surface_start
= surface
[s
] = p
;
1777 p
+= surface_count
[s
];
1778 set_layout
->stage
[s
].sampler_count
= sampler_count
[s
];
1779 set_layout
->stage
[s
].sampler_start
= sampler
[s
] = p
;
1780 p
+= sampler_count
[s
];
1783 uint32_t descriptor
= 0;
1784 int8_t dynamic_slot
= 0;
1786 for (uint32_t i
= 0; i
< pCreateInfo
->count
; i
++) {
1787 switch (pCreateInfo
->pBinding
[i
].descriptorType
) {
1788 case VK_DESCRIPTOR_TYPE_SAMPLER
:
1789 case VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER
:
1790 for_each_bit(s
, pCreateInfo
->pBinding
[i
].stageFlags
)
1791 for (uint32_t j
= 0; j
< pCreateInfo
->pBinding
[i
].count
; j
++) {
1792 sampler
[s
]->index
= descriptor
+ j
;
1793 sampler
[s
]->dynamic_slot
= -1;
1801 switch (pCreateInfo
->pBinding
[i
].descriptorType
) {
1802 case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC
:
1803 case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC
:
1811 switch (pCreateInfo
->pBinding
[i
].descriptorType
) {
1812 case VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER
:
1813 case VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE
:
1814 case VK_DESCRIPTOR_TYPE_STORAGE_IMAGE
:
1815 case VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER
:
1816 case VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER
:
1817 case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER
:
1818 case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER
:
1819 case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC
:
1820 case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC
:
1821 for_each_bit(s
, pCreateInfo
->pBinding
[i
].stageFlags
)
1822 for (uint32_t j
= 0; j
< pCreateInfo
->pBinding
[i
].count
; j
++) {
1823 surface
[s
]->index
= descriptor
+ j
;
1825 surface
[s
]->dynamic_slot
= dynamic_slot
+ j
;
1827 surface
[s
]->dynamic_slot
= -1;
1836 dynamic_slot
+= pCreateInfo
->pBinding
[i
].count
;
1838 descriptor
+= pCreateInfo
->pBinding
[i
].count
;
1841 *pSetLayout
= (VkDescriptorSetLayout
) set_layout
;
1846 VkResult
anv_BeginDescriptorPoolUpdate(
1848 VkDescriptorUpdateMode updateMode
)
1853 VkResult
anv_EndDescriptorPoolUpdate(
1860 VkResult
anv_CreateDescriptorPool(
1862 VkDescriptorPoolUsage poolUsage
,
1864 const VkDescriptorPoolCreateInfo
* pCreateInfo
,
1865 VkDescriptorPool
* pDescriptorPool
)
1867 *pDescriptorPool
= 1;
1872 VkResult
anv_ResetDescriptorPool(
1874 VkDescriptorPool descriptorPool
)
1879 VkResult
anv_AllocDescriptorSets(
1881 VkDescriptorPool descriptorPool
,
1882 VkDescriptorSetUsage setUsage
,
1884 const VkDescriptorSetLayout
* pSetLayouts
,
1885 VkDescriptorSet
* pDescriptorSets
,
1888 struct anv_device
*device
= (struct anv_device
*) _device
;
1889 const struct anv_descriptor_set_layout
*layout
;
1890 struct anv_descriptor_set
*set
;
1893 for (uint32_t i
= 0; i
< count
; i
++) {
1894 layout
= (struct anv_descriptor_set_layout
*) pSetLayouts
[i
];
1895 size
= sizeof(*set
) + layout
->count
* sizeof(set
->descriptors
[0]);
1896 set
= anv_device_alloc(device
, size
, 8,
1897 VK_SYSTEM_ALLOC_TYPE_API_OBJECT
);
1900 return vk_error(VK_ERROR_OUT_OF_HOST_MEMORY
);
1903 /* Descriptor sets may not be 100% filled out so we need to memset to
1904 * ensure that we can properly detect and handle holes.
1906 memset(set
, 0, size
);
1908 pDescriptorSets
[i
] = (VkDescriptorSet
) set
;
1916 void anv_ClearDescriptorSets(
1918 VkDescriptorPool descriptorPool
,
1920 const VkDescriptorSet
* pDescriptorSets
)
1924 void anv_UpdateDescriptors(
1926 VkDescriptorSet descriptorSet
,
1927 uint32_t updateCount
,
1928 const void** ppUpdateArray
)
1930 struct anv_descriptor_set
*set
= (struct anv_descriptor_set
*) descriptorSet
;
1931 VkUpdateSamplers
*update_samplers
;
1932 VkUpdateSamplerTextures
*update_sampler_textures
;
1933 VkUpdateImages
*update_images
;
1934 VkUpdateBuffers
*update_buffers
;
1935 VkUpdateAsCopy
*update_as_copy
;
1937 for (uint32_t i
= 0; i
< updateCount
; i
++) {
1938 const struct anv_common
*common
= ppUpdateArray
[i
];
1940 switch (common
->sType
) {
1941 case VK_STRUCTURE_TYPE_UPDATE_SAMPLERS
:
1942 update_samplers
= (VkUpdateSamplers
*) common
;
1944 for (uint32_t j
= 0; j
< update_samplers
->count
; j
++) {
1945 set
->descriptors
[update_samplers
->binding
+ j
].sampler
=
1946 (struct anv_sampler
*) update_samplers
->pSamplers
[j
];
1950 case VK_STRUCTURE_TYPE_UPDATE_SAMPLER_TEXTURES
:
1951 /* FIXME: Shouldn't this be *_UPDATE_SAMPLER_IMAGES? */
1952 update_sampler_textures
= (VkUpdateSamplerTextures
*) common
;
1954 for (uint32_t j
= 0; j
< update_sampler_textures
->count
; j
++) {
1955 set
->descriptors
[update_sampler_textures
->binding
+ j
].view
=
1956 (struct anv_surface_view
*)
1957 update_sampler_textures
->pSamplerImageViews
[j
].pImageView
->view
;
1958 set
->descriptors
[update_sampler_textures
->binding
+ j
].sampler
=
1959 (struct anv_sampler
*)
1960 update_sampler_textures
->pSamplerImageViews
[j
].sampler
;
1964 case VK_STRUCTURE_TYPE_UPDATE_IMAGES
:
1965 update_images
= (VkUpdateImages
*) common
;
1967 for (uint32_t j
= 0; j
< update_images
->count
; j
++) {
1968 set
->descriptors
[update_images
->binding
+ j
].view
=
1969 (struct anv_surface_view
*) update_images
->pImageViews
[j
].view
;
1973 case VK_STRUCTURE_TYPE_UPDATE_BUFFERS
:
1974 update_buffers
= (VkUpdateBuffers
*) common
;
1976 for (uint32_t j
= 0; j
< update_buffers
->count
; j
++) {
1977 set
->descriptors
[update_buffers
->binding
+ j
].view
=
1978 (struct anv_surface_view
*) update_buffers
->pBufferViews
[j
].view
;
1980 /* FIXME: descriptor arrays? */
1983 case VK_STRUCTURE_TYPE_UPDATE_AS_COPY
:
1984 update_as_copy
= (VkUpdateAsCopy
*) common
;
1985 (void) update_as_copy
;
1994 // State object functions
1996 static inline int64_t
1997 clamp_int64(int64_t x
, int64_t min
, int64_t max
)
2008 anv_dynamic_vp_state_destroy(struct anv_device
*device
,
2009 struct anv_object
*object
,
2010 VkObjectType obj_type
)
2012 struct anv_dynamic_vp_state
*state
= (void *)object
;
2014 assert(obj_type
== VK_OBJECT_TYPE_DYNAMIC_VP_STATE
);
2016 anv_state_pool_free(&device
->dynamic_state_pool
, state
->sf_clip_vp
);
2017 anv_state_pool_free(&device
->dynamic_state_pool
, state
->cc_vp
);
2018 anv_state_pool_free(&device
->dynamic_state_pool
, state
->scissor
);
2020 anv_device_free(device
, state
);
2023 VkResult
anv_CreateDynamicViewportState(
2025 const VkDynamicVpStateCreateInfo
* pCreateInfo
,
2026 VkDynamicVpState
* pState
)
2028 struct anv_device
*device
= (struct anv_device
*) _device
;
2029 struct anv_dynamic_vp_state
*state
;
2031 assert(pCreateInfo
->sType
== VK_STRUCTURE_TYPE_DYNAMIC_VP_STATE_CREATE_INFO
);
2033 state
= anv_device_alloc(device
, sizeof(*state
), 8,
2034 VK_SYSTEM_ALLOC_TYPE_API_OBJECT
);
2036 return vk_error(VK_ERROR_OUT_OF_HOST_MEMORY
);
2038 state
->base
.destructor
= anv_dynamic_vp_state_destroy
;
2040 unsigned count
= pCreateInfo
->viewportAndScissorCount
;
2041 state
->sf_clip_vp
= anv_state_pool_alloc(&device
->dynamic_state_pool
,
2043 state
->cc_vp
= anv_state_pool_alloc(&device
->dynamic_state_pool
,
2045 state
->scissor
= anv_state_pool_alloc(&device
->dynamic_state_pool
,
2048 for (uint32_t i
= 0; i
< pCreateInfo
->viewportAndScissorCount
; i
++) {
2049 const VkViewport
*vp
= &pCreateInfo
->pViewports
[i
];
2050 const VkRect
*s
= &pCreateInfo
->pScissors
[i
];
2052 struct GEN8_SF_CLIP_VIEWPORT sf_clip_viewport
= {
2053 .ViewportMatrixElementm00
= vp
->width
/ 2,
2054 .ViewportMatrixElementm11
= vp
->height
/ 2,
2055 .ViewportMatrixElementm22
= (vp
->maxDepth
- vp
->minDepth
) / 2,
2056 .ViewportMatrixElementm30
= vp
->originX
+ vp
->width
/ 2,
2057 .ViewportMatrixElementm31
= vp
->originY
+ vp
->height
/ 2,
2058 .ViewportMatrixElementm32
= (vp
->maxDepth
+ vp
->minDepth
) / 2,
2059 .XMinClipGuardband
= -1.0f
,
2060 .XMaxClipGuardband
= 1.0f
,
2061 .YMinClipGuardband
= -1.0f
,
2062 .YMaxClipGuardband
= 1.0f
,
2063 .XMinViewPort
= vp
->originX
,
2064 .XMaxViewPort
= vp
->originX
+ vp
->width
- 1,
2065 .YMinViewPort
= vp
->originY
,
2066 .YMaxViewPort
= vp
->originY
+ vp
->height
- 1,
2069 struct GEN8_CC_VIEWPORT cc_viewport
= {
2070 .MinimumDepth
= vp
->minDepth
,
2071 .MaximumDepth
= vp
->maxDepth
2074 /* Since xmax and ymax are inclusive, we have to have xmax < xmin or
2075 * ymax < ymin for empty clips. In case clip x, y, width height are all
2076 * 0, the clamps below produce 0 for xmin, ymin, xmax, ymax, which isn't
2077 * what we want. Just special case empty clips and produce a canonical
2079 static const struct GEN8_SCISSOR_RECT empty_scissor
= {
2080 .ScissorRectangleYMin
= 1,
2081 .ScissorRectangleXMin
= 1,
2082 .ScissorRectangleYMax
= 0,
2083 .ScissorRectangleXMax
= 0
2086 const int max
= 0xffff;
2087 struct GEN8_SCISSOR_RECT scissor
= {
2088 /* Do this math using int64_t so overflow gets clamped correctly. */
2089 .ScissorRectangleYMin
= clamp_int64(s
->offset
.y
, 0, max
),
2090 .ScissorRectangleXMin
= clamp_int64(s
->offset
.x
, 0, max
),
2091 .ScissorRectangleYMax
= clamp_int64((uint64_t) s
->offset
.y
+ s
->extent
.height
- 1, 0, max
),
2092 .ScissorRectangleXMax
= clamp_int64((uint64_t) s
->offset
.x
+ s
->extent
.width
- 1, 0, max
)
2095 GEN8_SF_CLIP_VIEWPORT_pack(NULL
, state
->sf_clip_vp
.map
+ i
* 64, &sf_clip_viewport
);
2096 GEN8_CC_VIEWPORT_pack(NULL
, state
->cc_vp
.map
+ i
* 32, &cc_viewport
);
2098 if (s
->extent
.width
<= 0 || s
->extent
.height
<= 0) {
2099 GEN8_SCISSOR_RECT_pack(NULL
, state
->scissor
.map
+ i
* 32, &empty_scissor
);
2101 GEN8_SCISSOR_RECT_pack(NULL
, state
->scissor
.map
+ i
* 32, &scissor
);
2105 *pState
= (VkDynamicVpState
) state
;
2110 VkResult
anv_CreateDynamicRasterState(
2112 const VkDynamicRsStateCreateInfo
* pCreateInfo
,
2113 VkDynamicRsState
* pState
)
2115 struct anv_device
*device
= (struct anv_device
*) _device
;
2116 struct anv_dynamic_rs_state
*state
;
2118 assert(pCreateInfo
->sType
== VK_STRUCTURE_TYPE_DYNAMIC_RS_STATE_CREATE_INFO
);
2120 state
= anv_device_alloc(device
, sizeof(*state
), 8,
2121 VK_SYSTEM_ALLOC_TYPE_API_OBJECT
);
2123 return vk_error(VK_ERROR_OUT_OF_HOST_MEMORY
);
2126 * float pointFadeThreshold;
2127 * // optional (GL45) - Size of point fade threshold
2130 struct GEN8_3DSTATE_SF sf
= {
2131 GEN8_3DSTATE_SF_header
,
2132 .LineWidth
= pCreateInfo
->lineWidth
,
2133 .PointWidth
= pCreateInfo
->pointSize
,
2136 GEN8_3DSTATE_SF_pack(NULL
, state
->state_sf
, &sf
);
2138 bool enable_bias
= pCreateInfo
->depthBias
!= 0.0f
||
2139 pCreateInfo
->slopeScaledDepthBias
!= 0.0f
;
2140 struct GEN8_3DSTATE_RASTER raster
= {
2141 .GlobalDepthOffsetEnableSolid
= enable_bias
,
2142 .GlobalDepthOffsetEnableWireframe
= enable_bias
,
2143 .GlobalDepthOffsetEnablePoint
= enable_bias
,
2144 .GlobalDepthOffsetConstant
= pCreateInfo
->depthBias
,
2145 .GlobalDepthOffsetScale
= pCreateInfo
->slopeScaledDepthBias
,
2146 .GlobalDepthOffsetClamp
= pCreateInfo
->depthBiasClamp
2149 GEN8_3DSTATE_RASTER_pack(NULL
, state
->state_raster
, &raster
);
2151 *pState
= (VkDynamicRsState
) state
;
2156 VkResult
anv_CreateDynamicColorBlendState(
2158 const VkDynamicCbStateCreateInfo
* pCreateInfo
,
2159 VkDynamicCbState
* pState
)
2161 struct anv_device
*device
= (struct anv_device
*) _device
;
2162 struct anv_dynamic_cb_state
*state
;
2164 assert(pCreateInfo
->sType
== VK_STRUCTURE_TYPE_DYNAMIC_CB_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_COLOR_CALC_STATE color_calc_state
= {
2172 .BlendConstantColorRed
= pCreateInfo
->blendConst
[0],
2173 .BlendConstantColorGreen
= pCreateInfo
->blendConst
[1],
2174 .BlendConstantColorBlue
= pCreateInfo
->blendConst
[2],
2175 .BlendConstantColorAlpha
= pCreateInfo
->blendConst
[3]
2178 GEN8_COLOR_CALC_STATE_pack(NULL
, state
->state_color_calc
, &color_calc_state
);
2180 *pState
= (VkDynamicCbState
) state
;
2185 VkResult
anv_CreateDynamicDepthStencilState(
2187 const VkDynamicDsStateCreateInfo
* pCreateInfo
,
2188 VkDynamicDsState
* pState
)
2190 struct anv_device
*device
= (struct anv_device
*) _device
;
2191 struct anv_dynamic_ds_state
*state
;
2193 assert(pCreateInfo
->sType
== VK_STRUCTURE_TYPE_DYNAMIC_DS_STATE_CREATE_INFO
);
2195 state
= anv_device_alloc(device
, sizeof(*state
), 8,
2196 VK_SYSTEM_ALLOC_TYPE_API_OBJECT
);
2198 return vk_error(VK_ERROR_OUT_OF_HOST_MEMORY
);
2200 struct GEN8_3DSTATE_WM_DEPTH_STENCIL wm_depth_stencil
= {
2201 GEN8_3DSTATE_WM_DEPTH_STENCIL_header
,
2203 /* Is this what we need to do? */
2204 .StencilBufferWriteEnable
= pCreateInfo
->stencilWriteMask
!= 0,
2206 .StencilTestMask
= pCreateInfo
->stencilReadMask
& 0xff,
2207 .StencilWriteMask
= pCreateInfo
->stencilWriteMask
& 0xff,
2209 .BackfaceStencilTestMask
= pCreateInfo
->stencilReadMask
& 0xff,
2210 .BackfaceStencilWriteMask
= pCreateInfo
->stencilWriteMask
& 0xff,
2213 GEN8_3DSTATE_WM_DEPTH_STENCIL_pack(NULL
, state
->state_wm_depth_stencil
,
2216 struct GEN8_COLOR_CALC_STATE color_calc_state
= {
2217 .StencilReferenceValue
= pCreateInfo
->stencilFrontRef
,
2218 .BackFaceStencilReferenceValue
= pCreateInfo
->stencilBackRef
2221 GEN8_COLOR_CALC_STATE_pack(NULL
, state
->state_color_calc
, &color_calc_state
);
2223 *pState
= (VkDynamicDsState
) state
;
2228 // Command buffer functions
2231 anv_cmd_buffer_destroy(struct anv_device
*device
,
2232 struct anv_object
*object
,
2233 VkObjectType obj_type
)
2235 struct anv_cmd_buffer
*cmd_buffer
= (struct anv_cmd_buffer
*) object
;
2237 assert(obj_type
== VK_OBJECT_TYPE_COMMAND_BUFFER
);
2239 /* Destroy all of the batch buffers */
2240 struct anv_batch_bo
*bbo
= cmd_buffer
->last_batch_bo
;
2242 struct anv_batch_bo
*prev
= bbo
->prev_batch_bo
;
2243 anv_batch_bo_destroy(bbo
, device
);
2246 anv_reloc_list_finish(&cmd_buffer
->batch
.relocs
, device
);
2248 /* Destroy all of the surface state buffers */
2249 bbo
= cmd_buffer
->surface_batch_bo
;
2251 struct anv_batch_bo
*prev
= bbo
->prev_batch_bo
;
2252 anv_batch_bo_destroy(bbo
, device
);
2255 anv_reloc_list_finish(&cmd_buffer
->surface_relocs
, device
);
2257 anv_state_stream_finish(&cmd_buffer
->surface_state_stream
);
2258 anv_state_stream_finish(&cmd_buffer
->dynamic_state_stream
);
2259 anv_device_free(device
, cmd_buffer
->exec2_objects
);
2260 anv_device_free(device
, cmd_buffer
->exec2_bos
);
2261 anv_device_free(device
, cmd_buffer
);
2265 anv_cmd_buffer_chain_batch(struct anv_batch
*batch
, void *_data
)
2267 struct anv_cmd_buffer
*cmd_buffer
= _data
;
2269 struct anv_batch_bo
*new_bbo
, *old_bbo
= cmd_buffer
->last_batch_bo
;
2271 VkResult result
= anv_batch_bo_create(cmd_buffer
->device
, &new_bbo
);
2272 if (result
!= VK_SUCCESS
)
2275 /* We set the end of the batch a little short so we would be sure we
2276 * have room for the chaining command. Since we're about to emit the
2277 * chaining command, let's set it back where it should go.
2279 batch
->end
+= GEN8_MI_BATCH_BUFFER_START_length
* 4;
2280 assert(batch
->end
== old_bbo
->bo
.map
+ old_bbo
->bo
.size
);
2282 anv_batch_emit(batch
, GEN8_MI_BATCH_BUFFER_START
,
2283 GEN8_MI_BATCH_BUFFER_START_header
,
2284 ._2ndLevelBatchBuffer
= _1stlevelbatch
,
2285 .AddressSpaceIndicator
= ASI_PPGTT
,
2286 .BatchBufferStartAddress
= { &new_bbo
->bo
, 0 },
2289 /* Pad out to a 2-dword aligned boundary with zeros */
2290 if ((uintptr_t)batch
->next
% 8 != 0) {
2291 *(uint32_t *)batch
->next
= 0;
2295 anv_batch_bo_finish(cmd_buffer
->last_batch_bo
, batch
);
2297 new_bbo
->prev_batch_bo
= old_bbo
;
2298 cmd_buffer
->last_batch_bo
= new_bbo
;
2300 anv_batch_bo_start(new_bbo
, batch
, GEN8_MI_BATCH_BUFFER_START_length
* 4);
2305 VkResult
anv_CreateCommandBuffer(
2307 const VkCmdBufferCreateInfo
* pCreateInfo
,
2308 VkCmdBuffer
* pCmdBuffer
)
2310 struct anv_device
*device
= (struct anv_device
*) _device
;
2311 struct anv_cmd_buffer
*cmd_buffer
;
2314 cmd_buffer
= anv_device_alloc(device
, sizeof(*cmd_buffer
), 8,
2315 VK_SYSTEM_ALLOC_TYPE_API_OBJECT
);
2316 if (cmd_buffer
== NULL
)
2317 return vk_error(VK_ERROR_OUT_OF_HOST_MEMORY
);
2319 cmd_buffer
->base
.destructor
= anv_cmd_buffer_destroy
;
2321 cmd_buffer
->device
= device
;
2322 cmd_buffer
->rs_state
= NULL
;
2323 cmd_buffer
->vp_state
= NULL
;
2324 cmd_buffer
->cb_state
= NULL
;
2325 cmd_buffer
->ds_state
= NULL
;
2326 memset(&cmd_buffer
->descriptors
, 0, sizeof(cmd_buffer
->descriptors
));
2328 result
= anv_batch_bo_create(device
, &cmd_buffer
->last_batch_bo
);
2329 if (result
!= VK_SUCCESS
)
2332 result
= anv_reloc_list_init(&cmd_buffer
->batch
.relocs
, device
);
2333 if (result
!= VK_SUCCESS
)
2336 cmd_buffer
->batch
.device
= device
;
2337 cmd_buffer
->batch
.extend_cb
= anv_cmd_buffer_chain_batch
;
2338 cmd_buffer
->batch
.user_data
= cmd_buffer
;
2340 anv_batch_bo_start(cmd_buffer
->last_batch_bo
, &cmd_buffer
->batch
,
2341 GEN8_MI_BATCH_BUFFER_START_length
* 4);
2343 result
= anv_batch_bo_create(device
, &cmd_buffer
->surface_batch_bo
);
2344 if (result
!= VK_SUCCESS
)
2345 goto fail_batch_relocs
;
2346 cmd_buffer
->surface_batch_bo
->first_reloc
= 0;
2348 result
= anv_reloc_list_init(&cmd_buffer
->surface_relocs
, device
);
2349 if (result
!= VK_SUCCESS
)
2350 goto fail_ss_batch_bo
;
2352 /* Start surface_next at 1 so surface offset 0 is invalid. */
2353 cmd_buffer
->surface_next
= 1;
2355 cmd_buffer
->exec2_objects
= NULL
;
2356 cmd_buffer
->exec2_bos
= NULL
;
2357 cmd_buffer
->exec2_array_length
= 0;
2359 anv_state_stream_init(&cmd_buffer
->surface_state_stream
,
2360 &device
->surface_state_block_pool
);
2361 anv_state_stream_init(&cmd_buffer
->dynamic_state_stream
,
2362 &device
->dynamic_state_block_pool
);
2364 cmd_buffer
->dirty
= 0;
2365 cmd_buffer
->vb_dirty
= 0;
2366 cmd_buffer
->descriptors_dirty
= 0;
2367 cmd_buffer
->pipeline
= NULL
;
2368 cmd_buffer
->vp_state
= NULL
;
2369 cmd_buffer
->rs_state
= NULL
;
2370 cmd_buffer
->ds_state
= NULL
;
2372 *pCmdBuffer
= (VkCmdBuffer
) cmd_buffer
;
2377 anv_batch_bo_destroy(cmd_buffer
->surface_batch_bo
, device
);
2379 anv_reloc_list_finish(&cmd_buffer
->batch
.relocs
, device
);
2381 anv_batch_bo_destroy(cmd_buffer
->last_batch_bo
, device
);
2383 anv_device_free(device
, cmd_buffer
);
2389 anv_cmd_buffer_emit_state_base_address(struct anv_cmd_buffer
*cmd_buffer
)
2391 struct anv_device
*device
= cmd_buffer
->device
;
2392 struct anv_bo
*scratch_bo
= NULL
;
2394 cmd_buffer
->scratch_size
= device
->scratch_block_pool
.size
;
2395 if (cmd_buffer
->scratch_size
> 0)
2396 scratch_bo
= &device
->scratch_block_pool
.bo
;
2398 anv_batch_emit(&cmd_buffer
->batch
, GEN8_STATE_BASE_ADDRESS
,
2399 .GeneralStateBaseAddress
= { scratch_bo
, 0 },
2400 .GeneralStateMemoryObjectControlState
= GEN8_MOCS
,
2401 .GeneralStateBaseAddressModifyEnable
= true,
2402 .GeneralStateBufferSize
= 0xfffff,
2403 .GeneralStateBufferSizeModifyEnable
= true,
2405 .SurfaceStateBaseAddress
= { &cmd_buffer
->surface_batch_bo
->bo
, 0 },
2406 .SurfaceStateMemoryObjectControlState
= GEN8_MOCS
,
2407 .SurfaceStateBaseAddressModifyEnable
= true,
2409 .DynamicStateBaseAddress
= { &device
->dynamic_state_block_pool
.bo
, 0 },
2410 .DynamicStateMemoryObjectControlState
= GEN8_MOCS
,
2411 .DynamicStateBaseAddressModifyEnable
= true,
2412 .DynamicStateBufferSize
= 0xfffff,
2413 .DynamicStateBufferSizeModifyEnable
= true,
2415 .IndirectObjectBaseAddress
= { NULL
, 0 },
2416 .IndirectObjectMemoryObjectControlState
= GEN8_MOCS
,
2417 .IndirectObjectBaseAddressModifyEnable
= true,
2418 .IndirectObjectBufferSize
= 0xfffff,
2419 .IndirectObjectBufferSizeModifyEnable
= true,
2421 .InstructionBaseAddress
= { &device
->instruction_block_pool
.bo
, 0 },
2422 .InstructionMemoryObjectControlState
= GEN8_MOCS
,
2423 .InstructionBaseAddressModifyEnable
= true,
2424 .InstructionBufferSize
= 0xfffff,
2425 .InstructionBuffersizeModifyEnable
= true);
2428 VkResult
anv_BeginCommandBuffer(
2429 VkCmdBuffer cmdBuffer
,
2430 const VkCmdBufferBeginInfo
* pBeginInfo
)
2432 struct anv_cmd_buffer
*cmd_buffer
= (struct anv_cmd_buffer
*) cmdBuffer
;
2434 anv_cmd_buffer_emit_state_base_address(cmd_buffer
);
2435 cmd_buffer
->current_pipeline
= UINT32_MAX
;
2441 anv_cmd_buffer_add_bo(struct anv_cmd_buffer
*cmd_buffer
,
2443 struct drm_i915_gem_relocation_entry
*relocs
,
2446 struct drm_i915_gem_exec_object2
*obj
;
2448 if (bo
->index
< cmd_buffer
->bo_count
&&
2449 cmd_buffer
->exec2_bos
[bo
->index
] == bo
)
2452 if (cmd_buffer
->bo_count
>= cmd_buffer
->exec2_array_length
) {
2453 uint32_t new_len
= cmd_buffer
->exec2_objects
?
2454 cmd_buffer
->exec2_array_length
* 2 : 64;
2456 struct drm_i915_gem_exec_object2
*new_objects
=
2457 anv_device_alloc(cmd_buffer
->device
, new_len
* sizeof(*new_objects
),
2458 8, VK_SYSTEM_ALLOC_TYPE_INTERNAL
);
2459 if (new_objects
== NULL
)
2460 return vk_error(VK_ERROR_OUT_OF_HOST_MEMORY
);
2462 struct anv_bo
**new_bos
=
2463 anv_device_alloc(cmd_buffer
->device
, new_len
* sizeof(*new_bos
),
2464 8, VK_SYSTEM_ALLOC_TYPE_INTERNAL
);
2465 if (new_objects
== NULL
) {
2466 anv_device_free(cmd_buffer
->device
, new_objects
);
2467 return vk_error(VK_ERROR_OUT_OF_HOST_MEMORY
);
2470 if (cmd_buffer
->exec2_objects
) {
2471 memcpy(new_objects
, cmd_buffer
->exec2_objects
,
2472 cmd_buffer
->bo_count
* sizeof(*new_objects
));
2473 memcpy(new_bos
, cmd_buffer
->exec2_bos
,
2474 cmd_buffer
->bo_count
* sizeof(*new_bos
));
2477 cmd_buffer
->exec2_objects
= new_objects
;
2478 cmd_buffer
->exec2_bos
= new_bos
;
2479 cmd_buffer
->exec2_array_length
= new_len
;
2482 assert(cmd_buffer
->bo_count
< cmd_buffer
->exec2_array_length
);
2484 bo
->index
= cmd_buffer
->bo_count
++;
2485 obj
= &cmd_buffer
->exec2_objects
[bo
->index
];
2486 cmd_buffer
->exec2_bos
[bo
->index
] = bo
;
2488 obj
->handle
= bo
->gem_handle
;
2489 obj
->relocation_count
= 0;
2490 obj
->relocs_ptr
= 0;
2492 obj
->offset
= bo
->offset
;
2498 obj
->relocation_count
= num_relocs
;
2499 obj
->relocs_ptr
= (uintptr_t) relocs
;
2506 anv_cmd_buffer_add_validate_bos(struct anv_cmd_buffer
*cmd_buffer
,
2507 struct anv_reloc_list
*list
)
2509 for (size_t i
= 0; i
< list
->num_relocs
; i
++)
2510 anv_cmd_buffer_add_bo(cmd_buffer
, list
->reloc_bos
[i
], NULL
, 0);
2514 anv_cmd_buffer_process_relocs(struct anv_cmd_buffer
*cmd_buffer
,
2515 struct anv_reloc_list
*list
)
2519 /* If the kernel supports I915_EXEC_NO_RELOC, it will compare offset in
2520 * struct drm_i915_gem_exec_object2 against the bos current offset and if
2521 * all bos haven't moved it will skip relocation processing alltogether.
2522 * If I915_EXEC_NO_RELOC is not supported, the kernel ignores the incoming
2523 * value of offset so we can set it either way. For that to work we need
2524 * to make sure all relocs use the same presumed offset.
2527 for (size_t i
= 0; i
< list
->num_relocs
; i
++) {
2528 bo
= list
->reloc_bos
[i
];
2529 if (bo
->offset
!= list
->relocs
[i
].presumed_offset
)
2530 cmd_buffer
->need_reloc
= true;
2532 list
->relocs
[i
].target_handle
= bo
->index
;
2536 VkResult
anv_EndCommandBuffer(
2537 VkCmdBuffer cmdBuffer
)
2539 struct anv_cmd_buffer
*cmd_buffer
= (struct anv_cmd_buffer
*) cmdBuffer
;
2540 struct anv_device
*device
= cmd_buffer
->device
;
2541 struct anv_batch
*batch
= &cmd_buffer
->batch
;
2543 anv_batch_emit(batch
, GEN8_MI_BATCH_BUFFER_END
);
2545 /* Round batch up to an even number of dwords. */
2546 if ((batch
->next
- batch
->start
) & 4)
2547 anv_batch_emit(batch
, GEN8_MI_NOOP
);
2549 anv_batch_bo_finish(cmd_buffer
->last_batch_bo
, &cmd_buffer
->batch
);
2550 cmd_buffer
->surface_batch_bo
->num_relocs
=
2551 cmd_buffer
->surface_relocs
.num_relocs
- cmd_buffer
->surface_batch_bo
->first_reloc
;
2552 cmd_buffer
->surface_batch_bo
->length
= cmd_buffer
->surface_next
;
2554 cmd_buffer
->bo_count
= 0;
2555 cmd_buffer
->need_reloc
= false;
2557 /* Lock for access to bo->index. */
2558 pthread_mutex_lock(&device
->mutex
);
2560 /* Add surface state bos first so we can add them with their relocs. */
2561 for (struct anv_batch_bo
*bbo
= cmd_buffer
->surface_batch_bo
;
2562 bbo
!= NULL
; bbo
= bbo
->prev_batch_bo
) {
2563 anv_cmd_buffer_add_bo(cmd_buffer
, &bbo
->bo
,
2564 &cmd_buffer
->surface_relocs
.relocs
[bbo
->first_reloc
],
2568 /* Add all of the BOs referenced by surface state */
2569 anv_cmd_buffer_add_validate_bos(cmd_buffer
, &cmd_buffer
->surface_relocs
);
2571 /* Add all but the first batch BO */
2572 struct anv_batch_bo
*batch_bo
= cmd_buffer
->last_batch_bo
;
2573 while (batch_bo
->prev_batch_bo
) {
2574 anv_cmd_buffer_add_bo(cmd_buffer
, &batch_bo
->bo
,
2575 &batch
->relocs
.relocs
[batch_bo
->first_reloc
],
2576 batch_bo
->num_relocs
);
2577 batch_bo
= batch_bo
->prev_batch_bo
;
2580 /* Add everything referenced by the batches */
2581 anv_cmd_buffer_add_validate_bos(cmd_buffer
, &batch
->relocs
);
2583 /* Add the first batch bo last */
2584 assert(batch_bo
->prev_batch_bo
== NULL
&& batch_bo
->first_reloc
== 0);
2585 anv_cmd_buffer_add_bo(cmd_buffer
, &batch_bo
->bo
,
2586 &batch
->relocs
.relocs
[batch_bo
->first_reloc
],
2587 batch_bo
->num_relocs
);
2588 assert(batch_bo
->bo
.index
== cmd_buffer
->bo_count
- 1);
2590 anv_cmd_buffer_process_relocs(cmd_buffer
, &cmd_buffer
->surface_relocs
);
2591 anv_cmd_buffer_process_relocs(cmd_buffer
, &batch
->relocs
);
2593 cmd_buffer
->execbuf
.buffers_ptr
= (uintptr_t) cmd_buffer
->exec2_objects
;
2594 cmd_buffer
->execbuf
.buffer_count
= cmd_buffer
->bo_count
;
2595 cmd_buffer
->execbuf
.batch_start_offset
= 0;
2596 cmd_buffer
->execbuf
.batch_len
= batch
->next
- batch
->start
;
2597 cmd_buffer
->execbuf
.cliprects_ptr
= 0;
2598 cmd_buffer
->execbuf
.num_cliprects
= 0;
2599 cmd_buffer
->execbuf
.DR1
= 0;
2600 cmd_buffer
->execbuf
.DR4
= 0;
2602 cmd_buffer
->execbuf
.flags
= I915_EXEC_HANDLE_LUT
;
2603 if (!cmd_buffer
->need_reloc
)
2604 cmd_buffer
->execbuf
.flags
|= I915_EXEC_NO_RELOC
;
2605 cmd_buffer
->execbuf
.flags
|= I915_EXEC_RENDER
;
2606 cmd_buffer
->execbuf
.rsvd1
= device
->context_id
;
2607 cmd_buffer
->execbuf
.rsvd2
= 0;
2609 pthread_mutex_unlock(&device
->mutex
);
2614 VkResult
anv_ResetCommandBuffer(
2615 VkCmdBuffer cmdBuffer
)
2617 struct anv_cmd_buffer
*cmd_buffer
= (struct anv_cmd_buffer
*) cmdBuffer
;
2619 /* Delete all but the first batch bo */
2620 while (cmd_buffer
->last_batch_bo
->prev_batch_bo
) {
2621 struct anv_batch_bo
*prev
= cmd_buffer
->last_batch_bo
->prev_batch_bo
;
2622 anv_batch_bo_destroy(cmd_buffer
->last_batch_bo
, cmd_buffer
->device
);
2623 cmd_buffer
->last_batch_bo
= prev
;
2625 assert(cmd_buffer
->last_batch_bo
->prev_batch_bo
== NULL
);
2627 cmd_buffer
->batch
.relocs
.num_relocs
= 0;
2628 anv_batch_bo_start(cmd_buffer
->last_batch_bo
, &cmd_buffer
->batch
,
2629 GEN8_MI_BATCH_BUFFER_START_length
* 4);
2631 /* Delete all but the first batch bo */
2632 while (cmd_buffer
->surface_batch_bo
->prev_batch_bo
) {
2633 struct anv_batch_bo
*prev
= cmd_buffer
->surface_batch_bo
->prev_batch_bo
;
2634 anv_batch_bo_destroy(cmd_buffer
->surface_batch_bo
, cmd_buffer
->device
);
2635 cmd_buffer
->surface_batch_bo
= prev
;
2637 assert(cmd_buffer
->surface_batch_bo
->prev_batch_bo
== NULL
);
2639 cmd_buffer
->surface_next
= 1;
2640 cmd_buffer
->surface_relocs
.num_relocs
= 0;
2642 cmd_buffer
->rs_state
= NULL
;
2643 cmd_buffer
->vp_state
= NULL
;
2644 cmd_buffer
->cb_state
= NULL
;
2645 cmd_buffer
->ds_state
= NULL
;
2650 // Command buffer building functions
2652 void anv_CmdBindPipeline(
2653 VkCmdBuffer cmdBuffer
,
2654 VkPipelineBindPoint pipelineBindPoint
,
2655 VkPipeline _pipeline
)
2657 struct anv_cmd_buffer
*cmd_buffer
= (struct anv_cmd_buffer
*) cmdBuffer
;
2658 struct anv_pipeline
*pipeline
= (struct anv_pipeline
*) _pipeline
;
2660 switch (pipelineBindPoint
) {
2661 case VK_PIPELINE_BIND_POINT_COMPUTE
:
2662 cmd_buffer
->compute_pipeline
= pipeline
;
2663 cmd_buffer
->compute_dirty
|= ANV_CMD_BUFFER_PIPELINE_DIRTY
;
2666 case VK_PIPELINE_BIND_POINT_GRAPHICS
:
2667 cmd_buffer
->pipeline
= pipeline
;
2668 cmd_buffer
->vb_dirty
|= pipeline
->vb_used
;
2669 cmd_buffer
->dirty
|= ANV_CMD_BUFFER_PIPELINE_DIRTY
;
2673 assert(!"invalid bind point");
2678 void anv_CmdBindDynamicStateObject(
2679 VkCmdBuffer cmdBuffer
,
2680 VkStateBindPoint stateBindPoint
,
2681 VkDynamicStateObject dynamicState
)
2683 struct anv_cmd_buffer
*cmd_buffer
= (struct anv_cmd_buffer
*) cmdBuffer
;
2685 switch (stateBindPoint
) {
2686 case VK_STATE_BIND_POINT_VIEWPORT
:
2687 cmd_buffer
->vp_state
= (struct anv_dynamic_vp_state
*) dynamicState
;
2688 cmd_buffer
->dirty
|= ANV_CMD_BUFFER_VP_DIRTY
;
2690 case VK_STATE_BIND_POINT_RASTER
:
2691 cmd_buffer
->rs_state
= (struct anv_dynamic_rs_state
*) dynamicState
;
2692 cmd_buffer
->dirty
|= ANV_CMD_BUFFER_RS_DIRTY
;
2694 case VK_STATE_BIND_POINT_COLOR_BLEND
:
2695 cmd_buffer
->cb_state
= (struct anv_dynamic_cb_state
*) dynamicState
;
2696 cmd_buffer
->dirty
|= ANV_CMD_BUFFER_CB_DIRTY
;
2698 case VK_STATE_BIND_POINT_DEPTH_STENCIL
:
2699 cmd_buffer
->ds_state
= (struct anv_dynamic_ds_state
*) dynamicState
;
2700 cmd_buffer
->dirty
|= ANV_CMD_BUFFER_DS_DIRTY
;
2707 static struct anv_state
2708 anv_cmd_buffer_alloc_surface_state(struct anv_cmd_buffer
*cmd_buffer
,
2709 uint32_t size
, uint32_t alignment
)
2711 struct anv_state state
;
2713 state
.offset
= ALIGN_U32(cmd_buffer
->surface_next
, alignment
);
2714 if (state
.offset
+ size
> cmd_buffer
->surface_batch_bo
->bo
.size
)
2715 return (struct anv_state
) { 0 };
2717 state
.map
= cmd_buffer
->surface_batch_bo
->bo
.map
+ state
.offset
;
2718 state
.alloc_size
= size
;
2719 cmd_buffer
->surface_next
= state
.offset
+ size
;
2721 assert(state
.offset
+ size
<= cmd_buffer
->surface_batch_bo
->bo
.size
);
2727 anv_cmd_buffer_new_surface_state_bo(struct anv_cmd_buffer
*cmd_buffer
)
2729 struct anv_batch_bo
*new_bbo
, *old_bbo
= cmd_buffer
->surface_batch_bo
;
2731 /* Finish off the old buffer */
2732 old_bbo
->num_relocs
=
2733 cmd_buffer
->surface_relocs
.num_relocs
- old_bbo
->first_reloc
;
2734 old_bbo
->length
= cmd_buffer
->surface_next
;
2736 VkResult result
= anv_batch_bo_create(cmd_buffer
->device
, &new_bbo
);
2737 if (result
!= VK_SUCCESS
)
2740 new_bbo
->first_reloc
= cmd_buffer
->surface_relocs
.num_relocs
;
2741 cmd_buffer
->surface_next
= 1;
2743 new_bbo
->prev_batch_bo
= old_bbo
;
2744 cmd_buffer
->surface_batch_bo
= new_bbo
;
2746 /* Re-emit state base addresses so we get the new surface state base
2747 * address before we start emitting binding tables etc.
2749 anv_cmd_buffer_emit_state_base_address(cmd_buffer
);
2751 /* It seems like just changing the state base addresses isn't enough.
2752 * Invalidating the cache seems to be enough to cause things to
2753 * propagate. However, I'm not 100% sure what we're supposed to do.
2755 anv_batch_emit(&cmd_buffer
->batch
, GEN8_PIPE_CONTROL
,
2756 .TextureCacheInvalidationEnable
= true);
2761 void anv_CmdBindDescriptorSets(
2762 VkCmdBuffer cmdBuffer
,
2763 VkPipelineBindPoint pipelineBindPoint
,
2766 const VkDescriptorSet
* pDescriptorSets
,
2767 uint32_t dynamicOffsetCount
,
2768 const uint32_t* pDynamicOffsets
)
2770 struct anv_cmd_buffer
*cmd_buffer
= (struct anv_cmd_buffer
*) cmdBuffer
;
2771 struct anv_pipeline_layout
*layout
;
2772 struct anv_descriptor_set
*set
;
2773 struct anv_descriptor_set_layout
*set_layout
;
2775 assert(firstSet
+ setCount
< MAX_SETS
);
2777 if (pipelineBindPoint
== VK_PIPELINE_BIND_POINT_GRAPHICS
)
2778 layout
= cmd_buffer
->pipeline
->layout
;
2780 layout
= cmd_buffer
->compute_pipeline
->layout
;
2782 uint32_t dynamic_slot
= 0;
2783 for (uint32_t i
= 0; i
< setCount
; i
++) {
2784 set
= (struct anv_descriptor_set
*) pDescriptorSets
[i
];
2785 set_layout
= layout
->set
[firstSet
+ i
].layout
;
2787 cmd_buffer
->descriptors
[firstSet
+ i
].set
= set
;
2789 assert(set_layout
->num_dynamic_buffers
<
2790 ARRAY_SIZE(cmd_buffer
->descriptors
[0].dynamic_offsets
));
2791 memcpy(cmd_buffer
->descriptors
[firstSet
+ i
].dynamic_offsets
,
2792 pDynamicOffsets
+ dynamic_slot
,
2793 set_layout
->num_dynamic_buffers
* sizeof(*pDynamicOffsets
));
2795 cmd_buffer
->descriptors_dirty
|= set_layout
->shader_stages
;
2797 dynamic_slot
+= set_layout
->num_dynamic_buffers
;
2801 void anv_CmdBindIndexBuffer(
2802 VkCmdBuffer cmdBuffer
,
2804 VkDeviceSize offset
,
2805 VkIndexType indexType
)
2807 struct anv_cmd_buffer
*cmd_buffer
= (struct anv_cmd_buffer
*) cmdBuffer
;
2808 struct anv_buffer
*buffer
= (struct anv_buffer
*) _buffer
;
2810 static const uint32_t vk_to_gen_index_type
[] = {
2811 [VK_INDEX_TYPE_UINT8
] = INDEX_BYTE
,
2812 [VK_INDEX_TYPE_UINT16
] = INDEX_WORD
,
2813 [VK_INDEX_TYPE_UINT32
] = INDEX_DWORD
,
2816 anv_batch_emit(&cmd_buffer
->batch
, GEN8_3DSTATE_INDEX_BUFFER
,
2817 .IndexFormat
= vk_to_gen_index_type
[indexType
],
2818 .MemoryObjectControlState
= GEN8_MOCS
,
2819 .BufferStartingAddress
= { buffer
->bo
, buffer
->offset
+ offset
},
2820 .BufferSize
= buffer
->size
- offset
);
2823 void anv_CmdBindVertexBuffers(
2824 VkCmdBuffer cmdBuffer
,
2825 uint32_t startBinding
,
2826 uint32_t bindingCount
,
2827 const VkBuffer
* pBuffers
,
2828 const VkDeviceSize
* pOffsets
)
2830 struct anv_cmd_buffer
*cmd_buffer
= (struct anv_cmd_buffer
*) cmdBuffer
;
2831 struct anv_vertex_binding
*vb
= cmd_buffer
->vertex_bindings
;
2833 /* We have to defer setting up vertex buffer since we need the buffer
2834 * stride from the pipeline. */
2836 assert(startBinding
+ bindingCount
< MAX_VBS
);
2837 for (uint32_t i
= 0; i
< bindingCount
; i
++) {
2838 vb
[startBinding
+ i
].buffer
= (struct anv_buffer
*) pBuffers
[i
];
2839 vb
[startBinding
+ i
].offset
= pOffsets
[i
];
2840 cmd_buffer
->vb_dirty
|= 1 << (startBinding
+ i
);
2845 cmd_buffer_emit_binding_table(struct anv_cmd_buffer
*cmd_buffer
,
2846 unsigned stage
, struct anv_state
*bt_state
)
2848 struct anv_pipeline_layout
*layout
;
2849 uint32_t color_attachments
, bias
, size
;
2851 if (stage
== VK_SHADER_STAGE_COMPUTE
)
2852 layout
= cmd_buffer
->compute_pipeline
->layout
;
2854 layout
= cmd_buffer
->pipeline
->layout
;
2856 if (stage
== VK_SHADER_STAGE_FRAGMENT
) {
2858 color_attachments
= cmd_buffer
->framebuffer
->color_attachment_count
;
2861 color_attachments
= 0;
2864 /* This is a little awkward: layout can be NULL but we still have to
2865 * allocate and set a binding table for the PS stage for render
2867 uint32_t surface_count
= layout
? layout
->stage
[stage
].surface_count
: 0;
2869 if (color_attachments
+ surface_count
== 0)
2872 size
= (bias
+ surface_count
) * sizeof(uint32_t);
2873 *bt_state
= anv_cmd_buffer_alloc_surface_state(cmd_buffer
, size
, 32);
2874 uint32_t *bt_map
= bt_state
->map
;
2876 if (bt_state
->map
== NULL
)
2877 return VK_ERROR_OUT_OF_DEVICE_MEMORY
;
2879 for (uint32_t ca
= 0; ca
< color_attachments
; ca
++) {
2880 const struct anv_surface_view
*view
=
2881 cmd_buffer
->framebuffer
->color_attachments
[ca
];
2883 struct anv_state state
=
2884 anv_cmd_buffer_alloc_surface_state(cmd_buffer
, 64, 64);
2886 if (state
.map
== NULL
)
2887 return VK_ERROR_OUT_OF_DEVICE_MEMORY
;
2889 memcpy(state
.map
, view
->surface_state
.map
, 64);
2891 /* The address goes in dwords 8 and 9 of the SURFACE_STATE */
2892 *(uint64_t *)(state
.map
+ 8 * 4) =
2893 anv_reloc_list_add(&cmd_buffer
->surface_relocs
,
2895 state
.offset
+ 8 * 4,
2896 view
->bo
, view
->offset
);
2898 bt_map
[ca
] = state
.offset
;
2904 for (uint32_t set
= 0; set
< layout
->num_sets
; set
++) {
2905 struct anv_descriptor_set_binding
*d
= &cmd_buffer
->descriptors
[set
];
2906 struct anv_descriptor_set_layout
*set_layout
= layout
->set
[set
].layout
;
2907 struct anv_descriptor_slot
*surface_slots
=
2908 set_layout
->stage
[stage
].surface_start
;
2910 uint32_t start
= bias
+ layout
->set
[set
].surface_start
[stage
];
2912 for (uint32_t b
= 0; b
< set_layout
->stage
[stage
].surface_count
; b
++) {
2913 struct anv_surface_view
*view
=
2914 d
->set
->descriptors
[surface_slots
[b
].index
].view
;
2919 struct anv_state state
=
2920 anv_cmd_buffer_alloc_surface_state(cmd_buffer
, 64, 64);
2922 if (state
.map
== NULL
)
2923 return VK_ERROR_OUT_OF_DEVICE_MEMORY
;
2926 if (surface_slots
[b
].dynamic_slot
>= 0) {
2927 uint32_t dynamic_offset
=
2928 d
->dynamic_offsets
[surface_slots
[b
].dynamic_slot
];
2930 offset
= view
->offset
+ dynamic_offset
;
2931 fill_buffer_surface_state(state
.map
, view
->format
, offset
,
2932 view
->range
- dynamic_offset
);
2934 offset
= view
->offset
;
2935 memcpy(state
.map
, view
->surface_state
.map
, 64);
2938 /* The address goes in dwords 8 and 9 of the SURFACE_STATE */
2939 *(uint64_t *)(state
.map
+ 8 * 4) =
2940 anv_reloc_list_add(&cmd_buffer
->surface_relocs
,
2942 state
.offset
+ 8 * 4,
2945 bt_map
[start
+ b
] = state
.offset
;
2953 cmd_buffer_emit_samplers(struct anv_cmd_buffer
*cmd_buffer
,
2954 unsigned stage
, struct anv_state
*state
)
2956 struct anv_pipeline_layout
*layout
;
2957 uint32_t sampler_count
;
2959 if (stage
== VK_SHADER_STAGE_COMPUTE
)
2960 layout
= cmd_buffer
->compute_pipeline
->layout
;
2962 layout
= cmd_buffer
->pipeline
->layout
;
2964 sampler_count
= layout
? layout
->stage
[stage
].sampler_count
: 0;
2965 if (sampler_count
== 0)
2968 uint32_t size
= sampler_count
* 16;
2969 *state
= anv_state_stream_alloc(&cmd_buffer
->dynamic_state_stream
, size
, 32);
2971 if (state
->map
== NULL
)
2972 return VK_ERROR_OUT_OF_DEVICE_MEMORY
;
2974 for (uint32_t set
= 0; set
< layout
->num_sets
; set
++) {
2975 struct anv_descriptor_set_binding
*d
= &cmd_buffer
->descriptors
[set
];
2976 struct anv_descriptor_set_layout
*set_layout
= layout
->set
[set
].layout
;
2977 struct anv_descriptor_slot
*sampler_slots
=
2978 set_layout
->stage
[stage
].sampler_start
;
2980 uint32_t start
= layout
->set
[set
].sampler_start
[stage
];
2982 for (uint32_t b
= 0; b
< set_layout
->stage
[stage
].sampler_count
; b
++) {
2983 struct anv_sampler
*sampler
=
2984 d
->set
->descriptors
[sampler_slots
[b
].index
].sampler
;
2989 memcpy(state
->map
+ (start
+ b
) * 16,
2990 sampler
->state
, sizeof(sampler
->state
));
2998 flush_descriptor_set(struct anv_cmd_buffer
*cmd_buffer
, uint32_t stage
)
3000 struct anv_state surfaces
= { 0, }, samplers
= { 0, };
3003 result
= cmd_buffer_emit_samplers(cmd_buffer
, stage
, &samplers
);
3004 if (result
!= VK_SUCCESS
)
3006 result
= cmd_buffer_emit_binding_table(cmd_buffer
, stage
, &surfaces
);
3007 if (result
!= VK_SUCCESS
)
3010 static const uint32_t sampler_state_opcodes
[] = {
3011 [VK_SHADER_STAGE_VERTEX
] = 43,
3012 [VK_SHADER_STAGE_TESS_CONTROL
] = 44, /* HS */
3013 [VK_SHADER_STAGE_TESS_EVALUATION
] = 45, /* DS */
3014 [VK_SHADER_STAGE_GEOMETRY
] = 46,
3015 [VK_SHADER_STAGE_FRAGMENT
] = 47,
3016 [VK_SHADER_STAGE_COMPUTE
] = 0,
3019 static const uint32_t binding_table_opcodes
[] = {
3020 [VK_SHADER_STAGE_VERTEX
] = 38,
3021 [VK_SHADER_STAGE_TESS_CONTROL
] = 39,
3022 [VK_SHADER_STAGE_TESS_EVALUATION
] = 40,
3023 [VK_SHADER_STAGE_GEOMETRY
] = 41,
3024 [VK_SHADER_STAGE_FRAGMENT
] = 42,
3025 [VK_SHADER_STAGE_COMPUTE
] = 0,
3028 if (samplers
.alloc_size
> 0) {
3029 anv_batch_emit(&cmd_buffer
->batch
,
3030 GEN8_3DSTATE_SAMPLER_STATE_POINTERS_VS
,
3031 ._3DCommandSubOpcode
= sampler_state_opcodes
[stage
],
3032 .PointertoVSSamplerState
= samplers
.offset
);
3035 if (surfaces
.alloc_size
> 0) {
3036 anv_batch_emit(&cmd_buffer
->batch
,
3037 GEN8_3DSTATE_BINDING_TABLE_POINTERS_VS
,
3038 ._3DCommandSubOpcode
= binding_table_opcodes
[stage
],
3039 .PointertoVSBindingTable
= surfaces
.offset
);
3046 flush_descriptor_sets(struct anv_cmd_buffer
*cmd_buffer
)
3048 uint32_t s
, dirty
= cmd_buffer
->descriptors_dirty
&
3049 cmd_buffer
->pipeline
->active_stages
;
3052 for_each_bit(s
, dirty
) {
3053 result
= flush_descriptor_set(cmd_buffer
, s
);
3054 if (result
!= VK_SUCCESS
)
3058 if (result
!= VK_SUCCESS
) {
3059 assert(result
== VK_ERROR_OUT_OF_DEVICE_MEMORY
);
3061 result
= anv_cmd_buffer_new_surface_state_bo(cmd_buffer
);
3062 assert(result
== VK_SUCCESS
);
3064 /* Re-emit all active binding tables */
3065 for_each_bit(s
, cmd_buffer
->pipeline
->active_stages
) {
3066 result
= flush_descriptor_set(cmd_buffer
, s
);
3068 /* It had better succeed this time */
3069 assert(result
== VK_SUCCESS
);
3073 cmd_buffer
->descriptors_dirty
&= ~cmd_buffer
->pipeline
->active_stages
;
3076 static struct anv_state
3077 anv_cmd_buffer_emit_dynamic(struct anv_cmd_buffer
*cmd_buffer
,
3078 uint32_t *a
, uint32_t dwords
, uint32_t alignment
)
3080 struct anv_state state
;
3082 state
= anv_state_stream_alloc(&cmd_buffer
->dynamic_state_stream
,
3083 dwords
* 4, alignment
);
3084 memcpy(state
.map
, a
, dwords
* 4);
3086 VG(VALGRIND_CHECK_MEM_IS_DEFINED(state
.map
, dwords
* 4));
3091 static struct anv_state
3092 anv_cmd_buffer_merge_dynamic(struct anv_cmd_buffer
*cmd_buffer
,
3093 uint32_t *a
, uint32_t *b
,
3094 uint32_t dwords
, uint32_t alignment
)
3096 struct anv_state state
;
3099 state
= anv_state_stream_alloc(&cmd_buffer
->dynamic_state_stream
,
3100 dwords
* 4, alignment
);
3102 for (uint32_t i
= 0; i
< dwords
; i
++)
3105 VG(VALGRIND_CHECK_MEM_IS_DEFINED(p
, dwords
* 4));
3111 flush_compute_descriptor_set(struct anv_cmd_buffer
*cmd_buffer
)
3113 struct anv_device
*device
= cmd_buffer
->device
;
3114 struct anv_pipeline
*pipeline
= cmd_buffer
->compute_pipeline
;
3115 struct anv_state surfaces
= { 0, }, samplers
= { 0, };
3118 result
= cmd_buffer_emit_samplers(cmd_buffer
,
3119 VK_SHADER_STAGE_COMPUTE
, &samplers
);
3120 if (result
!= VK_SUCCESS
)
3122 result
= cmd_buffer_emit_binding_table(cmd_buffer
,
3123 VK_SHADER_STAGE_COMPUTE
, &surfaces
);
3124 if (result
!= VK_SUCCESS
)
3127 struct GEN8_INTERFACE_DESCRIPTOR_DATA desc
= {
3128 .KernelStartPointer
= pipeline
->cs_simd
,
3129 .KernelStartPointerHigh
= 0,
3130 .BindingTablePointer
= surfaces
.offset
,
3131 .BindingTableEntryCount
= 0,
3132 .SamplerStatePointer
= samplers
.offset
,
3134 .NumberofThreadsinGPGPUThreadGroup
= 0 /* FIXME: Really? */
3137 uint32_t size
= GEN8_INTERFACE_DESCRIPTOR_DATA_length
* sizeof(uint32_t);
3138 struct anv_state state
=
3139 anv_state_pool_alloc(&device
->dynamic_state_pool
, size
, 64);
3141 GEN8_INTERFACE_DESCRIPTOR_DATA_pack(NULL
, state
.map
, &desc
);
3143 anv_batch_emit(&cmd_buffer
->batch
, GEN8_MEDIA_INTERFACE_DESCRIPTOR_LOAD
,
3144 .InterfaceDescriptorTotalLength
= size
,
3145 .InterfaceDescriptorDataStartAddress
= state
.offset
);
3151 anv_cmd_buffer_flush_compute_state(struct anv_cmd_buffer
*cmd_buffer
)
3153 struct anv_pipeline
*pipeline
= cmd_buffer
->compute_pipeline
;
3156 assert(pipeline
->active_stages
== VK_SHADER_STAGE_COMPUTE_BIT
);
3158 if (cmd_buffer
->current_pipeline
!= GPGPU
) {
3159 anv_batch_emit(&cmd_buffer
->batch
, GEN8_PIPELINE_SELECT
,
3160 .PipelineSelection
= GPGPU
);
3161 cmd_buffer
->current_pipeline
= GPGPU
;
3164 if (cmd_buffer
->compute_dirty
& ANV_CMD_BUFFER_PIPELINE_DIRTY
)
3165 anv_batch_emit_batch(&cmd_buffer
->batch
, &pipeline
->batch
);
3167 if ((cmd_buffer
->descriptors_dirty
& VK_SHADER_STAGE_COMPUTE_BIT
) ||
3168 (cmd_buffer
->compute_dirty
& ANV_CMD_BUFFER_PIPELINE_DIRTY
)) {
3169 result
= flush_compute_descriptor_set(cmd_buffer
);
3170 if (result
!= VK_SUCCESS
) {
3171 result
= anv_cmd_buffer_new_surface_state_bo(cmd_buffer
);
3172 assert(result
== VK_SUCCESS
);
3173 result
= flush_compute_descriptor_set(cmd_buffer
);
3174 assert(result
== VK_SUCCESS
);
3176 cmd_buffer
->descriptors_dirty
&= ~VK_SHADER_STAGE_COMPUTE
;
3179 cmd_buffer
->compute_dirty
= 0;
3183 anv_cmd_buffer_flush_state(struct anv_cmd_buffer
*cmd_buffer
)
3185 struct anv_pipeline
*pipeline
= cmd_buffer
->pipeline
;
3188 uint32_t vb_emit
= cmd_buffer
->vb_dirty
& pipeline
->vb_used
;
3190 assert((pipeline
->active_stages
& VK_SHADER_STAGE_COMPUTE_BIT
) == 0);
3192 if (cmd_buffer
->current_pipeline
!= _3D
) {
3193 anv_batch_emit(&cmd_buffer
->batch
, GEN8_PIPELINE_SELECT
,
3194 .PipelineSelection
= _3D
);
3195 cmd_buffer
->current_pipeline
= _3D
;
3199 const uint32_t num_buffers
= __builtin_popcount(vb_emit
);
3200 const uint32_t num_dwords
= 1 + num_buffers
* 4;
3202 p
= anv_batch_emitn(&cmd_buffer
->batch
, num_dwords
,
3203 GEN8_3DSTATE_VERTEX_BUFFERS
);
3205 for_each_bit(vb
, vb_emit
) {
3206 struct anv_buffer
*buffer
= cmd_buffer
->vertex_bindings
[vb
].buffer
;
3207 uint32_t offset
= cmd_buffer
->vertex_bindings
[vb
].offset
;
3209 struct GEN8_VERTEX_BUFFER_STATE state
= {
3210 .VertexBufferIndex
= vb
,
3211 .MemoryObjectControlState
= GEN8_MOCS
,
3212 .AddressModifyEnable
= true,
3213 .BufferPitch
= pipeline
->binding_stride
[vb
],
3214 .BufferStartingAddress
= { buffer
->bo
, buffer
->offset
+ offset
},
3215 .BufferSize
= buffer
->size
- offset
3218 GEN8_VERTEX_BUFFER_STATE_pack(&cmd_buffer
->batch
, &p
[1 + i
* 4], &state
);
3223 if (cmd_buffer
->dirty
& ANV_CMD_BUFFER_PIPELINE_DIRTY
) {
3224 /* If somebody compiled a pipeline after starting a command buffer the
3225 * scratch bo may have grown since we started this cmd buffer (and
3226 * emitted STATE_BASE_ADDRESS). If we're binding that pipeline now,
3227 * reemit STATE_BASE_ADDRESS so that we use the bigger scratch bo. */
3228 if (cmd_buffer
->scratch_size
< pipeline
->total_scratch
)
3229 anv_cmd_buffer_emit_state_base_address(cmd_buffer
);
3231 anv_batch_emit_batch(&cmd_buffer
->batch
, &pipeline
->batch
);
3234 if (cmd_buffer
->descriptors_dirty
)
3235 flush_descriptor_sets(cmd_buffer
);
3237 if (cmd_buffer
->dirty
& ANV_CMD_BUFFER_VP_DIRTY
) {
3238 anv_batch_emit(&cmd_buffer
->batch
, GEN8_3DSTATE_SCISSOR_STATE_POINTERS
,
3239 .ScissorRectPointer
= cmd_buffer
->vp_state
->scissor
.offset
);
3240 anv_batch_emit(&cmd_buffer
->batch
, GEN8_3DSTATE_VIEWPORT_STATE_POINTERS_CC
,
3241 .CCViewportPointer
= cmd_buffer
->vp_state
->cc_vp
.offset
);
3242 anv_batch_emit(&cmd_buffer
->batch
, GEN8_3DSTATE_VIEWPORT_STATE_POINTERS_SF_CLIP
,
3243 .SFClipViewportPointer
= cmd_buffer
->vp_state
->sf_clip_vp
.offset
);
3246 if (cmd_buffer
->dirty
& (ANV_CMD_BUFFER_PIPELINE_DIRTY
| ANV_CMD_BUFFER_RS_DIRTY
)) {
3247 anv_batch_emit_merge(&cmd_buffer
->batch
,
3248 cmd_buffer
->rs_state
->state_sf
, pipeline
->state_sf
);
3249 anv_batch_emit_merge(&cmd_buffer
->batch
,
3250 cmd_buffer
->rs_state
->state_raster
, pipeline
->state_raster
);
3253 if (cmd_buffer
->ds_state
&&
3254 (cmd_buffer
->dirty
& (ANV_CMD_BUFFER_PIPELINE_DIRTY
| ANV_CMD_BUFFER_DS_DIRTY
)))
3255 anv_batch_emit_merge(&cmd_buffer
->batch
,
3256 cmd_buffer
->ds_state
->state_wm_depth_stencil
,
3257 pipeline
->state_wm_depth_stencil
);
3259 if (cmd_buffer
->dirty
& (ANV_CMD_BUFFER_CB_DIRTY
| ANV_CMD_BUFFER_DS_DIRTY
)) {
3260 struct anv_state state
;
3261 if (cmd_buffer
->ds_state
== NULL
)
3262 state
= anv_cmd_buffer_emit_dynamic(cmd_buffer
,
3263 cmd_buffer
->cb_state
->state_color_calc
,
3264 GEN8_COLOR_CALC_STATE_length
, 64);
3265 else if (cmd_buffer
->cb_state
== NULL
)
3266 state
= anv_cmd_buffer_emit_dynamic(cmd_buffer
,
3267 cmd_buffer
->ds_state
->state_color_calc
,
3268 GEN8_COLOR_CALC_STATE_length
, 64);
3270 state
= anv_cmd_buffer_merge_dynamic(cmd_buffer
,
3271 cmd_buffer
->ds_state
->state_color_calc
,
3272 cmd_buffer
->cb_state
->state_color_calc
,
3273 GEN8_COLOR_CALC_STATE_length
, 64);
3275 anv_batch_emit(&cmd_buffer
->batch
,
3276 GEN8_3DSTATE_CC_STATE_POINTERS
,
3277 .ColorCalcStatePointer
= state
.offset
,
3278 .ColorCalcStatePointerValid
= true);
3281 cmd_buffer
->vb_dirty
&= ~vb_emit
;
3282 cmd_buffer
->dirty
= 0;
3286 VkCmdBuffer cmdBuffer
,
3287 uint32_t firstVertex
,
3288 uint32_t vertexCount
,
3289 uint32_t firstInstance
,
3290 uint32_t instanceCount
)
3292 struct anv_cmd_buffer
*cmd_buffer
= (struct anv_cmd_buffer
*) cmdBuffer
;
3294 anv_cmd_buffer_flush_state(cmd_buffer
);
3296 anv_batch_emit(&cmd_buffer
->batch
, GEN8_3DPRIMITIVE
,
3297 .VertexAccessType
= SEQUENTIAL
,
3298 .VertexCountPerInstance
= vertexCount
,
3299 .StartVertexLocation
= firstVertex
,
3300 .InstanceCount
= instanceCount
,
3301 .StartInstanceLocation
= firstInstance
,
3302 .BaseVertexLocation
= 0);
3305 void anv_CmdDrawIndexed(
3306 VkCmdBuffer cmdBuffer
,
3307 uint32_t firstIndex
,
3308 uint32_t indexCount
,
3309 int32_t vertexOffset
,
3310 uint32_t firstInstance
,
3311 uint32_t instanceCount
)
3313 struct anv_cmd_buffer
*cmd_buffer
= (struct anv_cmd_buffer
*) cmdBuffer
;
3315 anv_cmd_buffer_flush_state(cmd_buffer
);
3317 anv_batch_emit(&cmd_buffer
->batch
, GEN8_3DPRIMITIVE
,
3318 .VertexAccessType
= RANDOM
,
3319 .VertexCountPerInstance
= indexCount
,
3320 .StartVertexLocation
= firstIndex
,
3321 .InstanceCount
= instanceCount
,
3322 .StartInstanceLocation
= firstInstance
,
3323 .BaseVertexLocation
= vertexOffset
);
3327 anv_batch_lrm(struct anv_batch
*batch
,
3328 uint32_t reg
, struct anv_bo
*bo
, uint32_t offset
)
3330 anv_batch_emit(batch
, GEN8_MI_LOAD_REGISTER_MEM
,
3331 .RegisterAddress
= reg
,
3332 .MemoryAddress
= { bo
, offset
});
3336 anv_batch_lri(struct anv_batch
*batch
, uint32_t reg
, uint32_t imm
)
3338 anv_batch_emit(batch
, GEN8_MI_LOAD_REGISTER_IMM
,
3339 .RegisterOffset
= reg
,
3343 /* Auto-Draw / Indirect Registers */
3344 #define GEN7_3DPRIM_END_OFFSET 0x2420
3345 #define GEN7_3DPRIM_START_VERTEX 0x2430
3346 #define GEN7_3DPRIM_VERTEX_COUNT 0x2434
3347 #define GEN7_3DPRIM_INSTANCE_COUNT 0x2438
3348 #define GEN7_3DPRIM_START_INSTANCE 0x243C
3349 #define GEN7_3DPRIM_BASE_VERTEX 0x2440
3351 void anv_CmdDrawIndirect(
3352 VkCmdBuffer cmdBuffer
,
3354 VkDeviceSize offset
,
3358 struct anv_cmd_buffer
*cmd_buffer
= (struct anv_cmd_buffer
*) cmdBuffer
;
3359 struct anv_buffer
*buffer
= (struct anv_buffer
*) _buffer
;
3360 struct anv_bo
*bo
= buffer
->bo
;
3361 uint32_t bo_offset
= buffer
->offset
+ offset
;
3363 anv_cmd_buffer_flush_state(cmd_buffer
);
3365 anv_batch_lrm(&cmd_buffer
->batch
, GEN7_3DPRIM_VERTEX_COUNT
, bo
, bo_offset
);
3366 anv_batch_lrm(&cmd_buffer
->batch
, GEN7_3DPRIM_INSTANCE_COUNT
, bo
, bo_offset
+ 4);
3367 anv_batch_lrm(&cmd_buffer
->batch
, GEN7_3DPRIM_START_VERTEX
, bo
, bo_offset
+ 8);
3368 anv_batch_lrm(&cmd_buffer
->batch
, GEN7_3DPRIM_START_INSTANCE
, bo
, bo_offset
+ 12);
3369 anv_batch_lri(&cmd_buffer
->batch
, GEN7_3DPRIM_BASE_VERTEX
, 0);
3371 anv_batch_emit(&cmd_buffer
->batch
, GEN8_3DPRIMITIVE
,
3372 .IndirectParameterEnable
= true,
3373 .VertexAccessType
= SEQUENTIAL
);
3376 void anv_CmdDrawIndexedIndirect(
3377 VkCmdBuffer cmdBuffer
,
3379 VkDeviceSize offset
,
3383 struct anv_cmd_buffer
*cmd_buffer
= (struct anv_cmd_buffer
*) cmdBuffer
;
3384 struct anv_buffer
*buffer
= (struct anv_buffer
*) _buffer
;
3385 struct anv_bo
*bo
= buffer
->bo
;
3386 uint32_t bo_offset
= buffer
->offset
+ offset
;
3388 anv_cmd_buffer_flush_state(cmd_buffer
);
3390 anv_batch_lrm(&cmd_buffer
->batch
, GEN7_3DPRIM_VERTEX_COUNT
, bo
, bo_offset
);
3391 anv_batch_lrm(&cmd_buffer
->batch
, GEN7_3DPRIM_INSTANCE_COUNT
, bo
, bo_offset
+ 4);
3392 anv_batch_lrm(&cmd_buffer
->batch
, GEN7_3DPRIM_START_VERTEX
, bo
, bo_offset
+ 8);
3393 anv_batch_lrm(&cmd_buffer
->batch
, GEN7_3DPRIM_BASE_VERTEX
, bo
, bo_offset
+ 12);
3394 anv_batch_lrm(&cmd_buffer
->batch
, GEN7_3DPRIM_START_INSTANCE
, bo
, bo_offset
+ 16);
3396 anv_batch_emit(&cmd_buffer
->batch
, GEN8_3DPRIMITIVE
,
3397 .IndirectParameterEnable
= true,
3398 .VertexAccessType
= RANDOM
);
3401 void anv_CmdDispatch(
3402 VkCmdBuffer cmdBuffer
,
3407 struct anv_cmd_buffer
*cmd_buffer
= (struct anv_cmd_buffer
*) cmdBuffer
;
3408 struct anv_pipeline
*pipeline
= cmd_buffer
->compute_pipeline
;
3409 struct brw_cs_prog_data
*prog_data
= &pipeline
->cs_prog_data
;
3411 anv_cmd_buffer_flush_compute_state(cmd_buffer
);
3413 anv_batch_emit(&cmd_buffer
->batch
, GEN8_GPGPU_WALKER
,
3414 .SIMDSize
= prog_data
->simd_size
/ 16,
3415 .ThreadDepthCounterMaximum
= 0,
3416 .ThreadHeightCounterMaximum
= 0,
3417 .ThreadWidthCounterMaximum
= pipeline
->cs_thread_width_max
,
3418 .ThreadGroupIDXDimension
= x
,
3419 .ThreadGroupIDYDimension
= y
,
3420 .ThreadGroupIDZDimension
= z
,
3421 .RightExecutionMask
= pipeline
->cs_right_mask
,
3422 .BottomExecutionMask
= 0xffffffff);
3424 anv_batch_emit(&cmd_buffer
->batch
, GEN8_MEDIA_STATE_FLUSH
);
3427 #define GPGPU_DISPATCHDIMX 0x2500
3428 #define GPGPU_DISPATCHDIMY 0x2504
3429 #define GPGPU_DISPATCHDIMZ 0x2508
3431 void anv_CmdDispatchIndirect(
3432 VkCmdBuffer cmdBuffer
,
3434 VkDeviceSize offset
)
3436 struct anv_cmd_buffer
*cmd_buffer
= (struct anv_cmd_buffer
*) cmdBuffer
;
3437 struct anv_pipeline
*pipeline
= cmd_buffer
->compute_pipeline
;
3438 struct brw_cs_prog_data
*prog_data
= &pipeline
->cs_prog_data
;
3439 struct anv_buffer
*buffer
= (struct anv_buffer
*) _buffer
;
3440 struct anv_bo
*bo
= buffer
->bo
;
3441 uint32_t bo_offset
= buffer
->offset
+ offset
;
3443 anv_cmd_buffer_flush_compute_state(cmd_buffer
);
3445 anv_batch_lrm(&cmd_buffer
->batch
, GPGPU_DISPATCHDIMX
, bo
, bo_offset
);
3446 anv_batch_lrm(&cmd_buffer
->batch
, GPGPU_DISPATCHDIMY
, bo
, bo_offset
+ 4);
3447 anv_batch_lrm(&cmd_buffer
->batch
, GPGPU_DISPATCHDIMZ
, bo
, bo_offset
+ 8);
3449 anv_batch_emit(&cmd_buffer
->batch
, GEN8_GPGPU_WALKER
,
3450 .IndirectParameterEnable
= true,
3451 .SIMDSize
= prog_data
->simd_size
/ 16,
3452 .ThreadDepthCounterMaximum
= 0,
3453 .ThreadHeightCounterMaximum
= 0,
3454 .ThreadWidthCounterMaximum
= pipeline
->cs_thread_width_max
,
3455 .RightExecutionMask
= pipeline
->cs_right_mask
,
3456 .BottomExecutionMask
= 0xffffffff);
3458 anv_batch_emit(&cmd_buffer
->batch
, GEN8_MEDIA_STATE_FLUSH
);
3461 void anv_CmdSetEvent(
3462 VkCmdBuffer cmdBuffer
,
3464 VkPipeEvent pipeEvent
)
3469 void anv_CmdResetEvent(
3470 VkCmdBuffer cmdBuffer
,
3472 VkPipeEvent pipeEvent
)
3477 void anv_CmdWaitEvents(
3478 VkCmdBuffer cmdBuffer
,
3479 VkWaitEvent waitEvent
,
3480 uint32_t eventCount
,
3481 const VkEvent
* pEvents
,
3482 uint32_t memBarrierCount
,
3483 const void** ppMemBarriers
)
3488 void anv_CmdPipelineBarrier(
3489 VkCmdBuffer cmdBuffer
,
3490 VkWaitEvent waitEvent
,
3491 uint32_t pipeEventCount
,
3492 const VkPipeEvent
* pPipeEvents
,
3493 uint32_t memBarrierCount
,
3494 const void** ppMemBarriers
)
3496 struct anv_cmd_buffer
*cmd_buffer
= (struct anv_cmd_buffer
*)cmdBuffer
;
3499 struct GEN8_PIPE_CONTROL cmd
= {
3500 GEN8_PIPE_CONTROL_header
,
3501 .PostSyncOperation
= NoWrite
,
3504 /* XXX: I think waitEvent is a no-op on our HW. We should verify that. */
3506 for (uint32_t i
= 0; i
< pipeEventCount
; i
++) {
3507 switch (pPipeEvents
[i
]) {
3508 case VK_PIPE_EVENT_TOP_OF_PIPE
:
3509 /* This is just what PIPE_CONTROL does */
3511 case VK_PIPE_EVENT_VERTEX_PROCESSING_COMPLETE
:
3512 case VK_PIPE_EVENT_LOCAL_FRAGMENT_PROCESSING_COMPLETE
:
3513 case VK_PIPE_EVENT_FRAGMENT_PROCESSING_COMPLETE
:
3514 cmd
.StallAtPixelScoreboard
= true;
3516 case VK_PIPE_EVENT_GRAPHICS_PIPELINE_COMPLETE
:
3517 case VK_PIPE_EVENT_COMPUTE_PIPELINE_COMPLETE
:
3518 case VK_PIPE_EVENT_TRANSFER_COMPLETE
:
3519 case VK_PIPE_EVENT_COMMANDS_COMPLETE
:
3520 cmd
.CommandStreamerStallEnable
= true;
3523 unreachable("Invalid VkPipeEvent");
3527 /* XXX: Right now, we're really dumb and just flush whatever categories
3528 * the app asks for. One of these days we may make this a bit better
3529 * but right now that's all the hardware allows for in most areas.
3531 VkMemoryOutputFlags out_flags
= 0;
3532 VkMemoryInputFlags in_flags
= 0;
3534 for (uint32_t i
= 0; i
< memBarrierCount
; i
++) {
3535 const struct anv_common
*common
= ppMemBarriers
[i
];
3536 switch (common
->sType
) {
3537 case VK_STRUCTURE_TYPE_MEMORY_BARRIER
: {
3538 const VkMemoryBarrier
*barrier
= (VkMemoryBarrier
*)common
;
3539 out_flags
|= barrier
->outputMask
;
3540 in_flags
|= barrier
->inputMask
;
3543 case VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER
: {
3544 const VkBufferMemoryBarrier
*barrier
= (VkBufferMemoryBarrier
*)common
;
3545 out_flags
|= barrier
->outputMask
;
3546 in_flags
|= barrier
->inputMask
;
3549 case VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER
: {
3550 const VkImageMemoryBarrier
*barrier
= (VkImageMemoryBarrier
*)common
;
3551 out_flags
|= barrier
->outputMask
;
3552 in_flags
|= barrier
->inputMask
;
3556 unreachable("Invalid memory barrier type");
3560 for_each_bit(b
, out_flags
) {
3561 switch ((VkMemoryOutputFlags
)(1 << b
)) {
3562 case VK_MEMORY_OUTPUT_CPU_WRITE_BIT
:
3563 break; /* FIXME: Little-core systems */
3564 case VK_MEMORY_OUTPUT_SHADER_WRITE_BIT
:
3565 cmd
.DCFlushEnable
= true;
3567 case VK_MEMORY_OUTPUT_COLOR_ATTACHMENT_BIT
:
3568 cmd
.RenderTargetCacheFlushEnable
= true;
3570 case VK_MEMORY_OUTPUT_DEPTH_STENCIL_ATTACHMENT_BIT
:
3571 cmd
.DepthCacheFlushEnable
= true;
3573 case VK_MEMORY_OUTPUT_TRANSFER_BIT
:
3574 cmd
.RenderTargetCacheFlushEnable
= true;
3575 cmd
.DepthCacheFlushEnable
= true;
3578 unreachable("Invalid memory output flag");
3582 for_each_bit(b
, out_flags
) {
3583 switch ((VkMemoryInputFlags
)(1 << b
)) {
3584 case VK_MEMORY_INPUT_CPU_READ_BIT
:
3585 break; /* FIXME: Little-core systems */
3586 case VK_MEMORY_INPUT_INDIRECT_COMMAND_BIT
:
3587 case VK_MEMORY_INPUT_INDEX_FETCH_BIT
:
3588 case VK_MEMORY_INPUT_VERTEX_ATTRIBUTE_FETCH_BIT
:
3589 cmd
.VFCacheInvalidationEnable
= true;
3591 case VK_MEMORY_INPUT_UNIFORM_READ_BIT
:
3592 cmd
.ConstantCacheInvalidationEnable
= true;
3594 case VK_MEMORY_INPUT_SHADER_READ_BIT
:
3595 cmd
.DCFlushEnable
= true;
3596 cmd
.TextureCacheInvalidationEnable
= true;
3598 case VK_MEMORY_INPUT_COLOR_ATTACHMENT_BIT
:
3599 case VK_MEMORY_INPUT_DEPTH_STENCIL_ATTACHMENT_BIT
:
3600 break; /* XXX: Hunh? */
3601 case VK_MEMORY_INPUT_TRANSFER_BIT
:
3602 cmd
.TextureCacheInvalidationEnable
= true;
3607 dw
= anv_batch_emit_dwords(&cmd_buffer
->batch
, GEN8_PIPE_CONTROL_length
);
3608 GEN8_PIPE_CONTROL_pack(&cmd_buffer
->batch
, dw
, &cmd
);
3611 void anv_CmdInitAtomicCounters(
3612 VkCmdBuffer cmdBuffer
,
3613 VkPipelineBindPoint pipelineBindPoint
,
3614 uint32_t startCounter
,
3615 uint32_t counterCount
,
3616 const uint32_t* pData
)
3621 void anv_CmdLoadAtomicCounters(
3622 VkCmdBuffer cmdBuffer
,
3623 VkPipelineBindPoint pipelineBindPoint
,
3624 uint32_t startCounter
,
3625 uint32_t counterCount
,
3627 VkDeviceSize srcOffset
)
3632 void anv_CmdSaveAtomicCounters(
3633 VkCmdBuffer cmdBuffer
,
3634 VkPipelineBindPoint pipelineBindPoint
,
3635 uint32_t startCounter
,
3636 uint32_t counterCount
,
3637 VkBuffer destBuffer
,
3638 VkDeviceSize destOffset
)
3644 anv_framebuffer_destroy(struct anv_device
*device
,
3645 struct anv_object
*object
,
3646 VkObjectType obj_type
)
3648 struct anv_framebuffer
*fb
= (struct anv_framebuffer
*)object
;
3650 assert(obj_type
== VK_OBJECT_TYPE_FRAMEBUFFER
);
3652 anv_DestroyObject((VkDevice
) device
,
3653 VK_OBJECT_TYPE_DYNAMIC_VP_STATE
,
3656 anv_device_free(device
, fb
);
3659 VkResult
anv_CreateFramebuffer(
3661 const VkFramebufferCreateInfo
* pCreateInfo
,
3662 VkFramebuffer
* pFramebuffer
)
3664 struct anv_device
*device
= (struct anv_device
*) _device
;
3665 struct anv_framebuffer
*framebuffer
;
3667 static const struct anv_depth_stencil_view null_view
=
3668 { .depth_format
= D16_UNORM
, .depth_stride
= 0, .stencil_stride
= 0 };
3670 assert(pCreateInfo
->sType
== VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO
);
3672 framebuffer
= anv_device_alloc(device
, sizeof(*framebuffer
), 8,
3673 VK_SYSTEM_ALLOC_TYPE_API_OBJECT
);
3674 if (framebuffer
== NULL
)
3675 return vk_error(VK_ERROR_OUT_OF_HOST_MEMORY
);
3677 framebuffer
->base
.destructor
= anv_framebuffer_destroy
;
3679 framebuffer
->color_attachment_count
= pCreateInfo
->colorAttachmentCount
;
3680 for (uint32_t i
= 0; i
< pCreateInfo
->colorAttachmentCount
; i
++) {
3681 framebuffer
->color_attachments
[i
] =
3682 (struct anv_surface_view
*) pCreateInfo
->pColorAttachments
[i
].view
;
3685 if (pCreateInfo
->pDepthStencilAttachment
) {
3686 framebuffer
->depth_stencil
=
3687 (struct anv_depth_stencil_view
*) pCreateInfo
->pDepthStencilAttachment
->view
;
3689 framebuffer
->depth_stencil
= &null_view
;
3692 framebuffer
->sample_count
= pCreateInfo
->sampleCount
;
3693 framebuffer
->width
= pCreateInfo
->width
;
3694 framebuffer
->height
= pCreateInfo
->height
;
3695 framebuffer
->layers
= pCreateInfo
->layers
;
3697 anv_CreateDynamicViewportState((VkDevice
) device
,
3698 &(VkDynamicVpStateCreateInfo
) {
3699 .sType
= VK_STRUCTURE_TYPE_DYNAMIC_VP_STATE_CREATE_INFO
,
3700 .viewportAndScissorCount
= 1,
3701 .pViewports
= (VkViewport
[]) {
3705 .width
= pCreateInfo
->width
,
3706 .height
= pCreateInfo
->height
,
3711 .pScissors
= (VkRect
[]) {
3713 { pCreateInfo
->width
, pCreateInfo
->height
} },
3716 &framebuffer
->vp_state
);
3718 *pFramebuffer
= (VkFramebuffer
) framebuffer
;
3723 VkResult
anv_CreateRenderPass(
3725 const VkRenderPassCreateInfo
* pCreateInfo
,
3726 VkRenderPass
* pRenderPass
)
3728 struct anv_device
*device
= (struct anv_device
*) _device
;
3729 struct anv_render_pass
*pass
;
3732 assert(pCreateInfo
->sType
== VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO
);
3734 size
= sizeof(*pass
) +
3735 pCreateInfo
->layers
* sizeof(struct anv_render_pass_layer
);
3736 pass
= anv_device_alloc(device
, size
, 8,
3737 VK_SYSTEM_ALLOC_TYPE_API_OBJECT
);
3739 return vk_error(VK_ERROR_OUT_OF_HOST_MEMORY
);
3741 pass
->render_area
= pCreateInfo
->renderArea
;
3743 pass
->num_layers
= pCreateInfo
->layers
;
3745 pass
->num_clear_layers
= 0;
3746 for (uint32_t i
= 0; i
< pCreateInfo
->layers
; i
++) {
3747 pass
->layers
[i
].color_load_op
= pCreateInfo
->pColorLoadOps
[i
];
3748 pass
->layers
[i
].clear_color
= pCreateInfo
->pColorLoadClearValues
[i
];
3749 if (pass
->layers
[i
].color_load_op
== VK_ATTACHMENT_LOAD_OP_CLEAR
)
3750 pass
->num_clear_layers
++;
3753 *pRenderPass
= (VkRenderPass
) pass
;
3759 anv_cmd_buffer_emit_depth_stencil(struct anv_cmd_buffer
*cmd_buffer
,
3760 struct anv_render_pass
*pass
)
3762 const struct anv_depth_stencil_view
*view
=
3763 cmd_buffer
->framebuffer
->depth_stencil
;
3765 /* FIXME: Implement the PMA stall W/A */
3767 anv_batch_emit(&cmd_buffer
->batch
, GEN8_3DSTATE_DEPTH_BUFFER
,
3768 .SurfaceType
= SURFTYPE_2D
,
3769 .DepthWriteEnable
= view
->depth_stride
> 0,
3770 .StencilWriteEnable
= view
->stencil_stride
> 0,
3771 .HierarchicalDepthBufferEnable
= false,
3772 .SurfaceFormat
= view
->depth_format
,
3773 .SurfacePitch
= view
->depth_stride
> 0 ? view
->depth_stride
- 1 : 0,
3774 .SurfaceBaseAddress
= { view
->bo
, view
->depth_offset
},
3775 .Height
= pass
->render_area
.extent
.height
- 1,
3776 .Width
= pass
->render_area
.extent
.width
- 1,
3779 .MinimumArrayElement
= 0,
3780 .DepthBufferObjectControlState
= GEN8_MOCS
,
3781 .RenderTargetViewExtent
= 1 - 1,
3782 .SurfaceQPitch
= 0);
3784 /* Disable hierarchial depth buffers. */
3785 anv_batch_emit(&cmd_buffer
->batch
, GEN8_3DSTATE_HIER_DEPTH_BUFFER
);
3787 anv_batch_emit(&cmd_buffer
->batch
, GEN8_3DSTATE_STENCIL_BUFFER
,
3788 .StencilBufferEnable
= view
->stencil_stride
> 0,
3789 .StencilBufferObjectControlState
= GEN8_MOCS
,
3790 .SurfacePitch
= view
->stencil_stride
> 0 ? view
->stencil_stride
- 1 : 0,
3791 .SurfaceBaseAddress
= { view
->bo
, view
->stencil_offset
},
3792 .SurfaceQPitch
= 0);
3794 /* Clear the clear params. */
3795 anv_batch_emit(&cmd_buffer
->batch
, GEN8_3DSTATE_CLEAR_PARAMS
);
3798 void anv_CmdBeginRenderPass(
3799 VkCmdBuffer cmdBuffer
,
3800 const VkRenderPassBegin
* pRenderPassBegin
)
3802 struct anv_cmd_buffer
*cmd_buffer
= (struct anv_cmd_buffer
*) cmdBuffer
;
3803 struct anv_render_pass
*pass
= (struct anv_render_pass
*) pRenderPassBegin
->renderPass
;
3804 struct anv_framebuffer
*framebuffer
=
3805 (struct anv_framebuffer
*) pRenderPassBegin
->framebuffer
;
3807 cmd_buffer
->framebuffer
= framebuffer
;
3809 cmd_buffer
->descriptors_dirty
|= VK_SHADER_STAGE_FRAGMENT_BIT
;
3811 anv_batch_emit(&cmd_buffer
->batch
, GEN8_3DSTATE_DRAWING_RECTANGLE
,
3812 .ClippedDrawingRectangleYMin
= pass
->render_area
.offset
.y
,
3813 .ClippedDrawingRectangleXMin
= pass
->render_area
.offset
.x
,
3814 .ClippedDrawingRectangleYMax
=
3815 pass
->render_area
.offset
.y
+ pass
->render_area
.extent
.height
- 1,
3816 .ClippedDrawingRectangleXMax
=
3817 pass
->render_area
.offset
.x
+ pass
->render_area
.extent
.width
- 1,
3818 .DrawingRectangleOriginY
= 0,
3819 .DrawingRectangleOriginX
= 0);
3821 anv_cmd_buffer_emit_depth_stencil(cmd_buffer
, pass
);
3823 anv_cmd_buffer_clear(cmd_buffer
, pass
);
3826 void anv_CmdEndRenderPass(
3827 VkCmdBuffer cmdBuffer
,
3828 VkRenderPass renderPass
)
3830 /* Emit a flushing pipe control at the end of a pass. This is kind of a
3831 * hack but it ensures that render targets always actually get written.
3832 * Eventually, we should do flushing based on image format transitions
3833 * or something of that nature.
3835 struct anv_cmd_buffer
*cmd_buffer
= (struct anv_cmd_buffer
*)cmdBuffer
;
3836 anv_batch_emit(&cmd_buffer
->batch
, GEN8_PIPE_CONTROL
,
3837 .PostSyncOperation
= NoWrite
,
3838 .RenderTargetCacheFlushEnable
= true,
3839 .InstructionCacheInvalidateEnable
= true,
3840 .DepthCacheFlushEnable
= true,
3841 .VFCacheInvalidationEnable
= true,
3842 .TextureCacheInvalidationEnable
= true,
3843 .CommandStreamerStallEnable
= true);
3846 void vkCmdDbgMarkerBegin(
3847 VkCmdBuffer cmdBuffer
,
3848 const char* pMarker
)
3849 __attribute__ ((visibility ("default")));
3851 void vkCmdDbgMarkerEnd(
3852 VkCmdBuffer cmdBuffer
)
3853 __attribute__ ((visibility ("default")));
3855 VkResult
vkDbgSetObjectTag(
3860 __attribute__ ((visibility ("default")));
3863 void vkCmdDbgMarkerBegin(
3864 VkCmdBuffer cmdBuffer
,
3865 const char* pMarker
)
3869 void vkCmdDbgMarkerEnd(
3870 VkCmdBuffer cmdBuffer
)
3874 VkResult
vkDbgSetObjectTag(