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
31 #include "mesa/main/git_sha1.h"
34 anv_env_get_int(const char *name
)
36 const char *val
= getenv(name
);
41 return strtol(val
, NULL
, 0);
45 anv_physical_device_finish(struct anv_physical_device
*device
)
52 anv_physical_device_init(struct anv_physical_device
*device
,
53 struct anv_instance
*instance
,
56 device
->fd
= open(path
, O_RDWR
| O_CLOEXEC
);
58 return vk_error(VK_ERROR_UNAVAILABLE
);
60 device
->instance
= instance
;
63 device
->chipset_id
= anv_env_get_int("INTEL_DEVID_OVERRIDE");
64 device
->no_hw
= false;
65 if (device
->chipset_id
) {
66 /* INTEL_DEVID_OVERRIDE implies INTEL_NO_HW. */
69 device
->chipset_id
= anv_gem_get_param(device
->fd
, I915_PARAM_CHIPSET_ID
);
71 if (!device
->chipset_id
)
74 device
->name
= brw_get_device_name(device
->chipset_id
);
75 device
->info
= brw_get_device_info(device
->chipset_id
, -1);
79 if (!anv_gem_get_param(device
->fd
, I915_PARAM_HAS_WAIT_TIMEOUT
))
82 if (!anv_gem_get_param(device
->fd
, I915_PARAM_HAS_EXECBUF2
))
85 if (!anv_gem_get_param(device
->fd
, I915_PARAM_HAS_LLC
))
88 if (!anv_gem_get_param(device
->fd
, I915_PARAM_HAS_EXEC_CONSTANTS
))
94 anv_physical_device_finish(device
);
95 return vk_error(VK_ERROR_UNAVAILABLE
);
98 static void *default_alloc(
102 VkSystemAllocType allocType
)
107 static void default_free(
114 static const VkAllocCallbacks default_alloc_callbacks
= {
116 .pfnAlloc
= default_alloc
,
117 .pfnFree
= default_free
120 VkResult
anv_CreateInstance(
121 const VkInstanceCreateInfo
* pCreateInfo
,
122 VkInstance
* pInstance
)
124 struct anv_instance
*instance
;
125 const VkAllocCallbacks
*alloc_callbacks
= &default_alloc_callbacks
;
126 void *user_data
= NULL
;
128 assert(pCreateInfo
->sType
== VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO
);
130 if (pCreateInfo
->pAllocCb
) {
131 alloc_callbacks
= pCreateInfo
->pAllocCb
;
132 user_data
= pCreateInfo
->pAllocCb
->pUserData
;
134 instance
= alloc_callbacks
->pfnAlloc(user_data
, sizeof(*instance
), 8,
135 VK_SYSTEM_ALLOC_TYPE_API_OBJECT
);
137 return vk_error(VK_ERROR_OUT_OF_HOST_MEMORY
);
139 instance
->pAllocUserData
= alloc_callbacks
->pUserData
;
140 instance
->pfnAlloc
= alloc_callbacks
->pfnAlloc
;
141 instance
->pfnFree
= alloc_callbacks
->pfnFree
;
142 instance
->apiVersion
= pCreateInfo
->pAppInfo
->apiVersion
;
143 instance
->physicalDeviceCount
= 0;
145 *pInstance
= anv_instance_to_handle(instance
);
150 VkResult
anv_DestroyInstance(
151 VkInstance _instance
)
153 ANV_FROM_HANDLE(anv_instance
, instance
, _instance
);
155 if (instance
->physicalDeviceCount
> 0) {
156 anv_physical_device_finish(&instance
->physicalDevice
);
159 instance
->pfnFree(instance
->pAllocUserData
, instance
);
164 VkResult
anv_EnumeratePhysicalDevices(
165 VkInstance _instance
,
166 uint32_t* pPhysicalDeviceCount
,
167 VkPhysicalDevice
* pPhysicalDevices
)
169 ANV_FROM_HANDLE(anv_instance
, instance
, _instance
);
172 if (instance
->physicalDeviceCount
== 0) {
173 result
= anv_physical_device_init(&instance
->physicalDevice
,
174 instance
, "/dev/dri/renderD128");
175 if (result
!= VK_SUCCESS
)
178 instance
->physicalDeviceCount
= 1;
181 /* pPhysicalDeviceCount is an out parameter if pPhysicalDevices is NULL;
182 * otherwise it's an inout parameter.
184 * The Vulkan spec (git aaed022) says:
186 * pPhysicalDeviceCount is a pointer to an unsigned integer variable
187 * that is initialized with the number of devices the application is
188 * prepared to receive handles to. pname:pPhysicalDevices is pointer to
189 * an array of at least this many VkPhysicalDevice handles [...].
191 * Upon success, if pPhysicalDevices is NULL, vkEnumeratePhysicalDevices
192 * overwrites the contents of the variable pointed to by
193 * pPhysicalDeviceCount with the number of physical devices in in the
194 * instance; otherwise, vkEnumeratePhysicalDevices overwrites
195 * pPhysicalDeviceCount with the number of physical handles written to
198 if (!pPhysicalDevices
) {
199 *pPhysicalDeviceCount
= instance
->physicalDeviceCount
;
200 } else if (*pPhysicalDeviceCount
>= 1) {
201 pPhysicalDevices
[0] = anv_physical_device_to_handle(&instance
->physicalDevice
);
202 *pPhysicalDeviceCount
= 1;
204 *pPhysicalDeviceCount
= 0;
210 VkResult
anv_GetPhysicalDeviceFeatures(
211 VkPhysicalDevice physicalDevice
,
212 VkPhysicalDeviceFeatures
* pFeatures
)
214 anv_finishme("Get correct values for PhysicalDeviceFeatures");
216 *pFeatures
= (VkPhysicalDeviceFeatures
) {
217 .robustBufferAccess
= false,
218 .fullDrawIndexUint32
= false,
219 .imageCubeArray
= false,
220 .independentBlend
= false,
221 .geometryShader
= true,
222 .tessellationShader
= false,
223 .sampleRateShading
= false,
224 .dualSourceBlend
= true,
226 .instancedDrawIndirect
= true,
228 .depthBiasClamp
= false,
229 .fillModeNonSolid
= true,
230 .depthBounds
= false,
233 .textureCompressionETC2
= true,
234 .textureCompressionASTC_LDR
= true,
235 .textureCompressionBC
= true,
236 .pipelineStatisticsQuery
= true,
237 .vertexSideEffects
= false,
238 .tessellationSideEffects
= false,
239 .geometrySideEffects
= false,
240 .fragmentSideEffects
= false,
241 .shaderTessellationPointSize
= false,
242 .shaderGeometryPointSize
= true,
243 .shaderTextureGatherExtended
= true,
244 .shaderStorageImageExtendedFormats
= false,
245 .shaderStorageImageMultisample
= false,
246 .shaderStorageBufferArrayConstantIndexing
= false,
247 .shaderStorageImageArrayConstantIndexing
= false,
248 .shaderUniformBufferArrayDynamicIndexing
= true,
249 .shaderSampledImageArrayDynamicIndexing
= false,
250 .shaderStorageBufferArrayDynamicIndexing
= false,
251 .shaderStorageImageArrayDynamicIndexing
= false,
252 .shaderClipDistance
= false,
253 .shaderCullDistance
= false,
254 .shaderFloat64
= false,
255 .shaderInt64
= false,
256 .shaderFloat16
= false,
257 .shaderInt16
= false,
263 VkResult
anv_GetPhysicalDeviceLimits(
264 VkPhysicalDevice physicalDevice
,
265 VkPhysicalDeviceLimits
* pLimits
)
267 ANV_FROM_HANDLE(anv_physical_device
, physical_device
, physicalDevice
);
268 const struct brw_device_info
*devinfo
= physical_device
->info
;
270 anv_finishme("Get correct values for PhysicalDeviceLimits");
272 *pLimits
= (VkPhysicalDeviceLimits
) {
273 .maxImageDimension1D
= (1 << 14),
274 .maxImageDimension2D
= (1 << 14),
275 .maxImageDimension3D
= (1 << 10),
276 .maxImageDimensionCube
= (1 << 14),
277 .maxImageArrayLayers
= (1 << 10),
278 .maxTexelBufferSize
= (1 << 14),
279 .maxUniformBufferSize
= UINT32_MAX
,
280 .maxStorageBufferSize
= UINT32_MAX
,
281 .maxPushConstantsSize
= 128,
282 .maxMemoryAllocationCount
= UINT32_MAX
,
283 .maxBoundDescriptorSets
= MAX_SETS
,
284 .maxDescriptorSets
= UINT32_MAX
,
285 .maxPerStageDescriptorSamplers
= 64,
286 .maxPerStageDescriptorUniformBuffers
= 64,
287 .maxPerStageDescriptorStorageBuffers
= 64,
288 .maxPerStageDescriptorSampledImages
= 64,
289 .maxPerStageDescriptorStorageImages
= 64,
290 .maxDescriptorSetSamplers
= 256,
291 .maxDescriptorSetUniformBuffers
= 256,
292 .maxDescriptorSetStorageBuffers
= 256,
293 .maxDescriptorSetSampledImages
= 256,
294 .maxDescriptorSetStorageImages
= 256,
295 .maxVertexInputAttributes
= 32,
296 .maxVertexInputAttributeOffset
= 256,
297 .maxVertexInputBindingStride
= 256,
298 .maxVertexOutputComponents
= 32,
299 .maxTessGenLevel
= 0,
300 .maxTessPatchSize
= 0,
301 .maxTessControlPerVertexInputComponents
= 0,
302 .maxTessControlPerVertexOutputComponents
= 0,
303 .maxTessControlPerPatchOutputComponents
= 0,
304 .maxTessControlTotalOutputComponents
= 0,
305 .maxTessEvaluationInputComponents
= 0,
306 .maxTessEvaluationOutputComponents
= 0,
307 .maxGeometryShaderInvocations
= 6,
308 .maxGeometryInputComponents
= 16,
309 .maxGeometryOutputComponents
= 16,
310 .maxGeometryOutputVertices
= 16,
311 .maxGeometryTotalOutputComponents
= 16,
312 .maxFragmentInputComponents
= 16,
313 .maxFragmentOutputBuffers
= 8,
314 .maxFragmentDualSourceBuffers
= 2,
315 .maxFragmentCombinedOutputResources
= 8,
316 .maxComputeSharedMemorySize
= 1024,
317 .maxComputeWorkGroupCount
= {
318 16 * devinfo
->max_cs_threads
,
319 16 * devinfo
->max_cs_threads
,
320 16 * devinfo
->max_cs_threads
,
322 .maxComputeWorkGroupInvocations
= 16 * devinfo
->max_cs_threads
,
323 .maxComputeWorkGroupSize
= {
324 16 * devinfo
->max_cs_threads
,
325 16 * devinfo
->max_cs_threads
,
326 16 * devinfo
->max_cs_threads
,
328 .subPixelPrecisionBits
= 4 /* FIXME */,
329 .subTexelPrecisionBits
= 4 /* FIXME */,
330 .mipmapPrecisionBits
= 4 /* FIXME */,
331 .maxDrawIndexedIndexValue
= UINT32_MAX
,
332 .maxDrawIndirectInstanceCount
= UINT32_MAX
,
333 .primitiveRestartForPatches
= UINT32_MAX
,
334 .maxSamplerLodBias
= 16,
335 .maxSamplerAnisotropy
= 16,
337 .maxDynamicViewportStates
= UINT32_MAX
,
338 .maxViewportDimensions
= { (1 << 14), (1 << 14) },
339 .viewportBoundsRange
= { -1.0, 1.0 }, /* FIXME */
340 .viewportSubPixelBits
= 13, /* We take a float? */
341 .minMemoryMapAlignment
= 64, /* A cache line */
342 .minTexelBufferOffsetAlignment
= 1,
343 .minUniformBufferOffsetAlignment
= 1,
344 .minStorageBufferOffsetAlignment
= 1,
345 .minTexelOffset
= 0, /* FIXME */
346 .maxTexelOffset
= 0, /* FIXME */
347 .minTexelGatherOffset
= 0, /* FIXME */
348 .maxTexelGatherOffset
= 0, /* FIXME */
349 .minInterpolationOffset
= 0, /* FIXME */
350 .maxInterpolationOffset
= 0, /* FIXME */
351 .subPixelInterpolationOffsetBits
= 0, /* FIXME */
352 .maxFramebufferWidth
= (1 << 14),
353 .maxFramebufferHeight
= (1 << 14),
354 .maxFramebufferLayers
= (1 << 10),
355 .maxFramebufferColorSamples
= 8,
356 .maxFramebufferDepthSamples
= 8,
357 .maxFramebufferStencilSamples
= 8,
358 .maxColorAttachments
= MAX_RTS
,
359 .maxSampledImageColorSamples
= 8,
360 .maxSampledImageDepthSamples
= 8,
361 .maxSampledImageIntegerSamples
= 1,
362 .maxStorageImageSamples
= 1,
363 .maxSampleMaskWords
= 1,
364 .timestampFrequency
= 1000 * 1000 * 1000 / 80,
365 .maxClipDistances
= 0 /* FIXME */,
366 .maxCullDistances
= 0 /* FIXME */,
367 .maxCombinedClipAndCullDistances
= 0 /* FIXME */,
368 .pointSizeRange
= { 0.125, 255.875 },
369 .lineWidthRange
= { 0.0, 7.9921875 },
370 .pointSizeGranularity
= (1.0 / 8.0),
371 .lineWidthGranularity
= (1.0 / 128.0),
377 VkResult
anv_GetPhysicalDeviceProperties(
378 VkPhysicalDevice physicalDevice
,
379 VkPhysicalDeviceProperties
* pProperties
)
381 ANV_FROM_HANDLE(anv_physical_device
, pdevice
, physicalDevice
);
383 *pProperties
= (VkPhysicalDeviceProperties
) {
387 .deviceId
= pdevice
->chipset_id
,
388 .deviceType
= VK_PHYSICAL_DEVICE_TYPE_INTEGRATED_GPU
,
391 strcpy(pProperties
->deviceName
, pdevice
->name
);
392 snprintf((char *)pProperties
->pipelineCacheUUID
, VK_UUID_LENGTH
,
393 "anv-%s", MESA_GIT_SHA1
+ 4);
398 VkResult
anv_GetPhysicalDeviceQueueCount(
399 VkPhysicalDevice physicalDevice
,
407 VkResult
anv_GetPhysicalDeviceQueueProperties(
408 VkPhysicalDevice physicalDevice
,
410 VkPhysicalDeviceQueueProperties
* pQueueProperties
)
414 *pQueueProperties
= (VkPhysicalDeviceQueueProperties
) {
415 .queueFlags
= VK_QUEUE_GRAPHICS_BIT
|
416 VK_QUEUE_COMPUTE_BIT
|
419 .supportsTimestamps
= true,
425 VkResult
anv_GetPhysicalDeviceMemoryProperties(
426 VkPhysicalDevice physicalDevice
,
427 VkPhysicalDeviceMemoryProperties
* pMemoryProperties
)
429 ANV_FROM_HANDLE(anv_physical_device
, physical_device
, physicalDevice
);
431 size_t aperture_size
;
434 if (anv_gem_get_aperture(physical_device
, &aperture_size
) == -1)
435 return vk_error(VK_ERROR_UNAVAILABLE
);
437 /* Reserve some wiggle room for the driver by exposing only 75% of the
438 * aperture to the heap.
440 heap_size
= 3 * aperture_size
/ 4;
442 /* The property flags below are valid only for llc platforms. */
443 pMemoryProperties
->memoryTypeCount
= 1;
444 pMemoryProperties
->memoryTypes
[0] = (VkMemoryType
) {
445 .propertyFlags
= VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT
,
449 pMemoryProperties
->memoryHeapCount
= 1;
450 pMemoryProperties
->memoryHeaps
[0] = (VkMemoryHeap
) {
452 .flags
= VK_MEMORY_HEAP_HOST_LOCAL
,
458 PFN_vkVoidFunction
anv_GetInstanceProcAddr(
462 return anv_lookup_entrypoint(pName
);
465 PFN_vkVoidFunction
anv_GetDeviceProcAddr(
469 return anv_lookup_entrypoint(pName
);
473 parse_debug_flags(struct anv_device
*device
)
475 const char *debug
, *p
, *end
;
477 debug
= getenv("INTEL_DEBUG");
478 device
->dump_aub
= false;
480 for (p
= debug
; *p
; p
= end
+ 1) {
481 end
= strchrnul(p
, ',');
482 if (end
- p
== 3 && memcmp(p
, "aub", 3) == 0)
483 device
->dump_aub
= true;
484 if (end
- p
== 5 && memcmp(p
, "no_hw", 5) == 0)
485 device
->no_hw
= true;
493 anv_queue_init(struct anv_device
*device
, struct anv_queue
*queue
)
495 queue
->device
= device
;
496 queue
->pool
= &device
->surface_state_pool
;
498 queue
->completed_serial
= anv_state_pool_alloc(queue
->pool
, 4, 4);
499 if (queue
->completed_serial
.map
== NULL
)
500 return vk_error(VK_ERROR_OUT_OF_DEVICE_MEMORY
);
502 *(uint32_t *)queue
->completed_serial
.map
= 0;
503 queue
->next_serial
= 1;
509 anv_queue_finish(struct anv_queue
*queue
)
512 /* This gets torn down with the device so we only need to do this if
513 * valgrind is present.
515 anv_state_pool_free(queue
->pool
, queue
->completed_serial
);
520 anv_device_init_border_colors(struct anv_device
*device
)
522 static const VkClearColorValue border_colors
[] = {
523 [VK_BORDER_COLOR_FLOAT_TRANSPARENT_BLACK
] = { .f32
= { 0.0, 0.0, 0.0, 0.0 } },
524 [VK_BORDER_COLOR_FLOAT_OPAQUE_BLACK
] = { .f32
= { 0.0, 0.0, 0.0, 1.0 } },
525 [VK_BORDER_COLOR_FLOAT_OPAQUE_WHITE
] = { .f32
= { 1.0, 1.0, 1.0, 1.0 } },
526 [VK_BORDER_COLOR_INT_TRANSPARENT_BLACK
] = { .u32
= { 0, 0, 0, 0 } },
527 [VK_BORDER_COLOR_INT_OPAQUE_BLACK
] = { .u32
= { 0, 0, 0, 1 } },
528 [VK_BORDER_COLOR_INT_OPAQUE_WHITE
] = { .u32
= { 1, 1, 1, 1 } },
531 device
->border_colors
=
532 anv_state_pool_alloc(&device
->dynamic_state_pool
,
533 sizeof(border_colors
), 32);
534 memcpy(device
->border_colors
.map
, border_colors
, sizeof(border_colors
));
537 static const uint32_t BATCH_SIZE
= 8192;
539 VkResult
anv_CreateDevice(
540 VkPhysicalDevice physicalDevice
,
541 const VkDeviceCreateInfo
* pCreateInfo
,
544 ANV_FROM_HANDLE(anv_physical_device
, physical_device
, physicalDevice
);
545 struct anv_instance
*instance
= physical_device
->instance
;
546 struct anv_device
*device
;
548 assert(pCreateInfo
->sType
== VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO
);
550 device
= instance
->pfnAlloc(instance
->pAllocUserData
,
552 VK_SYSTEM_ALLOC_TYPE_API_OBJECT
);
554 return vk_error(VK_ERROR_OUT_OF_HOST_MEMORY
);
556 device
->no_hw
= physical_device
->no_hw
;
557 parse_debug_flags(device
);
559 device
->instance
= physical_device
->instance
;
561 /* XXX(chadv): Can we dup() physicalDevice->fd here? */
562 device
->fd
= open(physical_device
->path
, O_RDWR
| O_CLOEXEC
);
563 if (device
->fd
== -1)
566 device
->context_id
= anv_gem_create_context(device
);
567 if (device
->context_id
== -1)
570 anv_bo_pool_init(&device
->batch_bo_pool
, device
, BATCH_SIZE
);
572 anv_block_pool_init(&device
->dynamic_state_block_pool
, device
, 2048);
574 anv_state_pool_init(&device
->dynamic_state_pool
,
575 &device
->dynamic_state_block_pool
);
577 anv_block_pool_init(&device
->instruction_block_pool
, device
, 2048);
578 anv_block_pool_init(&device
->surface_state_block_pool
, device
, 2048);
580 anv_state_pool_init(&device
->surface_state_pool
,
581 &device
->surface_state_block_pool
);
583 anv_block_pool_init(&device
->scratch_block_pool
, device
, 0x10000);
585 device
->info
= *physical_device
->info
;
587 device
->compiler
= anv_compiler_create(device
);
588 device
->aub_writer
= NULL
;
590 pthread_mutex_init(&device
->mutex
, NULL
);
592 anv_queue_init(device
, &device
->queue
);
594 anv_device_init_meta(device
);
596 anv_device_init_border_colors(device
);
598 *pDevice
= anv_device_to_handle(device
);
605 anv_device_free(device
, device
);
607 return vk_error(VK_ERROR_UNAVAILABLE
);
610 VkResult
anv_DestroyDevice(
613 ANV_FROM_HANDLE(anv_device
, device
, _device
);
615 anv_compiler_destroy(device
->compiler
);
617 anv_queue_finish(&device
->queue
);
619 anv_device_finish_meta(device
);
622 /* We only need to free these to prevent valgrind errors. The backing
623 * BO will go away in a couple of lines so we don't actually leak.
625 anv_state_pool_free(&device
->dynamic_state_pool
, device
->border_colors
);
628 anv_bo_pool_finish(&device
->batch_bo_pool
);
629 anv_block_pool_finish(&device
->dynamic_state_block_pool
);
630 anv_block_pool_finish(&device
->instruction_block_pool
);
631 anv_block_pool_finish(&device
->surface_state_block_pool
);
635 if (device
->aub_writer
)
636 anv_aub_writer_destroy(device
->aub_writer
);
638 anv_device_free(device
, device
);
643 static const VkExtensionProperties global_extensions
[] = {
645 .extName
= "VK_WSI_LunarG",
650 VkResult
anv_GetGlobalExtensionCount(
653 *pCount
= ARRAY_SIZE(global_extensions
);
659 VkResult
anv_GetGlobalExtensionProperties(
660 uint32_t extensionIndex
,
661 VkExtensionProperties
* pProperties
)
663 assert(extensionIndex
< ARRAY_SIZE(global_extensions
));
665 *pProperties
= global_extensions
[extensionIndex
];
670 VkResult
anv_GetPhysicalDeviceExtensionCount(
671 VkPhysicalDevice physicalDevice
,
674 /* None supported at this time */
680 VkResult
anv_GetPhysicalDeviceExtensionProperties(
681 VkPhysicalDevice physicalDevice
,
682 uint32_t extensionIndex
,
683 VkExtensionProperties
* pProperties
)
685 /* None supported at this time */
686 return vk_error(VK_ERROR_INVALID_EXTENSION
);
689 VkResult
anv_EnumerateLayers(
690 VkPhysicalDevice physicalDevice
,
691 size_t maxStringSize
,
693 char* const* pOutLayers
,
701 VkResult
anv_GetDeviceQueue(
703 uint32_t queueNodeIndex
,
707 ANV_FROM_HANDLE(anv_device
, device
, _device
);
709 assert(queueIndex
== 0);
711 *pQueue
= anv_queue_to_handle(&device
->queue
);
717 anv_reloc_list_init(struct anv_reloc_list
*list
, struct anv_device
*device
)
719 list
->num_relocs
= 0;
720 list
->array_length
= 256;
722 anv_device_alloc(device
, list
->array_length
* sizeof(*list
->relocs
), 8,
723 VK_SYSTEM_ALLOC_TYPE_INTERNAL
);
725 if (list
->relocs
== NULL
)
726 return vk_error(VK_ERROR_OUT_OF_HOST_MEMORY
);
729 anv_device_alloc(device
, list
->array_length
* sizeof(*list
->reloc_bos
), 8,
730 VK_SYSTEM_ALLOC_TYPE_INTERNAL
);
732 if (list
->relocs
== NULL
) {
733 anv_device_free(device
, list
->relocs
);
734 return vk_error(VK_ERROR_OUT_OF_HOST_MEMORY
);
741 anv_reloc_list_finish(struct anv_reloc_list
*list
, struct anv_device
*device
)
743 anv_device_free(device
, list
->relocs
);
744 anv_device_free(device
, list
->reloc_bos
);
748 anv_reloc_list_grow(struct anv_reloc_list
*list
, struct anv_device
*device
,
749 size_t num_additional_relocs
)
751 if (list
->num_relocs
+ num_additional_relocs
<= list
->array_length
)
754 size_t new_length
= list
->array_length
* 2;
755 while (new_length
< list
->num_relocs
+ num_additional_relocs
)
758 struct drm_i915_gem_relocation_entry
*new_relocs
=
759 anv_device_alloc(device
, new_length
* sizeof(*list
->relocs
), 8,
760 VK_SYSTEM_ALLOC_TYPE_INTERNAL
);
761 if (new_relocs
== NULL
)
762 return vk_error(VK_ERROR_OUT_OF_HOST_MEMORY
);
764 struct anv_bo
**new_reloc_bos
=
765 anv_device_alloc(device
, new_length
* sizeof(*list
->reloc_bos
), 8,
766 VK_SYSTEM_ALLOC_TYPE_INTERNAL
);
767 if (new_relocs
== NULL
) {
768 anv_device_free(device
, new_relocs
);
769 return vk_error(VK_ERROR_OUT_OF_HOST_MEMORY
);
772 memcpy(new_relocs
, list
->relocs
, list
->num_relocs
* sizeof(*list
->relocs
));
773 memcpy(new_reloc_bos
, list
->reloc_bos
,
774 list
->num_relocs
* sizeof(*list
->reloc_bos
));
776 anv_device_free(device
, list
->relocs
);
777 anv_device_free(device
, list
->reloc_bos
);
779 list
->relocs
= new_relocs
;
780 list
->reloc_bos
= new_reloc_bos
;
786 anv_batch_bo_create(struct anv_device
*device
, struct anv_batch_bo
**bbo_out
)
790 struct anv_batch_bo
*bbo
=
791 anv_device_alloc(device
, sizeof(*bbo
), 8, VK_SYSTEM_ALLOC_TYPE_INTERNAL
);
793 return vk_error(VK_ERROR_OUT_OF_HOST_MEMORY
);
796 bbo
->prev_batch_bo
= NULL
;
798 result
= anv_bo_pool_alloc(&device
->batch_bo_pool
, &bbo
->bo
);
799 if (result
!= VK_SUCCESS
) {
800 anv_device_free(device
, bbo
);
810 anv_batch_bo_start(struct anv_batch_bo
*bbo
, struct anv_batch
*batch
,
811 size_t batch_padding
)
813 batch
->next
= batch
->start
= bbo
->bo
.map
;
814 batch
->end
= bbo
->bo
.map
+ bbo
->bo
.size
- batch_padding
;
815 bbo
->first_reloc
= batch
->relocs
.num_relocs
;
819 anv_batch_bo_finish(struct anv_batch_bo
*bbo
, struct anv_batch
*batch
)
821 assert(batch
->start
== bbo
->bo
.map
);
822 bbo
->length
= batch
->next
- batch
->start
;
823 VG(VALGRIND_CHECK_MEM_IS_DEFINED(batch
->start
, bbo
->length
));
824 bbo
->num_relocs
= batch
->relocs
.num_relocs
- bbo
->first_reloc
;
828 anv_batch_bo_destroy(struct anv_batch_bo
*bbo
, struct anv_device
*device
)
830 anv_bo_pool_free(&device
->batch_bo_pool
, &bbo
->bo
);
831 anv_device_free(device
, bbo
);
835 anv_batch_emit_dwords(struct anv_batch
*batch
, int num_dwords
)
837 if (batch
->next
+ num_dwords
* 4 > batch
->end
)
838 batch
->extend_cb(batch
, batch
->user_data
);
840 void *p
= batch
->next
;
842 batch
->next
+= num_dwords
* 4;
843 assert(batch
->next
<= batch
->end
);
849 anv_reloc_list_append(struct anv_reloc_list
*list
, struct anv_device
*device
,
850 struct anv_reloc_list
*other
, uint32_t offset
)
852 anv_reloc_list_grow(list
, device
, other
->num_relocs
);
853 /* TODO: Handle failure */
855 memcpy(&list
->relocs
[list
->num_relocs
], &other
->relocs
[0],
856 other
->num_relocs
* sizeof(other
->relocs
[0]));
857 memcpy(&list
->reloc_bos
[list
->num_relocs
], &other
->reloc_bos
[0],
858 other
->num_relocs
* sizeof(other
->reloc_bos
[0]));
860 for (uint32_t i
= 0; i
< other
->num_relocs
; i
++)
861 list
->relocs
[i
+ list
->num_relocs
].offset
+= offset
;
863 list
->num_relocs
+= other
->num_relocs
;
867 anv_reloc_list_add(struct anv_reloc_list
*list
, struct anv_device
*device
,
868 uint32_t offset
, struct anv_bo
*target_bo
, uint32_t delta
)
870 struct drm_i915_gem_relocation_entry
*entry
;
873 anv_reloc_list_grow(list
, device
, 1);
874 /* TODO: Handle failure */
876 /* XXX: Can we use I915_EXEC_HANDLE_LUT? */
877 index
= list
->num_relocs
++;
878 list
->reloc_bos
[index
] = target_bo
;
879 entry
= &list
->relocs
[index
];
880 entry
->target_handle
= target_bo
->gem_handle
;
881 entry
->delta
= delta
;
882 entry
->offset
= offset
;
883 entry
->presumed_offset
= target_bo
->offset
;
884 entry
->read_domains
= 0;
885 entry
->write_domain
= 0;
887 return target_bo
->offset
+ delta
;
891 anv_batch_emit_batch(struct anv_batch
*batch
, struct anv_batch
*other
)
893 uint32_t size
, offset
;
895 size
= other
->next
- other
->start
;
896 assert(size
% 4 == 0);
898 if (batch
->next
+ size
> batch
->end
)
899 batch
->extend_cb(batch
, batch
->user_data
);
901 assert(batch
->next
+ size
<= batch
->end
);
903 memcpy(batch
->next
, other
->start
, size
);
905 offset
= batch
->next
- batch
->start
;
906 anv_reloc_list_append(&batch
->relocs
, batch
->device
,
907 &other
->relocs
, offset
);
913 anv_batch_emit_reloc(struct anv_batch
*batch
,
914 void *location
, struct anv_bo
*bo
, uint32_t delta
)
916 return anv_reloc_list_add(&batch
->relocs
, batch
->device
,
917 location
- batch
->start
, bo
, delta
);
920 VkResult
anv_QueueSubmit(
922 uint32_t cmdBufferCount
,
923 const VkCmdBuffer
* pCmdBuffers
,
926 ANV_FROM_HANDLE(anv_queue
, queue
, _queue
);
927 ANV_FROM_HANDLE(anv_fence
, fence
, _fence
);
928 struct anv_device
*device
= queue
->device
;
931 for (uint32_t i
= 0; i
< cmdBufferCount
; i
++) {
932 ANV_FROM_HANDLE(anv_cmd_buffer
, cmd_buffer
, pCmdBuffers
[i
]);
934 if (device
->dump_aub
)
935 anv_cmd_buffer_dump(cmd_buffer
);
937 if (!device
->no_hw
) {
938 ret
= anv_gem_execbuffer(device
, &cmd_buffer
->execbuf
);
940 return vk_error(VK_ERROR_UNKNOWN
);
943 ret
= anv_gem_execbuffer(device
, &fence
->execbuf
);
945 return vk_error(VK_ERROR_UNKNOWN
);
948 for (uint32_t i
= 0; i
< cmd_buffer
->bo_count
; i
++)
949 cmd_buffer
->exec2_bos
[i
]->offset
= cmd_buffer
->exec2_objects
[i
].offset
;
951 *(uint32_t *)queue
->completed_serial
.map
= cmd_buffer
->serial
;
958 VkResult
anv_QueueWaitIdle(
961 ANV_FROM_HANDLE(anv_queue
, queue
, _queue
);
963 return vkDeviceWaitIdle(anv_device_to_handle(queue
->device
));
966 VkResult
anv_DeviceWaitIdle(
969 ANV_FROM_HANDLE(anv_device
, device
, _device
);
970 struct anv_state state
;
971 struct anv_batch batch
;
972 struct drm_i915_gem_execbuffer2 execbuf
;
973 struct drm_i915_gem_exec_object2 exec2_objects
[1];
974 struct anv_bo
*bo
= NULL
;
979 state
= anv_state_pool_alloc(&device
->dynamic_state_pool
, 32, 32);
980 bo
= &device
->dynamic_state_pool
.block_pool
->bo
;
981 batch
.start
= batch
.next
= state
.map
;
982 batch
.end
= state
.map
+ 32;
983 anv_batch_emit(&batch
, GEN8_MI_BATCH_BUFFER_END
);
984 anv_batch_emit(&batch
, GEN8_MI_NOOP
);
986 exec2_objects
[0].handle
= bo
->gem_handle
;
987 exec2_objects
[0].relocation_count
= 0;
988 exec2_objects
[0].relocs_ptr
= 0;
989 exec2_objects
[0].alignment
= 0;
990 exec2_objects
[0].offset
= bo
->offset
;
991 exec2_objects
[0].flags
= 0;
992 exec2_objects
[0].rsvd1
= 0;
993 exec2_objects
[0].rsvd2
= 0;
995 execbuf
.buffers_ptr
= (uintptr_t) exec2_objects
;
996 execbuf
.buffer_count
= 1;
997 execbuf
.batch_start_offset
= state
.offset
;
998 execbuf
.batch_len
= batch
.next
- state
.map
;
999 execbuf
.cliprects_ptr
= 0;
1000 execbuf
.num_cliprects
= 0;
1005 I915_EXEC_HANDLE_LUT
| I915_EXEC_NO_RELOC
| I915_EXEC_RENDER
;
1006 execbuf
.rsvd1
= device
->context_id
;
1009 if (!device
->no_hw
) {
1010 ret
= anv_gem_execbuffer(device
, &execbuf
);
1012 result
= vk_error(VK_ERROR_UNKNOWN
);
1016 timeout
= INT64_MAX
;
1017 ret
= anv_gem_wait(device
, bo
->gem_handle
, &timeout
);
1019 result
= vk_error(VK_ERROR_UNKNOWN
);
1024 anv_state_pool_free(&device
->dynamic_state_pool
, state
);
1029 anv_state_pool_free(&device
->dynamic_state_pool
, state
);
1035 anv_device_alloc(struct anv_device
* device
,
1038 VkSystemAllocType allocType
)
1040 return device
->instance
->pfnAlloc(device
->instance
->pAllocUserData
,
1047 anv_device_free(struct anv_device
* device
,
1050 return device
->instance
->pfnFree(device
->instance
->pAllocUserData
,
1055 anv_bo_init_new(struct anv_bo
*bo
, struct anv_device
*device
, uint64_t size
)
1057 bo
->gem_handle
= anv_gem_create(device
, size
);
1058 if (!bo
->gem_handle
)
1059 return vk_error(VK_ERROR_OUT_OF_DEVICE_MEMORY
);
1069 VkResult
anv_AllocMemory(
1071 const VkMemoryAllocInfo
* pAllocInfo
,
1072 VkDeviceMemory
* pMem
)
1074 ANV_FROM_HANDLE(anv_device
, device
, _device
);
1075 struct anv_device_memory
*mem
;
1078 assert(pAllocInfo
->sType
== VK_STRUCTURE_TYPE_MEMORY_ALLOC_INFO
);
1080 if (pAllocInfo
->memoryTypeIndex
!= 0) {
1081 /* We support exactly one memory heap. */
1082 return vk_error(VK_ERROR_INVALID_VALUE
);
1085 /* FINISHME: Fail if allocation request exceeds heap size. */
1087 mem
= anv_device_alloc(device
, sizeof(*mem
), 8,
1088 VK_SYSTEM_ALLOC_TYPE_API_OBJECT
);
1090 return vk_error(VK_ERROR_OUT_OF_HOST_MEMORY
);
1092 result
= anv_bo_init_new(&mem
->bo
, device
, pAllocInfo
->allocationSize
);
1093 if (result
!= VK_SUCCESS
)
1096 *pMem
= anv_device_memory_to_handle(mem
);
1101 anv_device_free(device
, mem
);
1106 VkResult
anv_FreeMemory(
1108 VkDeviceMemory _mem
)
1110 ANV_FROM_HANDLE(anv_device
, device
, _device
);
1111 ANV_FROM_HANDLE(anv_device_memory
, mem
, _mem
);
1114 anv_gem_munmap(mem
->bo
.map
, mem
->bo
.size
);
1116 if (mem
->bo
.gem_handle
!= 0)
1117 anv_gem_close(device
, mem
->bo
.gem_handle
);
1119 anv_device_free(device
, mem
);
1124 VkResult
anv_MapMemory(
1126 VkDeviceMemory _mem
,
1127 VkDeviceSize offset
,
1129 VkMemoryMapFlags flags
,
1132 ANV_FROM_HANDLE(anv_device
, device
, _device
);
1133 ANV_FROM_HANDLE(anv_device_memory
, mem
, _mem
);
1135 /* FIXME: Is this supposed to be thread safe? Since vkUnmapMemory() only
1136 * takes a VkDeviceMemory pointer, it seems like only one map of the memory
1137 * at a time is valid. We could just mmap up front and return an offset
1138 * pointer here, but that may exhaust virtual memory on 32 bit
1141 mem
->map
= anv_gem_mmap(device
, mem
->bo
.gem_handle
, offset
, size
);
1142 mem
->map_size
= size
;
1149 VkResult
anv_UnmapMemory(
1151 VkDeviceMemory _mem
)
1153 ANV_FROM_HANDLE(anv_device_memory
, mem
, _mem
);
1155 anv_gem_munmap(mem
->map
, mem
->map_size
);
1160 VkResult
anv_FlushMappedMemoryRanges(
1162 uint32_t memRangeCount
,
1163 const VkMappedMemoryRange
* pMemRanges
)
1165 /* clflush here for !llc platforms */
1170 VkResult
anv_InvalidateMappedMemoryRanges(
1172 uint32_t memRangeCount
,
1173 const VkMappedMemoryRange
* pMemRanges
)
1175 return anv_FlushMappedMemoryRanges(device
, memRangeCount
, pMemRanges
);
1178 VkResult
anv_DestroyObject(
1180 VkObjectType objType
,
1183 ANV_FROM_HANDLE(anv_device
, device
, _device
);
1186 case VK_OBJECT_TYPE_FENCE
:
1187 return anv_DestroyFence(_device
, (VkFence
) _object
);
1189 case VK_OBJECT_TYPE_INSTANCE
:
1190 return anv_DestroyInstance((VkInstance
) _object
);
1192 case VK_OBJECT_TYPE_PHYSICAL_DEVICE
:
1193 /* We don't want to actually destroy physical devices */
1196 case VK_OBJECT_TYPE_DEVICE
:
1197 assert(_device
== (VkDevice
) _object
);
1198 return anv_DestroyDevice((VkDevice
) _object
);
1200 case VK_OBJECT_TYPE_QUEUE
:
1204 case VK_OBJECT_TYPE_DEVICE_MEMORY
:
1205 return anv_FreeMemory(_device
, (VkDeviceMemory
) _object
);
1207 case VK_OBJECT_TYPE_DESCRIPTOR_POOL
:
1208 return anv_DestroyDescriptorPool(_device
, (VkDescriptorPool
) _object
);
1210 case VK_OBJECT_TYPE_PIPELINE_CACHE
:
1211 return anv_DestroyPipelineCache(_device
, (VkPipelineCache
) _object
);
1213 case VK_OBJECT_TYPE_BUFFER_VIEW
:
1214 return anv_DestroyBufferView(_device
, _object
);
1216 case VK_OBJECT_TYPE_IMAGE_VIEW
:
1217 return anv_DestroyImageView(_device
, _object
);
1219 case VK_OBJECT_TYPE_ATTACHMENT_VIEW
:
1220 return anv_DestroyAttachmentView(_device
, _object
);
1222 case VK_OBJECT_TYPE_IMAGE
:
1223 return anv_DestroyImage(_device
, _object
);
1225 case VK_OBJECT_TYPE_BUFFER
:
1226 return anv_DestroyBuffer(_device
, (VkBuffer
) _object
);
1228 case VK_OBJECT_TYPE_SHADER_MODULE
:
1229 return anv_DestroyShaderModule(_device
, (VkShaderModule
) _object
);
1231 case VK_OBJECT_TYPE_SHADER
:
1232 return anv_DestroyShader(_device
, (VkShader
) _object
);
1234 case VK_OBJECT_TYPE_PIPELINE_LAYOUT
:
1235 return anv_DestroyPipelineLayout(_device
, (VkPipelineLayout
) _object
);
1237 case VK_OBJECT_TYPE_SAMPLER
:
1238 return anv_DestroySampler(_device
, (VkSampler
) _object
);
1240 case VK_OBJECT_TYPE_DESCRIPTOR_SET_LAYOUT
:
1241 return anv_DestroyDescriptorSetLayout(_device
, (VkDescriptorSetLayout
) _object
);
1243 case VK_OBJECT_TYPE_DESCRIPTOR_SET
:
1244 case VK_OBJECT_TYPE_RENDER_PASS
:
1245 /* These are trivially destroyable */
1246 anv_device_free(device
, (void *) _object
);
1249 case VK_OBJECT_TYPE_DYNAMIC_VP_STATE
:
1250 return anv_DestroyDynamicViewportState(_device
, (VkDynamicViewportState
) _object
);
1252 case VK_OBJECT_TYPE_DYNAMIC_RS_STATE
:
1253 return anv_DestroyDynamicRasterState(_device
, (VkDynamicRasterState
) _object
);
1255 case VK_OBJECT_TYPE_DYNAMIC_CB_STATE
:
1256 return anv_DestroyDynamicColorBlendState(_device
, (VkDynamicColorBlendState
) _object
);
1258 case VK_OBJECT_TYPE_DYNAMIC_DS_STATE
:
1259 return anv_DestroyDynamicDepthStencilState(_device
, (VkDynamicDepthStencilState
) _object
);
1261 case VK_OBJECT_TYPE_FRAMEBUFFER
:
1262 return anv_DestroyFramebuffer(_device
, (VkFramebuffer
) _object
);
1264 case VK_OBJECT_TYPE_COMMAND_BUFFER
:
1265 return anv_DestroyCommandBuffer(_device
, (VkCmdBuffer
) _object
);
1268 case VK_OBJECT_TYPE_PIPELINE
:
1269 return anv_DestroyPipeline(_device
, (VkPipeline
) _object
);
1271 case VK_OBJECT_TYPE_QUERY_POOL
:
1272 return anv_DestroyQueryPool(_device
, (VkQueryPool
) _object
);
1274 case VK_OBJECT_TYPE_SEMAPHORE
:
1275 return anv_DestroySemaphore(_device
, (VkSemaphore
) _object
);
1277 case VK_OBJECT_TYPE_EVENT
:
1278 return anv_DestroyEvent(_device
, (VkEvent
) _object
);
1281 unreachable("Invalid object type");
1285 VkResult
anv_GetObjectMemoryRequirements(
1287 VkObjectType objType
,
1289 VkMemoryRequirements
* pMemoryRequirements
)
1292 /* The Vulkan spec (git aaed022) says:
1294 * memoryTypeBits is a bitfield and contains one bit set for every
1295 * supported memory type for the resource. The bit `1<<i` is set if and
1296 * only if the memory type `i` in the VkPhysicalDeviceMemoryProperties
1297 * structure for the physical device is supported.
1299 * We support exactly one memory type.
1301 pMemoryRequirements
->memoryTypeBits
= 1;
1304 case VK_OBJECT_TYPE_BUFFER
: {
1305 struct anv_buffer
*buffer
= anv_buffer_from_handle(object
);
1306 pMemoryRequirements
->size
= buffer
->size
;
1307 pMemoryRequirements
->alignment
= 16;
1310 case VK_OBJECT_TYPE_IMAGE
: {
1311 struct anv_image
*image
= anv_image_from_handle(object
);
1312 pMemoryRequirements
->size
= image
->size
;
1313 pMemoryRequirements
->alignment
= image
->alignment
;
1317 pMemoryRequirements
->size
= 0;
1324 VkResult
anv_BindObjectMemory(
1326 VkObjectType objType
,
1328 VkDeviceMemory _mem
,
1329 VkDeviceSize memOffset
)
1331 ANV_FROM_HANDLE(anv_device_memory
, mem
, _mem
);
1332 struct anv_buffer
*buffer
;
1333 struct anv_image
*image
;
1336 case VK_OBJECT_TYPE_BUFFER
:
1337 buffer
= anv_buffer_from_handle(object
);
1338 buffer
->bo
= &mem
->bo
;
1339 buffer
->offset
= memOffset
;
1341 case VK_OBJECT_TYPE_IMAGE
:
1342 image
= anv_image_from_handle(object
);
1343 image
->bo
= &mem
->bo
;
1344 image
->offset
= memOffset
;
1353 VkResult
anv_QueueBindSparseBufferMemory(
1356 VkDeviceSize rangeOffset
,
1357 VkDeviceSize rangeSize
,
1359 VkDeviceSize memOffset
)
1361 stub_return(VK_UNSUPPORTED
);
1364 VkResult
anv_QueueBindSparseImageMemory(
1367 const VkImageMemoryBindInfo
* pBindInfo
,
1369 VkDeviceSize memOffset
)
1371 stub_return(VK_UNSUPPORTED
);
1375 anv_fence_destroy(struct anv_device
*device
,
1376 struct anv_object
*object
,
1377 VkObjectType obj_type
)
1379 struct anv_fence
*fence
= (struct anv_fence
*) object
;
1381 assert(obj_type
== VK_OBJECT_TYPE_FENCE
);
1383 anv_DestroyFence(anv_device_to_handle(device
),
1384 anv_fence_to_handle(fence
));
1387 VkResult
anv_CreateFence(
1389 const VkFenceCreateInfo
* pCreateInfo
,
1392 ANV_FROM_HANDLE(anv_device
, device
, _device
);
1393 struct anv_fence
*fence
;
1394 struct anv_batch batch
;
1397 const uint32_t fence_size
= 128;
1399 assert(pCreateInfo
->sType
== VK_STRUCTURE_TYPE_FENCE_CREATE_INFO
);
1401 fence
= anv_device_alloc(device
, sizeof(*fence
), 8,
1402 VK_SYSTEM_ALLOC_TYPE_API_OBJECT
);
1404 return vk_error(VK_ERROR_OUT_OF_HOST_MEMORY
);
1406 result
= anv_bo_init_new(&fence
->bo
, device
, fence_size
);
1407 if (result
!= VK_SUCCESS
)
1410 fence
->base
.destructor
= anv_fence_destroy
;
1413 anv_gem_mmap(device
, fence
->bo
.gem_handle
, 0, fence
->bo
.size
);
1414 batch
.next
= batch
.start
= fence
->bo
.map
;
1415 batch
.end
= fence
->bo
.map
+ fence
->bo
.size
;
1416 anv_batch_emit(&batch
, GEN8_MI_BATCH_BUFFER_END
);
1417 anv_batch_emit(&batch
, GEN8_MI_NOOP
);
1419 fence
->exec2_objects
[0].handle
= fence
->bo
.gem_handle
;
1420 fence
->exec2_objects
[0].relocation_count
= 0;
1421 fence
->exec2_objects
[0].relocs_ptr
= 0;
1422 fence
->exec2_objects
[0].alignment
= 0;
1423 fence
->exec2_objects
[0].offset
= fence
->bo
.offset
;
1424 fence
->exec2_objects
[0].flags
= 0;
1425 fence
->exec2_objects
[0].rsvd1
= 0;
1426 fence
->exec2_objects
[0].rsvd2
= 0;
1428 fence
->execbuf
.buffers_ptr
= (uintptr_t) fence
->exec2_objects
;
1429 fence
->execbuf
.buffer_count
= 1;
1430 fence
->execbuf
.batch_start_offset
= 0;
1431 fence
->execbuf
.batch_len
= batch
.next
- fence
->bo
.map
;
1432 fence
->execbuf
.cliprects_ptr
= 0;
1433 fence
->execbuf
.num_cliprects
= 0;
1434 fence
->execbuf
.DR1
= 0;
1435 fence
->execbuf
.DR4
= 0;
1437 fence
->execbuf
.flags
=
1438 I915_EXEC_HANDLE_LUT
| I915_EXEC_NO_RELOC
| I915_EXEC_RENDER
;
1439 fence
->execbuf
.rsvd1
= device
->context_id
;
1440 fence
->execbuf
.rsvd2
= 0;
1442 *pFence
= anv_fence_to_handle(fence
);
1447 anv_device_free(device
, fence
);
1452 VkResult
anv_DestroyFence(
1456 ANV_FROM_HANDLE(anv_device
, device
, _device
);
1457 ANV_FROM_HANDLE(anv_fence
, fence
, _fence
);
1459 anv_gem_munmap(fence
->bo
.map
, fence
->bo
.size
);
1460 anv_gem_close(device
, fence
->bo
.gem_handle
);
1461 anv_device_free(device
, fence
);
1466 VkResult
anv_ResetFences(
1468 uint32_t fenceCount
,
1469 const VkFence
* pFences
)
1471 struct anv_fence
**fences
= (struct anv_fence
**) pFences
;
1473 for (uint32_t i
= 0; i
< fenceCount
; i
++)
1474 fences
[i
]->ready
= false;
1479 VkResult
anv_GetFenceStatus(
1483 ANV_FROM_HANDLE(anv_device
, device
, _device
);
1484 ANV_FROM_HANDLE(anv_fence
, fence
, _fence
);
1491 ret
= anv_gem_wait(device
, fence
->bo
.gem_handle
, &t
);
1493 fence
->ready
= true;
1497 return VK_NOT_READY
;
1500 VkResult
anv_WaitForFences(
1502 uint32_t fenceCount
,
1503 const VkFence
* pFences
,
1507 ANV_FROM_HANDLE(anv_device
, device
, _device
);
1508 int64_t t
= timeout
;
1511 /* FIXME: handle !waitAll */
1513 for (uint32_t i
= 0; i
< fenceCount
; i
++) {
1514 ANV_FROM_HANDLE(anv_fence
, fence
, pFences
[i
]);
1515 ret
= anv_gem_wait(device
, fence
->bo
.gem_handle
, &t
);
1516 if (ret
== -1 && errno
== ETIME
)
1519 return vk_error(VK_ERROR_UNKNOWN
);
1525 // Queue semaphore functions
1527 VkResult
anv_CreateSemaphore(
1529 const VkSemaphoreCreateInfo
* pCreateInfo
,
1530 VkSemaphore
* pSemaphore
)
1532 stub_return(VK_UNSUPPORTED
);
1535 VkResult
anv_DestroySemaphore(
1537 VkSemaphore semaphore
)
1539 stub_return(VK_UNSUPPORTED
);
1542 VkResult
anv_QueueSignalSemaphore(
1544 VkSemaphore semaphore
)
1546 stub_return(VK_UNSUPPORTED
);
1549 VkResult
anv_QueueWaitSemaphore(
1551 VkSemaphore semaphore
)
1553 stub_return(VK_UNSUPPORTED
);
1558 VkResult
anv_CreateEvent(
1560 const VkEventCreateInfo
* pCreateInfo
,
1563 stub_return(VK_UNSUPPORTED
);
1566 VkResult
anv_DestroyEvent(
1570 stub_return(VK_UNSUPPORTED
);
1573 VkResult
anv_GetEventStatus(
1577 stub_return(VK_UNSUPPORTED
);
1580 VkResult
anv_SetEvent(
1584 stub_return(VK_UNSUPPORTED
);
1587 VkResult
anv_ResetEvent(
1591 stub_return(VK_UNSUPPORTED
);
1596 VkResult
anv_CreateBuffer(
1598 const VkBufferCreateInfo
* pCreateInfo
,
1601 ANV_FROM_HANDLE(anv_device
, device
, _device
);
1602 struct anv_buffer
*buffer
;
1604 assert(pCreateInfo
->sType
== VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO
);
1606 buffer
= anv_device_alloc(device
, sizeof(*buffer
), 8,
1607 VK_SYSTEM_ALLOC_TYPE_API_OBJECT
);
1609 return vk_error(VK_ERROR_OUT_OF_HOST_MEMORY
);
1611 buffer
->size
= pCreateInfo
->size
;
1615 *pBuffer
= anv_buffer_to_handle(buffer
);
1620 VkResult
anv_DestroyBuffer(
1624 ANV_FROM_HANDLE(anv_device
, device
, _device
);
1625 ANV_FROM_HANDLE(anv_buffer
, buffer
, _buffer
);
1627 anv_device_free(device
, buffer
);
1632 // Buffer view functions
1635 fill_buffer_surface_state(void *state
, VkFormat format
,
1636 uint32_t offset
, uint32_t range
)
1638 const struct anv_format
*info
;
1640 info
= anv_format_for_vk_format(format
);
1641 /* This assumes RGBA float format. */
1642 uint32_t stride
= 4;
1643 uint32_t num_elements
= range
/ stride
;
1645 struct GEN8_RENDER_SURFACE_STATE surface_state
= {
1646 .SurfaceType
= SURFTYPE_BUFFER
,
1647 .SurfaceArray
= false,
1648 .SurfaceFormat
= info
->surface_format
,
1649 .SurfaceVerticalAlignment
= VALIGN4
,
1650 .SurfaceHorizontalAlignment
= HALIGN4
,
1652 .VerticalLineStride
= 0,
1653 .VerticalLineStrideOffset
= 0,
1654 .SamplerL2BypassModeDisable
= true,
1655 .RenderCacheReadWriteMode
= WriteOnlyCache
,
1656 .MemoryObjectControlState
= GEN8_MOCS
,
1657 .BaseMipLevel
= 0.0,
1659 .Height
= (num_elements
>> 7) & 0x3fff,
1660 .Width
= num_elements
& 0x7f,
1661 .Depth
= (num_elements
>> 21) & 0x3f,
1662 .SurfacePitch
= stride
- 1,
1663 .MinimumArrayElement
= 0,
1664 .NumberofMultisamples
= MULTISAMPLECOUNT_1
,
1669 .AuxiliarySurfaceMode
= AUX_NONE
,
1671 .GreenClearColor
= 0,
1672 .BlueClearColor
= 0,
1673 .AlphaClearColor
= 0,
1674 .ShaderChannelSelectRed
= SCS_RED
,
1675 .ShaderChannelSelectGreen
= SCS_GREEN
,
1676 .ShaderChannelSelectBlue
= SCS_BLUE
,
1677 .ShaderChannelSelectAlpha
= SCS_ALPHA
,
1678 .ResourceMinLOD
= 0.0,
1679 /* FIXME: We assume that the image must be bound at this time. */
1680 .SurfaceBaseAddress
= { NULL
, offset
},
1683 GEN8_RENDER_SURFACE_STATE_pack(NULL
, state
, &surface_state
);
1686 VkResult
anv_CreateBufferView(
1688 const VkBufferViewCreateInfo
* pCreateInfo
,
1689 VkBufferView
* pView
)
1691 ANV_FROM_HANDLE(anv_device
, device
, _device
);
1692 ANV_FROM_HANDLE(anv_buffer
, buffer
, pCreateInfo
->buffer
);
1693 struct anv_surface_view
*view
;
1695 assert(pCreateInfo
->sType
== VK_STRUCTURE_TYPE_BUFFER_VIEW_CREATE_INFO
);
1697 view
= anv_device_alloc(device
, sizeof(*view
), 8,
1698 VK_SYSTEM_ALLOC_TYPE_API_OBJECT
);
1700 return vk_error(VK_ERROR_OUT_OF_HOST_MEMORY
);
1702 view
->bo
= buffer
->bo
;
1703 view
->offset
= buffer
->offset
+ pCreateInfo
->offset
;
1704 view
->surface_state
=
1705 anv_state_pool_alloc(&device
->surface_state_pool
, 64, 64);
1706 view
->format
= pCreateInfo
->format
;
1707 view
->range
= pCreateInfo
->range
;
1709 fill_buffer_surface_state(view
->surface_state
.map
,
1710 pCreateInfo
->format
, view
->offset
, pCreateInfo
->range
);
1712 *pView
= (VkBufferView
) view
;
1717 VkResult
anv_DestroyBufferView(
1721 ANV_FROM_HANDLE(anv_device
, device
, _device
);
1722 struct anv_surface_view
*view
= (struct anv_surface_view
*)_view
;
1724 anv_surface_view_fini(device
, view
);
1725 anv_device_free(device
, view
);
1730 // Sampler functions
1732 VkResult
anv_CreateSampler(
1734 const VkSamplerCreateInfo
* pCreateInfo
,
1735 VkSampler
* pSampler
)
1737 ANV_FROM_HANDLE(anv_device
, device
, _device
);
1738 struct anv_sampler
*sampler
;
1739 uint32_t mag_filter
, min_filter
, max_anisotropy
;
1741 assert(pCreateInfo
->sType
== VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO
);
1743 sampler
= anv_device_alloc(device
, sizeof(*sampler
), 8,
1744 VK_SYSTEM_ALLOC_TYPE_API_OBJECT
);
1746 return vk_error(VK_ERROR_OUT_OF_HOST_MEMORY
);
1748 static const uint32_t vk_to_gen_tex_filter
[] = {
1749 [VK_TEX_FILTER_NEAREST
] = MAPFILTER_NEAREST
,
1750 [VK_TEX_FILTER_LINEAR
] = MAPFILTER_LINEAR
1753 static const uint32_t vk_to_gen_mipmap_mode
[] = {
1754 [VK_TEX_MIPMAP_MODE_BASE
] = MIPFILTER_NONE
,
1755 [VK_TEX_MIPMAP_MODE_NEAREST
] = MIPFILTER_NEAREST
,
1756 [VK_TEX_MIPMAP_MODE_LINEAR
] = MIPFILTER_LINEAR
1759 static const uint32_t vk_to_gen_tex_address
[] = {
1760 [VK_TEX_ADDRESS_WRAP
] = TCM_WRAP
,
1761 [VK_TEX_ADDRESS_MIRROR
] = TCM_MIRROR
,
1762 [VK_TEX_ADDRESS_CLAMP
] = TCM_CLAMP
,
1763 [VK_TEX_ADDRESS_MIRROR_ONCE
] = TCM_MIRROR_ONCE
,
1764 [VK_TEX_ADDRESS_CLAMP_BORDER
] = TCM_CLAMP_BORDER
,
1767 static const uint32_t vk_to_gen_compare_op
[] = {
1768 [VK_COMPARE_OP_NEVER
] = PREFILTEROPNEVER
,
1769 [VK_COMPARE_OP_LESS
] = PREFILTEROPLESS
,
1770 [VK_COMPARE_OP_EQUAL
] = PREFILTEROPEQUAL
,
1771 [VK_COMPARE_OP_LESS_EQUAL
] = PREFILTEROPLEQUAL
,
1772 [VK_COMPARE_OP_GREATER
] = PREFILTEROPGREATER
,
1773 [VK_COMPARE_OP_NOT_EQUAL
] = PREFILTEROPNOTEQUAL
,
1774 [VK_COMPARE_OP_GREATER_EQUAL
] = PREFILTEROPGEQUAL
,
1775 [VK_COMPARE_OP_ALWAYS
] = PREFILTEROPALWAYS
,
1778 if (pCreateInfo
->maxAnisotropy
> 1) {
1779 mag_filter
= MAPFILTER_ANISOTROPIC
;
1780 min_filter
= MAPFILTER_ANISOTROPIC
;
1781 max_anisotropy
= (pCreateInfo
->maxAnisotropy
- 2) / 2;
1783 mag_filter
= vk_to_gen_tex_filter
[pCreateInfo
->magFilter
];
1784 min_filter
= vk_to_gen_tex_filter
[pCreateInfo
->minFilter
];
1785 max_anisotropy
= RATIO21
;
1788 struct GEN8_SAMPLER_STATE sampler_state
= {
1789 .SamplerDisable
= false,
1790 .TextureBorderColorMode
= DX10OGL
,
1791 .LODPreClampMode
= 0,
1792 .BaseMipLevel
= 0.0,
1793 .MipModeFilter
= vk_to_gen_mipmap_mode
[pCreateInfo
->mipMode
],
1794 .MagModeFilter
= mag_filter
,
1795 .MinModeFilter
= min_filter
,
1796 .TextureLODBias
= pCreateInfo
->mipLodBias
* 256,
1797 .AnisotropicAlgorithm
= EWAApproximation
,
1798 .MinLOD
= pCreateInfo
->minLod
,
1799 .MaxLOD
= pCreateInfo
->maxLod
,
1800 .ChromaKeyEnable
= 0,
1801 .ChromaKeyIndex
= 0,
1803 .ShadowFunction
= vk_to_gen_compare_op
[pCreateInfo
->compareOp
],
1804 .CubeSurfaceControlMode
= 0,
1806 .IndirectStatePointer
=
1807 device
->border_colors
.offset
+
1808 pCreateInfo
->borderColor
* sizeof(float) * 4,
1810 .LODClampMagnificationMode
= MIPNONE
,
1811 .MaximumAnisotropy
= max_anisotropy
,
1812 .RAddressMinFilterRoundingEnable
= 0,
1813 .RAddressMagFilterRoundingEnable
= 0,
1814 .VAddressMinFilterRoundingEnable
= 0,
1815 .VAddressMagFilterRoundingEnable
= 0,
1816 .UAddressMinFilterRoundingEnable
= 0,
1817 .UAddressMagFilterRoundingEnable
= 0,
1818 .TrilinearFilterQuality
= 0,
1819 .NonnormalizedCoordinateEnable
= 0,
1820 .TCXAddressControlMode
= vk_to_gen_tex_address
[pCreateInfo
->addressU
],
1821 .TCYAddressControlMode
= vk_to_gen_tex_address
[pCreateInfo
->addressV
],
1822 .TCZAddressControlMode
= vk_to_gen_tex_address
[pCreateInfo
->addressW
],
1825 GEN8_SAMPLER_STATE_pack(NULL
, sampler
->state
, &sampler_state
);
1827 *pSampler
= anv_sampler_to_handle(sampler
);
1832 VkResult
anv_DestroySampler(
1836 ANV_FROM_HANDLE(anv_device
, device
, _device
);
1837 ANV_FROM_HANDLE(anv_sampler
, sampler
, _sampler
);
1839 anv_device_free(device
, sampler
);
1844 // Descriptor set functions
1846 VkResult
anv_CreateDescriptorSetLayout(
1848 const VkDescriptorSetLayoutCreateInfo
* pCreateInfo
,
1849 VkDescriptorSetLayout
* pSetLayout
)
1851 ANV_FROM_HANDLE(anv_device
, device
, _device
);
1852 struct anv_descriptor_set_layout
*set_layout
;
1854 assert(pCreateInfo
->sType
== VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO
);
1856 uint32_t sampler_count
[VK_SHADER_STAGE_NUM
] = { 0, };
1857 uint32_t surface_count
[VK_SHADER_STAGE_NUM
] = { 0, };
1858 uint32_t num_dynamic_buffers
= 0;
1860 uint32_t stages
= 0;
1863 for (uint32_t i
= 0; i
< pCreateInfo
->count
; i
++) {
1864 switch (pCreateInfo
->pBinding
[i
].descriptorType
) {
1865 case VK_DESCRIPTOR_TYPE_SAMPLER
:
1866 case VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER
:
1867 for_each_bit(s
, pCreateInfo
->pBinding
[i
].stageFlags
)
1868 sampler_count
[s
] += pCreateInfo
->pBinding
[i
].arraySize
;
1874 switch (pCreateInfo
->pBinding
[i
].descriptorType
) {
1875 case VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER
:
1876 case VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE
:
1877 case VK_DESCRIPTOR_TYPE_STORAGE_IMAGE
:
1878 case VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER
:
1879 case VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER
:
1880 case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER
:
1881 case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER
:
1882 case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC
:
1883 case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC
:
1884 case VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT
:
1885 for_each_bit(s
, pCreateInfo
->pBinding
[i
].stageFlags
)
1886 surface_count
[s
] += pCreateInfo
->pBinding
[i
].arraySize
;
1892 switch (pCreateInfo
->pBinding
[i
].descriptorType
) {
1893 case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC
:
1894 case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC
:
1895 num_dynamic_buffers
+= pCreateInfo
->pBinding
[i
].arraySize
;
1901 stages
|= pCreateInfo
->pBinding
[i
].stageFlags
;
1902 count
+= pCreateInfo
->pBinding
[i
].arraySize
;
1905 uint32_t sampler_total
= 0;
1906 uint32_t surface_total
= 0;
1907 for (uint32_t s
= 0; s
< VK_SHADER_STAGE_NUM
; s
++) {
1908 sampler_total
+= sampler_count
[s
];
1909 surface_total
+= surface_count
[s
];
1912 size_t size
= sizeof(*set_layout
) +
1913 (sampler_total
+ surface_total
) * sizeof(set_layout
->entries
[0]);
1914 set_layout
= anv_device_alloc(device
, size
, 8,
1915 VK_SYSTEM_ALLOC_TYPE_API_OBJECT
);
1917 return vk_error(VK_ERROR_OUT_OF_HOST_MEMORY
);
1919 set_layout
->num_dynamic_buffers
= num_dynamic_buffers
;
1920 set_layout
->count
= count
;
1921 set_layout
->shader_stages
= stages
;
1923 struct anv_descriptor_slot
*p
= set_layout
->entries
;
1924 struct anv_descriptor_slot
*sampler
[VK_SHADER_STAGE_NUM
];
1925 struct anv_descriptor_slot
*surface
[VK_SHADER_STAGE_NUM
];
1926 for (uint32_t s
= 0; s
< VK_SHADER_STAGE_NUM
; s
++) {
1927 set_layout
->stage
[s
].surface_count
= surface_count
[s
];
1928 set_layout
->stage
[s
].surface_start
= surface
[s
] = p
;
1929 p
+= surface_count
[s
];
1930 set_layout
->stage
[s
].sampler_count
= sampler_count
[s
];
1931 set_layout
->stage
[s
].sampler_start
= sampler
[s
] = p
;
1932 p
+= sampler_count
[s
];
1935 uint32_t descriptor
= 0;
1936 int8_t dynamic_slot
= 0;
1938 for (uint32_t i
= 0; i
< pCreateInfo
->count
; i
++) {
1939 switch (pCreateInfo
->pBinding
[i
].descriptorType
) {
1940 case VK_DESCRIPTOR_TYPE_SAMPLER
:
1941 case VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER
:
1942 for_each_bit(s
, pCreateInfo
->pBinding
[i
].stageFlags
)
1943 for (uint32_t j
= 0; j
< pCreateInfo
->pBinding
[i
].arraySize
; j
++) {
1944 sampler
[s
]->index
= descriptor
+ j
;
1945 sampler
[s
]->dynamic_slot
= -1;
1953 switch (pCreateInfo
->pBinding
[i
].descriptorType
) {
1954 case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC
:
1955 case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC
:
1963 switch (pCreateInfo
->pBinding
[i
].descriptorType
) {
1964 case VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER
:
1965 case VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE
:
1966 case VK_DESCRIPTOR_TYPE_STORAGE_IMAGE
:
1967 case VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER
:
1968 case VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER
:
1969 case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER
:
1970 case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER
:
1971 case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC
:
1972 case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC
:
1973 case VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT
:
1974 for_each_bit(s
, pCreateInfo
->pBinding
[i
].stageFlags
)
1975 for (uint32_t j
= 0; j
< pCreateInfo
->pBinding
[i
].arraySize
; j
++) {
1976 surface
[s
]->index
= descriptor
+ j
;
1978 surface
[s
]->dynamic_slot
= dynamic_slot
+ j
;
1980 surface
[s
]->dynamic_slot
= -1;
1989 dynamic_slot
+= pCreateInfo
->pBinding
[i
].arraySize
;
1991 descriptor
+= pCreateInfo
->pBinding
[i
].arraySize
;
1994 *pSetLayout
= anv_descriptor_set_layout_to_handle(set_layout
);
1999 VkResult
anv_DestroyDescriptorSetLayout(
2001 VkDescriptorSetLayout _set_layout
)
2003 ANV_FROM_HANDLE(anv_device
, device
, _device
);
2004 ANV_FROM_HANDLE(anv_descriptor_set_layout
, set_layout
, _set_layout
);
2006 anv_device_free(device
, set_layout
);
2011 VkResult
anv_CreateDescriptorPool(
2013 VkDescriptorPoolUsage poolUsage
,
2015 const VkDescriptorPoolCreateInfo
* pCreateInfo
,
2016 VkDescriptorPool
* pDescriptorPool
)
2018 *pDescriptorPool
= 1;
2023 VkResult
anv_DestroyDescriptorPool(
2025 VkDescriptorPool _pool
)
2027 /* VkDescriptorPool is a dummy object. */
2031 VkResult
anv_ResetDescriptorPool(
2033 VkDescriptorPool descriptorPool
)
2038 VkResult
anv_AllocDescriptorSets(
2040 VkDescriptorPool descriptorPool
,
2041 VkDescriptorSetUsage setUsage
,
2043 const VkDescriptorSetLayout
* pSetLayouts
,
2044 VkDescriptorSet
* pDescriptorSets
,
2047 ANV_FROM_HANDLE(anv_device
, device
, _device
);
2048 struct anv_descriptor_set
*set
;
2051 for (uint32_t i
= 0; i
< count
; i
++) {
2052 ANV_FROM_HANDLE(anv_descriptor_set_layout
, layout
, pSetLayouts
[i
]);
2053 size
= sizeof(*set
) + layout
->count
* sizeof(set
->descriptors
[0]);
2054 set
= anv_device_alloc(device
, size
, 8,
2055 VK_SYSTEM_ALLOC_TYPE_API_OBJECT
);
2058 return vk_error(VK_ERROR_OUT_OF_HOST_MEMORY
);
2061 /* Descriptor sets may not be 100% filled out so we need to memset to
2062 * ensure that we can properly detect and handle holes.
2064 memset(set
, 0, size
);
2066 pDescriptorSets
[i
] = anv_descriptor_set_to_handle(set
);
2074 VkResult
anv_UpdateDescriptorSets(
2076 uint32_t writeCount
,
2077 const VkWriteDescriptorSet
* pDescriptorWrites
,
2079 const VkCopyDescriptorSet
* pDescriptorCopies
)
2081 for (uint32_t i
= 0; i
< writeCount
; i
++) {
2082 const VkWriteDescriptorSet
*write
= &pDescriptorWrites
[i
];
2083 ANV_FROM_HANDLE(anv_descriptor_set
, set
, write
->destSet
);
2085 switch (write
->descriptorType
) {
2086 case VK_DESCRIPTOR_TYPE_SAMPLER
:
2087 case VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER
:
2088 for (uint32_t j
= 0; j
< write
->count
; j
++) {
2089 set
->descriptors
[write
->destBinding
+ j
].sampler
=
2090 anv_sampler_from_handle(write
->pDescriptors
[j
].sampler
);
2093 if (write
->descriptorType
== VK_DESCRIPTOR_TYPE_SAMPLER
)
2098 case VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE
:
2099 case VK_DESCRIPTOR_TYPE_STORAGE_IMAGE
:
2100 for (uint32_t j
= 0; j
< write
->count
; j
++) {
2101 set
->descriptors
[write
->destBinding
+ j
].view
=
2102 (struct anv_surface_view
*)write
->pDescriptors
[j
].imageView
;
2106 case VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER
:
2107 case VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER
:
2108 anv_finishme("texel buffers not implemented");
2111 case VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT
:
2112 anv_finishme("input attachments not implemented");
2115 case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER
:
2116 case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER
:
2117 case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC
:
2118 case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC
:
2119 for (uint32_t j
= 0; j
< write
->count
; j
++) {
2120 set
->descriptors
[write
->destBinding
+ j
].view
=
2121 (struct anv_surface_view
*)write
->pDescriptors
[j
].bufferView
;
2129 for (uint32_t i
= 0; i
< copyCount
; i
++) {
2130 const VkCopyDescriptorSet
*copy
= &pDescriptorCopies
[i
];
2131 ANV_FROM_HANDLE(anv_descriptor_set
, src
, copy
->destSet
);
2132 ANV_FROM_HANDLE(anv_descriptor_set
, dest
, copy
->destSet
);
2133 for (uint32_t j
= 0; j
< copy
->count
; j
++) {
2134 dest
->descriptors
[copy
->destBinding
+ j
] =
2135 src
->descriptors
[copy
->srcBinding
+ j
];
2142 // State object functions
2144 static inline int64_t
2145 clamp_int64(int64_t x
, int64_t min
, int64_t max
)
2156 anv_dynamic_vp_state_destroy(struct anv_device
*device
,
2157 struct anv_object
*object
,
2158 VkObjectType obj_type
)
2160 struct anv_dynamic_vp_state
*vp_state
= (void *) object
;
2162 assert(obj_type
== VK_OBJECT_TYPE_DYNAMIC_VP_STATE
);
2164 anv_DestroyDynamicViewportState(anv_device_to_handle(device
),
2165 anv_dynamic_vp_state_to_handle(vp_state
));
2168 VkResult
anv_CreateDynamicViewportState(
2170 const VkDynamicViewportStateCreateInfo
* pCreateInfo
,
2171 VkDynamicViewportState
* pState
)
2173 ANV_FROM_HANDLE(anv_device
, device
, _device
);
2174 struct anv_dynamic_vp_state
*state
;
2176 assert(pCreateInfo
->sType
== VK_STRUCTURE_TYPE_DYNAMIC_VP_STATE_CREATE_INFO
);
2178 state
= anv_device_alloc(device
, sizeof(*state
), 8,
2179 VK_SYSTEM_ALLOC_TYPE_API_OBJECT
);
2181 return vk_error(VK_ERROR_OUT_OF_HOST_MEMORY
);
2183 state
->base
.destructor
= anv_dynamic_vp_state_destroy
;
2185 unsigned count
= pCreateInfo
->viewportAndScissorCount
;
2186 state
->sf_clip_vp
= anv_state_pool_alloc(&device
->dynamic_state_pool
,
2188 state
->cc_vp
= anv_state_pool_alloc(&device
->dynamic_state_pool
,
2190 state
->scissor
= anv_state_pool_alloc(&device
->dynamic_state_pool
,
2193 for (uint32_t i
= 0; i
< pCreateInfo
->viewportAndScissorCount
; i
++) {
2194 const VkViewport
*vp
= &pCreateInfo
->pViewports
[i
];
2195 const VkRect2D
*s
= &pCreateInfo
->pScissors
[i
];
2197 struct GEN8_SF_CLIP_VIEWPORT sf_clip_viewport
= {
2198 .ViewportMatrixElementm00
= vp
->width
/ 2,
2199 .ViewportMatrixElementm11
= vp
->height
/ 2,
2200 .ViewportMatrixElementm22
= (vp
->maxDepth
- vp
->minDepth
) / 2,
2201 .ViewportMatrixElementm30
= vp
->originX
+ vp
->width
/ 2,
2202 .ViewportMatrixElementm31
= vp
->originY
+ vp
->height
/ 2,
2203 .ViewportMatrixElementm32
= (vp
->maxDepth
+ vp
->minDepth
) / 2,
2204 .XMinClipGuardband
= -1.0f
,
2205 .XMaxClipGuardband
= 1.0f
,
2206 .YMinClipGuardband
= -1.0f
,
2207 .YMaxClipGuardband
= 1.0f
,
2208 .XMinViewPort
= vp
->originX
,
2209 .XMaxViewPort
= vp
->originX
+ vp
->width
- 1,
2210 .YMinViewPort
= vp
->originY
,
2211 .YMaxViewPort
= vp
->originY
+ vp
->height
- 1,
2214 struct GEN8_CC_VIEWPORT cc_viewport
= {
2215 .MinimumDepth
= vp
->minDepth
,
2216 .MaximumDepth
= vp
->maxDepth
2219 /* Since xmax and ymax are inclusive, we have to have xmax < xmin or
2220 * ymax < ymin for empty clips. In case clip x, y, width height are all
2221 * 0, the clamps below produce 0 for xmin, ymin, xmax, ymax, which isn't
2222 * what we want. Just special case empty clips and produce a canonical
2224 static const struct GEN8_SCISSOR_RECT empty_scissor
= {
2225 .ScissorRectangleYMin
= 1,
2226 .ScissorRectangleXMin
= 1,
2227 .ScissorRectangleYMax
= 0,
2228 .ScissorRectangleXMax
= 0
2231 const int max
= 0xffff;
2232 struct GEN8_SCISSOR_RECT scissor
= {
2233 /* Do this math using int64_t so overflow gets clamped correctly. */
2234 .ScissorRectangleYMin
= clamp_int64(s
->offset
.y
, 0, max
),
2235 .ScissorRectangleXMin
= clamp_int64(s
->offset
.x
, 0, max
),
2236 .ScissorRectangleYMax
= clamp_int64((uint64_t) s
->offset
.y
+ s
->extent
.height
- 1, 0, max
),
2237 .ScissorRectangleXMax
= clamp_int64((uint64_t) s
->offset
.x
+ s
->extent
.width
- 1, 0, max
)
2240 GEN8_SF_CLIP_VIEWPORT_pack(NULL
, state
->sf_clip_vp
.map
+ i
* 64, &sf_clip_viewport
);
2241 GEN8_CC_VIEWPORT_pack(NULL
, state
->cc_vp
.map
+ i
* 32, &cc_viewport
);
2243 if (s
->extent
.width
<= 0 || s
->extent
.height
<= 0) {
2244 GEN8_SCISSOR_RECT_pack(NULL
, state
->scissor
.map
+ i
* 32, &empty_scissor
);
2246 GEN8_SCISSOR_RECT_pack(NULL
, state
->scissor
.map
+ i
* 32, &scissor
);
2250 *pState
= anv_dynamic_vp_state_to_handle(state
);
2255 VkResult
anv_DestroyDynamicViewportState(
2257 VkDynamicViewportState _vp_state
)
2259 ANV_FROM_HANDLE(anv_device
, device
, _device
);
2260 ANV_FROM_HANDLE(anv_dynamic_vp_state
, vp_state
, _vp_state
);
2262 anv_state_pool_free(&device
->dynamic_state_pool
, vp_state
->sf_clip_vp
);
2263 anv_state_pool_free(&device
->dynamic_state_pool
, vp_state
->cc_vp
);
2264 anv_state_pool_free(&device
->dynamic_state_pool
, vp_state
->scissor
);
2266 anv_device_free(device
, vp_state
);
2271 VkResult
anv_CreateDynamicRasterState(
2273 const VkDynamicRasterStateCreateInfo
* pCreateInfo
,
2274 VkDynamicRasterState
* pState
)
2276 ANV_FROM_HANDLE(anv_device
, device
, _device
);
2277 struct anv_dynamic_rs_state
*state
;
2279 assert(pCreateInfo
->sType
== VK_STRUCTURE_TYPE_DYNAMIC_RS_STATE_CREATE_INFO
);
2281 state
= anv_device_alloc(device
, sizeof(*state
), 8,
2282 VK_SYSTEM_ALLOC_TYPE_API_OBJECT
);
2284 return vk_error(VK_ERROR_OUT_OF_HOST_MEMORY
);
2286 struct GEN8_3DSTATE_SF sf
= {
2287 GEN8_3DSTATE_SF_header
,
2288 .LineWidth
= pCreateInfo
->lineWidth
,
2291 GEN8_3DSTATE_SF_pack(NULL
, state
->state_sf
, &sf
);
2293 bool enable_bias
= pCreateInfo
->depthBias
!= 0.0f
||
2294 pCreateInfo
->slopeScaledDepthBias
!= 0.0f
;
2295 struct GEN8_3DSTATE_RASTER raster
= {
2296 .GlobalDepthOffsetEnableSolid
= enable_bias
,
2297 .GlobalDepthOffsetEnableWireframe
= enable_bias
,
2298 .GlobalDepthOffsetEnablePoint
= enable_bias
,
2299 .GlobalDepthOffsetConstant
= pCreateInfo
->depthBias
,
2300 .GlobalDepthOffsetScale
= pCreateInfo
->slopeScaledDepthBias
,
2301 .GlobalDepthOffsetClamp
= pCreateInfo
->depthBiasClamp
2304 GEN8_3DSTATE_RASTER_pack(NULL
, state
->state_raster
, &raster
);
2306 *pState
= anv_dynamic_rs_state_to_handle(state
);
2311 VkResult
anv_DestroyDynamicRasterState(
2313 VkDynamicRasterState _rs_state
)
2315 ANV_FROM_HANDLE(anv_device
, device
, _device
);
2316 ANV_FROM_HANDLE(anv_dynamic_rs_state
, rs_state
, _rs_state
);
2318 anv_device_free(device
, rs_state
);
2323 VkResult
anv_CreateDynamicColorBlendState(
2325 const VkDynamicColorBlendStateCreateInfo
* pCreateInfo
,
2326 VkDynamicColorBlendState
* pState
)
2328 ANV_FROM_HANDLE(anv_device
, device
, _device
);
2329 struct anv_dynamic_cb_state
*state
;
2331 assert(pCreateInfo
->sType
== VK_STRUCTURE_TYPE_DYNAMIC_CB_STATE_CREATE_INFO
);
2333 state
= anv_device_alloc(device
, sizeof(*state
), 8,
2334 VK_SYSTEM_ALLOC_TYPE_API_OBJECT
);
2336 return vk_error(VK_ERROR_OUT_OF_HOST_MEMORY
);
2338 struct GEN8_COLOR_CALC_STATE color_calc_state
= {
2339 .BlendConstantColorRed
= pCreateInfo
->blendConst
[0],
2340 .BlendConstantColorGreen
= pCreateInfo
->blendConst
[1],
2341 .BlendConstantColorBlue
= pCreateInfo
->blendConst
[2],
2342 .BlendConstantColorAlpha
= pCreateInfo
->blendConst
[3]
2345 GEN8_COLOR_CALC_STATE_pack(NULL
, state
->state_color_calc
, &color_calc_state
);
2347 *pState
= anv_dynamic_cb_state_to_handle(state
);
2352 VkResult
anv_DestroyDynamicColorBlendState(
2354 VkDynamicColorBlendState _cb_state
)
2356 ANV_FROM_HANDLE(anv_device
, device
, _device
);
2357 ANV_FROM_HANDLE(anv_dynamic_cb_state
, cb_state
, _cb_state
);
2359 anv_device_free(device
, cb_state
);
2364 VkResult
anv_CreateDynamicDepthStencilState(
2366 const VkDynamicDepthStencilStateCreateInfo
* pCreateInfo
,
2367 VkDynamicDepthStencilState
* pState
)
2369 ANV_FROM_HANDLE(anv_device
, device
, _device
);
2370 struct anv_dynamic_ds_state
*state
;
2372 assert(pCreateInfo
->sType
== VK_STRUCTURE_TYPE_DYNAMIC_DS_STATE_CREATE_INFO
);
2374 state
= anv_device_alloc(device
, sizeof(*state
), 8,
2375 VK_SYSTEM_ALLOC_TYPE_API_OBJECT
);
2377 return vk_error(VK_ERROR_OUT_OF_HOST_MEMORY
);
2379 struct GEN8_3DSTATE_WM_DEPTH_STENCIL wm_depth_stencil
= {
2380 GEN8_3DSTATE_WM_DEPTH_STENCIL_header
,
2382 /* Is this what we need to do? */
2383 .StencilBufferWriteEnable
= pCreateInfo
->stencilWriteMask
!= 0,
2385 .StencilTestMask
= pCreateInfo
->stencilReadMask
& 0xff,
2386 .StencilWriteMask
= pCreateInfo
->stencilWriteMask
& 0xff,
2388 .BackfaceStencilTestMask
= pCreateInfo
->stencilReadMask
& 0xff,
2389 .BackfaceStencilWriteMask
= pCreateInfo
->stencilWriteMask
& 0xff,
2392 GEN8_3DSTATE_WM_DEPTH_STENCIL_pack(NULL
, state
->state_wm_depth_stencil
,
2395 struct GEN8_COLOR_CALC_STATE color_calc_state
= {
2396 .StencilReferenceValue
= pCreateInfo
->stencilFrontRef
,
2397 .BackFaceStencilReferenceValue
= pCreateInfo
->stencilBackRef
2400 GEN8_COLOR_CALC_STATE_pack(NULL
, state
->state_color_calc
, &color_calc_state
);
2402 *pState
= anv_dynamic_ds_state_to_handle(state
);
2407 VkResult
anv_DestroyDynamicDepthStencilState(
2409 VkDynamicDepthStencilState _ds_state
)
2411 ANV_FROM_HANDLE(anv_device
, device
, _device
);
2412 ANV_FROM_HANDLE(anv_dynamic_ds_state
, ds_state
, _ds_state
);
2414 anv_device_free(device
, ds_state
);
2419 // Command buffer functions
2422 anv_cmd_buffer_destroy(struct anv_device
*device
,
2423 struct anv_object
*object
,
2424 VkObjectType obj_type
)
2426 struct anv_cmd_buffer
*cmd_buffer
= (struct anv_cmd_buffer
*) object
;
2428 assert(obj_type
== VK_OBJECT_TYPE_COMMAND_BUFFER
);
2430 anv_DestroyCommandBuffer(anv_device_to_handle(device
),
2431 anv_cmd_buffer_to_handle(cmd_buffer
));
2435 anv_cmd_buffer_chain_batch(struct anv_batch
*batch
, void *_data
)
2437 struct anv_cmd_buffer
*cmd_buffer
= _data
;
2439 struct anv_batch_bo
*new_bbo
, *old_bbo
= cmd_buffer
->last_batch_bo
;
2441 VkResult result
= anv_batch_bo_create(cmd_buffer
->device
, &new_bbo
);
2442 if (result
!= VK_SUCCESS
)
2445 /* We set the end of the batch a little short so we would be sure we
2446 * have room for the chaining command. Since we're about to emit the
2447 * chaining command, let's set it back where it should go.
2449 batch
->end
+= GEN8_MI_BATCH_BUFFER_START_length
* 4;
2450 assert(batch
->end
== old_bbo
->bo
.map
+ old_bbo
->bo
.size
);
2452 anv_batch_emit(batch
, GEN8_MI_BATCH_BUFFER_START
,
2453 GEN8_MI_BATCH_BUFFER_START_header
,
2454 ._2ndLevelBatchBuffer
= _1stlevelbatch
,
2455 .AddressSpaceIndicator
= ASI_PPGTT
,
2456 .BatchBufferStartAddress
= { &new_bbo
->bo
, 0 },
2459 /* Pad out to a 2-dword aligned boundary with zeros */
2460 if ((uintptr_t)batch
->next
% 8 != 0) {
2461 *(uint32_t *)batch
->next
= 0;
2465 anv_batch_bo_finish(cmd_buffer
->last_batch_bo
, batch
);
2467 new_bbo
->prev_batch_bo
= old_bbo
;
2468 cmd_buffer
->last_batch_bo
= new_bbo
;
2470 anv_batch_bo_start(new_bbo
, batch
, GEN8_MI_BATCH_BUFFER_START_length
* 4);
2475 VkResult
anv_CreateCommandBuffer(
2477 const VkCmdBufferCreateInfo
* pCreateInfo
,
2478 VkCmdBuffer
* pCmdBuffer
)
2480 ANV_FROM_HANDLE(anv_device
, device
, _device
);
2481 struct anv_cmd_buffer
*cmd_buffer
;
2484 assert(pCreateInfo
->level
== VK_CMD_BUFFER_LEVEL_PRIMARY
);
2486 cmd_buffer
= anv_device_alloc(device
, sizeof(*cmd_buffer
), 8,
2487 VK_SYSTEM_ALLOC_TYPE_API_OBJECT
);
2488 if (cmd_buffer
== NULL
)
2489 return vk_error(VK_ERROR_OUT_OF_HOST_MEMORY
);
2491 cmd_buffer
->base
.destructor
= anv_cmd_buffer_destroy
;
2493 cmd_buffer
->device
= device
;
2494 cmd_buffer
->rs_state
= NULL
;
2495 cmd_buffer
->vp_state
= NULL
;
2496 cmd_buffer
->cb_state
= NULL
;
2497 cmd_buffer
->ds_state
= NULL
;
2498 memset(&cmd_buffer
->state_vf
, 0, sizeof(cmd_buffer
->state_vf
));
2499 memset(&cmd_buffer
->descriptors
, 0, sizeof(cmd_buffer
->descriptors
));
2501 result
= anv_batch_bo_create(device
, &cmd_buffer
->last_batch_bo
);
2502 if (result
!= VK_SUCCESS
)
2505 result
= anv_reloc_list_init(&cmd_buffer
->batch
.relocs
, device
);
2506 if (result
!= VK_SUCCESS
)
2509 cmd_buffer
->batch
.device
= device
;
2510 cmd_buffer
->batch
.extend_cb
= anv_cmd_buffer_chain_batch
;
2511 cmd_buffer
->batch
.user_data
= cmd_buffer
;
2513 anv_batch_bo_start(cmd_buffer
->last_batch_bo
, &cmd_buffer
->batch
,
2514 GEN8_MI_BATCH_BUFFER_START_length
* 4);
2516 result
= anv_batch_bo_create(device
, &cmd_buffer
->surface_batch_bo
);
2517 if (result
!= VK_SUCCESS
)
2518 goto fail_batch_relocs
;
2519 cmd_buffer
->surface_batch_bo
->first_reloc
= 0;
2521 result
= anv_reloc_list_init(&cmd_buffer
->surface_relocs
, device
);
2522 if (result
!= VK_SUCCESS
)
2523 goto fail_ss_batch_bo
;
2525 /* Start surface_next at 1 so surface offset 0 is invalid. */
2526 cmd_buffer
->surface_next
= 1;
2528 cmd_buffer
->exec2_objects
= NULL
;
2529 cmd_buffer
->exec2_bos
= NULL
;
2530 cmd_buffer
->exec2_array_length
= 0;
2532 anv_state_stream_init(&cmd_buffer
->surface_state_stream
,
2533 &device
->surface_state_block_pool
);
2534 anv_state_stream_init(&cmd_buffer
->dynamic_state_stream
,
2535 &device
->dynamic_state_block_pool
);
2537 cmd_buffer
->dirty
= 0;
2538 cmd_buffer
->vb_dirty
= 0;
2539 cmd_buffer
->descriptors_dirty
= 0;
2540 cmd_buffer
->pipeline
= NULL
;
2541 cmd_buffer
->vp_state
= NULL
;
2542 cmd_buffer
->rs_state
= NULL
;
2543 cmd_buffer
->ds_state
= NULL
;
2545 *pCmdBuffer
= anv_cmd_buffer_to_handle(cmd_buffer
);
2550 anv_batch_bo_destroy(cmd_buffer
->surface_batch_bo
, device
);
2552 anv_reloc_list_finish(&cmd_buffer
->batch
.relocs
, device
);
2554 anv_batch_bo_destroy(cmd_buffer
->last_batch_bo
, device
);
2556 anv_device_free(device
, cmd_buffer
);
2561 VkResult
anv_DestroyCommandBuffer(
2563 VkCmdBuffer _cmd_buffer
)
2565 ANV_FROM_HANDLE(anv_device
, device
, _device
);
2566 ANV_FROM_HANDLE(anv_cmd_buffer
, cmd_buffer
, _cmd_buffer
);
2568 /* Destroy all of the batch buffers */
2569 struct anv_batch_bo
*bbo
= cmd_buffer
->last_batch_bo
;
2571 struct anv_batch_bo
*prev
= bbo
->prev_batch_bo
;
2572 anv_batch_bo_destroy(bbo
, device
);
2575 anv_reloc_list_finish(&cmd_buffer
->batch
.relocs
, device
);
2577 /* Destroy all of the surface state buffers */
2578 bbo
= cmd_buffer
->surface_batch_bo
;
2580 struct anv_batch_bo
*prev
= bbo
->prev_batch_bo
;
2581 anv_batch_bo_destroy(bbo
, device
);
2584 anv_reloc_list_finish(&cmd_buffer
->surface_relocs
, device
);
2586 anv_state_stream_finish(&cmd_buffer
->surface_state_stream
);
2587 anv_state_stream_finish(&cmd_buffer
->dynamic_state_stream
);
2588 anv_device_free(device
, cmd_buffer
->exec2_objects
);
2589 anv_device_free(device
, cmd_buffer
->exec2_bos
);
2590 anv_device_free(device
, cmd_buffer
);
2596 anv_cmd_buffer_emit_state_base_address(struct anv_cmd_buffer
*cmd_buffer
)
2598 struct anv_device
*device
= cmd_buffer
->device
;
2599 struct anv_bo
*scratch_bo
= NULL
;
2601 cmd_buffer
->scratch_size
= device
->scratch_block_pool
.size
;
2602 if (cmd_buffer
->scratch_size
> 0)
2603 scratch_bo
= &device
->scratch_block_pool
.bo
;
2605 anv_batch_emit(&cmd_buffer
->batch
, GEN8_STATE_BASE_ADDRESS
,
2606 .GeneralStateBaseAddress
= { scratch_bo
, 0 },
2607 .GeneralStateMemoryObjectControlState
= GEN8_MOCS
,
2608 .GeneralStateBaseAddressModifyEnable
= true,
2609 .GeneralStateBufferSize
= 0xfffff,
2610 .GeneralStateBufferSizeModifyEnable
= true,
2612 .SurfaceStateBaseAddress
= { &cmd_buffer
->surface_batch_bo
->bo
, 0 },
2613 .SurfaceStateMemoryObjectControlState
= GEN8_MOCS
,
2614 .SurfaceStateBaseAddressModifyEnable
= true,
2616 .DynamicStateBaseAddress
= { &device
->dynamic_state_block_pool
.bo
, 0 },
2617 .DynamicStateMemoryObjectControlState
= GEN8_MOCS
,
2618 .DynamicStateBaseAddressModifyEnable
= true,
2619 .DynamicStateBufferSize
= 0xfffff,
2620 .DynamicStateBufferSizeModifyEnable
= true,
2622 .IndirectObjectBaseAddress
= { NULL
, 0 },
2623 .IndirectObjectMemoryObjectControlState
= GEN8_MOCS
,
2624 .IndirectObjectBaseAddressModifyEnable
= true,
2625 .IndirectObjectBufferSize
= 0xfffff,
2626 .IndirectObjectBufferSizeModifyEnable
= true,
2628 .InstructionBaseAddress
= { &device
->instruction_block_pool
.bo
, 0 },
2629 .InstructionMemoryObjectControlState
= GEN8_MOCS
,
2630 .InstructionBaseAddressModifyEnable
= true,
2631 .InstructionBufferSize
= 0xfffff,
2632 .InstructionBuffersizeModifyEnable
= true);
2635 VkResult
anv_BeginCommandBuffer(
2636 VkCmdBuffer cmdBuffer
,
2637 const VkCmdBufferBeginInfo
* pBeginInfo
)
2639 ANV_FROM_HANDLE(anv_cmd_buffer
, cmd_buffer
, cmdBuffer
);
2641 anv_cmd_buffer_emit_state_base_address(cmd_buffer
);
2642 cmd_buffer
->current_pipeline
= UINT32_MAX
;
2648 anv_cmd_buffer_add_bo(struct anv_cmd_buffer
*cmd_buffer
,
2650 struct drm_i915_gem_relocation_entry
*relocs
,
2653 struct drm_i915_gem_exec_object2
*obj
;
2655 if (bo
->index
< cmd_buffer
->bo_count
&&
2656 cmd_buffer
->exec2_bos
[bo
->index
] == bo
)
2659 if (cmd_buffer
->bo_count
>= cmd_buffer
->exec2_array_length
) {
2660 uint32_t new_len
= cmd_buffer
->exec2_objects
?
2661 cmd_buffer
->exec2_array_length
* 2 : 64;
2663 struct drm_i915_gem_exec_object2
*new_objects
=
2664 anv_device_alloc(cmd_buffer
->device
, new_len
* sizeof(*new_objects
),
2665 8, VK_SYSTEM_ALLOC_TYPE_INTERNAL
);
2666 if (new_objects
== NULL
)
2667 return vk_error(VK_ERROR_OUT_OF_HOST_MEMORY
);
2669 struct anv_bo
**new_bos
=
2670 anv_device_alloc(cmd_buffer
->device
, new_len
* sizeof(*new_bos
),
2671 8, VK_SYSTEM_ALLOC_TYPE_INTERNAL
);
2672 if (new_objects
== NULL
) {
2673 anv_device_free(cmd_buffer
->device
, new_objects
);
2674 return vk_error(VK_ERROR_OUT_OF_HOST_MEMORY
);
2677 if (cmd_buffer
->exec2_objects
) {
2678 memcpy(new_objects
, cmd_buffer
->exec2_objects
,
2679 cmd_buffer
->bo_count
* sizeof(*new_objects
));
2680 memcpy(new_bos
, cmd_buffer
->exec2_bos
,
2681 cmd_buffer
->bo_count
* sizeof(*new_bos
));
2684 cmd_buffer
->exec2_objects
= new_objects
;
2685 cmd_buffer
->exec2_bos
= new_bos
;
2686 cmd_buffer
->exec2_array_length
= new_len
;
2689 assert(cmd_buffer
->bo_count
< cmd_buffer
->exec2_array_length
);
2691 bo
->index
= cmd_buffer
->bo_count
++;
2692 obj
= &cmd_buffer
->exec2_objects
[bo
->index
];
2693 cmd_buffer
->exec2_bos
[bo
->index
] = bo
;
2695 obj
->handle
= bo
->gem_handle
;
2696 obj
->relocation_count
= 0;
2697 obj
->relocs_ptr
= 0;
2699 obj
->offset
= bo
->offset
;
2705 obj
->relocation_count
= num_relocs
;
2706 obj
->relocs_ptr
= (uintptr_t) relocs
;
2713 anv_cmd_buffer_add_validate_bos(struct anv_cmd_buffer
*cmd_buffer
,
2714 struct anv_reloc_list
*list
)
2716 for (size_t i
= 0; i
< list
->num_relocs
; i
++)
2717 anv_cmd_buffer_add_bo(cmd_buffer
, list
->reloc_bos
[i
], NULL
, 0);
2721 anv_cmd_buffer_process_relocs(struct anv_cmd_buffer
*cmd_buffer
,
2722 struct anv_reloc_list
*list
)
2726 /* If the kernel supports I915_EXEC_NO_RELOC, it will compare offset in
2727 * struct drm_i915_gem_exec_object2 against the bos current offset and if
2728 * all bos haven't moved it will skip relocation processing alltogether.
2729 * If I915_EXEC_NO_RELOC is not supported, the kernel ignores the incoming
2730 * value of offset so we can set it either way. For that to work we need
2731 * to make sure all relocs use the same presumed offset.
2734 for (size_t i
= 0; i
< list
->num_relocs
; i
++) {
2735 bo
= list
->reloc_bos
[i
];
2736 if (bo
->offset
!= list
->relocs
[i
].presumed_offset
)
2737 cmd_buffer
->need_reloc
= true;
2739 list
->relocs
[i
].target_handle
= bo
->index
;
2743 VkResult
anv_EndCommandBuffer(
2744 VkCmdBuffer cmdBuffer
)
2746 ANV_FROM_HANDLE(anv_cmd_buffer
, cmd_buffer
, cmdBuffer
);
2747 struct anv_device
*device
= cmd_buffer
->device
;
2748 struct anv_batch
*batch
= &cmd_buffer
->batch
;
2750 anv_batch_emit(batch
, GEN8_MI_BATCH_BUFFER_END
);
2752 /* Round batch up to an even number of dwords. */
2753 if ((batch
->next
- batch
->start
) & 4)
2754 anv_batch_emit(batch
, GEN8_MI_NOOP
);
2756 anv_batch_bo_finish(cmd_buffer
->last_batch_bo
, &cmd_buffer
->batch
);
2757 cmd_buffer
->surface_batch_bo
->num_relocs
=
2758 cmd_buffer
->surface_relocs
.num_relocs
- cmd_buffer
->surface_batch_bo
->first_reloc
;
2759 cmd_buffer
->surface_batch_bo
->length
= cmd_buffer
->surface_next
;
2761 cmd_buffer
->bo_count
= 0;
2762 cmd_buffer
->need_reloc
= false;
2764 /* Lock for access to bo->index. */
2765 pthread_mutex_lock(&device
->mutex
);
2767 /* Add surface state bos first so we can add them with their relocs. */
2768 for (struct anv_batch_bo
*bbo
= cmd_buffer
->surface_batch_bo
;
2769 bbo
!= NULL
; bbo
= bbo
->prev_batch_bo
) {
2770 anv_cmd_buffer_add_bo(cmd_buffer
, &bbo
->bo
,
2771 &cmd_buffer
->surface_relocs
.relocs
[bbo
->first_reloc
],
2775 /* Add all of the BOs referenced by surface state */
2776 anv_cmd_buffer_add_validate_bos(cmd_buffer
, &cmd_buffer
->surface_relocs
);
2778 /* Add all but the first batch BO */
2779 struct anv_batch_bo
*batch_bo
= cmd_buffer
->last_batch_bo
;
2780 while (batch_bo
->prev_batch_bo
) {
2781 anv_cmd_buffer_add_bo(cmd_buffer
, &batch_bo
->bo
,
2782 &batch
->relocs
.relocs
[batch_bo
->first_reloc
],
2783 batch_bo
->num_relocs
);
2784 batch_bo
= batch_bo
->prev_batch_bo
;
2787 /* Add everything referenced by the batches */
2788 anv_cmd_buffer_add_validate_bos(cmd_buffer
, &batch
->relocs
);
2790 /* Add the first batch bo last */
2791 assert(batch_bo
->prev_batch_bo
== NULL
&& batch_bo
->first_reloc
== 0);
2792 anv_cmd_buffer_add_bo(cmd_buffer
, &batch_bo
->bo
,
2793 &batch
->relocs
.relocs
[batch_bo
->first_reloc
],
2794 batch_bo
->num_relocs
);
2795 assert(batch_bo
->bo
.index
== cmd_buffer
->bo_count
- 1);
2797 anv_cmd_buffer_process_relocs(cmd_buffer
, &cmd_buffer
->surface_relocs
);
2798 anv_cmd_buffer_process_relocs(cmd_buffer
, &batch
->relocs
);
2800 cmd_buffer
->execbuf
.buffers_ptr
= (uintptr_t) cmd_buffer
->exec2_objects
;
2801 cmd_buffer
->execbuf
.buffer_count
= cmd_buffer
->bo_count
;
2802 cmd_buffer
->execbuf
.batch_start_offset
= 0;
2803 cmd_buffer
->execbuf
.batch_len
= batch
->next
- batch
->start
;
2804 cmd_buffer
->execbuf
.cliprects_ptr
= 0;
2805 cmd_buffer
->execbuf
.num_cliprects
= 0;
2806 cmd_buffer
->execbuf
.DR1
= 0;
2807 cmd_buffer
->execbuf
.DR4
= 0;
2809 cmd_buffer
->execbuf
.flags
= I915_EXEC_HANDLE_LUT
;
2810 if (!cmd_buffer
->need_reloc
)
2811 cmd_buffer
->execbuf
.flags
|= I915_EXEC_NO_RELOC
;
2812 cmd_buffer
->execbuf
.flags
|= I915_EXEC_RENDER
;
2813 cmd_buffer
->execbuf
.rsvd1
= device
->context_id
;
2814 cmd_buffer
->execbuf
.rsvd2
= 0;
2816 pthread_mutex_unlock(&device
->mutex
);
2821 VkResult
anv_ResetCommandBuffer(
2822 VkCmdBuffer cmdBuffer
)
2824 ANV_FROM_HANDLE(anv_cmd_buffer
, cmd_buffer
, cmdBuffer
);
2826 /* Delete all but the first batch bo */
2827 while (cmd_buffer
->last_batch_bo
->prev_batch_bo
) {
2828 struct anv_batch_bo
*prev
= cmd_buffer
->last_batch_bo
->prev_batch_bo
;
2829 anv_batch_bo_destroy(cmd_buffer
->last_batch_bo
, cmd_buffer
->device
);
2830 cmd_buffer
->last_batch_bo
= prev
;
2832 assert(cmd_buffer
->last_batch_bo
->prev_batch_bo
== NULL
);
2834 cmd_buffer
->batch
.relocs
.num_relocs
= 0;
2835 anv_batch_bo_start(cmd_buffer
->last_batch_bo
, &cmd_buffer
->batch
,
2836 GEN8_MI_BATCH_BUFFER_START_length
* 4);
2838 /* Delete all but the first batch bo */
2839 while (cmd_buffer
->surface_batch_bo
->prev_batch_bo
) {
2840 struct anv_batch_bo
*prev
= cmd_buffer
->surface_batch_bo
->prev_batch_bo
;
2841 anv_batch_bo_destroy(cmd_buffer
->surface_batch_bo
, cmd_buffer
->device
);
2842 cmd_buffer
->surface_batch_bo
= prev
;
2844 assert(cmd_buffer
->surface_batch_bo
->prev_batch_bo
== NULL
);
2846 cmd_buffer
->surface_next
= 1;
2847 cmd_buffer
->surface_relocs
.num_relocs
= 0;
2849 cmd_buffer
->rs_state
= NULL
;
2850 cmd_buffer
->vp_state
= NULL
;
2851 cmd_buffer
->cb_state
= NULL
;
2852 cmd_buffer
->ds_state
= NULL
;
2857 // Command buffer building functions
2859 void anv_CmdBindPipeline(
2860 VkCmdBuffer cmdBuffer
,
2861 VkPipelineBindPoint pipelineBindPoint
,
2862 VkPipeline _pipeline
)
2864 ANV_FROM_HANDLE(anv_cmd_buffer
, cmd_buffer
, cmdBuffer
);
2865 ANV_FROM_HANDLE(anv_pipeline
, pipeline
, _pipeline
);
2867 switch (pipelineBindPoint
) {
2868 case VK_PIPELINE_BIND_POINT_COMPUTE
:
2869 cmd_buffer
->compute_pipeline
= pipeline
;
2870 cmd_buffer
->compute_dirty
|= ANV_CMD_BUFFER_PIPELINE_DIRTY
;
2873 case VK_PIPELINE_BIND_POINT_GRAPHICS
:
2874 cmd_buffer
->pipeline
= pipeline
;
2875 cmd_buffer
->vb_dirty
|= pipeline
->vb_used
;
2876 cmd_buffer
->dirty
|= ANV_CMD_BUFFER_PIPELINE_DIRTY
;
2880 assert(!"invalid bind point");
2885 void anv_CmdBindDynamicViewportState(
2886 VkCmdBuffer cmdBuffer
,
2887 VkDynamicViewportState dynamicViewportState
)
2889 ANV_FROM_HANDLE(anv_cmd_buffer
, cmd_buffer
, cmdBuffer
);
2890 ANV_FROM_HANDLE(anv_dynamic_vp_state
, vp_state
, dynamicViewportState
);
2892 cmd_buffer
->vp_state
= vp_state
;
2893 cmd_buffer
->dirty
|= ANV_CMD_BUFFER_VP_DIRTY
;
2896 void anv_CmdBindDynamicRasterState(
2897 VkCmdBuffer cmdBuffer
,
2898 VkDynamicRasterState dynamicRasterState
)
2900 ANV_FROM_HANDLE(anv_cmd_buffer
, cmd_buffer
, cmdBuffer
);
2901 ANV_FROM_HANDLE(anv_dynamic_rs_state
, rs_state
, dynamicRasterState
);
2903 cmd_buffer
->rs_state
= rs_state
;
2904 cmd_buffer
->dirty
|= ANV_CMD_BUFFER_RS_DIRTY
;
2907 void anv_CmdBindDynamicColorBlendState(
2908 VkCmdBuffer cmdBuffer
,
2909 VkDynamicColorBlendState dynamicColorBlendState
)
2911 ANV_FROM_HANDLE(anv_cmd_buffer
, cmd_buffer
, cmdBuffer
);
2912 ANV_FROM_HANDLE(anv_dynamic_cb_state
, cb_state
, dynamicColorBlendState
);
2914 cmd_buffer
->cb_state
= cb_state
;
2915 cmd_buffer
->dirty
|= ANV_CMD_BUFFER_CB_DIRTY
;
2918 void anv_CmdBindDynamicDepthStencilState(
2919 VkCmdBuffer cmdBuffer
,
2920 VkDynamicDepthStencilState dynamicDepthStencilState
)
2922 ANV_FROM_HANDLE(anv_cmd_buffer
, cmd_buffer
, cmdBuffer
);
2923 ANV_FROM_HANDLE(anv_dynamic_ds_state
, ds_state
, dynamicDepthStencilState
);
2925 cmd_buffer
->ds_state
= ds_state
;
2926 cmd_buffer
->dirty
|= ANV_CMD_BUFFER_DS_DIRTY
;
2929 static struct anv_state
2930 anv_cmd_buffer_alloc_surface_state(struct anv_cmd_buffer
*cmd_buffer
,
2931 uint32_t size
, uint32_t alignment
)
2933 struct anv_state state
;
2935 state
.offset
= align_u32(cmd_buffer
->surface_next
, alignment
);
2936 if (state
.offset
+ size
> cmd_buffer
->surface_batch_bo
->bo
.size
)
2937 return (struct anv_state
) { 0 };
2939 state
.map
= cmd_buffer
->surface_batch_bo
->bo
.map
+ state
.offset
;
2940 state
.alloc_size
= size
;
2941 cmd_buffer
->surface_next
= state
.offset
+ size
;
2943 assert(state
.offset
+ size
<= cmd_buffer
->surface_batch_bo
->bo
.size
);
2949 anv_cmd_buffer_new_surface_state_bo(struct anv_cmd_buffer
*cmd_buffer
)
2951 struct anv_batch_bo
*new_bbo
, *old_bbo
= cmd_buffer
->surface_batch_bo
;
2953 /* Finish off the old buffer */
2954 old_bbo
->num_relocs
=
2955 cmd_buffer
->surface_relocs
.num_relocs
- old_bbo
->first_reloc
;
2956 old_bbo
->length
= cmd_buffer
->surface_next
;
2958 VkResult result
= anv_batch_bo_create(cmd_buffer
->device
, &new_bbo
);
2959 if (result
!= VK_SUCCESS
)
2962 new_bbo
->first_reloc
= cmd_buffer
->surface_relocs
.num_relocs
;
2963 cmd_buffer
->surface_next
= 1;
2965 new_bbo
->prev_batch_bo
= old_bbo
;
2966 cmd_buffer
->surface_batch_bo
= new_bbo
;
2968 /* Re-emit state base addresses so we get the new surface state base
2969 * address before we start emitting binding tables etc.
2971 anv_cmd_buffer_emit_state_base_address(cmd_buffer
);
2973 /* It seems like just changing the state base addresses isn't enough.
2974 * Invalidating the cache seems to be enough to cause things to
2975 * propagate. However, I'm not 100% sure what we're supposed to do.
2977 anv_batch_emit(&cmd_buffer
->batch
, GEN8_PIPE_CONTROL
,
2978 .TextureCacheInvalidationEnable
= true);
2983 void anv_CmdBindDescriptorSets(
2984 VkCmdBuffer cmdBuffer
,
2985 VkPipelineBindPoint pipelineBindPoint
,
2986 VkPipelineLayout _layout
,
2989 const VkDescriptorSet
* pDescriptorSets
,
2990 uint32_t dynamicOffsetCount
,
2991 const uint32_t* pDynamicOffsets
)
2993 ANV_FROM_HANDLE(anv_cmd_buffer
, cmd_buffer
, cmdBuffer
);
2994 ANV_FROM_HANDLE(anv_pipeline_layout
, layout
, _layout
);
2995 struct anv_descriptor_set_layout
*set_layout
;
2997 assert(firstSet
+ setCount
< MAX_SETS
);
2999 uint32_t dynamic_slot
= 0;
3000 for (uint32_t i
= 0; i
< setCount
; i
++) {
3001 ANV_FROM_HANDLE(anv_descriptor_set
, set
, pDescriptorSets
[i
]);
3002 set_layout
= layout
->set
[firstSet
+ i
].layout
;
3004 cmd_buffer
->descriptors
[firstSet
+ i
].set
= set
;
3006 assert(set_layout
->num_dynamic_buffers
<
3007 ARRAY_SIZE(cmd_buffer
->descriptors
[0].dynamic_offsets
));
3008 memcpy(cmd_buffer
->descriptors
[firstSet
+ i
].dynamic_offsets
,
3009 pDynamicOffsets
+ dynamic_slot
,
3010 set_layout
->num_dynamic_buffers
* sizeof(*pDynamicOffsets
));
3012 cmd_buffer
->descriptors_dirty
|= set_layout
->shader_stages
;
3014 dynamic_slot
+= set_layout
->num_dynamic_buffers
;
3018 void anv_CmdBindIndexBuffer(
3019 VkCmdBuffer cmdBuffer
,
3021 VkDeviceSize offset
,
3022 VkIndexType indexType
)
3024 ANV_FROM_HANDLE(anv_cmd_buffer
, cmd_buffer
, cmdBuffer
);
3025 ANV_FROM_HANDLE(anv_buffer
, buffer
, _buffer
);
3027 static const uint32_t vk_to_gen_index_type
[] = {
3028 [VK_INDEX_TYPE_UINT16
] = INDEX_WORD
,
3029 [VK_INDEX_TYPE_UINT32
] = INDEX_DWORD
,
3032 struct GEN8_3DSTATE_VF vf
= {
3033 GEN8_3DSTATE_VF_header
,
3034 .CutIndex
= (indexType
== VK_INDEX_TYPE_UINT16
) ? UINT16_MAX
: UINT32_MAX
,
3036 GEN8_3DSTATE_VF_pack(NULL
, cmd_buffer
->state_vf
, &vf
);
3038 cmd_buffer
->dirty
|= ANV_CMD_BUFFER_INDEX_BUFFER_DIRTY
;
3040 anv_batch_emit(&cmd_buffer
->batch
, GEN8_3DSTATE_INDEX_BUFFER
,
3041 .IndexFormat
= vk_to_gen_index_type
[indexType
],
3042 .MemoryObjectControlState
= GEN8_MOCS
,
3043 .BufferStartingAddress
= { buffer
->bo
, buffer
->offset
+ offset
},
3044 .BufferSize
= buffer
->size
- offset
);
3047 void anv_CmdBindVertexBuffers(
3048 VkCmdBuffer cmdBuffer
,
3049 uint32_t startBinding
,
3050 uint32_t bindingCount
,
3051 const VkBuffer
* pBuffers
,
3052 const VkDeviceSize
* pOffsets
)
3054 ANV_FROM_HANDLE(anv_cmd_buffer
, cmd_buffer
, cmdBuffer
);
3055 struct anv_vertex_binding
*vb
= cmd_buffer
->vertex_bindings
;
3057 /* We have to defer setting up vertex buffer since we need the buffer
3058 * stride from the pipeline. */
3060 assert(startBinding
+ bindingCount
< MAX_VBS
);
3061 for (uint32_t i
= 0; i
< bindingCount
; i
++) {
3062 vb
[startBinding
+ i
].buffer
= anv_buffer_from_handle(pBuffers
[i
]);
3063 vb
[startBinding
+ i
].offset
= pOffsets
[i
];
3064 cmd_buffer
->vb_dirty
|= 1 << (startBinding
+ i
);
3069 cmd_buffer_emit_binding_table(struct anv_cmd_buffer
*cmd_buffer
,
3070 unsigned stage
, struct anv_state
*bt_state
)
3072 struct anv_framebuffer
*fb
= cmd_buffer
->framebuffer
;
3073 struct anv_subpass
*subpass
= cmd_buffer
->subpass
;
3074 struct anv_pipeline_layout
*layout
;
3075 uint32_t attachments
, bias
, size
;
3077 if (stage
== VK_SHADER_STAGE_COMPUTE
)
3078 layout
= cmd_buffer
->compute_pipeline
->layout
;
3080 layout
= cmd_buffer
->pipeline
->layout
;
3082 if (stage
== VK_SHADER_STAGE_FRAGMENT
) {
3084 attachments
= subpass
->color_count
;
3090 /* This is a little awkward: layout can be NULL but we still have to
3091 * allocate and set a binding table for the PS stage for render
3093 uint32_t surface_count
= layout
? layout
->stage
[stage
].surface_count
: 0;
3095 if (attachments
+ surface_count
== 0)
3098 size
= (bias
+ surface_count
) * sizeof(uint32_t);
3099 *bt_state
= anv_cmd_buffer_alloc_surface_state(cmd_buffer
, size
, 32);
3100 uint32_t *bt_map
= bt_state
->map
;
3102 if (bt_state
->map
== NULL
)
3103 return VK_ERROR_OUT_OF_DEVICE_MEMORY
;
3105 /* This is highly annoying. The Vulkan spec puts the depth-stencil
3106 * attachments in with the color attachments. Unfortunately, thanks to
3107 * other aspects of the API, we cana't really saparate them before this
3108 * point. Therefore, we have to walk all of the attachments but only
3109 * put the color attachments into the binding table.
3111 for (uint32_t a
= 0; a
< attachments
; a
++) {
3112 const struct anv_attachment_view
*attachment
=
3113 fb
->attachments
[subpass
->color_attachments
[a
]];
3115 assert(attachment
->attachment_type
== ANV_ATTACHMENT_VIEW_TYPE_COLOR
);
3116 const struct anv_color_attachment_view
*view
=
3117 (const struct anv_color_attachment_view
*)attachment
;
3119 struct anv_state state
=
3120 anv_cmd_buffer_alloc_surface_state(cmd_buffer
, 64, 64);
3122 if (state
.map
== NULL
)
3123 return VK_ERROR_OUT_OF_DEVICE_MEMORY
;
3125 memcpy(state
.map
, view
->view
.surface_state
.map
, 64);
3127 /* The address goes in dwords 8 and 9 of the SURFACE_STATE */
3128 *(uint64_t *)(state
.map
+ 8 * 4) =
3129 anv_reloc_list_add(&cmd_buffer
->surface_relocs
,
3131 state
.offset
+ 8 * 4,
3132 view
->view
.bo
, view
->view
.offset
);
3134 bt_map
[a
] = state
.offset
;
3140 for (uint32_t set
= 0; set
< layout
->num_sets
; set
++) {
3141 struct anv_descriptor_set_binding
*d
= &cmd_buffer
->descriptors
[set
];
3142 struct anv_descriptor_set_layout
*set_layout
= layout
->set
[set
].layout
;
3143 struct anv_descriptor_slot
*surface_slots
=
3144 set_layout
->stage
[stage
].surface_start
;
3146 uint32_t start
= bias
+ layout
->set
[set
].surface_start
[stage
];
3148 for (uint32_t b
= 0; b
< set_layout
->stage
[stage
].surface_count
; b
++) {
3149 struct anv_surface_view
*view
=
3150 d
->set
->descriptors
[surface_slots
[b
].index
].view
;
3155 struct anv_state state
=
3156 anv_cmd_buffer_alloc_surface_state(cmd_buffer
, 64, 64);
3158 if (state
.map
== NULL
)
3159 return VK_ERROR_OUT_OF_DEVICE_MEMORY
;
3162 if (surface_slots
[b
].dynamic_slot
>= 0) {
3163 uint32_t dynamic_offset
=
3164 d
->dynamic_offsets
[surface_slots
[b
].dynamic_slot
];
3166 offset
= view
->offset
+ dynamic_offset
;
3167 fill_buffer_surface_state(state
.map
, view
->format
, offset
,
3168 view
->range
- dynamic_offset
);
3170 offset
= view
->offset
;
3171 memcpy(state
.map
, view
->surface_state
.map
, 64);
3174 /* The address goes in dwords 8 and 9 of the SURFACE_STATE */
3175 *(uint64_t *)(state
.map
+ 8 * 4) =
3176 anv_reloc_list_add(&cmd_buffer
->surface_relocs
,
3178 state
.offset
+ 8 * 4,
3181 bt_map
[start
+ b
] = state
.offset
;
3189 cmd_buffer_emit_samplers(struct anv_cmd_buffer
*cmd_buffer
,
3190 unsigned stage
, struct anv_state
*state
)
3192 struct anv_pipeline_layout
*layout
;
3193 uint32_t sampler_count
;
3195 if (stage
== VK_SHADER_STAGE_COMPUTE
)
3196 layout
= cmd_buffer
->compute_pipeline
->layout
;
3198 layout
= cmd_buffer
->pipeline
->layout
;
3200 sampler_count
= layout
? layout
->stage
[stage
].sampler_count
: 0;
3201 if (sampler_count
== 0)
3204 uint32_t size
= sampler_count
* 16;
3205 *state
= anv_state_stream_alloc(&cmd_buffer
->dynamic_state_stream
, size
, 32);
3207 if (state
->map
== NULL
)
3208 return VK_ERROR_OUT_OF_DEVICE_MEMORY
;
3210 for (uint32_t set
= 0; set
< layout
->num_sets
; set
++) {
3211 struct anv_descriptor_set_binding
*d
= &cmd_buffer
->descriptors
[set
];
3212 struct anv_descriptor_set_layout
*set_layout
= layout
->set
[set
].layout
;
3213 struct anv_descriptor_slot
*sampler_slots
=
3214 set_layout
->stage
[stage
].sampler_start
;
3216 uint32_t start
= layout
->set
[set
].sampler_start
[stage
];
3218 for (uint32_t b
= 0; b
< set_layout
->stage
[stage
].sampler_count
; b
++) {
3219 struct anv_sampler
*sampler
=
3220 d
->set
->descriptors
[sampler_slots
[b
].index
].sampler
;
3225 memcpy(state
->map
+ (start
+ b
) * 16,
3226 sampler
->state
, sizeof(sampler
->state
));
3234 flush_descriptor_set(struct anv_cmd_buffer
*cmd_buffer
, uint32_t stage
)
3236 struct anv_state surfaces
= { 0, }, samplers
= { 0, };
3239 result
= cmd_buffer_emit_samplers(cmd_buffer
, stage
, &samplers
);
3240 if (result
!= VK_SUCCESS
)
3242 result
= cmd_buffer_emit_binding_table(cmd_buffer
, stage
, &surfaces
);
3243 if (result
!= VK_SUCCESS
)
3246 static const uint32_t sampler_state_opcodes
[] = {
3247 [VK_SHADER_STAGE_VERTEX
] = 43,
3248 [VK_SHADER_STAGE_TESS_CONTROL
] = 44, /* HS */
3249 [VK_SHADER_STAGE_TESS_EVALUATION
] = 45, /* DS */
3250 [VK_SHADER_STAGE_GEOMETRY
] = 46,
3251 [VK_SHADER_STAGE_FRAGMENT
] = 47,
3252 [VK_SHADER_STAGE_COMPUTE
] = 0,
3255 static const uint32_t binding_table_opcodes
[] = {
3256 [VK_SHADER_STAGE_VERTEX
] = 38,
3257 [VK_SHADER_STAGE_TESS_CONTROL
] = 39,
3258 [VK_SHADER_STAGE_TESS_EVALUATION
] = 40,
3259 [VK_SHADER_STAGE_GEOMETRY
] = 41,
3260 [VK_SHADER_STAGE_FRAGMENT
] = 42,
3261 [VK_SHADER_STAGE_COMPUTE
] = 0,
3264 if (samplers
.alloc_size
> 0) {
3265 anv_batch_emit(&cmd_buffer
->batch
,
3266 GEN8_3DSTATE_SAMPLER_STATE_POINTERS_VS
,
3267 ._3DCommandSubOpcode
= sampler_state_opcodes
[stage
],
3268 .PointertoVSSamplerState
= samplers
.offset
);
3271 if (surfaces
.alloc_size
> 0) {
3272 anv_batch_emit(&cmd_buffer
->batch
,
3273 GEN8_3DSTATE_BINDING_TABLE_POINTERS_VS
,
3274 ._3DCommandSubOpcode
= binding_table_opcodes
[stage
],
3275 .PointertoVSBindingTable
= surfaces
.offset
);
3282 flush_descriptor_sets(struct anv_cmd_buffer
*cmd_buffer
)
3284 uint32_t s
, dirty
= cmd_buffer
->descriptors_dirty
&
3285 cmd_buffer
->pipeline
->active_stages
;
3287 VkResult result
= VK_SUCCESS
;
3288 for_each_bit(s
, dirty
) {
3289 result
= flush_descriptor_set(cmd_buffer
, s
);
3290 if (result
!= VK_SUCCESS
)
3294 if (result
!= VK_SUCCESS
) {
3295 assert(result
== VK_ERROR_OUT_OF_DEVICE_MEMORY
);
3297 result
= anv_cmd_buffer_new_surface_state_bo(cmd_buffer
);
3298 assert(result
== VK_SUCCESS
);
3300 /* Re-emit all active binding tables */
3301 for_each_bit(s
, cmd_buffer
->pipeline
->active_stages
) {
3302 result
= flush_descriptor_set(cmd_buffer
, s
);
3304 /* It had better succeed this time */
3305 assert(result
== VK_SUCCESS
);
3309 cmd_buffer
->descriptors_dirty
&= ~cmd_buffer
->pipeline
->active_stages
;
3312 static struct anv_state
3313 anv_cmd_buffer_emit_dynamic(struct anv_cmd_buffer
*cmd_buffer
,
3314 uint32_t *a
, uint32_t dwords
, uint32_t alignment
)
3316 struct anv_state state
;
3318 state
= anv_state_stream_alloc(&cmd_buffer
->dynamic_state_stream
,
3319 dwords
* 4, alignment
);
3320 memcpy(state
.map
, a
, dwords
* 4);
3322 VG(VALGRIND_CHECK_MEM_IS_DEFINED(state
.map
, dwords
* 4));
3327 static struct anv_state
3328 anv_cmd_buffer_merge_dynamic(struct anv_cmd_buffer
*cmd_buffer
,
3329 uint32_t *a
, uint32_t *b
,
3330 uint32_t dwords
, uint32_t alignment
)
3332 struct anv_state state
;
3335 state
= anv_state_stream_alloc(&cmd_buffer
->dynamic_state_stream
,
3336 dwords
* 4, alignment
);
3338 for (uint32_t i
= 0; i
< dwords
; i
++)
3341 VG(VALGRIND_CHECK_MEM_IS_DEFINED(p
, dwords
* 4));
3347 flush_compute_descriptor_set(struct anv_cmd_buffer
*cmd_buffer
)
3349 struct anv_device
*device
= cmd_buffer
->device
;
3350 struct anv_pipeline
*pipeline
= cmd_buffer
->compute_pipeline
;
3351 struct anv_state surfaces
= { 0, }, samplers
= { 0, };
3354 result
= cmd_buffer_emit_samplers(cmd_buffer
,
3355 VK_SHADER_STAGE_COMPUTE
, &samplers
);
3356 if (result
!= VK_SUCCESS
)
3358 result
= cmd_buffer_emit_binding_table(cmd_buffer
,
3359 VK_SHADER_STAGE_COMPUTE
, &surfaces
);
3360 if (result
!= VK_SUCCESS
)
3363 struct GEN8_INTERFACE_DESCRIPTOR_DATA desc
= {
3364 .KernelStartPointer
= pipeline
->cs_simd
,
3365 .KernelStartPointerHigh
= 0,
3366 .BindingTablePointer
= surfaces
.offset
,
3367 .BindingTableEntryCount
= 0,
3368 .SamplerStatePointer
= samplers
.offset
,
3370 .NumberofThreadsinGPGPUThreadGroup
= 0 /* FIXME: Really? */
3373 uint32_t size
= GEN8_INTERFACE_DESCRIPTOR_DATA_length
* sizeof(uint32_t);
3374 struct anv_state state
=
3375 anv_state_pool_alloc(&device
->dynamic_state_pool
, size
, 64);
3377 GEN8_INTERFACE_DESCRIPTOR_DATA_pack(NULL
, state
.map
, &desc
);
3379 anv_batch_emit(&cmd_buffer
->batch
, GEN8_MEDIA_INTERFACE_DESCRIPTOR_LOAD
,
3380 .InterfaceDescriptorTotalLength
= size
,
3381 .InterfaceDescriptorDataStartAddress
= state
.offset
);
3387 anv_cmd_buffer_flush_compute_state(struct anv_cmd_buffer
*cmd_buffer
)
3389 struct anv_pipeline
*pipeline
= cmd_buffer
->compute_pipeline
;
3392 assert(pipeline
->active_stages
== VK_SHADER_STAGE_COMPUTE_BIT
);
3394 if (cmd_buffer
->current_pipeline
!= GPGPU
) {
3395 anv_batch_emit(&cmd_buffer
->batch
, GEN8_PIPELINE_SELECT
,
3396 .PipelineSelection
= GPGPU
);
3397 cmd_buffer
->current_pipeline
= GPGPU
;
3400 if (cmd_buffer
->compute_dirty
& ANV_CMD_BUFFER_PIPELINE_DIRTY
)
3401 anv_batch_emit_batch(&cmd_buffer
->batch
, &pipeline
->batch
);
3403 if ((cmd_buffer
->descriptors_dirty
& VK_SHADER_STAGE_COMPUTE_BIT
) ||
3404 (cmd_buffer
->compute_dirty
& ANV_CMD_BUFFER_PIPELINE_DIRTY
)) {
3405 result
= flush_compute_descriptor_set(cmd_buffer
);
3406 if (result
!= VK_SUCCESS
) {
3407 result
= anv_cmd_buffer_new_surface_state_bo(cmd_buffer
);
3408 assert(result
== VK_SUCCESS
);
3409 result
= flush_compute_descriptor_set(cmd_buffer
);
3410 assert(result
== VK_SUCCESS
);
3412 cmd_buffer
->descriptors_dirty
&= ~VK_SHADER_STAGE_COMPUTE
;
3415 cmd_buffer
->compute_dirty
= 0;
3419 anv_cmd_buffer_flush_state(struct anv_cmd_buffer
*cmd_buffer
)
3421 struct anv_pipeline
*pipeline
= cmd_buffer
->pipeline
;
3424 uint32_t vb_emit
= cmd_buffer
->vb_dirty
& pipeline
->vb_used
;
3426 assert((pipeline
->active_stages
& VK_SHADER_STAGE_COMPUTE_BIT
) == 0);
3428 if (cmd_buffer
->current_pipeline
!= _3D
) {
3429 anv_batch_emit(&cmd_buffer
->batch
, GEN8_PIPELINE_SELECT
,
3430 .PipelineSelection
= _3D
);
3431 cmd_buffer
->current_pipeline
= _3D
;
3435 const uint32_t num_buffers
= __builtin_popcount(vb_emit
);
3436 const uint32_t num_dwords
= 1 + num_buffers
* 4;
3438 p
= anv_batch_emitn(&cmd_buffer
->batch
, num_dwords
,
3439 GEN8_3DSTATE_VERTEX_BUFFERS
);
3441 for_each_bit(vb
, vb_emit
) {
3442 struct anv_buffer
*buffer
= cmd_buffer
->vertex_bindings
[vb
].buffer
;
3443 uint32_t offset
= cmd_buffer
->vertex_bindings
[vb
].offset
;
3445 struct GEN8_VERTEX_BUFFER_STATE state
= {
3446 .VertexBufferIndex
= vb
,
3447 .MemoryObjectControlState
= GEN8_MOCS
,
3448 .AddressModifyEnable
= true,
3449 .BufferPitch
= pipeline
->binding_stride
[vb
],
3450 .BufferStartingAddress
= { buffer
->bo
, buffer
->offset
+ offset
},
3451 .BufferSize
= buffer
->size
- offset
3454 GEN8_VERTEX_BUFFER_STATE_pack(&cmd_buffer
->batch
, &p
[1 + i
* 4], &state
);
3459 if (cmd_buffer
->dirty
& ANV_CMD_BUFFER_PIPELINE_DIRTY
) {
3460 /* If somebody compiled a pipeline after starting a command buffer the
3461 * scratch bo may have grown since we started this cmd buffer (and
3462 * emitted STATE_BASE_ADDRESS). If we're binding that pipeline now,
3463 * reemit STATE_BASE_ADDRESS so that we use the bigger scratch bo. */
3464 if (cmd_buffer
->scratch_size
< pipeline
->total_scratch
)
3465 anv_cmd_buffer_emit_state_base_address(cmd_buffer
);
3467 anv_batch_emit_batch(&cmd_buffer
->batch
, &pipeline
->batch
);
3470 if (cmd_buffer
->descriptors_dirty
)
3471 flush_descriptor_sets(cmd_buffer
);
3473 if (cmd_buffer
->dirty
& ANV_CMD_BUFFER_VP_DIRTY
) {
3474 anv_batch_emit(&cmd_buffer
->batch
, GEN8_3DSTATE_SCISSOR_STATE_POINTERS
,
3475 .ScissorRectPointer
= cmd_buffer
->vp_state
->scissor
.offset
);
3476 anv_batch_emit(&cmd_buffer
->batch
, GEN8_3DSTATE_VIEWPORT_STATE_POINTERS_CC
,
3477 .CCViewportPointer
= cmd_buffer
->vp_state
->cc_vp
.offset
);
3478 anv_batch_emit(&cmd_buffer
->batch
, GEN8_3DSTATE_VIEWPORT_STATE_POINTERS_SF_CLIP
,
3479 .SFClipViewportPointer
= cmd_buffer
->vp_state
->sf_clip_vp
.offset
);
3482 if (cmd_buffer
->dirty
& (ANV_CMD_BUFFER_PIPELINE_DIRTY
| ANV_CMD_BUFFER_RS_DIRTY
)) {
3483 anv_batch_emit_merge(&cmd_buffer
->batch
,
3484 cmd_buffer
->rs_state
->state_sf
, pipeline
->state_sf
);
3485 anv_batch_emit_merge(&cmd_buffer
->batch
,
3486 cmd_buffer
->rs_state
->state_raster
, pipeline
->state_raster
);
3489 if (cmd_buffer
->ds_state
&&
3490 (cmd_buffer
->dirty
& (ANV_CMD_BUFFER_PIPELINE_DIRTY
| ANV_CMD_BUFFER_DS_DIRTY
)))
3491 anv_batch_emit_merge(&cmd_buffer
->batch
,
3492 cmd_buffer
->ds_state
->state_wm_depth_stencil
,
3493 pipeline
->state_wm_depth_stencil
);
3495 if (cmd_buffer
->dirty
& (ANV_CMD_BUFFER_CB_DIRTY
| ANV_CMD_BUFFER_DS_DIRTY
)) {
3496 struct anv_state state
;
3497 if (cmd_buffer
->ds_state
== NULL
)
3498 state
= anv_cmd_buffer_emit_dynamic(cmd_buffer
,
3499 cmd_buffer
->cb_state
->state_color_calc
,
3500 GEN8_COLOR_CALC_STATE_length
, 64);
3501 else if (cmd_buffer
->cb_state
== NULL
)
3502 state
= anv_cmd_buffer_emit_dynamic(cmd_buffer
,
3503 cmd_buffer
->ds_state
->state_color_calc
,
3504 GEN8_COLOR_CALC_STATE_length
, 64);
3506 state
= anv_cmd_buffer_merge_dynamic(cmd_buffer
,
3507 cmd_buffer
->ds_state
->state_color_calc
,
3508 cmd_buffer
->cb_state
->state_color_calc
,
3509 GEN8_COLOR_CALC_STATE_length
, 64);
3511 anv_batch_emit(&cmd_buffer
->batch
,
3512 GEN8_3DSTATE_CC_STATE_POINTERS
,
3513 .ColorCalcStatePointer
= state
.offset
,
3514 .ColorCalcStatePointerValid
= true);
3517 if (cmd_buffer
->dirty
& (ANV_CMD_BUFFER_PIPELINE_DIRTY
| ANV_CMD_BUFFER_INDEX_BUFFER_DIRTY
)) {
3518 anv_batch_emit_merge(&cmd_buffer
->batch
,
3519 cmd_buffer
->state_vf
, pipeline
->state_vf
);
3522 cmd_buffer
->vb_dirty
&= ~vb_emit
;
3523 cmd_buffer
->dirty
= 0;
3527 VkCmdBuffer cmdBuffer
,
3528 uint32_t firstVertex
,
3529 uint32_t vertexCount
,
3530 uint32_t firstInstance
,
3531 uint32_t instanceCount
)
3533 ANV_FROM_HANDLE(anv_cmd_buffer
, cmd_buffer
, cmdBuffer
);
3535 anv_cmd_buffer_flush_state(cmd_buffer
);
3537 anv_batch_emit(&cmd_buffer
->batch
, GEN8_3DPRIMITIVE
,
3538 .VertexAccessType
= SEQUENTIAL
,
3539 .VertexCountPerInstance
= vertexCount
,
3540 .StartVertexLocation
= firstVertex
,
3541 .InstanceCount
= instanceCount
,
3542 .StartInstanceLocation
= firstInstance
,
3543 .BaseVertexLocation
= 0);
3546 void anv_CmdDrawIndexed(
3547 VkCmdBuffer cmdBuffer
,
3548 uint32_t firstIndex
,
3549 uint32_t indexCount
,
3550 int32_t vertexOffset
,
3551 uint32_t firstInstance
,
3552 uint32_t instanceCount
)
3554 ANV_FROM_HANDLE(anv_cmd_buffer
, cmd_buffer
, cmdBuffer
);
3556 anv_cmd_buffer_flush_state(cmd_buffer
);
3558 anv_batch_emit(&cmd_buffer
->batch
, GEN8_3DPRIMITIVE
,
3559 .VertexAccessType
= RANDOM
,
3560 .VertexCountPerInstance
= indexCount
,
3561 .StartVertexLocation
= firstIndex
,
3562 .InstanceCount
= instanceCount
,
3563 .StartInstanceLocation
= firstInstance
,
3564 .BaseVertexLocation
= vertexOffset
);
3568 anv_batch_lrm(struct anv_batch
*batch
,
3569 uint32_t reg
, struct anv_bo
*bo
, uint32_t offset
)
3571 anv_batch_emit(batch
, GEN8_MI_LOAD_REGISTER_MEM
,
3572 .RegisterAddress
= reg
,
3573 .MemoryAddress
= { bo
, offset
});
3577 anv_batch_lri(struct anv_batch
*batch
, uint32_t reg
, uint32_t imm
)
3579 anv_batch_emit(batch
, GEN8_MI_LOAD_REGISTER_IMM
,
3580 .RegisterOffset
= reg
,
3584 /* Auto-Draw / Indirect Registers */
3585 #define GEN7_3DPRIM_END_OFFSET 0x2420
3586 #define GEN7_3DPRIM_START_VERTEX 0x2430
3587 #define GEN7_3DPRIM_VERTEX_COUNT 0x2434
3588 #define GEN7_3DPRIM_INSTANCE_COUNT 0x2438
3589 #define GEN7_3DPRIM_START_INSTANCE 0x243C
3590 #define GEN7_3DPRIM_BASE_VERTEX 0x2440
3592 void anv_CmdDrawIndirect(
3593 VkCmdBuffer cmdBuffer
,
3595 VkDeviceSize offset
,
3599 ANV_FROM_HANDLE(anv_cmd_buffer
, cmd_buffer
, cmdBuffer
);
3600 ANV_FROM_HANDLE(anv_buffer
, buffer
, _buffer
);
3601 struct anv_bo
*bo
= buffer
->bo
;
3602 uint32_t bo_offset
= buffer
->offset
+ offset
;
3604 anv_cmd_buffer_flush_state(cmd_buffer
);
3606 anv_batch_lrm(&cmd_buffer
->batch
, GEN7_3DPRIM_VERTEX_COUNT
, bo
, bo_offset
);
3607 anv_batch_lrm(&cmd_buffer
->batch
, GEN7_3DPRIM_INSTANCE_COUNT
, bo
, bo_offset
+ 4);
3608 anv_batch_lrm(&cmd_buffer
->batch
, GEN7_3DPRIM_START_VERTEX
, bo
, bo_offset
+ 8);
3609 anv_batch_lrm(&cmd_buffer
->batch
, GEN7_3DPRIM_START_INSTANCE
, bo
, bo_offset
+ 12);
3610 anv_batch_lri(&cmd_buffer
->batch
, GEN7_3DPRIM_BASE_VERTEX
, 0);
3612 anv_batch_emit(&cmd_buffer
->batch
, GEN8_3DPRIMITIVE
,
3613 .IndirectParameterEnable
= true,
3614 .VertexAccessType
= SEQUENTIAL
);
3617 void anv_CmdDrawIndexedIndirect(
3618 VkCmdBuffer cmdBuffer
,
3620 VkDeviceSize offset
,
3624 ANV_FROM_HANDLE(anv_cmd_buffer
, cmd_buffer
, cmdBuffer
);
3625 ANV_FROM_HANDLE(anv_buffer
, buffer
, _buffer
);
3626 struct anv_bo
*bo
= buffer
->bo
;
3627 uint32_t bo_offset
= buffer
->offset
+ offset
;
3629 anv_cmd_buffer_flush_state(cmd_buffer
);
3631 anv_batch_lrm(&cmd_buffer
->batch
, GEN7_3DPRIM_VERTEX_COUNT
, bo
, bo_offset
);
3632 anv_batch_lrm(&cmd_buffer
->batch
, GEN7_3DPRIM_INSTANCE_COUNT
, bo
, bo_offset
+ 4);
3633 anv_batch_lrm(&cmd_buffer
->batch
, GEN7_3DPRIM_START_VERTEX
, bo
, bo_offset
+ 8);
3634 anv_batch_lrm(&cmd_buffer
->batch
, GEN7_3DPRIM_BASE_VERTEX
, bo
, bo_offset
+ 12);
3635 anv_batch_lrm(&cmd_buffer
->batch
, GEN7_3DPRIM_START_INSTANCE
, bo
, bo_offset
+ 16);
3637 anv_batch_emit(&cmd_buffer
->batch
, GEN8_3DPRIMITIVE
,
3638 .IndirectParameterEnable
= true,
3639 .VertexAccessType
= RANDOM
);
3642 void anv_CmdDispatch(
3643 VkCmdBuffer cmdBuffer
,
3648 ANV_FROM_HANDLE(anv_cmd_buffer
, cmd_buffer
, cmdBuffer
);
3649 struct anv_pipeline
*pipeline
= cmd_buffer
->compute_pipeline
;
3650 struct brw_cs_prog_data
*prog_data
= &pipeline
->cs_prog_data
;
3652 anv_cmd_buffer_flush_compute_state(cmd_buffer
);
3654 anv_batch_emit(&cmd_buffer
->batch
, GEN8_GPGPU_WALKER
,
3655 .SIMDSize
= prog_data
->simd_size
/ 16,
3656 .ThreadDepthCounterMaximum
= 0,
3657 .ThreadHeightCounterMaximum
= 0,
3658 .ThreadWidthCounterMaximum
= pipeline
->cs_thread_width_max
,
3659 .ThreadGroupIDXDimension
= x
,
3660 .ThreadGroupIDYDimension
= y
,
3661 .ThreadGroupIDZDimension
= z
,
3662 .RightExecutionMask
= pipeline
->cs_right_mask
,
3663 .BottomExecutionMask
= 0xffffffff);
3665 anv_batch_emit(&cmd_buffer
->batch
, GEN8_MEDIA_STATE_FLUSH
);
3668 #define GPGPU_DISPATCHDIMX 0x2500
3669 #define GPGPU_DISPATCHDIMY 0x2504
3670 #define GPGPU_DISPATCHDIMZ 0x2508
3672 void anv_CmdDispatchIndirect(
3673 VkCmdBuffer cmdBuffer
,
3675 VkDeviceSize offset
)
3677 ANV_FROM_HANDLE(anv_cmd_buffer
, cmd_buffer
, cmdBuffer
);
3678 ANV_FROM_HANDLE(anv_buffer
, buffer
, _buffer
);
3679 struct anv_pipeline
*pipeline
= cmd_buffer
->compute_pipeline
;
3680 struct brw_cs_prog_data
*prog_data
= &pipeline
->cs_prog_data
;
3681 struct anv_bo
*bo
= buffer
->bo
;
3682 uint32_t bo_offset
= buffer
->offset
+ offset
;
3684 anv_cmd_buffer_flush_compute_state(cmd_buffer
);
3686 anv_batch_lrm(&cmd_buffer
->batch
, GPGPU_DISPATCHDIMX
, bo
, bo_offset
);
3687 anv_batch_lrm(&cmd_buffer
->batch
, GPGPU_DISPATCHDIMY
, bo
, bo_offset
+ 4);
3688 anv_batch_lrm(&cmd_buffer
->batch
, GPGPU_DISPATCHDIMZ
, bo
, bo_offset
+ 8);
3690 anv_batch_emit(&cmd_buffer
->batch
, GEN8_GPGPU_WALKER
,
3691 .IndirectParameterEnable
= true,
3692 .SIMDSize
= prog_data
->simd_size
/ 16,
3693 .ThreadDepthCounterMaximum
= 0,
3694 .ThreadHeightCounterMaximum
= 0,
3695 .ThreadWidthCounterMaximum
= pipeline
->cs_thread_width_max
,
3696 .RightExecutionMask
= pipeline
->cs_right_mask
,
3697 .BottomExecutionMask
= 0xffffffff);
3699 anv_batch_emit(&cmd_buffer
->batch
, GEN8_MEDIA_STATE_FLUSH
);
3702 void anv_CmdSetEvent(
3703 VkCmdBuffer cmdBuffer
,
3705 VkPipeEvent pipeEvent
)
3710 void anv_CmdResetEvent(
3711 VkCmdBuffer cmdBuffer
,
3713 VkPipeEvent pipeEvent
)
3718 void anv_CmdWaitEvents(
3719 VkCmdBuffer cmdBuffer
,
3720 VkWaitEvent waitEvent
,
3721 uint32_t eventCount
,
3722 const VkEvent
* pEvents
,
3723 VkPipeEventFlags pipeEventMask
,
3724 uint32_t memBarrierCount
,
3725 const void* const* ppMemBarriers
)
3730 void anv_CmdPipelineBarrier(
3731 VkCmdBuffer cmdBuffer
,
3732 VkWaitEvent waitEvent
,
3733 VkPipeEventFlags pipeEventMask
,
3734 uint32_t memBarrierCount
,
3735 const void* const* ppMemBarriers
)
3737 ANV_FROM_HANDLE(anv_cmd_buffer
, cmd_buffer
, cmdBuffer
);
3740 struct GEN8_PIPE_CONTROL cmd
= {
3741 GEN8_PIPE_CONTROL_header
,
3742 .PostSyncOperation
= NoWrite
,
3745 /* XXX: I think waitEvent is a no-op on our HW. We should verify that. */
3747 if (anv_clear_mask(&pipeEventMask
, VK_PIPE_EVENT_TOP_OF_PIPE_BIT
)) {
3748 /* This is just what PIPE_CONTROL does */
3751 if (anv_clear_mask(&pipeEventMask
,
3752 VK_PIPE_EVENT_VERTEX_PROCESSING_COMPLETE_BIT
|
3753 VK_PIPE_EVENT_LOCAL_FRAGMENT_PROCESSING_COMPLETE_BIT
|
3754 VK_PIPE_EVENT_FRAGMENT_PROCESSING_COMPLETE_BIT
)) {
3755 cmd
.StallAtPixelScoreboard
= true;
3759 if (anv_clear_mask(&pipeEventMask
,
3760 VK_PIPE_EVENT_GRAPHICS_PIPELINE_COMPLETE_BIT
|
3761 VK_PIPE_EVENT_COMPUTE_PIPELINE_COMPLETE_BIT
|
3762 VK_PIPE_EVENT_TRANSFER_COMPLETE_BIT
|
3763 VK_PIPE_EVENT_COMMANDS_COMPLETE_BIT
)) {
3764 cmd
.CommandStreamerStallEnable
= true;
3767 if (anv_clear_mask(&pipeEventMask
, VK_PIPE_EVENT_CPU_SIGNAL_BIT
)) {
3768 anv_finishme("VK_PIPE_EVENT_CPU_SIGNAL_BIT");
3771 /* We checked all known VkPipeEventFlags. */
3772 anv_assert(pipeEventMask
== 0);
3774 /* XXX: Right now, we're really dumb and just flush whatever categories
3775 * the app asks for. One of these days we may make this a bit better
3776 * but right now that's all the hardware allows for in most areas.
3778 VkMemoryOutputFlags out_flags
= 0;
3779 VkMemoryInputFlags in_flags
= 0;
3781 for (uint32_t i
= 0; i
< memBarrierCount
; i
++) {
3782 const struct anv_common
*common
= ppMemBarriers
[i
];
3783 switch (common
->sType
) {
3784 case VK_STRUCTURE_TYPE_MEMORY_BARRIER
: {
3785 const VkMemoryBarrier
*barrier
= (VkMemoryBarrier
*)common
;
3786 out_flags
|= barrier
->outputMask
;
3787 in_flags
|= barrier
->inputMask
;
3790 case VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER
: {
3791 const VkBufferMemoryBarrier
*barrier
= (VkBufferMemoryBarrier
*)common
;
3792 out_flags
|= barrier
->outputMask
;
3793 in_flags
|= barrier
->inputMask
;
3796 case VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER
: {
3797 const VkImageMemoryBarrier
*barrier
= (VkImageMemoryBarrier
*)common
;
3798 out_flags
|= barrier
->outputMask
;
3799 in_flags
|= barrier
->inputMask
;
3803 unreachable("Invalid memory barrier type");
3807 for_each_bit(b
, out_flags
) {
3808 switch ((VkMemoryOutputFlags
)(1 << b
)) {
3809 case VK_MEMORY_OUTPUT_HOST_WRITE_BIT
:
3810 break; /* FIXME: Little-core systems */
3811 case VK_MEMORY_OUTPUT_SHADER_WRITE_BIT
:
3812 cmd
.DCFlushEnable
= true;
3814 case VK_MEMORY_OUTPUT_COLOR_ATTACHMENT_BIT
:
3815 cmd
.RenderTargetCacheFlushEnable
= true;
3817 case VK_MEMORY_OUTPUT_DEPTH_STENCIL_ATTACHMENT_BIT
:
3818 cmd
.DepthCacheFlushEnable
= true;
3820 case VK_MEMORY_OUTPUT_TRANSFER_BIT
:
3821 cmd
.RenderTargetCacheFlushEnable
= true;
3822 cmd
.DepthCacheFlushEnable
= true;
3825 unreachable("Invalid memory output flag");
3829 for_each_bit(b
, out_flags
) {
3830 switch ((VkMemoryInputFlags
)(1 << b
)) {
3831 case VK_MEMORY_INPUT_HOST_READ_BIT
:
3832 break; /* FIXME: Little-core systems */
3833 case VK_MEMORY_INPUT_INDIRECT_COMMAND_BIT
:
3834 case VK_MEMORY_INPUT_INDEX_FETCH_BIT
:
3835 case VK_MEMORY_INPUT_VERTEX_ATTRIBUTE_FETCH_BIT
:
3836 cmd
.VFCacheInvalidationEnable
= true;
3838 case VK_MEMORY_INPUT_UNIFORM_READ_BIT
:
3839 cmd
.ConstantCacheInvalidationEnable
= true;
3841 case VK_MEMORY_INPUT_SHADER_READ_BIT
:
3842 cmd
.DCFlushEnable
= true;
3843 cmd
.TextureCacheInvalidationEnable
= true;
3845 case VK_MEMORY_INPUT_COLOR_ATTACHMENT_BIT
:
3846 case VK_MEMORY_INPUT_DEPTH_STENCIL_ATTACHMENT_BIT
:
3847 break; /* XXX: Hunh? */
3848 case VK_MEMORY_INPUT_TRANSFER_BIT
:
3849 cmd
.TextureCacheInvalidationEnable
= true;
3854 dw
= anv_batch_emit_dwords(&cmd_buffer
->batch
, GEN8_PIPE_CONTROL_length
);
3855 GEN8_PIPE_CONTROL_pack(&cmd_buffer
->batch
, dw
, &cmd
);
3859 anv_framebuffer_destroy(struct anv_device
*device
,
3860 struct anv_object
*object
,
3861 VkObjectType obj_type
)
3863 struct anv_framebuffer
*fb
= (struct anv_framebuffer
*)object
;
3865 assert(obj_type
== VK_OBJECT_TYPE_FRAMEBUFFER
);
3867 anv_DestroyFramebuffer(anv_device_to_handle(device
),
3868 anv_framebuffer_to_handle(fb
));
3871 VkResult
anv_CreateFramebuffer(
3873 const VkFramebufferCreateInfo
* pCreateInfo
,
3874 VkFramebuffer
* pFramebuffer
)
3876 ANV_FROM_HANDLE(anv_device
, device
, _device
);
3877 struct anv_framebuffer
*framebuffer
;
3879 assert(pCreateInfo
->sType
== VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO
);
3881 size_t size
= sizeof(*framebuffer
) +
3882 sizeof(struct anv_attachment_view
*) * pCreateInfo
->attachmentCount
;
3883 framebuffer
= anv_device_alloc(device
, size
, 8,
3884 VK_SYSTEM_ALLOC_TYPE_API_OBJECT
);
3885 if (framebuffer
== NULL
)
3886 return vk_error(VK_ERROR_OUT_OF_HOST_MEMORY
);
3888 framebuffer
->base
.destructor
= anv_framebuffer_destroy
;
3890 framebuffer
->attachment_count
= pCreateInfo
->attachmentCount
;
3891 for (uint32_t i
= 0; i
< pCreateInfo
->attachmentCount
; i
++) {
3892 ANV_FROM_HANDLE(anv_attachment_view
, view
,
3893 pCreateInfo
->pAttachments
[i
].view
);
3895 framebuffer
->attachments
[i
] = view
;
3898 framebuffer
->width
= pCreateInfo
->width
;
3899 framebuffer
->height
= pCreateInfo
->height
;
3900 framebuffer
->layers
= pCreateInfo
->layers
;
3902 anv_CreateDynamicViewportState(anv_device_to_handle(device
),
3903 &(VkDynamicViewportStateCreateInfo
) {
3904 .sType
= VK_STRUCTURE_TYPE_DYNAMIC_VP_STATE_CREATE_INFO
,
3905 .viewportAndScissorCount
= 1,
3906 .pViewports
= (VkViewport
[]) {
3910 .width
= pCreateInfo
->width
,
3911 .height
= pCreateInfo
->height
,
3916 .pScissors
= (VkRect2D
[]) {
3918 { pCreateInfo
->width
, pCreateInfo
->height
} },
3921 &framebuffer
->vp_state
);
3923 *pFramebuffer
= anv_framebuffer_to_handle(framebuffer
);
3928 VkResult
anv_DestroyFramebuffer(
3932 ANV_FROM_HANDLE(anv_device
, device
, _device
);
3933 ANV_FROM_HANDLE(anv_framebuffer
, fb
, _fb
);
3935 anv_DestroyDynamicViewportState(anv_device_to_handle(device
),
3937 anv_device_free(device
, fb
);
3942 VkResult
anv_CreateRenderPass(
3944 const VkRenderPassCreateInfo
* pCreateInfo
,
3945 VkRenderPass
* pRenderPass
)
3947 ANV_FROM_HANDLE(anv_device
, device
, _device
);
3948 struct anv_render_pass
*pass
;
3951 assert(pCreateInfo
->sType
== VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO
);
3953 size
= sizeof(*pass
) +
3954 pCreateInfo
->subpassCount
* sizeof(struct anv_subpass
);
3955 pass
= anv_device_alloc(device
, size
, 8,
3956 VK_SYSTEM_ALLOC_TYPE_API_OBJECT
);
3958 return vk_error(VK_ERROR_OUT_OF_HOST_MEMORY
);
3960 pass
->attachment_count
= pCreateInfo
->attachmentCount
;
3961 size
= pCreateInfo
->attachmentCount
* sizeof(*pass
->attachments
);
3962 pass
->attachments
= anv_device_alloc(device
, size
, 8,
3963 VK_SYSTEM_ALLOC_TYPE_API_OBJECT
);
3964 for (uint32_t i
= 0; i
< pCreateInfo
->attachmentCount
; i
++) {
3965 pass
->attachments
[i
].format
= pCreateInfo
->pAttachments
[i
].format
;
3966 pass
->attachments
[i
].samples
= pCreateInfo
->pAttachments
[i
].samples
;
3967 pass
->attachments
[i
].load_op
= pCreateInfo
->pAttachments
[i
].loadOp
;
3968 pass
->attachments
[i
].stencil_load_op
= pCreateInfo
->pAttachments
[i
].stencilLoadOp
;
3969 // pass->attachments[i].store_op = pCreateInfo->pAttachments[i].storeOp;
3970 // pass->attachments[i].stencil_store_op = pCreateInfo->pAttachments[i].stencilStoreOp;
3973 for (uint32_t i
= 0; i
< pCreateInfo
->subpassCount
; i
++) {
3974 const VkSubpassDescription
*desc
= &pCreateInfo
->pSubpasses
[i
];
3975 struct anv_subpass
*subpass
= &pass
->subpasses
[i
];
3977 subpass
->input_count
= desc
->inputCount
;
3978 subpass
->input_attachments
=
3979 anv_device_alloc(device
, desc
->inputCount
* sizeof(uint32_t),
3980 8, VK_SYSTEM_ALLOC_TYPE_API_OBJECT
);
3981 for (uint32_t j
= 0; j
< desc
->inputCount
; j
++)
3982 subpass
->input_attachments
[j
] = desc
->inputAttachments
[j
].attachment
;
3984 subpass
->color_count
= desc
->colorCount
;
3985 subpass
->color_attachments
=
3986 anv_device_alloc(device
, desc
->colorCount
* sizeof(uint32_t),
3987 8, VK_SYSTEM_ALLOC_TYPE_API_OBJECT
);
3988 for (uint32_t j
= 0; j
< desc
->colorCount
; j
++)
3989 subpass
->color_attachments
[j
] = desc
->colorAttachments
[j
].attachment
;
3991 if (desc
->resolveAttachments
) {
3992 subpass
->resolve_attachments
=
3993 anv_device_alloc(device
, desc
->colorCount
* sizeof(uint32_t),
3994 8, VK_SYSTEM_ALLOC_TYPE_API_OBJECT
);
3995 for (uint32_t j
= 0; j
< desc
->colorCount
; j
++)
3996 subpass
->resolve_attachments
[j
] = desc
->resolveAttachments
[j
].attachment
;
3999 subpass
->depth_stencil_attachment
= desc
->depthStencilAttachment
.attachment
;
4002 *pRenderPass
= anv_render_pass_to_handle(pass
);
4007 VkResult
anv_DestroyRenderPass(
4011 ANV_FROM_HANDLE(anv_device
, device
, _device
);
4012 ANV_FROM_HANDLE(anv_render_pass
, pass
, _pass
);
4014 anv_device_free(device
, pass
->attachments
);
4016 for (uint32_t i
= 0; i
< pass
->attachment_count
; i
++) {
4017 anv_device_free(device
, pass
->subpasses
[i
].input_attachments
);
4018 anv_device_free(device
, pass
->subpasses
[i
].color_attachments
);
4019 anv_device_free(device
, pass
->subpasses
[i
].resolve_attachments
);
4022 anv_device_free(device
, pass
);
4027 VkResult
anv_GetRenderAreaGranularity(
4029 VkRenderPass renderPass
,
4030 VkExtent2D
* pGranularity
)
4032 *pGranularity
= (VkExtent2D
) { 1, 1 };
4038 anv_cmd_buffer_emit_depth_stencil(struct anv_cmd_buffer
*cmd_buffer
)
4040 struct anv_subpass
*subpass
= cmd_buffer
->subpass
;
4041 struct anv_framebuffer
*fb
= cmd_buffer
->framebuffer
;
4042 const struct anv_depth_stencil_view
*view
;
4044 static const struct anv_depth_stencil_view null_view
=
4045 { .depth_format
= D16_UNORM
, .depth_stride
= 0, .stencil_stride
= 0 };
4047 if (subpass
->depth_stencil_attachment
!= VK_ATTACHMENT_UNUSED
) {
4048 const struct anv_attachment_view
*aview
=
4049 fb
->attachments
[subpass
->depth_stencil_attachment
];
4050 assert(aview
->attachment_type
== ANV_ATTACHMENT_VIEW_TYPE_DEPTH_STENCIL
);
4051 view
= (const struct anv_depth_stencil_view
*)aview
;
4056 /* FIXME: Implement the PMA stall W/A */
4057 /* FIXME: Width and Height are wrong */
4059 anv_batch_emit(&cmd_buffer
->batch
, GEN8_3DSTATE_DEPTH_BUFFER
,
4060 .SurfaceType
= SURFTYPE_2D
,
4061 .DepthWriteEnable
= view
->depth_stride
> 0,
4062 .StencilWriteEnable
= view
->stencil_stride
> 0,
4063 .HierarchicalDepthBufferEnable
= false,
4064 .SurfaceFormat
= view
->depth_format
,
4065 .SurfacePitch
= view
->depth_stride
> 0 ? view
->depth_stride
- 1 : 0,
4066 .SurfaceBaseAddress
= { view
->bo
, view
->depth_offset
},
4067 .Height
= cmd_buffer
->framebuffer
->height
- 1,
4068 .Width
= cmd_buffer
->framebuffer
->width
- 1,
4071 .MinimumArrayElement
= 0,
4072 .DepthBufferObjectControlState
= GEN8_MOCS
,
4073 .RenderTargetViewExtent
= 1 - 1,
4074 .SurfaceQPitch
= view
->depth_qpitch
>> 2);
4076 /* Disable hierarchial depth buffers. */
4077 anv_batch_emit(&cmd_buffer
->batch
, GEN8_3DSTATE_HIER_DEPTH_BUFFER
);
4079 anv_batch_emit(&cmd_buffer
->batch
, GEN8_3DSTATE_STENCIL_BUFFER
,
4080 .StencilBufferEnable
= view
->stencil_stride
> 0,
4081 .StencilBufferObjectControlState
= GEN8_MOCS
,
4082 .SurfacePitch
= view
->stencil_stride
> 0 ? view
->stencil_stride
- 1 : 0,
4083 .SurfaceBaseAddress
= { view
->bo
, view
->stencil_offset
},
4084 .SurfaceQPitch
= view
->stencil_qpitch
>> 2);
4086 /* Clear the clear params. */
4087 anv_batch_emit(&cmd_buffer
->batch
, GEN8_3DSTATE_CLEAR_PARAMS
);
4090 void anv_CmdPushConstants(
4091 VkCmdBuffer cmdBuffer
,
4092 VkPipelineLayout layout
,
4093 VkShaderStageFlags stageFlags
,
4102 anv_cmd_buffer_begin_subpass(struct anv_cmd_buffer
*cmd_buffer
,
4103 struct anv_subpass
*subpass
)
4105 cmd_buffer
->subpass
= subpass
;
4107 cmd_buffer
->descriptors_dirty
|= VK_SHADER_STAGE_FRAGMENT_BIT
;
4109 anv_cmd_buffer_emit_depth_stencil(cmd_buffer
);
4112 void anv_CmdBeginRenderPass(
4113 VkCmdBuffer cmdBuffer
,
4114 const VkRenderPassBeginInfo
* pRenderPassBegin
,
4115 VkRenderPassContents contents
)
4117 ANV_FROM_HANDLE(anv_cmd_buffer
, cmd_buffer
, cmdBuffer
);
4118 ANV_FROM_HANDLE(anv_render_pass
, pass
, pRenderPassBegin
->renderPass
);
4119 ANV_FROM_HANDLE(anv_framebuffer
, framebuffer
, pRenderPassBegin
->framebuffer
);
4121 assert(contents
== VK_RENDER_PASS_CONTENTS_INLINE
);
4123 cmd_buffer
->framebuffer
= framebuffer
;
4124 cmd_buffer
->pass
= pass
;
4126 const VkRect2D
*render_area
= &pRenderPassBegin
->renderArea
;
4128 anv_batch_emit(&cmd_buffer
->batch
, GEN8_3DSTATE_DRAWING_RECTANGLE
,
4129 .ClippedDrawingRectangleYMin
= render_area
->offset
.y
,
4130 .ClippedDrawingRectangleXMin
= render_area
->offset
.x
,
4131 .ClippedDrawingRectangleYMax
=
4132 render_area
->offset
.y
+ render_area
->extent
.height
- 1,
4133 .ClippedDrawingRectangleXMax
=
4134 render_area
->offset
.x
+ render_area
->extent
.width
- 1,
4135 .DrawingRectangleOriginY
= 0,
4136 .DrawingRectangleOriginX
= 0);
4138 anv_cmd_buffer_clear_attachments(cmd_buffer
, pass
,
4139 pRenderPassBegin
->pAttachmentClearValues
);
4141 anv_cmd_buffer_begin_subpass(cmd_buffer
, pass
->subpasses
);
4144 void anv_CmdNextSubpass(
4145 VkCmdBuffer cmdBuffer
,
4146 VkRenderPassContents contents
)
4148 ANV_FROM_HANDLE(anv_cmd_buffer
, cmd_buffer
, cmdBuffer
);
4150 assert(contents
== VK_RENDER_PASS_CONTENTS_INLINE
);
4152 cmd_buffer
->subpass
++;
4153 anv_cmd_buffer_begin_subpass(cmd_buffer
, cmd_buffer
->subpass
+ 1);
4156 void anv_CmdEndRenderPass(
4157 VkCmdBuffer cmdBuffer
)
4159 ANV_FROM_HANDLE(anv_cmd_buffer
, cmd_buffer
, cmdBuffer
);
4161 /* Emit a flushing pipe control at the end of a pass. This is kind of a
4162 * hack but it ensures that render targets always actually get written.
4163 * Eventually, we should do flushing based on image format transitions
4164 * or something of that nature.
4166 anv_batch_emit(&cmd_buffer
->batch
, GEN8_PIPE_CONTROL
,
4167 .PostSyncOperation
= NoWrite
,
4168 .RenderTargetCacheFlushEnable
= true,
4169 .InstructionCacheInvalidateEnable
= true,
4170 .DepthCacheFlushEnable
= true,
4171 .VFCacheInvalidationEnable
= true,
4172 .TextureCacheInvalidationEnable
= true,
4173 .CommandStreamerStallEnable
= true);
4176 void anv_CmdExecuteCommands(
4177 VkCmdBuffer cmdBuffer
,
4178 uint32_t cmdBuffersCount
,
4179 const VkCmdBuffer
* pCmdBuffers
)
4184 void vkCmdDbgMarkerBegin(
4185 VkCmdBuffer cmdBuffer
,
4186 const char* pMarker
)
4187 __attribute__ ((visibility ("default")));
4189 void vkCmdDbgMarkerEnd(
4190 VkCmdBuffer cmdBuffer
)
4191 __attribute__ ((visibility ("default")));
4193 VkResult
vkDbgSetObjectTag(
4198 __attribute__ ((visibility ("default")));
4201 void vkCmdDbgMarkerBegin(
4202 VkCmdBuffer cmdBuffer
,
4203 const char* pMarker
)
4207 void vkCmdDbgMarkerEnd(
4208 VkCmdBuffer cmdBuffer
)
4212 VkResult
vkDbgSetObjectTag(