anv/device: Update features and limits
[mesa.git] / src / vulkan / anv_device.c
1 /*
2 * Copyright © 2015 Intel Corporation
3 *
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:
10 *
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
13 * Software.
14 *
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
21 * IN THE SOFTWARE.
22 */
23
24 #include <assert.h>
25 #include <stdbool.h>
26 #include <string.h>
27 #include <unistd.h>
28 #include <fcntl.h>
29
30 #include "anv_private.h"
31 #include "mesa/main/git_sha1.h"
32 #include "util/strtod.h"
33
34 #include "gen7_pack.h"
35
36 struct anv_dispatch_table dtable;
37
38 static void
39 compiler_debug_log(void *data, const char *fmt, ...)
40 { }
41
42 static void
43 compiler_perf_log(void *data, const char *fmt, ...)
44 {
45 va_list args;
46 va_start(args, fmt);
47
48 if (unlikely(INTEL_DEBUG & DEBUG_PERF))
49 vfprintf(stderr, fmt, args);
50
51 va_end(args);
52 }
53
54 static VkResult
55 anv_physical_device_init(struct anv_physical_device *device,
56 struct anv_instance *instance,
57 const char *path)
58 {
59 VkResult result;
60 int fd;
61
62 fd = open(path, O_RDWR | O_CLOEXEC);
63 if (fd < 0)
64 return vk_errorf(VK_ERROR_INITIALIZATION_FAILED,
65 "failed to open %s: %m", path);
66
67 device->_loader_data.loaderMagic = ICD_LOADER_MAGIC;
68 device->instance = instance;
69 device->path = path;
70
71 device->chipset_id = anv_gem_get_param(fd, I915_PARAM_CHIPSET_ID);
72 if (!device->chipset_id) {
73 result = vk_errorf(VK_ERROR_INITIALIZATION_FAILED,
74 "failed to get chipset id: %m");
75 goto fail;
76 }
77
78 device->name = brw_get_device_name(device->chipset_id);
79 device->info = brw_get_device_info(device->chipset_id);
80 if (!device->info) {
81 result = vk_errorf(VK_ERROR_INITIALIZATION_FAILED,
82 "failed to get device info");
83 goto fail;
84 }
85
86 if (device->info->is_haswell) {
87 fprintf(stderr, "WARNING: Haswell Vulkan support is incomplete\n");
88 } else if (device->info->gen == 7 && !device->info->is_baytrail) {
89 fprintf(stderr, "WARNING: Ivy Bridge Vulkan support is incomplete\n");
90 } else if (device->info->gen == 7 && device->info->is_baytrail) {
91 fprintf(stderr, "WARNING: Bay Trail Vulkan support is incomplete\n");
92 } else if (device->info->gen >= 8) {
93 /* Broadwell, Cherryview, Skylake, Broxton, Kabylake is as fully
94 * supported as anything */
95 } else {
96 result = vk_errorf(VK_ERROR_INCOMPATIBLE_DRIVER,
97 "Vulkan not yet supported on %s", device->name);
98 goto fail;
99 }
100
101 if (anv_gem_get_aperture(fd, &device->aperture_size) == -1) {
102 result = vk_errorf(VK_ERROR_INITIALIZATION_FAILED,
103 "failed to get aperture size: %m");
104 goto fail;
105 }
106
107 if (!anv_gem_get_param(fd, I915_PARAM_HAS_WAIT_TIMEOUT)) {
108 result = vk_errorf(VK_ERROR_INITIALIZATION_FAILED,
109 "kernel missing gem wait");
110 goto fail;
111 }
112
113 if (!anv_gem_get_param(fd, I915_PARAM_HAS_EXECBUF2)) {
114 result = vk_errorf(VK_ERROR_INITIALIZATION_FAILED,
115 "kernel missing execbuf2");
116 goto fail;
117 }
118
119 if (!device->info->has_llc &&
120 anv_gem_get_param(fd, I915_PARAM_MMAP_VERSION) < 1) {
121 result = vk_errorf(VK_ERROR_INITIALIZATION_FAILED,
122 "kernel missing wc mmap");
123 goto fail;
124 }
125
126 close(fd);
127
128 brw_process_intel_debug_variable();
129
130 device->compiler = brw_compiler_create(NULL, device->info);
131 if (device->compiler == NULL) {
132 result = vk_error(VK_ERROR_OUT_OF_HOST_MEMORY);
133 goto fail;
134 }
135 device->compiler->shader_debug_log = compiler_debug_log;
136 device->compiler->shader_perf_log = compiler_perf_log;
137
138 isl_device_init(&device->isl_dev, device->info);
139
140 return VK_SUCCESS;
141
142 fail:
143 close(fd);
144 return result;
145 }
146
147 static void
148 anv_physical_device_finish(struct anv_physical_device *device)
149 {
150 ralloc_free(device->compiler);
151 }
152
153 static const VkExtensionProperties global_extensions[] = {
154 {
155 .extensionName = VK_KHR_SURFACE_EXTENSION_NAME,
156 .specVersion = 24,
157 },
158 {
159 .extensionName = VK_KHR_XCB_SURFACE_EXTENSION_NAME,
160 .specVersion = 5,
161 },
162 #ifdef HAVE_WAYLAND_PLATFORM
163 {
164 .extensionName = VK_KHR_WAYLAND_SURFACE_EXTENSION_NAME,
165 .specVersion = 4,
166 },
167 #endif
168 };
169
170 static const VkExtensionProperties device_extensions[] = {
171 {
172 .extensionName = VK_KHR_SWAPCHAIN_EXTENSION_NAME,
173 .specVersion = 67,
174 },
175 };
176
177 static void *
178 default_alloc_func(void *pUserData, size_t size, size_t align,
179 VkSystemAllocationScope allocationScope)
180 {
181 return malloc(size);
182 }
183
184 static void *
185 default_realloc_func(void *pUserData, void *pOriginal, size_t size,
186 size_t align, VkSystemAllocationScope allocationScope)
187 {
188 return realloc(pOriginal, size);
189 }
190
191 static void
192 default_free_func(void *pUserData, void *pMemory)
193 {
194 free(pMemory);
195 }
196
197 static const VkAllocationCallbacks default_alloc = {
198 .pUserData = NULL,
199 .pfnAllocation = default_alloc_func,
200 .pfnReallocation = default_realloc_func,
201 .pfnFree = default_free_func,
202 };
203
204 VkResult anv_CreateInstance(
205 const VkInstanceCreateInfo* pCreateInfo,
206 const VkAllocationCallbacks* pAllocator,
207 VkInstance* pInstance)
208 {
209 struct anv_instance *instance;
210
211 assert(pCreateInfo->sType == VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO);
212
213 if (pCreateInfo->pApplicationInfo->apiVersion != VK_MAKE_VERSION(0, 210, 1))
214 return vk_error(VK_ERROR_INCOMPATIBLE_DRIVER);
215
216 for (uint32_t i = 0; i < pCreateInfo->enabledExtensionNameCount; i++) {
217 bool found = false;
218 for (uint32_t j = 0; j < ARRAY_SIZE(global_extensions); j++) {
219 if (strcmp(pCreateInfo->ppEnabledExtensionNames[i],
220 global_extensions[j].extensionName) == 0) {
221 found = true;
222 break;
223 }
224 }
225 if (!found)
226 return vk_error(VK_ERROR_EXTENSION_NOT_PRESENT);
227 }
228
229 instance = anv_alloc2(&default_alloc, pAllocator, sizeof(*instance), 8,
230 VK_SYSTEM_ALLOCATION_SCOPE_OBJECT);
231 if (!instance)
232 return vk_error(VK_ERROR_OUT_OF_HOST_MEMORY);
233
234 instance->_loader_data.loaderMagic = ICD_LOADER_MAGIC;
235
236 if (pAllocator)
237 instance->alloc = *pAllocator;
238 else
239 instance->alloc = default_alloc;
240
241 instance->apiVersion = pCreateInfo->pApplicationInfo->apiVersion;
242 instance->physicalDeviceCount = -1;
243
244 _mesa_locale_init();
245
246 VG(VALGRIND_CREATE_MEMPOOL(instance, 0, false));
247
248 anv_init_wsi(instance);
249
250 *pInstance = anv_instance_to_handle(instance);
251
252 return VK_SUCCESS;
253 }
254
255 void anv_DestroyInstance(
256 VkInstance _instance,
257 const VkAllocationCallbacks* pAllocator)
258 {
259 ANV_FROM_HANDLE(anv_instance, instance, _instance);
260
261 if (instance->physicalDeviceCount > 0) {
262 /* We support at most one physical device. */
263 assert(instance->physicalDeviceCount == 1);
264 anv_physical_device_finish(&instance->physicalDevice);
265 }
266
267 anv_finish_wsi(instance);
268
269 VG(VALGRIND_DESTROY_MEMPOOL(instance));
270
271 _mesa_locale_fini();
272
273 anv_free(&instance->alloc, instance);
274 }
275
276 VkResult anv_EnumeratePhysicalDevices(
277 VkInstance _instance,
278 uint32_t* pPhysicalDeviceCount,
279 VkPhysicalDevice* pPhysicalDevices)
280 {
281 ANV_FROM_HANDLE(anv_instance, instance, _instance);
282 VkResult result;
283
284 if (instance->physicalDeviceCount < 0) {
285 result = anv_physical_device_init(&instance->physicalDevice,
286 instance, "/dev/dri/renderD128");
287 if (result == VK_ERROR_INCOMPATIBLE_DRIVER) {
288 instance->physicalDeviceCount = 0;
289 } else if (result == VK_SUCCESS) {
290 instance->physicalDeviceCount = 1;
291 } else {
292 return result;
293 }
294 }
295
296 /* pPhysicalDeviceCount is an out parameter if pPhysicalDevices is NULL;
297 * otherwise it's an inout parameter.
298 *
299 * The Vulkan spec (git aaed022) says:
300 *
301 * pPhysicalDeviceCount is a pointer to an unsigned integer variable
302 * that is initialized with the number of devices the application is
303 * prepared to receive handles to. pname:pPhysicalDevices is pointer to
304 * an array of at least this many VkPhysicalDevice handles [...].
305 *
306 * Upon success, if pPhysicalDevices is NULL, vkEnumeratePhysicalDevices
307 * overwrites the contents of the variable pointed to by
308 * pPhysicalDeviceCount with the number of physical devices in in the
309 * instance; otherwise, vkEnumeratePhysicalDevices overwrites
310 * pPhysicalDeviceCount with the number of physical handles written to
311 * pPhysicalDevices.
312 */
313 if (!pPhysicalDevices) {
314 *pPhysicalDeviceCount = instance->physicalDeviceCount;
315 } else if (*pPhysicalDeviceCount >= 1) {
316 pPhysicalDevices[0] = anv_physical_device_to_handle(&instance->physicalDevice);
317 *pPhysicalDeviceCount = 1;
318 } else {
319 *pPhysicalDeviceCount = 0;
320 }
321
322 return VK_SUCCESS;
323 }
324
325 void anv_GetPhysicalDeviceFeatures(
326 VkPhysicalDevice physicalDevice,
327 VkPhysicalDeviceFeatures* pFeatures)
328 {
329 anv_finishme("Get correct values for PhysicalDeviceFeatures");
330
331 *pFeatures = (VkPhysicalDeviceFeatures) {
332 .robustBufferAccess = false,
333 .fullDrawIndexUint32 = false,
334 .imageCubeArray = false,
335 .independentBlend = false,
336 .geometryShader = true,
337 .tessellationShader = false,
338 .sampleRateShading = false,
339 .dualSrcBlend = true,
340 .logicOp = true,
341 .multiDrawIndirect = false,
342 .drawIndirectFirstInstance = false,
343 .depthClamp = false,
344 .depthBiasClamp = false,
345 .fillModeNonSolid = true,
346 .depthBounds = false,
347 .wideLines = true,
348 .largePoints = true,
349 .alphaToOne = true,
350 .multiViewport = true,
351 .samplerAnisotropy = false, /* FINISHME */
352 .textureCompressionETC2 = true,
353 .textureCompressionASTC_LDR = true,
354 .textureCompressionBC = true,
355 .occlusionQueryPrecise = false, /* FINISHME */
356 .pipelineStatisticsQuery = true,
357 .vertexPipelineStoresAndAtomics = false,
358 .fragmentStoresAndAtomics = true,
359 .shaderTessellationAndGeometryPointSize = true,
360 .shaderImageGatherExtended = true,
361 .shaderStorageImageExtendedFormats = false,
362 .shaderStorageImageMultisample = false,
363 .shaderUniformBufferArrayDynamicIndexing = true,
364 .shaderSampledImageArrayDynamicIndexing = false,
365 .shaderStorageBufferArrayDynamicIndexing = false,
366 .shaderStorageImageArrayDynamicIndexing = false,
367 .shaderStorageImageReadWithoutFormat = false,
368 .shaderStorageImageWriteWithoutFormat = true,
369 .shaderClipDistance = false,
370 .shaderCullDistance = false,
371 .shaderFloat64 = false,
372 .shaderInt64 = false,
373 .shaderInt16 = false,
374 .alphaToOne = true,
375 .variableMultisampleRate = false,
376 .inheritedQueries = false,
377 };
378 }
379
380 void anv_GetPhysicalDeviceProperties(
381 VkPhysicalDevice physicalDevice,
382 VkPhysicalDeviceProperties* pProperties)
383 {
384 ANV_FROM_HANDLE(anv_physical_device, pdevice, physicalDevice);
385 const struct brw_device_info *devinfo = pdevice->info;
386
387 anv_finishme("Get correct values for VkPhysicalDeviceLimits");
388
389 const float time_stamp_base = devinfo->gen >= 9 ? 83.333 : 80.0;
390
391 VkSampleCountFlags sample_counts =
392 VK_SAMPLE_COUNT_1_BIT |
393 VK_SAMPLE_COUNT_2_BIT |
394 VK_SAMPLE_COUNT_4_BIT |
395 VK_SAMPLE_COUNT_8_BIT;
396
397 VkPhysicalDeviceLimits limits = {
398 .maxImageDimension1D = (1 << 14),
399 .maxImageDimension2D = (1 << 14),
400 .maxImageDimension3D = (1 << 10),
401 .maxImageDimensionCube = (1 << 14),
402 .maxImageArrayLayers = (1 << 10),
403 .maxTexelBufferElements = (1 << 14),
404 .maxUniformBufferRange = UINT32_MAX,
405 .maxStorageBufferRange = UINT32_MAX,
406 .maxPushConstantsSize = MAX_PUSH_CONSTANTS_SIZE,
407 .maxMemoryAllocationCount = UINT32_MAX,
408 .maxSamplerAllocationCount = UINT32_MAX,
409 .bufferImageGranularity = 64, /* A cache line */
410 .sparseAddressSpaceSize = 0,
411 .maxBoundDescriptorSets = MAX_SETS,
412 .maxPerStageDescriptorSamplers = 64,
413 .maxPerStageDescriptorUniformBuffers = 64,
414 .maxPerStageDescriptorStorageBuffers = 64,
415 .maxPerStageDescriptorSampledImages = 64,
416 .maxPerStageDescriptorStorageImages = 64,
417 .maxPerStageDescriptorInputAttachments = 64,
418 .maxPerStageResources = 128,
419 .maxDescriptorSetSamplers = 256,
420 .maxDescriptorSetUniformBuffers = 256,
421 .maxDescriptorSetUniformBuffersDynamic = 256,
422 .maxDescriptorSetStorageBuffers = 256,
423 .maxDescriptorSetStorageBuffersDynamic = 256,
424 .maxDescriptorSetSampledImages = 256,
425 .maxDescriptorSetStorageImages = 256,
426 .maxDescriptorSetInputAttachments = 256,
427 .maxVertexInputAttributes = 32,
428 .maxVertexInputBindings = 32,
429 .maxVertexInputAttributeOffset = 256,
430 .maxVertexInputBindingStride = 256,
431 .maxVertexOutputComponents = 32,
432 .maxTessellationGenerationLevel = 0,
433 .maxTessellationPatchSize = 0,
434 .maxTessellationControlPerVertexInputComponents = 0,
435 .maxTessellationControlPerVertexOutputComponents = 0,
436 .maxTessellationControlPerPatchOutputComponents = 0,
437 .maxTessellationControlTotalOutputComponents = 0,
438 .maxTessellationEvaluationInputComponents = 0,
439 .maxTessellationEvaluationOutputComponents = 0,
440 .maxGeometryShaderInvocations = 6,
441 .maxGeometryInputComponents = 16,
442 .maxGeometryOutputComponents = 16,
443 .maxGeometryOutputVertices = 16,
444 .maxGeometryTotalOutputComponents = 16,
445 .maxFragmentInputComponents = 16,
446 .maxFragmentOutputAttachments = 8,
447 .maxFragmentDualSrcAttachments = 2,
448 .maxFragmentCombinedOutputResources = 8,
449 .maxComputeSharedMemorySize = 1024,
450 .maxComputeWorkGroupCount = {
451 16 * devinfo->max_cs_threads,
452 16 * devinfo->max_cs_threads,
453 16 * devinfo->max_cs_threads,
454 },
455 .maxComputeWorkGroupInvocations = 16 * devinfo->max_cs_threads,
456 .maxComputeWorkGroupSize = {
457 16 * devinfo->max_cs_threads,
458 16 * devinfo->max_cs_threads,
459 16 * devinfo->max_cs_threads,
460 },
461 .subPixelPrecisionBits = 4 /* FIXME */,
462 .subTexelPrecisionBits = 4 /* FIXME */,
463 .mipmapPrecisionBits = 4 /* FIXME */,
464 .maxDrawIndexedIndexValue = UINT32_MAX,
465 .maxDrawIndirectCount = UINT32_MAX,
466 .maxSamplerLodBias = 16,
467 .maxSamplerAnisotropy = 16,
468 .maxViewports = MAX_VIEWPORTS,
469 .maxViewportDimensions = { (1 << 14), (1 << 14) },
470 .viewportBoundsRange = { -1.0, 1.0 }, /* FIXME */
471 .viewportSubPixelBits = 13, /* We take a float? */
472 .minMemoryMapAlignment = 4096, /* A page */
473 .minTexelBufferOffsetAlignment = 1,
474 .minUniformBufferOffsetAlignment = 1,
475 .minStorageBufferOffsetAlignment = 1,
476 .minTexelOffset = 0, /* FIXME */
477 .maxTexelOffset = 0, /* FIXME */
478 .minTexelGatherOffset = 0, /* FIXME */
479 .maxTexelGatherOffset = 0, /* FIXME */
480 .minInterpolationOffset = 0, /* FIXME */
481 .maxInterpolationOffset = 0, /* FIXME */
482 .subPixelInterpolationOffsetBits = 0, /* FIXME */
483 .maxFramebufferWidth = (1 << 14),
484 .maxFramebufferHeight = (1 << 14),
485 .maxFramebufferLayers = (1 << 10),
486 .framebufferColorSampleCounts = sample_counts,
487 .framebufferDepthSampleCounts = sample_counts,
488 .framebufferStencilSampleCounts = sample_counts,
489 .framebufferNoAttachmentsSampleCounts = sample_counts,
490 .maxColorAttachments = MAX_RTS,
491 .sampledImageColorSampleCounts = sample_counts,
492 .sampledImageIntegerSampleCounts = VK_SAMPLE_COUNT_1_BIT,
493 .sampledImageDepthSampleCounts = sample_counts,
494 .sampledImageStencilSampleCounts = sample_counts,
495 .storageImageSampleCounts = VK_SAMPLE_COUNT_1_BIT,
496 .maxSampleMaskWords = 1,
497 .timestampComputeAndGraphics = false,
498 .timestampPeriod = time_stamp_base / (1000 * 1000 * 1000),
499 .maxClipDistances = 0 /* FIXME */,
500 .maxCullDistances = 0 /* FIXME */,
501 .maxCombinedClipAndCullDistances = 0 /* FIXME */,
502 .discreteQueuePriorities = 1,
503 .pointSizeRange = { 0.125, 255.875 },
504 .lineWidthRange = { 0.0, 7.9921875 },
505 .pointSizeGranularity = (1.0 / 8.0),
506 .lineWidthGranularity = (1.0 / 128.0),
507 .strictLines = false, /* FINISHME */
508 .standardSampleLocations = true, /* FINISHME */
509 .optimalBufferCopyOffsetAlignment = 128,
510 .optimalBufferCopyRowPitchAlignment = 128,
511 .nonCoherentAtomSize = 64,
512 };
513
514 *pProperties = (VkPhysicalDeviceProperties) {
515 .apiVersion = VK_MAKE_VERSION(0, 210, 1),
516 .driverVersion = 1,
517 .vendorID = 0x8086,
518 .deviceID = pdevice->chipset_id,
519 .deviceType = VK_PHYSICAL_DEVICE_TYPE_INTEGRATED_GPU,
520 .limits = limits,
521 .sparseProperties = {0}, /* Broadwell doesn't do sparse. */
522 };
523
524 strcpy(pProperties->deviceName, pdevice->name);
525 snprintf((char *)pProperties->pipelineCacheUUID, VK_UUID_SIZE,
526 "anv-%s", MESA_GIT_SHA1 + 4);
527 }
528
529 void anv_GetPhysicalDeviceQueueFamilyProperties(
530 VkPhysicalDevice physicalDevice,
531 uint32_t* pCount,
532 VkQueueFamilyProperties* pQueueFamilyProperties)
533 {
534 if (pQueueFamilyProperties == NULL) {
535 *pCount = 1;
536 return;
537 }
538
539 assert(*pCount >= 1);
540
541 *pQueueFamilyProperties = (VkQueueFamilyProperties) {
542 .queueFlags = VK_QUEUE_GRAPHICS_BIT |
543 VK_QUEUE_COMPUTE_BIT |
544 VK_QUEUE_TRANSFER_BIT,
545 .queueCount = 1,
546 .timestampValidBits = 36, /* XXX: Real value here */
547 .minImageTransferGranularity = (VkExtent3D) { 1, 1, 1 },
548 };
549 }
550
551 void anv_GetPhysicalDeviceMemoryProperties(
552 VkPhysicalDevice physicalDevice,
553 VkPhysicalDeviceMemoryProperties* pMemoryProperties)
554 {
555 ANV_FROM_HANDLE(anv_physical_device, physical_device, physicalDevice);
556 VkDeviceSize heap_size;
557
558 /* Reserve some wiggle room for the driver by exposing only 75% of the
559 * aperture to the heap.
560 */
561 heap_size = 3 * physical_device->aperture_size / 4;
562
563 if (physical_device->info->has_llc) {
564 /* Big core GPUs share LLC with the CPU and thus one memory type can be
565 * both cached and coherent at the same time.
566 */
567 pMemoryProperties->memoryTypeCount = 1;
568 pMemoryProperties->memoryTypes[0] = (VkMemoryType) {
569 .propertyFlags = VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT |
570 VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT |
571 VK_MEMORY_PROPERTY_HOST_COHERENT_BIT |
572 VK_MEMORY_PROPERTY_HOST_CACHED_BIT,
573 .heapIndex = 0,
574 };
575 } else {
576 /* The spec requires that we expose a host-visible, coherent memory
577 * type, but Atom GPUs don't share LLC. Thus we offer two memory types
578 * to give the application a choice between cached, but not coherent and
579 * coherent but uncached (WC though).
580 */
581 pMemoryProperties->memoryTypeCount = 2;
582 pMemoryProperties->memoryTypes[0] = (VkMemoryType) {
583 .propertyFlags = VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT |
584 VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT |
585 VK_MEMORY_PROPERTY_HOST_COHERENT_BIT,
586 .heapIndex = 0,
587 };
588 pMemoryProperties->memoryTypes[1] = (VkMemoryType) {
589 .propertyFlags = VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT |
590 VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT |
591 VK_MEMORY_PROPERTY_HOST_CACHED_BIT,
592 .heapIndex = 0,
593 };
594 }
595
596 pMemoryProperties->memoryHeapCount = 1;
597 pMemoryProperties->memoryHeaps[0] = (VkMemoryHeap) {
598 .size = heap_size,
599 .flags = VK_MEMORY_HEAP_DEVICE_LOCAL_BIT,
600 };
601 }
602
603 PFN_vkVoidFunction anv_GetInstanceProcAddr(
604 VkInstance instance,
605 const char* pName)
606 {
607 return anv_lookup_entrypoint(pName);
608 }
609
610 PFN_vkVoidFunction anv_GetDeviceProcAddr(
611 VkDevice device,
612 const char* pName)
613 {
614 return anv_lookup_entrypoint(pName);
615 }
616
617 static VkResult
618 anv_queue_init(struct anv_device *device, struct anv_queue *queue)
619 {
620 queue->_loader_data.loaderMagic = ICD_LOADER_MAGIC;
621 queue->device = device;
622 queue->pool = &device->surface_state_pool;
623
624 return VK_SUCCESS;
625 }
626
627 static void
628 anv_queue_finish(struct anv_queue *queue)
629 {
630 }
631
632 static struct anv_state
633 anv_state_pool_emit_data(struct anv_state_pool *pool, size_t size, size_t align, const void *p)
634 {
635 struct anv_state state;
636
637 state = anv_state_pool_alloc(pool, size, align);
638 memcpy(state.map, p, size);
639
640 if (!pool->block_pool->device->info.has_llc)
641 anv_state_clflush(state);
642
643 return state;
644 }
645
646 static void
647 anv_device_init_border_colors(struct anv_device *device)
648 {
649 static const VkClearColorValue border_colors[] = {
650 [VK_BORDER_COLOR_FLOAT_TRANSPARENT_BLACK] = { .float32 = { 0.0, 0.0, 0.0, 0.0 } },
651 [VK_BORDER_COLOR_FLOAT_OPAQUE_BLACK] = { .float32 = { 0.0, 0.0, 0.0, 1.0 } },
652 [VK_BORDER_COLOR_FLOAT_OPAQUE_WHITE] = { .float32 = { 1.0, 1.0, 1.0, 1.0 } },
653 [VK_BORDER_COLOR_INT_TRANSPARENT_BLACK] = { .uint32 = { 0, 0, 0, 0 } },
654 [VK_BORDER_COLOR_INT_OPAQUE_BLACK] = { .uint32 = { 0, 0, 0, 1 } },
655 [VK_BORDER_COLOR_INT_OPAQUE_WHITE] = { .uint32 = { 1, 1, 1, 1 } },
656 };
657
658 device->border_colors = anv_state_pool_emit_data(&device->dynamic_state_pool,
659 sizeof(border_colors), 32, border_colors);
660 }
661
662 VkResult anv_CreateDevice(
663 VkPhysicalDevice physicalDevice,
664 const VkDeviceCreateInfo* pCreateInfo,
665 const VkAllocationCallbacks* pAllocator,
666 VkDevice* pDevice)
667 {
668 ANV_FROM_HANDLE(anv_physical_device, physical_device, physicalDevice);
669 VkResult result;
670 struct anv_device *device;
671
672 assert(pCreateInfo->sType == VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO);
673
674 for (uint32_t i = 0; i < pCreateInfo->enabledExtensionNameCount; i++) {
675 bool found = false;
676 for (uint32_t j = 0; j < ARRAY_SIZE(device_extensions); j++) {
677 if (strcmp(pCreateInfo->ppEnabledExtensionNames[i],
678 device_extensions[j].extensionName) == 0) {
679 found = true;
680 break;
681 }
682 }
683 if (!found)
684 return vk_error(VK_ERROR_EXTENSION_NOT_PRESENT);
685 }
686
687 anv_set_dispatch_devinfo(physical_device->info);
688
689 device = anv_alloc2(&physical_device->instance->alloc, pAllocator,
690 sizeof(*device), 8,
691 VK_SYSTEM_ALLOCATION_SCOPE_OBJECT);
692 if (!device)
693 return vk_error(VK_ERROR_OUT_OF_HOST_MEMORY);
694
695 device->_loader_data.loaderMagic = ICD_LOADER_MAGIC;
696 device->instance = physical_device->instance;
697
698 if (pAllocator)
699 device->alloc = *pAllocator;
700 else
701 device->alloc = physical_device->instance->alloc;
702
703 /* XXX(chadv): Can we dup() physicalDevice->fd here? */
704 device->fd = open(physical_device->path, O_RDWR | O_CLOEXEC);
705 if (device->fd == -1) {
706 result = vk_error(VK_ERROR_INITIALIZATION_FAILED);
707 goto fail_device;
708 }
709
710 device->context_id = anv_gem_create_context(device);
711 if (device->context_id == -1) {
712 result = vk_error(VK_ERROR_INITIALIZATION_FAILED);
713 goto fail_fd;
714 }
715
716 device->info = *physical_device->info;
717 device->isl_dev = physical_device->isl_dev;
718
719 pthread_mutex_init(&device->mutex, NULL);
720
721 anv_bo_pool_init(&device->batch_bo_pool, device, ANV_CMD_BUFFER_BATCH_SIZE);
722
723 anv_block_pool_init(&device->dynamic_state_block_pool, device, 16384);
724
725 anv_state_pool_init(&device->dynamic_state_pool,
726 &device->dynamic_state_block_pool);
727
728 anv_block_pool_init(&device->instruction_block_pool, device, 128 * 1024);
729 anv_pipeline_cache_init(&device->default_pipeline_cache, device);
730
731 anv_block_pool_init(&device->surface_state_block_pool, device, 4096);
732
733 anv_state_pool_init(&device->surface_state_pool,
734 &device->surface_state_block_pool);
735
736 anv_bo_init_new(&device->workaround_bo, device, 1024);
737
738 anv_block_pool_init(&device->scratch_block_pool, device, 0x10000);
739
740 anv_queue_init(device, &device->queue);
741
742 result = anv_device_init_meta(device);
743 if (result != VK_SUCCESS)
744 goto fail_fd;
745
746 anv_device_init_border_colors(device);
747
748 *pDevice = anv_device_to_handle(device);
749
750 return VK_SUCCESS;
751
752 fail_fd:
753 close(device->fd);
754 fail_device:
755 anv_free(&device->alloc, device);
756
757 return result;
758 }
759
760 void anv_DestroyDevice(
761 VkDevice _device,
762 const VkAllocationCallbacks* pAllocator)
763 {
764 ANV_FROM_HANDLE(anv_device, device, _device);
765
766 anv_queue_finish(&device->queue);
767
768 anv_device_finish_meta(device);
769
770 #ifdef HAVE_VALGRIND
771 /* We only need to free these to prevent valgrind errors. The backing
772 * BO will go away in a couple of lines so we don't actually leak.
773 */
774 anv_state_pool_free(&device->dynamic_state_pool, device->border_colors);
775 #endif
776
777 anv_gem_munmap(device->workaround_bo.map, device->workaround_bo.size);
778 anv_gem_close(device, device->workaround_bo.gem_handle);
779
780 anv_bo_pool_finish(&device->batch_bo_pool);
781 anv_state_pool_finish(&device->dynamic_state_pool);
782 anv_block_pool_finish(&device->dynamic_state_block_pool);
783 anv_block_pool_finish(&device->instruction_block_pool);
784 anv_state_pool_finish(&device->surface_state_pool);
785 anv_block_pool_finish(&device->surface_state_block_pool);
786 anv_block_pool_finish(&device->scratch_block_pool);
787
788 close(device->fd);
789
790 pthread_mutex_destroy(&device->mutex);
791
792 anv_free(&device->alloc, device);
793 }
794
795 VkResult anv_EnumerateInstanceExtensionProperties(
796 const char* pLayerName,
797 uint32_t* pPropertyCount,
798 VkExtensionProperties* pProperties)
799 {
800 if (pProperties == NULL) {
801 *pPropertyCount = ARRAY_SIZE(global_extensions);
802 return VK_SUCCESS;
803 }
804
805 assert(*pPropertyCount >= ARRAY_SIZE(global_extensions));
806
807 *pPropertyCount = ARRAY_SIZE(global_extensions);
808 memcpy(pProperties, global_extensions, sizeof(global_extensions));
809
810 return VK_SUCCESS;
811 }
812
813 VkResult anv_EnumerateDeviceExtensionProperties(
814 VkPhysicalDevice physicalDevice,
815 const char* pLayerName,
816 uint32_t* pPropertyCount,
817 VkExtensionProperties* pProperties)
818 {
819 if (pProperties == NULL) {
820 *pPropertyCount = ARRAY_SIZE(device_extensions);
821 return VK_SUCCESS;
822 }
823
824 assert(*pPropertyCount >= ARRAY_SIZE(device_extensions));
825
826 *pPropertyCount = ARRAY_SIZE(device_extensions);
827 memcpy(pProperties, device_extensions, sizeof(device_extensions));
828
829 return VK_SUCCESS;
830 }
831
832 VkResult anv_EnumerateInstanceLayerProperties(
833 uint32_t* pPropertyCount,
834 VkLayerProperties* pProperties)
835 {
836 if (pProperties == NULL) {
837 *pPropertyCount = 0;
838 return VK_SUCCESS;
839 }
840
841 /* None supported at this time */
842 return vk_error(VK_ERROR_LAYER_NOT_PRESENT);
843 }
844
845 VkResult anv_EnumerateDeviceLayerProperties(
846 VkPhysicalDevice physicalDevice,
847 uint32_t* pPropertyCount,
848 VkLayerProperties* pProperties)
849 {
850 if (pProperties == NULL) {
851 *pPropertyCount = 0;
852 return VK_SUCCESS;
853 }
854
855 /* None supported at this time */
856 return vk_error(VK_ERROR_LAYER_NOT_PRESENT);
857 }
858
859 void anv_GetDeviceQueue(
860 VkDevice _device,
861 uint32_t queueNodeIndex,
862 uint32_t queueIndex,
863 VkQueue* pQueue)
864 {
865 ANV_FROM_HANDLE(anv_device, device, _device);
866
867 assert(queueIndex == 0);
868
869 *pQueue = anv_queue_to_handle(&device->queue);
870 }
871
872 VkResult anv_QueueSubmit(
873 VkQueue _queue,
874 uint32_t submitCount,
875 const VkSubmitInfo* pSubmits,
876 VkFence _fence)
877 {
878 ANV_FROM_HANDLE(anv_queue, queue, _queue);
879 ANV_FROM_HANDLE(anv_fence, fence, _fence);
880 struct anv_device *device = queue->device;
881 int ret;
882
883 for (uint32_t i = 0; i < submitCount; i++) {
884 for (uint32_t j = 0; j < pSubmits[i].commandBufferCount; j++) {
885 ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer,
886 pSubmits[i].pCommandBuffers[j]);
887 assert(cmd_buffer->level == VK_COMMAND_BUFFER_LEVEL_PRIMARY);
888
889 ret = anv_gem_execbuffer(device, &cmd_buffer->execbuf2.execbuf);
890 if (ret != 0) {
891 /* We don't know the real error. */
892 return vk_errorf(VK_ERROR_OUT_OF_DEVICE_MEMORY,
893 "execbuf2 failed: %m");
894 }
895
896 if (fence) {
897 ret = anv_gem_execbuffer(device, &fence->execbuf);
898 if (ret != 0) {
899 /* We don't know the real error. */
900 return vk_errorf(VK_ERROR_OUT_OF_DEVICE_MEMORY,
901 "execbuf2 failed: %m");
902 }
903 }
904
905 for (uint32_t k = 0; k < cmd_buffer->execbuf2.bo_count; k++)
906 cmd_buffer->execbuf2.bos[k]->offset = cmd_buffer->execbuf2.objects[k].offset;
907 }
908 }
909
910 return VK_SUCCESS;
911 }
912
913 VkResult anv_QueueWaitIdle(
914 VkQueue _queue)
915 {
916 ANV_FROM_HANDLE(anv_queue, queue, _queue);
917
918 return ANV_CALL(DeviceWaitIdle)(anv_device_to_handle(queue->device));
919 }
920
921 VkResult anv_DeviceWaitIdle(
922 VkDevice _device)
923 {
924 ANV_FROM_HANDLE(anv_device, device, _device);
925 struct anv_state state;
926 struct anv_batch batch;
927 struct drm_i915_gem_execbuffer2 execbuf;
928 struct drm_i915_gem_exec_object2 exec2_objects[1];
929 struct anv_bo *bo = NULL;
930 VkResult result;
931 int64_t timeout;
932 int ret;
933
934 state = anv_state_pool_alloc(&device->dynamic_state_pool, 32, 32);
935 bo = &device->dynamic_state_pool.block_pool->bo;
936 batch.start = batch.next = state.map;
937 batch.end = state.map + 32;
938 anv_batch_emit(&batch, GEN7_MI_BATCH_BUFFER_END);
939 anv_batch_emit(&batch, GEN7_MI_NOOP);
940
941 if (!device->info.has_llc)
942 anv_state_clflush(state);
943
944 exec2_objects[0].handle = bo->gem_handle;
945 exec2_objects[0].relocation_count = 0;
946 exec2_objects[0].relocs_ptr = 0;
947 exec2_objects[0].alignment = 0;
948 exec2_objects[0].offset = bo->offset;
949 exec2_objects[0].flags = 0;
950 exec2_objects[0].rsvd1 = 0;
951 exec2_objects[0].rsvd2 = 0;
952
953 execbuf.buffers_ptr = (uintptr_t) exec2_objects;
954 execbuf.buffer_count = 1;
955 execbuf.batch_start_offset = state.offset;
956 execbuf.batch_len = batch.next - state.map;
957 execbuf.cliprects_ptr = 0;
958 execbuf.num_cliprects = 0;
959 execbuf.DR1 = 0;
960 execbuf.DR4 = 0;
961
962 execbuf.flags =
963 I915_EXEC_HANDLE_LUT | I915_EXEC_NO_RELOC | I915_EXEC_RENDER;
964 execbuf.rsvd1 = device->context_id;
965 execbuf.rsvd2 = 0;
966
967 ret = anv_gem_execbuffer(device, &execbuf);
968 if (ret != 0) {
969 /* We don't know the real error. */
970 result = vk_errorf(VK_ERROR_OUT_OF_DEVICE_MEMORY, "execbuf2 failed: %m");
971 goto fail;
972 }
973
974 timeout = INT64_MAX;
975 ret = anv_gem_wait(device, bo->gem_handle, &timeout);
976 if (ret != 0) {
977 /* We don't know the real error. */
978 result = vk_errorf(VK_ERROR_OUT_OF_DEVICE_MEMORY, "execbuf2 failed: %m");
979 goto fail;
980 }
981
982 anv_state_pool_free(&device->dynamic_state_pool, state);
983
984 return VK_SUCCESS;
985
986 fail:
987 anv_state_pool_free(&device->dynamic_state_pool, state);
988
989 return result;
990 }
991
992 VkResult
993 anv_bo_init_new(struct anv_bo *bo, struct anv_device *device, uint64_t size)
994 {
995 bo->gem_handle = anv_gem_create(device, size);
996 if (!bo->gem_handle)
997 return vk_error(VK_ERROR_OUT_OF_DEVICE_MEMORY);
998
999 bo->map = NULL;
1000 bo->index = 0;
1001 bo->offset = 0;
1002 bo->size = size;
1003
1004 return VK_SUCCESS;
1005 }
1006
1007 VkResult anv_AllocateMemory(
1008 VkDevice _device,
1009 const VkMemoryAllocateInfo* pAllocateInfo,
1010 const VkAllocationCallbacks* pAllocator,
1011 VkDeviceMemory* pMem)
1012 {
1013 ANV_FROM_HANDLE(anv_device, device, _device);
1014 struct anv_device_memory *mem;
1015 VkResult result;
1016
1017 assert(pAllocateInfo->sType == VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO);
1018
1019 if (pAllocateInfo->allocationSize == 0) {
1020 /* Apparently, this is allowed */
1021 *pMem = VK_NULL_HANDLE;
1022 return VK_SUCCESS;
1023 }
1024
1025 /* We support exactly one memory heap. */
1026 assert(pAllocateInfo->memoryTypeIndex == 0 ||
1027 (!device->info.has_llc && pAllocateInfo->memoryTypeIndex < 2));
1028
1029 /* FINISHME: Fail if allocation request exceeds heap size. */
1030
1031 mem = anv_alloc2(&device->alloc, pAllocator, sizeof(*mem), 8,
1032 VK_SYSTEM_ALLOCATION_SCOPE_OBJECT);
1033 if (mem == NULL)
1034 return vk_error(VK_ERROR_OUT_OF_HOST_MEMORY);
1035
1036 /* The kernel is going to give us whole pages anyway */
1037 uint64_t alloc_size = align_u64(pAllocateInfo->allocationSize, 4096);
1038
1039 result = anv_bo_init_new(&mem->bo, device, alloc_size);
1040 if (result != VK_SUCCESS)
1041 goto fail;
1042
1043 mem->type_index = pAllocateInfo->memoryTypeIndex;
1044
1045 *pMem = anv_device_memory_to_handle(mem);
1046
1047 return VK_SUCCESS;
1048
1049 fail:
1050 anv_free2(&device->alloc, pAllocator, mem);
1051
1052 return result;
1053 }
1054
1055 void anv_FreeMemory(
1056 VkDevice _device,
1057 VkDeviceMemory _mem,
1058 const VkAllocationCallbacks* pAllocator)
1059 {
1060 ANV_FROM_HANDLE(anv_device, device, _device);
1061 ANV_FROM_HANDLE(anv_device_memory, mem, _mem);
1062
1063 if (mem == NULL)
1064 return;
1065
1066 if (mem->bo.map)
1067 anv_gem_munmap(mem->bo.map, mem->bo.size);
1068
1069 if (mem->bo.gem_handle != 0)
1070 anv_gem_close(device, mem->bo.gem_handle);
1071
1072 anv_free2(&device->alloc, pAllocator, mem);
1073 }
1074
1075 VkResult anv_MapMemory(
1076 VkDevice _device,
1077 VkDeviceMemory _memory,
1078 VkDeviceSize offset,
1079 VkDeviceSize size,
1080 VkMemoryMapFlags flags,
1081 void** ppData)
1082 {
1083 ANV_FROM_HANDLE(anv_device, device, _device);
1084 ANV_FROM_HANDLE(anv_device_memory, mem, _memory);
1085
1086 if (mem == NULL) {
1087 *ppData = NULL;
1088 return VK_SUCCESS;
1089 }
1090
1091 /* FIXME: Is this supposed to be thread safe? Since vkUnmapMemory() only
1092 * takes a VkDeviceMemory pointer, it seems like only one map of the memory
1093 * at a time is valid. We could just mmap up front and return an offset
1094 * pointer here, but that may exhaust virtual memory on 32 bit
1095 * userspace. */
1096
1097 uint32_t gem_flags = 0;
1098 if (!device->info.has_llc && mem->type_index == 0)
1099 gem_flags |= I915_MMAP_WC;
1100
1101 /* GEM will fail to map if the offset isn't 4k-aligned. Round down. */
1102 uint64_t map_offset = offset & ~4095ull;
1103 assert(offset >= map_offset);
1104 uint64_t map_size = (offset + size) - map_offset;
1105
1106 /* Let's map whole pages */
1107 map_size = align_u64(map_size, 4096);
1108
1109 mem->map = anv_gem_mmap(device, mem->bo.gem_handle,
1110 map_offset, map_size, gem_flags);
1111 mem->map_size = map_size;
1112
1113 *ppData = mem->map + (offset - map_offset);
1114
1115 return VK_SUCCESS;
1116 }
1117
1118 void anv_UnmapMemory(
1119 VkDevice _device,
1120 VkDeviceMemory _memory)
1121 {
1122 ANV_FROM_HANDLE(anv_device_memory, mem, _memory);
1123
1124 if (mem == NULL)
1125 return;
1126
1127 anv_gem_munmap(mem->map, mem->map_size);
1128 }
1129
1130 static void
1131 clflush_mapped_ranges(struct anv_device *device,
1132 uint32_t count,
1133 const VkMappedMemoryRange *ranges)
1134 {
1135 for (uint32_t i = 0; i < count; i++) {
1136 ANV_FROM_HANDLE(anv_device_memory, mem, ranges[i].memory);
1137 void *p = mem->map + (ranges[i].offset & ~CACHELINE_MASK);
1138 void *end = mem->map + ranges[i].offset + ranges[i].size;
1139
1140 while (p < end) {
1141 __builtin_ia32_clflush(p);
1142 p += CACHELINE_SIZE;
1143 }
1144 }
1145 }
1146
1147 VkResult anv_FlushMappedMemoryRanges(
1148 VkDevice _device,
1149 uint32_t memoryRangeCount,
1150 const VkMappedMemoryRange* pMemoryRanges)
1151 {
1152 ANV_FROM_HANDLE(anv_device, device, _device);
1153
1154 if (device->info.has_llc)
1155 return VK_SUCCESS;
1156
1157 /* Make sure the writes we're flushing have landed. */
1158 __builtin_ia32_sfence();
1159
1160 clflush_mapped_ranges(device, memoryRangeCount, pMemoryRanges);
1161
1162 return VK_SUCCESS;
1163 }
1164
1165 VkResult anv_InvalidateMappedMemoryRanges(
1166 VkDevice _device,
1167 uint32_t memoryRangeCount,
1168 const VkMappedMemoryRange* pMemoryRanges)
1169 {
1170 ANV_FROM_HANDLE(anv_device, device, _device);
1171
1172 if (device->info.has_llc)
1173 return VK_SUCCESS;
1174
1175 clflush_mapped_ranges(device, memoryRangeCount, pMemoryRanges);
1176
1177 /* Make sure no reads get moved up above the invalidate. */
1178 __builtin_ia32_lfence();
1179
1180 return VK_SUCCESS;
1181 }
1182
1183 void anv_GetBufferMemoryRequirements(
1184 VkDevice device,
1185 VkBuffer _buffer,
1186 VkMemoryRequirements* pMemoryRequirements)
1187 {
1188 ANV_FROM_HANDLE(anv_buffer, buffer, _buffer);
1189
1190 /* The Vulkan spec (git aaed022) says:
1191 *
1192 * memoryTypeBits is a bitfield and contains one bit set for every
1193 * supported memory type for the resource. The bit `1<<i` is set if and
1194 * only if the memory type `i` in the VkPhysicalDeviceMemoryProperties
1195 * structure for the physical device is supported.
1196 *
1197 * We support exactly one memory type.
1198 */
1199 pMemoryRequirements->memoryTypeBits = 1;
1200
1201 pMemoryRequirements->size = buffer->size;
1202 pMemoryRequirements->alignment = 16;
1203 }
1204
1205 void anv_GetImageMemoryRequirements(
1206 VkDevice device,
1207 VkImage _image,
1208 VkMemoryRequirements* pMemoryRequirements)
1209 {
1210 ANV_FROM_HANDLE(anv_image, image, _image);
1211
1212 /* The Vulkan spec (git aaed022) says:
1213 *
1214 * memoryTypeBits is a bitfield and contains one bit set for every
1215 * supported memory type for the resource. The bit `1<<i` is set if and
1216 * only if the memory type `i` in the VkPhysicalDeviceMemoryProperties
1217 * structure for the physical device is supported.
1218 *
1219 * We support exactly one memory type.
1220 */
1221 pMemoryRequirements->memoryTypeBits = 1;
1222
1223 pMemoryRequirements->size = image->size;
1224 pMemoryRequirements->alignment = image->alignment;
1225 }
1226
1227 void anv_GetImageSparseMemoryRequirements(
1228 VkDevice device,
1229 VkImage image,
1230 uint32_t* pSparseMemoryRequirementCount,
1231 VkSparseImageMemoryRequirements* pSparseMemoryRequirements)
1232 {
1233 stub();
1234 }
1235
1236 void anv_GetDeviceMemoryCommitment(
1237 VkDevice device,
1238 VkDeviceMemory memory,
1239 VkDeviceSize* pCommittedMemoryInBytes)
1240 {
1241 *pCommittedMemoryInBytes = 0;
1242 }
1243
1244 VkResult anv_BindBufferMemory(
1245 VkDevice device,
1246 VkBuffer _buffer,
1247 VkDeviceMemory _memory,
1248 VkDeviceSize memoryOffset)
1249 {
1250 ANV_FROM_HANDLE(anv_device_memory, mem, _memory);
1251 ANV_FROM_HANDLE(anv_buffer, buffer, _buffer);
1252
1253 if (mem) {
1254 buffer->bo = &mem->bo;
1255 buffer->offset = memoryOffset;
1256 } else {
1257 buffer->bo = NULL;
1258 buffer->offset = 0;
1259 }
1260
1261 return VK_SUCCESS;
1262 }
1263
1264 VkResult anv_BindImageMemory(
1265 VkDevice device,
1266 VkImage _image,
1267 VkDeviceMemory _memory,
1268 VkDeviceSize memoryOffset)
1269 {
1270 ANV_FROM_HANDLE(anv_device_memory, mem, _memory);
1271 ANV_FROM_HANDLE(anv_image, image, _image);
1272
1273 if (mem) {
1274 image->bo = &mem->bo;
1275 image->offset = memoryOffset;
1276 } else {
1277 image->bo = NULL;
1278 image->offset = 0;
1279 }
1280
1281 return VK_SUCCESS;
1282 }
1283
1284 VkResult anv_QueueBindSparse(
1285 VkQueue queue,
1286 uint32_t bindInfoCount,
1287 const VkBindSparseInfo* pBindInfo,
1288 VkFence fence)
1289 {
1290 stub_return(VK_ERROR_INCOMPATIBLE_DRIVER);
1291 }
1292
1293 VkResult anv_CreateFence(
1294 VkDevice _device,
1295 const VkFenceCreateInfo* pCreateInfo,
1296 const VkAllocationCallbacks* pAllocator,
1297 VkFence* pFence)
1298 {
1299 ANV_FROM_HANDLE(anv_device, device, _device);
1300 struct anv_fence *fence;
1301 struct anv_batch batch;
1302 VkResult result;
1303
1304 const uint32_t fence_size = 128;
1305
1306 assert(pCreateInfo->sType == VK_STRUCTURE_TYPE_FENCE_CREATE_INFO);
1307
1308 fence = anv_alloc2(&device->alloc, pAllocator, sizeof(*fence), 8,
1309 VK_SYSTEM_ALLOCATION_SCOPE_OBJECT);
1310 if (fence == NULL)
1311 return vk_error(VK_ERROR_OUT_OF_HOST_MEMORY);
1312
1313 result = anv_bo_init_new(&fence->bo, device, fence_size);
1314 if (result != VK_SUCCESS)
1315 goto fail;
1316
1317 fence->bo.map =
1318 anv_gem_mmap(device, fence->bo.gem_handle, 0, fence->bo.size, 0);
1319 batch.next = batch.start = fence->bo.map;
1320 batch.end = fence->bo.map + fence->bo.size;
1321 anv_batch_emit(&batch, GEN7_MI_BATCH_BUFFER_END);
1322 anv_batch_emit(&batch, GEN7_MI_NOOP);
1323
1324 if (!device->info.has_llc) {
1325 assert(((uintptr_t) fence->bo.map & CACHELINE_MASK) == 0);
1326 assert(batch.next - fence->bo.map <= CACHELINE_SIZE);
1327 __builtin_ia32_sfence();
1328 __builtin_ia32_clflush(fence->bo.map);
1329 }
1330
1331 fence->exec2_objects[0].handle = fence->bo.gem_handle;
1332 fence->exec2_objects[0].relocation_count = 0;
1333 fence->exec2_objects[0].relocs_ptr = 0;
1334 fence->exec2_objects[0].alignment = 0;
1335 fence->exec2_objects[0].offset = fence->bo.offset;
1336 fence->exec2_objects[0].flags = 0;
1337 fence->exec2_objects[0].rsvd1 = 0;
1338 fence->exec2_objects[0].rsvd2 = 0;
1339
1340 fence->execbuf.buffers_ptr = (uintptr_t) fence->exec2_objects;
1341 fence->execbuf.buffer_count = 1;
1342 fence->execbuf.batch_start_offset = 0;
1343 fence->execbuf.batch_len = batch.next - fence->bo.map;
1344 fence->execbuf.cliprects_ptr = 0;
1345 fence->execbuf.num_cliprects = 0;
1346 fence->execbuf.DR1 = 0;
1347 fence->execbuf.DR4 = 0;
1348
1349 fence->execbuf.flags =
1350 I915_EXEC_HANDLE_LUT | I915_EXEC_NO_RELOC | I915_EXEC_RENDER;
1351 fence->execbuf.rsvd1 = device->context_id;
1352 fence->execbuf.rsvd2 = 0;
1353
1354 *pFence = anv_fence_to_handle(fence);
1355
1356 return VK_SUCCESS;
1357
1358 fail:
1359 anv_free2(&device->alloc, pAllocator, fence);
1360
1361 return result;
1362 }
1363
1364 void anv_DestroyFence(
1365 VkDevice _device,
1366 VkFence _fence,
1367 const VkAllocationCallbacks* pAllocator)
1368 {
1369 ANV_FROM_HANDLE(anv_device, device, _device);
1370 ANV_FROM_HANDLE(anv_fence, fence, _fence);
1371
1372 anv_gem_munmap(fence->bo.map, fence->bo.size);
1373 anv_gem_close(device, fence->bo.gem_handle);
1374 anv_free2(&device->alloc, pAllocator, fence);
1375 }
1376
1377 VkResult anv_ResetFences(
1378 VkDevice _device,
1379 uint32_t fenceCount,
1380 const VkFence* pFences)
1381 {
1382 for (uint32_t i = 0; i < fenceCount; i++) {
1383 ANV_FROM_HANDLE(anv_fence, fence, pFences[i]);
1384 fence->ready = false;
1385 }
1386
1387 return VK_SUCCESS;
1388 }
1389
1390 VkResult anv_GetFenceStatus(
1391 VkDevice _device,
1392 VkFence _fence)
1393 {
1394 ANV_FROM_HANDLE(anv_device, device, _device);
1395 ANV_FROM_HANDLE(anv_fence, fence, _fence);
1396 int64_t t = 0;
1397 int ret;
1398
1399 if (fence->ready)
1400 return VK_SUCCESS;
1401
1402 ret = anv_gem_wait(device, fence->bo.gem_handle, &t);
1403 if (ret == 0) {
1404 fence->ready = true;
1405 return VK_SUCCESS;
1406 }
1407
1408 return VK_NOT_READY;
1409 }
1410
1411 VkResult anv_WaitForFences(
1412 VkDevice _device,
1413 uint32_t fenceCount,
1414 const VkFence* pFences,
1415 VkBool32 waitAll,
1416 uint64_t timeout)
1417 {
1418 ANV_FROM_HANDLE(anv_device, device, _device);
1419
1420 /* DRM_IOCTL_I915_GEM_WAIT uses a signed 64 bit timeout and is supposed
1421 * to block indefinitely timeouts <= 0. Unfortunately, this was broken
1422 * for a couple of kernel releases. Since there's no way to know
1423 * whether or not the kernel we're using is one of the broken ones, the
1424 * best we can do is to clamp the timeout to INT64_MAX. This limits the
1425 * maximum timeout from 584 years to 292 years - likely not a big deal.
1426 */
1427 if (timeout > INT64_MAX)
1428 timeout = INT64_MAX;
1429
1430 int64_t t = timeout;
1431
1432 /* FIXME: handle !waitAll */
1433
1434 for (uint32_t i = 0; i < fenceCount; i++) {
1435 ANV_FROM_HANDLE(anv_fence, fence, pFences[i]);
1436 int ret = anv_gem_wait(device, fence->bo.gem_handle, &t);
1437 if (ret == -1 && errno == ETIME) {
1438 return VK_TIMEOUT;
1439 } else if (ret == -1) {
1440 /* We don't know the real error. */
1441 return vk_errorf(VK_ERROR_OUT_OF_DEVICE_MEMORY,
1442 "gem wait failed: %m");
1443 }
1444 }
1445
1446 return VK_SUCCESS;
1447 }
1448
1449 // Queue semaphore functions
1450
1451 VkResult anv_CreateSemaphore(
1452 VkDevice device,
1453 const VkSemaphoreCreateInfo* pCreateInfo,
1454 const VkAllocationCallbacks* pAllocator,
1455 VkSemaphore* pSemaphore)
1456 {
1457 /* The DRM execbuffer ioctl always execute in-oder, even between different
1458 * rings. As such, there's nothing to do for the user space semaphore.
1459 */
1460
1461 *pSemaphore = (VkSemaphore)1;
1462
1463 return VK_SUCCESS;
1464 }
1465
1466 void anv_DestroySemaphore(
1467 VkDevice device,
1468 VkSemaphore semaphore,
1469 const VkAllocationCallbacks* pAllocator)
1470 {
1471 }
1472
1473 // Event functions
1474
1475 VkResult anv_CreateEvent(
1476 VkDevice _device,
1477 const VkEventCreateInfo* pCreateInfo,
1478 const VkAllocationCallbacks* pAllocator,
1479 VkEvent* pEvent)
1480 {
1481 ANV_FROM_HANDLE(anv_device, device, _device);
1482 struct anv_state state;
1483 struct anv_event *event;
1484
1485 assert(pCreateInfo->sType == VK_STRUCTURE_TYPE_EVENT_CREATE_INFO);
1486
1487 state = anv_state_pool_alloc(&device->dynamic_state_pool,
1488 sizeof(*event), 4);
1489 event = state.map;
1490 event->state = state;
1491 event->semaphore = VK_EVENT_RESET;
1492
1493 if (!device->info.has_llc) {
1494 /* Make sure the writes we're flushing have landed. */
1495 __builtin_ia32_sfence();
1496 __builtin_ia32_clflush(event);
1497 }
1498
1499 *pEvent = anv_event_to_handle(event);
1500
1501 return VK_SUCCESS;
1502 }
1503
1504 void anv_DestroyEvent(
1505 VkDevice _device,
1506 VkEvent _event,
1507 const VkAllocationCallbacks* pAllocator)
1508 {
1509 ANV_FROM_HANDLE(anv_device, device, _device);
1510 ANV_FROM_HANDLE(anv_event, event, _event);
1511
1512 anv_state_pool_free(&device->dynamic_state_pool, event->state);
1513 }
1514
1515 VkResult anv_GetEventStatus(
1516 VkDevice _device,
1517 VkEvent _event)
1518 {
1519 ANV_FROM_HANDLE(anv_device, device, _device);
1520 ANV_FROM_HANDLE(anv_event, event, _event);
1521
1522 if (!device->info.has_llc) {
1523 /* Make sure the writes we're flushing have landed. */
1524 __builtin_ia32_clflush(event);
1525 __builtin_ia32_lfence();
1526 }
1527
1528 return event->semaphore;
1529 }
1530
1531 VkResult anv_SetEvent(
1532 VkDevice _device,
1533 VkEvent _event)
1534 {
1535 ANV_FROM_HANDLE(anv_device, device, _device);
1536 ANV_FROM_HANDLE(anv_event, event, _event);
1537
1538 event->semaphore = VK_EVENT_SET;
1539
1540 if (!device->info.has_llc) {
1541 /* Make sure the writes we're flushing have landed. */
1542 __builtin_ia32_sfence();
1543 __builtin_ia32_clflush(event);
1544 }
1545
1546 return VK_SUCCESS;
1547 }
1548
1549 VkResult anv_ResetEvent(
1550 VkDevice _device,
1551 VkEvent _event)
1552 {
1553 ANV_FROM_HANDLE(anv_device, device, _device);
1554 ANV_FROM_HANDLE(anv_event, event, _event);
1555
1556 event->semaphore = VK_EVENT_RESET;
1557
1558 if (!device->info.has_llc) {
1559 /* Make sure the writes we're flushing have landed. */
1560 __builtin_ia32_sfence();
1561 __builtin_ia32_clflush(event);
1562 }
1563
1564 return VK_SUCCESS;
1565 }
1566
1567 // Buffer functions
1568
1569 VkResult anv_CreateBuffer(
1570 VkDevice _device,
1571 const VkBufferCreateInfo* pCreateInfo,
1572 const VkAllocationCallbacks* pAllocator,
1573 VkBuffer* pBuffer)
1574 {
1575 ANV_FROM_HANDLE(anv_device, device, _device);
1576 struct anv_buffer *buffer;
1577
1578 assert(pCreateInfo->sType == VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO);
1579
1580 buffer = anv_alloc2(&device->alloc, pAllocator, sizeof(*buffer), 8,
1581 VK_SYSTEM_ALLOCATION_SCOPE_OBJECT);
1582 if (buffer == NULL)
1583 return vk_error(VK_ERROR_OUT_OF_HOST_MEMORY);
1584
1585 buffer->size = pCreateInfo->size;
1586 buffer->usage = pCreateInfo->usage;
1587 buffer->bo = NULL;
1588 buffer->offset = 0;
1589
1590 *pBuffer = anv_buffer_to_handle(buffer);
1591
1592 return VK_SUCCESS;
1593 }
1594
1595 void anv_DestroyBuffer(
1596 VkDevice _device,
1597 VkBuffer _buffer,
1598 const VkAllocationCallbacks* pAllocator)
1599 {
1600 ANV_FROM_HANDLE(anv_device, device, _device);
1601 ANV_FROM_HANDLE(anv_buffer, buffer, _buffer);
1602
1603 anv_free2(&device->alloc, pAllocator, buffer);
1604 }
1605
1606 void
1607 anv_fill_buffer_surface_state(struct anv_device *device, void *state,
1608 enum isl_format format,
1609 uint32_t offset, uint32_t range, uint32_t stride)
1610 {
1611 switch (device->info.gen) {
1612 case 7:
1613 if (device->info.is_haswell)
1614 gen75_fill_buffer_surface_state(state, format, offset, range, stride);
1615 else
1616 gen7_fill_buffer_surface_state(state, format, offset, range, stride);
1617 break;
1618 case 8:
1619 gen8_fill_buffer_surface_state(state, format, offset, range, stride);
1620 break;
1621 case 9:
1622 gen9_fill_buffer_surface_state(state, format, offset, range, stride);
1623 break;
1624 default:
1625 unreachable("unsupported gen\n");
1626 }
1627 }
1628
1629 void anv_DestroySampler(
1630 VkDevice _device,
1631 VkSampler _sampler,
1632 const VkAllocationCallbacks* pAllocator)
1633 {
1634 ANV_FROM_HANDLE(anv_device, device, _device);
1635 ANV_FROM_HANDLE(anv_sampler, sampler, _sampler);
1636
1637 anv_free2(&device->alloc, pAllocator, sampler);
1638 }
1639
1640 VkResult anv_CreateFramebuffer(
1641 VkDevice _device,
1642 const VkFramebufferCreateInfo* pCreateInfo,
1643 const VkAllocationCallbacks* pAllocator,
1644 VkFramebuffer* pFramebuffer)
1645 {
1646 ANV_FROM_HANDLE(anv_device, device, _device);
1647 struct anv_framebuffer *framebuffer;
1648
1649 assert(pCreateInfo->sType == VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO);
1650
1651 size_t size = sizeof(*framebuffer) +
1652 sizeof(struct anv_image_view *) * pCreateInfo->attachmentCount;
1653 framebuffer = anv_alloc2(&device->alloc, pAllocator, size, 8,
1654 VK_SYSTEM_ALLOCATION_SCOPE_OBJECT);
1655 if (framebuffer == NULL)
1656 return vk_error(VK_ERROR_OUT_OF_HOST_MEMORY);
1657
1658 framebuffer->attachment_count = pCreateInfo->attachmentCount;
1659 for (uint32_t i = 0; i < pCreateInfo->attachmentCount; i++) {
1660 VkImageView _iview = pCreateInfo->pAttachments[i];
1661 framebuffer->attachments[i] = anv_image_view_from_handle(_iview);
1662 }
1663
1664 framebuffer->width = pCreateInfo->width;
1665 framebuffer->height = pCreateInfo->height;
1666 framebuffer->layers = pCreateInfo->layers;
1667
1668 *pFramebuffer = anv_framebuffer_to_handle(framebuffer);
1669
1670 return VK_SUCCESS;
1671 }
1672
1673 void anv_DestroyFramebuffer(
1674 VkDevice _device,
1675 VkFramebuffer _fb,
1676 const VkAllocationCallbacks* pAllocator)
1677 {
1678 ANV_FROM_HANDLE(anv_device, device, _device);
1679 ANV_FROM_HANDLE(anv_framebuffer, fb, _fb);
1680
1681 anv_free2(&device->alloc, pAllocator, fb);
1682 }
1683
1684 void vkCmdDbgMarkerBegin(
1685 VkCommandBuffer commandBuffer,
1686 const char* pMarker)
1687 __attribute__ ((visibility ("default")));
1688
1689 void vkCmdDbgMarkerEnd(
1690 VkCommandBuffer commandBuffer)
1691 __attribute__ ((visibility ("default")));
1692
1693 void vkCmdDbgMarkerBegin(
1694 VkCommandBuffer commandBuffer,
1695 const char* pMarker)
1696 {
1697 }
1698
1699 void vkCmdDbgMarkerEnd(
1700 VkCommandBuffer commandBuffer)
1701 {
1702 }