X-Git-Url: https://git.libre-soc.org/?a=blobdiff_plain;f=src%2Fintel%2Fvulkan%2Fanv_device.c;h=e64790e9685e27d0eac2eadb413d0dfda16c0253;hb=90ab43d1bbb825cef6fe9acd04a1e8e18cddb372;hp=7a5cb234ac5b0dddab6595557f62b264461f5be9;hpb=59f57289959702e528b68bdd0d06488089517a00;p=mesa.git diff --git a/src/intel/vulkan/anv_device.c b/src/intel/vulkan/anv_device.c index 7a5cb234ac5..e64790e9685 100644 --- a/src/intel/vulkan/anv_device.c +++ b/src/intel/vulkan/anv_device.c @@ -28,7 +28,7 @@ #include #include "anv_private.h" -#include "mesa/main/git_sha1.h" +#include "anv_timestamp.h" #include "util/strtod.h" #include "util/debug.h" @@ -67,12 +67,13 @@ anv_physical_device_init(struct anv_physical_device *device, device->_loader_data.loaderMagic = ICD_LOADER_MAGIC; device->instance = instance; - device->path = path; + + assert(strlen(path) < ARRAY_SIZE(device->path)); + strncpy(device->path, path, ARRAY_SIZE(device->path)); device->chipset_id = anv_gem_get_param(fd, I915_PARAM_CHIPSET_ID); if (!device->chipset_id) { - result = vk_errorf(VK_ERROR_INITIALIZATION_FAILED, - "failed to get chipset id: %m"); + result = VK_ERROR_INITIALIZATION_FAILED; goto fail; } @@ -99,6 +100,17 @@ anv_physical_device_init(struct anv_physical_device *device, goto fail; } + device->cmd_parser_version = -1; + if (device->info->gen == 7) { + device->cmd_parser_version = + anv_gem_get_param(fd, I915_PARAM_CMD_PARSER_VERSION); + if (device->cmd_parser_version == -1) { + result = vk_errorf(VK_ERROR_INITIALIZATION_FAILED, + "failed to get command parser version"); + goto fail; + } + } + if (anv_gem_get_aperture(fd, &device->aperture_size) == -1) { result = vk_errorf(VK_ERROR_INITIALIZATION_FAILED, "failed to get aperture size: %m"); @@ -138,6 +150,10 @@ anv_physical_device_init(struct anv_physical_device *device, device->compiler->shader_debug_log = compiler_debug_log; device->compiler->shader_perf_log = compiler_perf_log; + result = anv_init_wsi(device); + if (result != VK_SUCCESS) + goto fail; + /* XXX: Actually detect bit6 swizzling */ isl_device_init(&device->isl_dev, device->info, swizzled); @@ -151,6 +167,7 @@ fail: static void anv_physical_device_finish(struct anv_physical_device *device) { + anv_finish_wsi(device); ralloc_free(device->compiler); } @@ -159,11 +176,19 @@ static const VkExtensionProperties global_extensions[] = { .extensionName = VK_KHR_SURFACE_EXTENSION_NAME, .specVersion = 25, }, +#ifdef VK_USE_PLATFORM_XCB_KHR { .extensionName = VK_KHR_XCB_SURFACE_EXTENSION_NAME, .specVersion = 5, }, -#ifdef HAVE_WAYLAND_PLATFORM +#endif +#ifdef VK_USE_PLATFORM_XLIB_KHR + { + .extensionName = VK_KHR_XLIB_SURFACE_EXTENSION_NAME, + .specVersion = 5, + }, +#endif +#ifdef VK_USE_PLATFORM_WAYLAND_KHR { .extensionName = VK_KHR_WAYLAND_SURFACE_EXTENSION_NAME, .specVersion = 4, @@ -214,11 +239,16 @@ VkResult anv_CreateInstance( assert(pCreateInfo->sType == VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO); - uint32_t client_version = pCreateInfo->pApplicationInfo ? - pCreateInfo->pApplicationInfo->apiVersion : - VK_MAKE_VERSION(1, 0, 0); + uint32_t client_version; + if (pCreateInfo->pApplicationInfo && + pCreateInfo->pApplicationInfo->apiVersion != 0) { + client_version = pCreateInfo->pApplicationInfo->apiVersion; + } else { + client_version = VK_MAKE_VERSION(1, 0, 0); + } + if (VK_MAKE_VERSION(1, 0, 0) > client_version || - client_version > VK_MAKE_VERSION(1, 0, 3)) { + client_version > VK_MAKE_VERSION(1, 0, 0xfff)) { return vk_errorf(VK_ERROR_INCOMPATIBLE_DRIVER, "Client requested version %d.%d.%d", VK_VERSION_MAJOR(client_version), @@ -254,14 +284,10 @@ VkResult anv_CreateInstance( instance->apiVersion = client_version; instance->physicalDeviceCount = -1; - memset(instance->wsi, 0, sizeof(instance->wsi)); - _mesa_locale_init(); VG(VALGRIND_CREATE_MEMPOOL(instance, 0, false)); - anv_init_wsi(instance); - *pInstance = anv_instance_to_handle(instance); return VK_SUCCESS; @@ -279,8 +305,6 @@ void anv_DestroyInstance( anv_physical_device_finish(&instance->physicalDevice); } - anv_finish_wsi(instance); - VG(VALGRIND_DESTROY_MEMPOOL(instance)); _mesa_locale_fini(); @@ -297,8 +321,15 @@ VkResult anv_EnumeratePhysicalDevices( VkResult result; if (instance->physicalDeviceCount < 0) { - result = anv_physical_device_init(&instance->physicalDevice, - instance, "/dev/dri/renderD128"); + char path[20]; + for (unsigned i = 0; i < 8; i++) { + snprintf(path, sizeof(path), "/dev/dri/renderD%d", 128 + i); + result = anv_physical_device_init(&instance->physicalDevice, + instance, path); + if (result == VK_SUCCESS) + break; + } + if (result == VK_ERROR_INCOMPATIBLE_DRIVER) { instance->physicalDeviceCount = 0; } else if (result == VK_SUCCESS) { @@ -347,15 +378,15 @@ void anv_GetPhysicalDeviceFeatures( .robustBufferAccess = true, .fullDrawIndexUint32 = true, .imageCubeArray = false, - .independentBlend = pdevice->info->gen >= 8, + .independentBlend = true, .geometryShader = true, .tessellationShader = false, - .sampleRateShading = false, + .sampleRateShading = true, .dualSrcBlend = true, .logicOp = true, .multiDrawIndirect = false, .drawIndirectFirstInstance = false, - .depthClamp = false, + .depthClamp = true, .depthBiasClamp = false, .fillModeNonSolid = true, .depthBounds = false, @@ -364,15 +395,15 @@ void anv_GetPhysicalDeviceFeatures( .alphaToOne = true, .multiViewport = true, .samplerAnisotropy = false, /* FINISHME */ - .textureCompressionETC2 = true, - .textureCompressionASTC_LDR = true, + .textureCompressionETC2 = pdevice->info->gen >= 8 || + pdevice->info->is_baytrail, + .textureCompressionASTC_LDR = pdevice->info->gen >= 9, /* FINISHME CHV */ .textureCompressionBC = true, .occlusionQueryPrecise = true, - .pipelineStatisticsQuery = true, - .vertexPipelineStoresAndAtomics = pdevice->info->gen >= 8, + .pipelineStatisticsQuery = false, .fragmentStoresAndAtomics = true, .shaderTessellationAndGeometryPointSize = true, - .shaderImageGatherExtended = true, + .shaderImageGatherExtended = false, .shaderStorageImageExtendedFormats = false, .shaderStorageImageMultisample = false, .shaderUniformBufferArrayDynamicIndexing = true, @@ -390,13 +421,18 @@ void anv_GetPhysicalDeviceFeatures( .variableMultisampleRate = false, .inheritedQueries = false, }; + + /* We can't do image stores in vec4 shaders */ + pFeatures->vertexPipelineStoresAndAtomics = + pdevice->compiler->scalar_stage[MESA_SHADER_VERTEX] && + pdevice->compiler->scalar_stage[MESA_SHADER_GEOMETRY]; } void anv_device_get_cache_uuid(void *uuid) { memset(uuid, 0, VK_UUID_SIZE); - snprintf(uuid, VK_UUID_SIZE, "anv-%s", MESA_GIT_SHA1 + 4); + snprintf(uuid, VK_UUID_SIZE, "anv-%s", ANV_TIMESTAMP); } void anv_GetPhysicalDeviceProperties( @@ -406,22 +442,24 @@ void anv_GetPhysicalDeviceProperties( ANV_FROM_HANDLE(anv_physical_device, pdevice, physicalDevice); const struct brw_device_info *devinfo = pdevice->info; - anv_finishme("Get correct values for VkPhysicalDeviceLimits"); - const float time_stamp_base = devinfo->gen >= 9 ? 83.333 : 80.0; + /* See assertions made when programming the buffer surface state. */ + const uint32_t max_raw_buffer_sz = devinfo->gen >= 7 ? + (1ul << 30) : (1ul << 27); + VkSampleCountFlags sample_counts = isl_device_get_sample_counts(&pdevice->isl_dev); VkPhysicalDeviceLimits limits = { .maxImageDimension1D = (1 << 14), .maxImageDimension2D = (1 << 14), - .maxImageDimension3D = (1 << 10), + .maxImageDimension3D = (1 << 11), .maxImageDimensionCube = (1 << 14), - .maxImageArrayLayers = (1 << 10), + .maxImageArrayLayers = (1 << 11), .maxTexelBufferElements = 128 * 1024 * 1024, - .maxUniformBufferRange = UINT32_MAX, - .maxStorageBufferRange = UINT32_MAX, + .maxUniformBufferRange = (1ul << 27), + .maxStorageBufferRange = max_raw_buffer_sz, .maxPushConstantsSize = MAX_PUSH_CONSTANTS_SIZE, .maxMemoryAllocationCount = UINT32_MAX, .maxSamplerAllocationCount = 64 * 1024, @@ -482,7 +520,7 @@ void anv_GetPhysicalDeviceProperties( .maxSamplerAnisotropy = 16, .maxViewports = MAX_VIEWPORTS, .maxViewportDimensions = { (1 << 14), (1 << 14) }, - .viewportBoundsRange = { -16384.0, 16384.0 }, + .viewportBoundsRange = { INT16_MIN, INT16_MAX }, .viewportSubPixelBits = 13, /* We take a float? */ .minMemoryMapAlignment = 4096, /* A page */ .minTexelBufferOffsetAlignment = 1, @@ -492,9 +530,9 @@ void anv_GetPhysicalDeviceProperties( .maxTexelOffset = 7, .minTexelGatherOffset = -8, .maxTexelGatherOffset = 7, - .minInterpolationOffset = 0, /* FIXME */ - .maxInterpolationOffset = 0, /* FIXME */ - .subPixelInterpolationOffsetBits = 0, /* FIXME */ + .minInterpolationOffset = -0.5, + .maxInterpolationOffset = 0.4375, + .subPixelInterpolationOffsetBits = 4, .maxFramebufferWidth = (1 << 14), .maxFramebufferHeight = (1 << 14), .maxFramebufferLayers = (1 << 10), @@ -527,7 +565,7 @@ void anv_GetPhysicalDeviceProperties( }; *pProperties = (VkPhysicalDeviceProperties) { - .apiVersion = VK_MAKE_VERSION(1, 0, 2), + .apiVersion = VK_MAKE_VERSION(1, 0, 5), .driverVersion = 1, .vendorID = 0x8086, .deviceID = pdevice->chipset_id, @@ -711,8 +749,7 @@ anv_device_submit_simple_batch(struct anv_device *device, /* Kernel driver requires 8 byte aligned batch length */ size = align_u32(batch->next - batch->start, 8); - assert(size < device->batch_bo_pool.bo_size); - result = anv_bo_pool_alloc(&device->batch_bo_pool, &bo); + result = anv_bo_pool_alloc(&device->batch_bo_pool, &bo, size); if (result != VK_SUCCESS) return result; @@ -822,9 +859,19 @@ VkResult anv_CreateDevice( device->info = *physical_device->info; device->isl_dev = physical_device->isl_dev; + /* On Broadwell and later, we can use batch chaining to more efficiently + * implement growing command buffers. Prior to Haswell, the kernel + * command parser gets in the way and we have to fall back to growing + * the batch. + */ + device->can_chain_batches = device->info.gen >= 8; + + device->robust_buffer_access = pCreateInfo->pEnabledFeatures && + pCreateInfo->pEnabledFeatures->robustBufferAccess; + pthread_mutex_init(&device->mutex, NULL); - anv_bo_pool_init(&device->batch_bo_pool, device, ANV_CMD_BUFFER_BATCH_SIZE); + anv_bo_pool_init(&device->batch_bo_pool, device); anv_block_pool_init(&device->dynamic_state_block_pool, device, 16384); @@ -841,7 +888,7 @@ VkResult anv_CreateDevice( anv_bo_init_new(&device->workaround_bo, device, 1024); - anv_block_pool_init(&device->scratch_block_pool, device, 0x10000); + anv_scratch_pool_init(device, &device->scratch_pool); anv_queue_init(device, &device->queue); @@ -910,7 +957,7 @@ void anv_DestroyDevice( anv_block_pool_finish(&device->instruction_block_pool); anv_state_pool_finish(&device->surface_state_pool); anv_block_pool_finish(&device->surface_state_block_pool); - anv_block_pool_finish(&device->scratch_block_pool); + anv_scratch_pool_finish(device, &device->scratch_pool); close(device->fd); @@ -1055,8 +1102,8 @@ VkResult anv_DeviceWaitIdle( batch.start = batch.next = cmds; batch.end = (void *) cmds + sizeof(cmds); - anv_batch_emit(&batch, GEN7_MI_BATCH_BUFFER_END); - anv_batch_emit(&batch, GEN7_MI_NOOP); + anv_batch_emit(&batch, GEN7_MI_BATCH_BUFFER_END, bbe); + anv_batch_emit(&batch, GEN7_MI_NOOP, noop); return anv_device_submit_simple_batch(device, &batch); } @@ -1378,35 +1425,33 @@ VkResult anv_CreateFence( VkFence* pFence) { ANV_FROM_HANDLE(anv_device, device, _device); + struct anv_bo fence_bo; struct anv_fence *fence; struct anv_batch batch; VkResult result; - const uint32_t fence_size = 128; - assert(pCreateInfo->sType == VK_STRUCTURE_TYPE_FENCE_CREATE_INFO); - fence = anv_alloc2(&device->alloc, pAllocator, sizeof(*fence), 8, - VK_SYSTEM_ALLOCATION_SCOPE_OBJECT); - if (fence == NULL) - return vk_error(VK_ERROR_OUT_OF_HOST_MEMORY); - - result = anv_bo_init_new(&fence->bo, device, fence_size); + result = anv_bo_pool_alloc(&device->batch_bo_pool, &fence_bo, 4096); if (result != VK_SUCCESS) - goto fail; + return result; + + /* Fences are small. Just store the CPU data structure in the BO. */ + fence = fence_bo.map; + fence->bo = fence_bo; - fence->bo.map = - anv_gem_mmap(device, fence->bo.gem_handle, 0, fence->bo.size, 0); - batch.next = batch.start = fence->bo.map; + /* Place the batch after the CPU data but on its own cache line. */ + const uint32_t batch_offset = align_u32(sizeof(*fence), CACHELINE_SIZE); + batch.next = batch.start = fence->bo.map + batch_offset; batch.end = fence->bo.map + fence->bo.size; - anv_batch_emit(&batch, GEN7_MI_BATCH_BUFFER_END); - anv_batch_emit(&batch, GEN7_MI_NOOP); + anv_batch_emit(&batch, GEN7_MI_BATCH_BUFFER_END, bbe); + anv_batch_emit(&batch, GEN7_MI_NOOP, noop); if (!device->info.has_llc) { - assert(((uintptr_t) fence->bo.map & CACHELINE_MASK) == 0); - assert(batch.next - fence->bo.map <= CACHELINE_SIZE); + assert(((uintptr_t) batch.start & CACHELINE_MASK) == 0); + assert(batch.next - batch.start <= CACHELINE_SIZE); __builtin_ia32_mfence(); - __builtin_ia32_clflush(fence->bo.map); + __builtin_ia32_clflush(batch.start); } fence->exec2_objects[0].handle = fence->bo.gem_handle; @@ -1420,8 +1465,8 @@ VkResult anv_CreateFence( fence->execbuf.buffers_ptr = (uintptr_t) fence->exec2_objects; fence->execbuf.buffer_count = 1; - fence->execbuf.batch_start_offset = 0; - fence->execbuf.batch_len = batch.next - fence->bo.map; + fence->execbuf.batch_start_offset = batch.start - fence->bo.map; + fence->execbuf.batch_len = batch.next - batch.start; fence->execbuf.cliprects_ptr = 0; fence->execbuf.num_cliprects = 0; fence->execbuf.DR1 = 0; @@ -1437,11 +1482,6 @@ VkResult anv_CreateFence( *pFence = anv_fence_to_handle(fence); return VK_SUCCESS; - - fail: - anv_free2(&device->alloc, pAllocator, fence); - - return result; } void anv_DestroyFence( @@ -1452,9 +1492,8 @@ void anv_DestroyFence( ANV_FROM_HANDLE(anv_device, device, _device); ANV_FROM_HANDLE(anv_fence, fence, _fence); - anv_gem_munmap(fence->bo.map, fence->bo.size); - anv_gem_close(device, fence->bo.gem_handle); - anv_free2(&device->alloc, pAllocator, fence); + assert(fence->bo.map == fence); + anv_bo_pool_free(&device->batch_bo_pool, &fence->bo); } VkResult anv_ResetFences( @@ -1692,24 +1731,12 @@ anv_fill_buffer_surface_state(struct anv_device *device, struct anv_state state, enum isl_format format, uint32_t offset, uint32_t range, uint32_t stride) { - switch (device->info.gen) { - case 7: - if (device->info.is_haswell) - gen75_fill_buffer_surface_state(state.map, format, offset, range, - stride); - else - gen7_fill_buffer_surface_state(state.map, format, offset, range, - stride); - break; - case 8: - gen8_fill_buffer_surface_state(state.map, format, offset, range, stride); - break; - case 9: - gen9_fill_buffer_surface_state(state.map, format, offset, range, stride); - break; - default: - unreachable("unsupported gen\n"); - } + isl_buffer_fill_state(&device->isl_dev, state.map, + .address = offset, + .mocs = device->default_mocs, + .size = range, + .format = format, + .stride = stride); if (!device->info.has_llc) anv_state_clflush(state);