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