anv_device.c 179 KB
Newer Older
Kristian Høgsberg's avatar
Kristian Høgsberg committed
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26
/*
 * Copyright © 2015 Intel Corporation
 *
 * Permission is hereby granted, free of charge, to any person obtaining a
 * copy of this software and associated documentation files (the "Software"),
 * to deal in the Software without restriction, including without limitation
 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
 * and/or sell copies of the Software, and to permit persons to whom the
 * Software is furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice (including the next
 * paragraph) shall be included in all copies or substantial portions of the
 * Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
 * IN THE SOFTWARE.
 */

#include <assert.h>
#include <stdbool.h>
#include <string.h>
27
#include <sys/sysmacros.h>
28
#include <sys/mman.h>
29
#include <sys/stat.h>
Kristian Høgsberg's avatar
Kristian Høgsberg committed
30 31
#include <unistd.h>
#include <fcntl.h>
32
#include "drm-uapi/drm_fourcc.h"
33 34
#include "drm-uapi/drm.h"
#include <xf86drm.h>
Kristian Høgsberg's avatar
Kristian Høgsberg committed
35

36
#include "anv_private.h"
37
#include "util/debug.h"
38
#include "util/build_id.h"
39
#include "util/disk_cache.h"
40
#include "util/mesa-sha1.h"
41
#include "util/os_file.h"
42
#include "util/os_misc.h"
43
#include "util/u_atomic.h"
44
#include "util/u_string.h"
45
#include "util/driconf.h"
46
#include "git_sha1.h"
47
#include "vk_util.h"
48
#include "vk_deferred_operation.h"
49
#include "common/gen_aux_map.h"
50
#include "common/gen_defines.h"
51
#include "common/gen_uuid.h"
52
#include "compiler/glsl_types.h"
Kristian Høgsberg's avatar
Kristian Høgsberg committed
53

54
#include "genxml/gen7_pack.h"
55

56
static const driOptionDescription anv_dri_options[] = {
57 58
   DRI_CONF_SECTION_PERFORMANCE
      DRI_CONF_VK_X11_OVERRIDE_MIN_IMAGE_COUNT(0)
59
      DRI_CONF_VK_X11_STRICT_IMAGE_COUNT(false)
60
   DRI_CONF_SECTION_END
61 62

   DRI_CONF_SECTION_DEBUG
63 64
      DRI_CONF_ALWAYS_FLUSH_CACHE(false)
      DRI_CONF_VK_WSI_FORCE_BGRA8_UNORM_FIRST(false)
65
   DRI_CONF_SECTION_END
66
};
Eric Engestrom's avatar
Eric Engestrom committed
67

68 69 70 71 72
/* This is probably far to big but it reflects the max size used for messages
 * in OpenGLs KHR_debug.
 */
#define MAX_DEBUG_MESSAGE_LENGTH    4096

73 74 75
/* Render engine timestamp register */
#define TIMESTAMP 0x2358

76 77 78 79 80
/* The "RAW" clocks on Linux are called "FAST" on FreeBSD */
#if !defined(CLOCK_MONOTONIC_RAW) && defined(CLOCK_MONOTONIC_FAST)
#define CLOCK_MONOTONIC_RAW CLOCK_MONOTONIC_FAST
#endif

81 82
static void
compiler_debug_log(void *data, const char *fmt, ...)
83 84 85
{
   char str[MAX_DEBUG_MESSAGE_LENGTH];
   struct anv_device *device = (struct anv_device *)data;
86
   struct anv_instance *instance = device->physical->instance;
87

88
   if (list_is_empty(&instance->debug_report_callbacks.callbacks))
89 90 91 92 93 94 95
      return;

   va_list args;
   va_start(args, fmt);
   (void) vsnprintf(str, MAX_DEBUG_MESSAGE_LENGTH, fmt, args);
   va_end(args);

96
   vk_debug_report(&instance->debug_report_callbacks,
97 98 99 100
                   VK_DEBUG_REPORT_DEBUG_BIT_EXT,
                   VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT,
                   0, 0, 0, "anv", str);
}
101 102 103 104 105 106 107

static void
compiler_perf_log(void *data, const char *fmt, ...)
{
   va_list args;
   va_start(args, fmt);

108
   if (INTEL_DEBUG & DEBUG_PERF)
109
      mesa_logd_v(fmt, args);
110 111 112 113

   va_end(args);
}

114 115
static uint64_t
anv_compute_heap_size(int fd, uint64_t gtt_size)
116 117
{
   /* Query the total ram from the system */
118 119 120
   uint64_t total_ram;
   if (!os_get_total_physical_memory(&total_ram))
      return 0;
121 122 123 124 125 126 127 128 129 130 131 132 133 134 135

   /* We don't want to burn too much ram with the GPU.  If the user has 4GiB
    * or less, we use at most half.  If they have more than 4GiB, we use 3/4.
    */
   uint64_t available_ram;
   if (total_ram <= 4ull * 1024ull * 1024ull * 1024ull)
      available_ram = total_ram / 2;
   else
      available_ram = total_ram * 3 / 4;

   /* We also want to leave some padding for things we allocate in the driver,
    * so don't go over 3/4 of the GTT either.
    */
   uint64_t available_gtt = gtt_size * 3 / 4;

136
   return MIN2(available_ram, available_gtt);
137 138
}

139 140 141
static VkResult
anv_physical_device_init_heaps(struct anv_physical_device *device, int fd)
{
142
   if (anv_gem_get_context_param(fd, 0, I915_CONTEXT_PARAM_GTT_SIZE,
143
                                 &device->gtt_size) == -1) {
144 145 146 147 148 149
      /* If, for whatever reason, we can't actually get the GTT size from the
       * kernel (too old?) fall back to the aperture size.
       */
      anv_perf_warn(NULL, NULL,
                    "Failed to get I915_CONTEXT_PARAM_GTT_SIZE: %m");

150
      if (gen_get_aperture_size(fd, &device->gtt_size) == -1) {
151 152 153
         return vk_errorfi(device->instance, NULL,
                           VK_ERROR_INITIALIZATION_FAILED,
                           "failed to get aperture size: %m");
154 155 156
      }
   }

157 158 159
   /* We only allow 48-bit addresses with softpin because knowing the actual
    * address is required for the vertex cache flush workaround.
    */
160
   device->supports_48bit_addresses = (device->info.gen >= 8) &&
161
                                      device->has_softpin &&
162
                                      device->gtt_size > (4ULL << 30 /* GiB */);
163

164
   uint64_t heap_size = anv_compute_heap_size(fd, device->gtt_size);
165

166 167 168 169 170 171
   if (heap_size > (2ull << 30) && !device->supports_48bit_addresses) {
      /* When running with an overridden PCI ID, we may get a GTT size from
       * the kernel that is greater than 2 GiB but the execbuf check for 48bit
       * address support can still fail.  Just clamp the address space size to
       * 2 GiB if we don't have 48-bit support.
       */
172
      mesa_logw("%s:%d: The kernel reported a GTT size larger than 2 GiB but "
173 174 175 176 177
                        "not support for 48-bit addresses",
                        __FILE__, __LINE__);
      heap_size = 2ull << 30;
   }

178 179 180 181 182
   device->memory.heap_count = 1;
   device->memory.heaps[0] = (struct anv_memory_heap) {
      .size = heap_size,
      .flags = VK_MEMORY_HEAP_DEVICE_LOCAL_BIT,
   };
183

184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218
   uint32_t type_count = 0;
   for (uint32_t heap = 0; heap < device->memory.heap_count; heap++) {
      if (device->info.has_llc) {
         /* Big core GPUs share LLC with the CPU and thus one memory type can be
          * both cached and coherent at the same time.
          */
         device->memory.types[type_count++] = (struct anv_memory_type) {
            .propertyFlags = VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT |
                             VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT |
                             VK_MEMORY_PROPERTY_HOST_COHERENT_BIT |
                             VK_MEMORY_PROPERTY_HOST_CACHED_BIT,
            .heapIndex = heap,
         };
      } else {
         /* The spec requires that we expose a host-visible, coherent memory
          * type, but Atom GPUs don't share LLC. Thus we offer two memory types
          * to give the application a choice between cached, but not coherent and
          * coherent but uncached (WC though).
          */
         device->memory.types[type_count++] = (struct anv_memory_type) {
            .propertyFlags = VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT |
                             VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT |
                             VK_MEMORY_PROPERTY_HOST_COHERENT_BIT,
            .heapIndex = heap,
         };
         device->memory.types[type_count++] = (struct anv_memory_type) {
            .propertyFlags = VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT |
                             VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT |
                             VK_MEMORY_PROPERTY_HOST_CACHED_BIT,
            .heapIndex = heap,
         };
      }
   }
   device->memory.type_count = type_count;

219 220 221
   return VK_SUCCESS;
}

222 223
static VkResult
anv_physical_device_init_uuids(struct anv_physical_device *device)
224
{
225 226
   const struct build_id_note *note =
      build_id_find_nhdr_for_addr(anv_physical_device_init_uuids);
227
   if (!note) {
228 229 230
      return vk_errorfi(device->instance, NULL,
                        VK_ERROR_INITIALIZATION_FAILED,
                        "Failed to find build-id");
231
   }
232

233
   unsigned build_id_len = build_id_length(note);
234
   if (build_id_len < 20) {
235 236 237
      return vk_errorfi(device->instance, NULL,
                        VK_ERROR_INITIALIZATION_FAILED,
                        "build-id too short.  It needs to be a SHA");
238
   }
239

240 241
   memcpy(device->driver_build_sha1, build_id_data(note), 20);

242 243 244 245
   struct mesa_sha1 sha1_ctx;
   uint8_t sha1[20];
   STATIC_ASSERT(VK_UUID_SIZE <= sizeof(sha1));

246 247 248
   /* The pipeline cache UUID is used for determining when a pipeline cache is
    * invalid.  It needs both a driver build and the PCI ID of the device.
    */
249 250
   _mesa_sha1_init(&sha1_ctx);
   _mesa_sha1_update(&sha1_ctx, build_id_data(note), build_id_len);
251 252
   _mesa_sha1_update(&sha1_ctx, &device->info.chipset_id,
                     sizeof(device->info.chipset_id));
253 254
   _mesa_sha1_update(&sha1_ctx, &device->always_use_bindless,
                     sizeof(device->always_use_bindless));
255 256
   _mesa_sha1_update(&sha1_ctx, &device->has_a64_buffer_access,
                     sizeof(device->has_a64_buffer_access));
257 258 259 260
   _mesa_sha1_update(&sha1_ctx, &device->has_bindless_images,
                     sizeof(device->has_bindless_images));
   _mesa_sha1_update(&sha1_ctx, &device->has_bindless_samplers,
                     sizeof(device->has_bindless_samplers));
261
   _mesa_sha1_final(&sha1_ctx, sha1);
262
   memcpy(device->pipeline_cache_uuid, sha1, VK_UUID_SIZE);
263

264
   gen_uuid_compute_driver_id(device->driver_uuid, &device->info, VK_UUID_SIZE);
265
   gen_uuid_compute_device_id(device->device_uuid, &device->isl_dev, VK_UUID_SIZE);
266

267
   return VK_SUCCESS;
268 269
}

270 271 272 273
static void
anv_physical_device_init_disk_cache(struct anv_physical_device *device)
{
#ifdef ENABLE_SHADER_CACHE
274
   char renderer[10];
275
   ASSERTED int len = snprintf(renderer, sizeof(renderer), "anv_%04x",
276
                               device->info.chipset_id);
277
   assert(len == sizeof(renderer) - 2);
278 279 280 281

   char timestamp[41];
   _mesa_sha1_format(timestamp, device->driver_build_sha1);

282 283
   const uint64_t driver_flags =
      brw_get_compiler_config_value(device->compiler);
284
   device->disk_cache = disk_cache_create(renderer, timestamp, driver_flags);
285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300
#else
   device->disk_cache = NULL;
#endif
}

static void
anv_physical_device_free_disk_cache(struct anv_physical_device *device)
{
#ifdef ENABLE_SHADER_CACHE
   if (device->disk_cache)
      disk_cache_destroy(device->disk_cache);
#else
   assert(device->disk_cache == NULL);
#endif
}

Kristian Høgsberg's avatar
Kristian Høgsberg committed
301
static VkResult
302 303 304
anv_physical_device_try_create(struct anv_instance *instance,
                               drmDevicePtr drm_device,
                               struct anv_physical_device **device_out)
Kristian Høgsberg's avatar
Kristian Høgsberg committed
305
{
306 307
   const char *primary_path = drm_device->nodes[DRM_NODE_PRIMARY];
   const char *path = drm_device->nodes[DRM_NODE_RENDER];
308
   VkResult result;
309
   int fd;
310
   int master_fd = -1;
311

312 313
   brw_process_intel_debug_variable();

314
   fd = open(path, O_RDWR | O_CLOEXEC);
315 316 317 318 319 320 321 322
   if (fd < 0) {
      if (errno == ENOMEM) {
         return vk_errorfi(instance, NULL, VK_ERROR_OUT_OF_HOST_MEMORY,
                        "Unable to open device %s: out of memory", path);
      }
      return vk_errorfi(instance, NULL, VK_ERROR_INCOMPATIBLE_DRIVER,
                        "Unable to open device %s: %m", path);
   }
Kristian Høgsberg's avatar
Kristian Høgsberg committed
323

324 325
   struct gen_device_info devinfo;
   if (!gen_get_device_info_from_fd(fd, &devinfo)) {
326
      result = vk_error(VK_ERROR_INCOMPATIBLE_DRIVER);
327
      goto fail_fd;
328
   }
329

330
   const char *device_name = gen_get_device_name(devinfo.chipset_id);
331

332
   if (devinfo.is_haswell) {
333
      mesa_logw("Haswell Vulkan support is incomplete");
334
   } else if (devinfo.gen == 7 && !devinfo.is_baytrail) {
335
      mesa_logw("Ivy Bridge Vulkan support is incomplete");
336
   } else if (devinfo.gen == 7 && devinfo.is_baytrail) {
337
      mesa_logw("Bay Trail Vulkan support is incomplete");
338 339
   } else if (devinfo.gen >= 8 && devinfo.gen <= 12) {
      /* Gen8-12 fully supported */
340
   } else {
341
      result = vk_errorfi(instance, NULL, VK_ERROR_INCOMPATIBLE_DRIVER,
342
                          "Vulkan not yet supported on %s", device_name);
343 344 345 346 347 348 349 350 351
      goto fail_fd;
   }

   struct anv_physical_device *device =
      vk_alloc(&instance->alloc, sizeof(*device), 8,
               VK_SYSTEM_ALLOCATION_SCOPE_INSTANCE);
   if (device == NULL) {
      result = vk_error(VK_ERROR_OUT_OF_HOST_MEMORY);
      goto fail_fd;
352 353
   }

354
   vk_object_base_init(NULL, &device->base, VK_OBJECT_TYPE_PHYSICAL_DEVICE);
355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371
   device->instance = instance;

   assert(strlen(path) < ARRAY_SIZE(device->path));
   snprintf(device->path, ARRAY_SIZE(device->path), "%s", path);

   device->info = devinfo;
   device->name = device_name;

   device->no_hw = device->info.no_hw;
   if (getenv("INTEL_NO_HW") != NULL)
      device->no_hw = true;

   device->pci_info.domain = drm_device->businfo.pci->domain;
   device->pci_info.bus = drm_device->businfo.pci->bus;
   device->pci_info.device = drm_device->businfo.pci->dev;
   device->pci_info.function = drm_device->businfo.pci->func;

372
   device->cmd_parser_version = -1;
373
   if (device->info.gen == 7) {
374 375 376
      device->cmd_parser_version =
         anv_gem_get_param(fd, I915_PARAM_CMD_PARSER_VERSION);
      if (device->cmd_parser_version == -1) {
377 378 379
         result = vk_errorfi(device->instance, NULL,
                             VK_ERROR_INITIALIZATION_FAILED,
                             "failed to get command parser version");
380
         goto fail_alloc;
381 382 383
      }
   }

384
   if (!anv_gem_get_param(fd, I915_PARAM_HAS_WAIT_TIMEOUT)) {
385 386 387
      result = vk_errorfi(device->instance, NULL,
                          VK_ERROR_INITIALIZATION_FAILED,
                          "kernel missing gem wait");
388
      goto fail_alloc;
389
   }
Kristian Høgsberg's avatar
Kristian Høgsberg committed
390

391
   if (!anv_gem_get_param(fd, I915_PARAM_HAS_EXECBUF2)) {
392 393 394
      result = vk_errorfi(device->instance, NULL,
                          VK_ERROR_INITIALIZATION_FAILED,
                          "kernel missing execbuf2");
395
      goto fail_alloc;
396
   }
Kristian Høgsberg's avatar
Kristian Høgsberg committed
397

398
   if (!device->info.has_llc &&
399
       anv_gem_get_param(fd, I915_PARAM_MMAP_VERSION) < 1) {
400 401 402
      result = vk_errorfi(device->instance, NULL,
                          VK_ERROR_INITIALIZATION_FAILED,
                          "kernel missing wc mmap");
403
      goto fail_alloc;
404 405
   }

406
   device->has_softpin = anv_gem_get_param(fd, I915_PARAM_HAS_EXEC_SOFTPIN);
407
   device->has_exec_async = anv_gem_get_param(fd, I915_PARAM_HAS_EXEC_ASYNC);
408
   device->has_exec_capture = anv_gem_get_param(fd, I915_PARAM_HAS_EXEC_CAPTURE);
409
   device->has_exec_fence = anv_gem_get_param(fd, I915_PARAM_HAS_EXEC_FENCE);
410
   device->has_syncobj = anv_gem_get_param(fd, I915_PARAM_HAS_EXEC_FENCE_ARRAY);
411 412
   device->has_syncobj_wait = device->has_syncobj &&
                              anv_gem_supports_syncobj_wait(fd);
413 414 415
   device->has_syncobj_wait_available =
      anv_gem_get_drm_cap(fd, DRM_CAP_SYNCOBJ_TIMELINE) != 0;

416
   device->has_context_priority = anv_gem_has_context_priority(fd);
417

418 419
   result = anv_physical_device_init_heaps(device, fd);
   if (result != VK_SUCCESS)
420
      goto fail_alloc;
421

422 423
   device->use_softpin = device->has_softpin &&
                         device->supports_48bit_addresses;
424

425 426 427
   device->has_context_isolation =
      anv_gem_get_param(fd, I915_PARAM_HAS_CONTEXT_ISOLATION);

428 429 430 431 432
   device->has_exec_timeline =
      anv_gem_get_param(fd, I915_PARAM_HAS_EXEC_TIMELINE_FENCES);
   if (env_var_as_boolean("ANV_QUEUE_THREAD_DISABLE", false))
      device->has_exec_timeline = false;

433 434 435
   device->has_thread_submit =
      device->has_syncobj_wait_available && device->has_exec_timeline;

436 437 438
   device->always_use_bindless =
      env_var_as_boolean("ANV_ALWAYS_BINDLESS", false);

439 440 441 442
   device->use_call_secondary =
      device->use_softpin &&
      !env_var_as_boolean("ANV_DISABLE_SECONDARY_CMD_BUFFER_CALLS", false);

443 444 445 446 447
   /* We first got the A64 messages on broadwell and we can only use them if
    * we can pass addresses directly into the shader which requires softpin.
    */
   device->has_a64_buffer_access = device->info.gen >= 8 &&
                                   device->use_softpin;
448

449 450 451 452 453 454 455 456 457 458 459 460 461
   /* We first get bindless image access on Skylake and we can only really do
    * it if we don't have any relocations so we need softpin.
    */
   device->has_bindless_images = device->info.gen >= 9 &&
                                 device->use_softpin;

   /* We've had bindless samplers since Ivy Bridge (forever in Vulkan terms)
    * because it's just a matter of setting the sampler address in the sample
    * message header.  However, we've not bothered to wire it up for vec4 so
    * we leave it disabled on gen7.
    */
   device->has_bindless_samplers = device->info.gen >= 8;

462 463
   device->has_implicit_ccs = device->info.has_aux_map;

464 465 466 467 468
   /* Check if we can read the GPU timestamp register from the CPU */
   uint64_t u64_ignore;
   device->has_reg_timestamp = anv_gem_reg_read(fd, TIMESTAMP | I915_REG_READ_8B_WA,
                                                &u64_ignore) == 0;

469 470
   uint64_t avail_mem;
   device->has_mem_available = os_get_available_system_memory(&avail_mem);
471

472 473 474
   device->always_flush_cache =
      driQueryOptionb(&instance->dri_options, "always_flush_cache");

475 476 477
   device->has_mmap_offset =
      anv_gem_get_param(fd, I915_PARAM_MMAP_GTT_VERSION) >= 4;

478
   /* GENs prior to 8 do not support EU/Subslice info */
479
   if (device->info.gen >= 8) {
480 481 482 483 484 485 486 487
      device->subslice_total = anv_gem_get_param(fd, I915_PARAM_SUBSLICE_TOTAL);
      device->eu_total = anv_gem_get_param(fd, I915_PARAM_EU_TOTAL);

      /* Without this information, we cannot get the right Braswell
       * brandstrings, and we have to use conservative numbers for GPGPU on
       * many platforms, but otherwise, things will just work.
       */
      if (device->subslice_total < 1 || device->eu_total < 1) {
488
         mesa_logw("Kernel 4.1 required to properly query GPU properties");
489
      }
490 491
   } else if (device->info.gen == 7) {
      device->subslice_total = 1 << (device->info.gt - 1);
492 493
   }

494
   if (device->info.is_cherryview &&
495
       device->subslice_total > 0 && device->eu_total > 0) {
496 497 498
      /* Logical CS threads = EUs per subslice * num threads per EU */
      uint32_t max_cs_threads =
         device->eu_total / device->subslice_total * device->info.num_thread_per_eu;
499 500

      /* Fuse configurations may give more threads than expected, never less. */
501 502
      if (max_cs_threads > device->info.max_cs_threads)
         device->info.max_cs_threads = max_cs_threads;
503 504
   }

505
   device->compiler = brw_compiler_create(NULL, &device->info);
506 507
   if (device->compiler == NULL) {
      result = vk_error(VK_ERROR_OUT_OF_HOST_MEMORY);
508
      goto fail_alloc;
509
   }
510 511
   device->compiler->shader_debug_log = compiler_debug_log;
   device->compiler->shader_perf_log = compiler_perf_log;
512
   device->compiler->supports_pull_constants = false;
513 514
   device->compiler->constant_buffer_0_is_relative =
      device->info.gen < 8 || !device->has_context_isolation;
515
   device->compiler->supports_shader_constants = true;
516
   device->compiler->compact_params = false;
517
   device->compiler->indirect_ubos_use_sampler = device->info.gen < 12;
518

519 520 521 522 523 524 525 526 527 528 529 530 531 532
   /* Broadwell PRM says:
    *
    *   "Before Gen8, there was a historical configuration control field to
    *    swizzle address bit[6] for in X/Y tiling modes. This was set in three
    *    different places: TILECTL[1:0], ARB_MODE[5:4], and
    *    DISP_ARB_CTL[14:13].
    *
    *    For Gen8 and subsequent generations, the swizzle fields are all
    *    reserved, and the CPU's memory controller performs all address
    *    swizzling modifications."
    */
   bool swizzled =
      device->info.gen < 8 && anv_gem_get_bit6_swizzle(fd, I915_TILING_X);

533 534 535 536
   isl_device_init(&device->isl_dev, &device->info, swizzled);

   result = anv_physical_device_init_uuids(device);
   if (result != VK_SUCCESS)
537
      goto fail_compiler;
538

539 540
   anv_physical_device_init_disk_cache(device);

541 542 543 544 545 546 547 548 549 550 551 552 553 554
   if (instance->enabled_extensions.KHR_display) {
      master_fd = open(primary_path, O_RDWR | O_CLOEXEC);
      if (master_fd >= 0) {
         /* prod the device with a GETPARAM call which will fail if
          * we don't have permission to even render on this device
          */
         if (anv_gem_get_param(master_fd, I915_PARAM_CHIPSET_ID) == 0) {
            close(master_fd);
            master_fd = -1;
         }
      }
   }
   device->master_fd = master_fd;

555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572
   struct stat st;
   if (stat(path, &st) != 0) {
      result = vk_errorfi(instance, NULL, VK_ERROR_INITIALIZATION_FAILED,
                          "failed to stat DRM node %s", path);
      goto fail_disk_cache;
   }
   device->local_node[0] = (int64_t) major(st.st_rdev);
   device->local_node[1] = (int64_t) minor(st.st_rdev);
   if (master_fd != -1) {
      if (stat(primary_path, &st) != 0) {
         result = vk_errorfi(instance, NULL, VK_ERROR_INITIALIZATION_FAILED,
                             "failed to stat DRM node %s", primary_path);
         goto fail_disk_cache;
      }
      device->master_node[0] = (int64_t) major(st.st_rdev);
      device->master_node[1] = (int64_t) minor(st.st_rdev);
   }

573
   result = anv_init_wsi(device);
574 575
   if (result != VK_SUCCESS)
      goto fail_disk_cache;
576

577 578
   device->perf = anv_get_perf(&device->info, fd);

579 580 581
   anv_physical_device_get_supported_extensions(device,
                                                &device->supported_extensions);

582

583
   device->local_fd = fd;
584

585 586
   *device_out = device;

Kristian Høgsberg's avatar
Kristian Høgsberg committed
587
   return VK_SUCCESS;
588

589 590 591 592 593 594 595
fail_disk_cache:
   anv_physical_device_free_disk_cache(device);
fail_compiler:
   ralloc_free(device->compiler);
fail_alloc:
   vk_free(&instance->alloc, device);
fail_fd:
596
   close(fd);
597 598
   if (master_fd != -1)
      close(master_fd);
599
   return result;
Kristian Høgsberg's avatar
Kristian Høgsberg committed
600 601
}

602
static void
603
anv_physical_device_destroy(struct anv_physical_device *device)
604
{
605
   anv_finish_wsi(device);
606
   anv_physical_device_free_disk_cache(device);
607
   ralloc_free(device->compiler);
608
   ralloc_free(device->perf);
609
   close(device->local_fd);
610 611
   if (device->master_fd >= 0)
      close(device->master_fd);
612
   vk_object_base_finish(&device->base);
613
   vk_free(&device->instance->alloc, device);
614 615
}

616
static void *
617
default_alloc_func(void *pUserData, size_t size, size_t align,
618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642
                   VkSystemAllocationScope allocationScope)
{
   return malloc(size);
}

static void *
default_realloc_func(void *pUserData, void *pOriginal, size_t size,
                     size_t align, VkSystemAllocationScope allocationScope)
{
   return realloc(pOriginal, size);
}

static void
default_free_func(void *pUserData, void *pMemory)
{
   free(pMemory);
}

static const VkAllocationCallbacks default_alloc = {
   .pUserData = NULL,
   .pfnAllocation = default_alloc_func,
   .pfnReallocation = default_realloc_func,
   .pfnFree = default_free_func,
};

643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660
VkResult anv_EnumerateInstanceExtensionProperties(
    const char*                                 pLayerName,
    uint32_t*                                   pPropertyCount,
    VkExtensionProperties*                      pProperties)
{
   VK_OUTARRAY_MAKE(out, pProperties, pPropertyCount);

   for (int i = 0; i < ANV_INSTANCE_EXTENSION_COUNT; i++) {
      if (anv_instance_extensions_supported.extensions[i]) {
         vk_outarray_append(&out, prop) {
            *prop = anv_instance_extensions[i];
         }
      }
   }

   return vk_outarray_status(&out);
}

661 662 663 664 665 666 667 668 669 670 671 672 673
static void
anv_init_dri_options(struct anv_instance *instance)
{
   driParseOptionInfo(&instance->available_dri_options, anv_dri_options,
                      ARRAY_SIZE(anv_dri_options));
   driParseConfigFiles(&instance->dri_options,
                       &instance->available_dri_options, 0, "anv", NULL,
                       instance->app_info.app_name,
                       instance->app_info.app_version,
                       instance->app_info.engine_name,
                       instance->app_info.engine_version);
}

674
VkResult anv_CreateInstance(
Kristian Høgsberg's avatar
Kristian Høgsberg committed
675
    const VkInstanceCreateInfo*                 pCreateInfo,
676
    const VkAllocationCallbacks*                pAllocator,
Kristian Høgsberg's avatar
Kristian Høgsberg committed
677 678 679
    VkInstance*                                 pInstance)
{
   struct anv_instance *instance;
680
   VkResult result;
Kristian Høgsberg's avatar
Kristian Høgsberg committed
681 682 683

   assert(pCreateInfo->sType == VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO);

684
   struct anv_instance_extension_table enabled_extensions = {};
685
   for (uint32_t i = 0; i < pCreateInfo->enabledExtensionCount; i++) {
686 687 688 689 690 691 692 693 694 695 696
      int idx;
      for (idx = 0; idx < ANV_INSTANCE_EXTENSION_COUNT; idx++) {
         if (strcmp(pCreateInfo->ppEnabledExtensionNames[i],
                    anv_instance_extensions[idx].extensionName) == 0)
            break;
      }

      if (idx >= ANV_INSTANCE_EXTENSION_COUNT)
         return vk_error(VK_ERROR_EXTENSION_NOT_PRESENT);

      if (!anv_instance_extensions_supported.extensions[idx])
Chad Versace's avatar
Chad Versace committed
697
         return vk_error(VK_ERROR_EXTENSION_NOT_PRESENT);
698 699

      enabled_extensions.extensions[idx] = true;
700 701
   }

702
   instance = vk_alloc2(&default_alloc, pAllocator, sizeof(*instance), 8,
703
                         VK_SYSTEM_ALLOCATION_SCOPE_INSTANCE);
Kristian Høgsberg's avatar
Kristian Høgsberg committed
704 705 706
   if (!instance)
      return vk_error(VK_ERROR_OUT_OF_HOST_MEMORY);

707
   vk_object_base_init(NULL, &instance->base, VK_OBJECT_TYPE_INSTANCE);
708 709 710 711 712 713

   if (pAllocator)
      instance->alloc = *pAllocator;
   else
      instance->alloc = default_alloc;

714 715 716 717 718 719 720 721 722 723 724 725 726 727 728
   instance->app_info = (struct anv_app_info) { .api_version = 0 };
   if (pCreateInfo->pApplicationInfo) {
      const VkApplicationInfo *app = pCreateInfo->pApplicationInfo;

      instance->app_info.app_name =
         vk_strdup(&instance->alloc, app->pApplicationName,
                   VK_SYSTEM_ALLOCATION_SCOPE_INSTANCE);
      instance->app_info.app_version = app->applicationVersion;

      instance->app_info.engine_name =
         vk_strdup(&instance->alloc, app->pEngineName,
                   VK_SYSTEM_ALLOCATION_SCOPE_INSTANCE);
      instance->app_info.engine_version = app->engineVersion;

      instance->app_info.api_version = app->apiVersion;
729 730
   }

731
   if (instance->app_info.api_version == 0)
732
      instance->app_info.api_version = VK_API_VERSION_1_0;
733

734
   instance->enabled_extensions = enabled_extensions;
735 736 737 738 739

   for (unsigned i = 0; i < ARRAY_SIZE(instance->dispatch.entrypoints); i++) {
      /* Vulkan requires that entrypoints for extensions which have not been
       * enabled must not be advertised.
       */
740 741
      if (!anv_instance_entrypoint_is_enabled(i, instance->app_info.api_version,
                                              &instance->enabled_extensions)) {
742
         instance->dispatch.entrypoints[i] = NULL;
743 744
      } else {
         instance->dispatch.entrypoints[i] =
745 746 747 748
            anv_instance_dispatch_table.entrypoints[i];
      }
   }

749
   for (unsigned i = 0; i < ARRAY_SIZE(instance->physical_device_dispatch.entrypoints); i++) {
750 751 752 753 754
      /* Vulkan requires that entrypoints for extensions which have not been
       * enabled must not be advertised.
       */
      if (!anv_physical_device_entrypoint_is_enabled(i, instance->app_info.api_version,
                                                     &instance->enabled_extensions)) {
755
         instance->physical_device_dispatch.entrypoints[i] = NULL;
756
      } else {
757
         instance->physical_device_dispatch.entrypoints[i] =
758 759 760 761
            anv_physical_device_dispatch_table.entrypoints[i];
      }
   }

762 763 764 765 766 767 768 769 770
   for (unsigned i = 0; i < ARRAY_SIZE(instance->device_dispatch.entrypoints); i++) {
      /* Vulkan requires that entrypoints for extensions which have not been
       * enabled must not be advertised.
       */
      if (!anv_device_entrypoint_is_enabled(i, instance->app_info.api_version,
                                            &instance->enabled_extensions, NULL)) {
         instance->device_dispatch.entrypoints[i] = NULL;
      } else {
         instance->device_dispatch.entrypoints[i] =
771
            anv_device_dispatch_table.entrypoints[i];
772 773 774
      }
   }

775 776
   instance->physical_devices_enumerated = false;
   list_inithead(&instance->physical_devices);
Kristian Høgsberg's avatar
Kristian Høgsberg committed
777

778 779
   result = vk_debug_report_instance_init(&instance->debug_report_callbacks);
   if (result != VK_SUCCESS) {
780
      vk_free2(&default_alloc, pAllocator, instance);
781
      return vk_error(result);
782 783
   }

784 785 786
   instance->pipeline_cache_enabled =
      env_var_as_boolean("ANV_ENABLE_PIPELINE_CACHE", true);

787
   glsl_type_singleton_init_or_ref();
788

789 790
   VG(VALGRIND_CREATE_MEMPOOL(instance, 0, false));

791
   anv_init_dri_options(instance);
Eric Engestrom's avatar
Eric Engestrom committed
792

793
   *pInstance = anv_instance_to_handle(instance);
Kristian Høgsberg's avatar
Kristian Høgsberg committed
794 795 796 797

   return VK_SUCCESS;
}

798
void anv_DestroyInstance(
799 800
    VkInstance                                  _instance,
    const VkAllocationCallbacks*                pAllocator)
Kristian Høgsberg's avatar
Kristian Høgsberg committed
801
{
802
   ANV_FROM_HANDLE(anv_instance, instance, _instance);
Kristian Høgsberg's avatar
Kristian Høgsberg committed
803

804 805 806
   if (!instance)
      return;

807 808 809
   list_for_each_entry_safe(struct anv_physical_device, pdevice,
                            &instance->physical_devices, link)
      anv_physical_device_destroy(pdevice);
810

811 812
   vk_free(&instance->alloc, (char *)instance->app_info.app_name);
   vk_free(&instance->alloc, (char *)instance->app_info.engine_name);
813

814 815
   VG(VALGRIND_DESTROY_MEMPOOL(instance));

816
   vk_debug_report_instance_destroy(&instance->debug_report_callbacks);
817

818
   glsl_type_singleton_decref();
819

Eric Engestrom's avatar
Eric Engestrom committed
820 821 822
   driDestroyOptionCache(&instance->dri_options);
   driDestroyOptionInfo(&instance->available_dri_options);

823
   vk_object_base_finish(&instance->base);
824
   vk_free(&instance->alloc, instance);
825 826
}

827
static VkResult
828
anv_enumerate_physical_devices(struct anv_instance *instance)
829
{
830 831 832 833 834
   if (instance->physical_devices_enumerated)
      return VK_SUCCESS;

   instance->physical_devices_enumerated = true;

835 836 837 838
   /* TODO: Check for more devices ? */
   drmDevicePtr devices[8];
   int max_devices;

839
   max_devices = drmGetDevices2(0, devices, ARRAY_SIZE(devices));
840
   if (max_devices < 1)
841
      return VK_SUCCESS;
842

843
   VkResult result = VK_SUCCESS;
844 845 846 847 848
   for (unsigned i = 0; i < (unsigned)max_devices; i++) {
      if (devices[i]->available_nodes & 1 << DRM_NODE_RENDER &&
          devices[i]->bustype == DRM_BUS_PCI &&
          devices[i]->deviceinfo.pci->vendor_id == 0x8086) {

849 850 851
         struct anv_physical_device *pdevice;
         result = anv_physical_device_try_create(instance, devices[i],
                                                 &pdevice);
852 853 854
         /* Incompatible DRM device, skip. */
         if (result == VK_ERROR_INCOMPATIBLE_DRIVER) {
            result = VK_SUCCESS;
855
            continue;
856 857 858 859 860
         }

         /* Error creating the physical device, report the error. */
         if (result != VK_SUCCESS)
            break;
861 862

         list_addtail(&pdevice->link, &instance->physical_devices);
863 864
      }
   }
865
   drmFreeDevices(devices, max_devices);
866

867
   /* If we successfully enumerated any devices, call it success */
868
   return result;
869
}
870

871
VkResult anv_EnumeratePhysicalDevices(
Kristian Høgsberg's avatar
Kristian Høgsberg committed
872 873 874 875
    VkInstance                                  _instance,
    uint32_t*                                   pPhysicalDeviceCount,
    VkPhysicalDevice*                           pPhysicalDevices)
{
876
   ANV_FROM_HANDLE(anv_instance, instance, _instance);
877
   VK_OUTARRAY_MAKE(out, pPhysicalDevices, pPhysicalDeviceCount);
878

879
   VkResult result = anv_enumerate_physical_devices(instance);
880 881 882
   if (result != VK_SUCCESS)
      return result;

883 884 885 886 887
   list_for_each_entry(struct anv_physical_device, pdevice,
                       &instance->physical_devices, link) {
      vk_outarray_append(&out, i) {
         *i = anv_physical_device_to_handle(pdevice);
      }
888
   }
Kristian Høgsberg's avatar
Kristian Høgsberg committed
889

890 891 892 893 894 895 896 897 898 899 900 901
   return vk_outarray_status(&out);
}

VkResult anv_EnumeratePhysicalDeviceGroups(
    VkInstance                                  _instance,
    uint32_t*                                   pPhysicalDeviceGroupCount,
    VkPhysicalDeviceGroupProperties*            pPhysicalDeviceGroupProperties)
{
   ANV_FROM_HANDLE(anv_instance, instance, _instance);
   VK_OUTARRAY_MAKE(out, pPhysicalDeviceGroupProperties,
                         pPhysicalDeviceGroupCount);

902
   VkResult result = anv_enumerate_physical_devices(instance);
903 904 905
   if (result != VK_SUCCESS)
      return result;

906 907 908 909 910 911 912
   list_for_each_entry(struct anv_physical_device, pdevice,
                       &instance->physical_devices, link) {
      vk_outarray_append(&out, p) {
         p->physicalDeviceCount = 1;
         memset(p->physicalDevices, 0, sizeof(p->physicalDevices));
         p->physicalDevices[0] = anv_physical_device_to_handle(pdevice);
         p->subsetAllocation = false;
913

914 915 916
         vk_foreach_struct(ext, p->pNext)
            anv_debug_ignored_stype(ext->sType);
      }
917
   }
Kristian Høgsberg's avatar