anv: Enable tessellation shaders.
[mesa.git] / src / intel / vulkan / anv_device.c
index 6ad5316c50cee6f7fbcc53827bbc79b1af263f11..f58d1ac24b5b926a5af113eb41dd202c93e54f2c 100644 (file)
  * IN THE SOFTWARE.
  */
 
+#include <dlfcn.h>
 #include <assert.h>
 #include <stdbool.h>
 #include <string.h>
 #include <sys/mman.h>
+#include <sys/stat.h>
 #include <unistd.h>
 #include <fcntl.h>
 
 #include "anv_private.h"
-#include "anv_timestamp.h"
 #include "util/strtod.h"
 #include "util/debug.h"
 
@@ -53,6 +54,34 @@ compiler_perf_log(void *data, const char *fmt, ...)
    va_end(args);
 }
 
+static bool
+anv_get_function_timestamp(void *ptr, uint32_t* timestamp)
+{
+   Dl_info info;
+   struct stat st;
+   if (!dladdr(ptr, &info) || !info.dli_fname)
+      return false;
+
+   if (stat(info.dli_fname, &st))
+      return false;
+
+   *timestamp = st.st_mtim.tv_sec;
+   return true;
+}
+
+static bool
+anv_device_get_cache_uuid(void *uuid)
+{
+   uint32_t timestamp;
+
+   memset(uuid, 0, VK_UUID_SIZE);
+   if (!anv_get_function_timestamp(anv_device_get_cache_uuid, &timestamp))
+      return false;
+
+   snprintf(uuid, VK_UUID_SIZE, "anv-%d", timestamp);
+   return true;
+}
+
 static VkResult
 anv_physical_device_init(struct anv_physical_device *device,
                          struct anv_instance *instance,
@@ -134,6 +163,11 @@ anv_physical_device_init(struct anv_physical_device *device,
       goto fail;
    }
 
+   if (!anv_device_get_cache_uuid(device->uuid)) {
+      result = vk_errorf(VK_ERROR_INITIALIZATION_FAILED,
+                         "cannot generate UUID");
+      goto fail;
+   }
    bool swizzled = anv_gem_get_bit6_swizzle(fd, I915_TILING_X);
 
    /* GENs prior to 8 do not support EU/Subslice info */
@@ -163,8 +197,6 @@ anv_physical_device_init(struct anv_physical_device *device,
          device->info.max_cs_threads = max_cs_threads;
    }
 
-   close(fd);
-
    brw_process_intel_debug_variable();
 
    device->compiler = brw_compiler_create(NULL, &device->info);
@@ -176,12 +208,14 @@ anv_physical_device_init(struct anv_physical_device *device,
    device->compiler->shader_perf_log = compiler_perf_log;
 
    result = anv_init_wsi(device);
-   if (result != VK_SUCCESS)
-       goto fail;
+   if (result != VK_SUCCESS) {
+      ralloc_free(device->compiler);
+      goto fail;
+   }
 
-   /* XXX: Actually detect bit6 swizzling */
    isl_device_init(&device->isl_dev, &device->info, swizzled);
 
+   close(fd);
    return VK_SUCCESS;
 
 fail:
@@ -226,6 +260,10 @@ static const VkExtensionProperties device_extensions[] = {
       .extensionName = VK_KHR_SWAPCHAIN_EXTENSION_NAME,
       .specVersion = 68,
    },
+   {
+      .extensionName = VK_KHR_SAMPLER_MIRROR_CLAMP_TO_EDGE_EXTENSION_NAME,
+      .specVersion = 1,
+   }
 };
 
 static void *
@@ -404,17 +442,17 @@ void anv_GetPhysicalDeviceFeatures(
    *pFeatures = (VkPhysicalDeviceFeatures) {
       .robustBufferAccess                       = true,
       .fullDrawIndexUint32                      = true,
-      .imageCubeArray                           = false,
+      .imageCubeArray                           = true,
       .independentBlend                         = true,
       .geometryShader                           = true,
-      .tessellationShader                       = false,
+      .tessellationShader                       = true,
       .sampleRateShading                        = true,
       .dualSrcBlend                             = true,
       .logicOp                                  = true,
       .multiDrawIndirect                        = false,
-      .drawIndirectFirstInstance                = false,
+      .drawIndirectFirstInstance                = true,
       .depthClamp                               = true,
-      .depthBiasClamp                           = false,
+      .depthBiasClamp                           = true,
       .fillModeNonSolid                         = true,
       .depthBounds                              = false,
       .wideLines                                = true,
@@ -430,21 +468,21 @@ void anv_GetPhysicalDeviceFeatures(
       .pipelineStatisticsQuery                  = false,
       .fragmentStoresAndAtomics                 = true,
       .shaderTessellationAndGeometryPointSize   = true,
-      .shaderImageGatherExtended                = false,
-      .shaderStorageImageExtendedFormats        = false,
+      .shaderImageGatherExtended                = true,
+      .shaderStorageImageExtendedFormats        = true,
       .shaderStorageImageMultisample            = false,
+      .shaderStorageImageReadWithoutFormat      = false,
+      .shaderStorageImageWriteWithoutFormat     = false,
       .shaderUniformBufferArrayDynamicIndexing  = true,
       .shaderSampledImageArrayDynamicIndexing   = true,
       .shaderStorageBufferArrayDynamicIndexing  = true,
       .shaderStorageImageArrayDynamicIndexing   = true,
-      .shaderStorageImageReadWithoutFormat      = false,
-      .shaderStorageImageWriteWithoutFormat     = true,
       .shaderClipDistance                       = true,
       .shaderCullDistance                       = true,
-      .shaderFloat64                            = false,
+      .shaderFloat64                            = pdevice->info.gen >= 8,
       .shaderInt64                              = false,
       .shaderInt16                              = false,
-      .alphaToOne                               = true,
+      .shaderResourceMinLod                     = false,
       .variableMultisampleRate                  = false,
       .inheritedQueries                         = false,
    };
@@ -455,13 +493,6 @@ void anv_GetPhysicalDeviceFeatures(
       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", ANV_TIMESTAMP);
-}
-
 void anv_GetPhysicalDeviceProperties(
     VkPhysicalDevice                            physicalDevice,
     VkPhysicalDeviceProperties*                 pProperties)
@@ -513,14 +544,14 @@ void anv_GetPhysicalDeviceProperties(
       .maxVertexInputAttributeOffset            = 2047,
       .maxVertexInputBindingStride              = 2048,
       .maxVertexOutputComponents                = 128,
-      .maxTessellationGenerationLevel           = 0,
-      .maxTessellationPatchSize                 = 0,
-      .maxTessellationControlPerVertexInputComponents = 0,
-      .maxTessellationControlPerVertexOutputComponents = 0,
-      .maxTessellationControlPerPatchOutputComponents = 0,
-      .maxTessellationControlTotalOutputComponents = 0,
-      .maxTessellationEvaluationInputComponents = 0,
-      .maxTessellationEvaluationOutputComponents = 0,
+      .maxTessellationGenerationLevel           = 64,
+      .maxTessellationPatchSize                 = 32,
+      .maxTessellationControlPerVertexInputComponents = 128,
+      .maxTessellationControlPerVertexOutputComponents = 128,
+      .maxTessellationControlPerPatchOutputComponents = 128,
+      .maxTessellationControlTotalOutputComponents = 2048,
+      .maxTessellationEvaluationInputComponents = 128,
+      .maxTessellationEvaluationOutputComponents = 128,
       .maxGeometryShaderInvocations             = 32,
       .maxGeometryInputComponents               = 64,
       .maxGeometryOutputComponents              = 128,
@@ -528,7 +559,7 @@ void anv_GetPhysicalDeviceProperties(
       .maxGeometryTotalOutputComponents         = 1024,
       .maxFragmentInputComponents               = 128,
       .maxFragmentOutputAttachments             = 8,
-      .maxFragmentDualSrcAttachments            = 2,
+      .maxFragmentDualSrcAttachments            = 1,
       .maxFragmentCombinedOutputResources       = 8,
       .maxComputeSharedMemorySize               = 32768,
       .maxComputeWorkGroupCount                 = { 65535, 65535, 65535 },
@@ -551,18 +582,18 @@ void anv_GetPhysicalDeviceProperties(
       .viewportSubPixelBits                     = 13, /* We take a float? */
       .minMemoryMapAlignment                    = 4096, /* A page */
       .minTexelBufferOffsetAlignment            = 1,
-      .minUniformBufferOffsetAlignment          = 1,
-      .minStorageBufferOffsetAlignment          = 1,
+      .minUniformBufferOffsetAlignment          = 16,
+      .minStorageBufferOffsetAlignment          = 4,
       .minTexelOffset                           = -8,
       .maxTexelOffset                           = 7,
-      .minTexelGatherOffset                     = -8,
-      .maxTexelGatherOffset                     = 7,
+      .minTexelGatherOffset                     = -32,
+      .maxTexelGatherOffset                     = 31,
       .minInterpolationOffset                   = -0.5,
       .maxInterpolationOffset                   = 0.4375,
       .subPixelInterpolationOffsetBits          = 4,
       .maxFramebufferWidth                      = (1 << 14),
       .maxFramebufferHeight                     = (1 << 14),
-      .maxFramebufferLayers                     = (1 << 10),
+      .maxFramebufferLayers                     = (1 << 11),
       .framebufferColorSampleCounts             = sample_counts,
       .framebufferDepthSampleCounts             = sample_counts,
       .framebufferStencilSampleCounts           = sample_counts,
@@ -602,7 +633,7 @@ void anv_GetPhysicalDeviceProperties(
    };
 
    strcpy(pProperties->deviceName, pdevice->name);
-   anv_device_get_cache_uuid(pProperties->pipelineCacheUUID);
+   memcpy(pProperties->pipelineCacheUUID, pdevice->uuid, VK_UUID_SIZE);
 }
 
 void anv_GetPhysicalDeviceQueueFamilyProperties(
@@ -615,7 +646,14 @@ void anv_GetPhysicalDeviceQueueFamilyProperties(
       return;
    }
 
-   assert(*pCount >= 1);
+   /* The spec implicitly allows the incoming count to be 0. From the Vulkan
+    * 1.0.38 spec, Section 4.1 Physical Devices:
+    *
+    *     If the value referenced by pQueueFamilyPropertyCount is not 0 [then
+    *     do stuff].
+    */
+   if (*pCount == 0)
+      return;
 
    *pQueueFamilyProperties = (VkQueueFamilyProperties) {
       .queueFlags = VK_QUEUE_GRAPHICS_BIT |
@@ -625,6 +663,8 @@ void anv_GetPhysicalDeviceQueueFamilyProperties(
       .timestampValidBits = 36, /* XXX: Real value here */
       .minImageTransferGranularity = (VkExtent3D) { 1, 1, 1 },
    };
+
+   *pCount = 1;
 }
 
 void anv_GetPhysicalDeviceMemoryProperties(
@@ -710,14 +750,12 @@ PFN_vkVoidFunction anv_GetDeviceProcAddr(
    return anv_lookup_entrypoint(&device->info, pName);
 }
 
-static VkResult
+static void
 anv_queue_init(struct anv_device *device, struct anv_queue *queue)
 {
    queue->_loader_data.loaderMagic = ICD_LOADER_MAGIC;
    queue->device = device;
    queue->pool = &device->surface_state_pool;
-
-   return VK_SUCCESS;
 }
 
 static void
@@ -968,10 +1006,10 @@ void anv_DestroyDevice(
 {
    ANV_FROM_HANDLE(anv_device, device, _device);
 
-   anv_queue_finish(&device->queue);
-
    anv_device_finish_blorp(device);
 
+   anv_queue_finish(&device->queue);
+
 #ifdef HAVE_VALGRIND
    /* We only need to free these to prevent valgrind errors.  The backing
     * BO will go away in a couple of lines so we don't actually leak.
@@ -979,22 +1017,27 @@ void anv_DestroyDevice(
    anv_state_pool_free(&device->dynamic_state_pool, device->border_colors);
 #endif
 
+   anv_scratch_pool_finish(device, &device->scratch_pool);
+
    anv_gem_munmap(device->workaround_bo.map, device->workaround_bo.size);
    anv_gem_close(device, device->workaround_bo.gem_handle);
 
-   anv_bo_pool_finish(&device->batch_bo_pool);
-   anv_state_pool_finish(&device->dynamic_state_pool);
-   anv_block_pool_finish(&device->dynamic_state_block_pool);
-   anv_state_pool_finish(&device->instruction_state_pool);
-   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_scratch_pool_finish(device, &device->scratch_pool);
+   anv_state_pool_finish(&device->instruction_state_pool);
+   anv_block_pool_finish(&device->instruction_block_pool);
+   anv_state_pool_finish(&device->dynamic_state_pool);
+   anv_block_pool_finish(&device->dynamic_state_block_pool);
 
-   close(device->fd);
+   anv_bo_pool_finish(&device->batch_bo_pool);
 
+   pthread_cond_destroy(&device->queue_submit);
    pthread_mutex_destroy(&device->mutex);
 
+   anv_gem_destroy_context(device, device->context_id);
+
+   close(device->fd);
+
    vk_free(&device->alloc, device);
 }
 
@@ -1008,10 +1051,11 @@ VkResult anv_EnumerateInstanceExtensionProperties(
       return VK_SUCCESS;
    }
 
-   assert(*pPropertyCount >= ARRAY_SIZE(global_extensions));
+   *pPropertyCount = MIN2(*pPropertyCount, ARRAY_SIZE(global_extensions));
+   typed_memcpy(pProperties, global_extensions, *pPropertyCount);
 
-   *pPropertyCount = ARRAY_SIZE(global_extensions);
-   memcpy(pProperties, global_extensions, sizeof(global_extensions));
+   if (*pPropertyCount < ARRAY_SIZE(global_extensions))
+      return VK_INCOMPLETE;
 
    return VK_SUCCESS;
 }
@@ -1027,10 +1071,11 @@ VkResult anv_EnumerateDeviceExtensionProperties(
       return VK_SUCCESS;
    }
 
-   assert(*pPropertyCount >= ARRAY_SIZE(device_extensions));
+   *pPropertyCount = MIN2(*pPropertyCount, ARRAY_SIZE(device_extensions));
+   typed_memcpy(pProperties, device_extensions, *pPropertyCount);
 
-   *pPropertyCount = ARRAY_SIZE(device_extensions);
-   memcpy(pProperties, device_extensions, sizeof(device_extensions));
+   if (*pPropertyCount < ARRAY_SIZE(device_extensions))
+      return VK_INCOMPLETE;
 
    return VK_SUCCESS;
 }
@@ -1210,11 +1255,8 @@ VkResult anv_AllocateMemory(
 
    assert(pAllocateInfo->sType == VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO);
 
-   if (pAllocateInfo->allocationSize == 0) {
-      /* Apparently, this is allowed */
-      *pMem = VK_NULL_HANDLE;
-      return VK_SUCCESS;
-   }
+   /* The Vulkan 1.0.33 spec says "allocationSize must be greater than 0". */
+   assert(pAllocateInfo->allocationSize > 0);
 
    /* We support exactly one memory heap. */
    assert(pAllocateInfo->memoryTypeIndex == 0 ||