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