zink: switch to passing VkPhysicalDeviceFeatures2 in VkDeviceCreateInfo
[mesa.git] / src / gallium / drivers / zink / zink_screen.c
index b3299976f8f3ddd2ae185e7d2581963c35413112..71b7345dc88d331d553743ca03e47ed5d19251b5 100644 (file)
@@ -37,7 +37,7 @@
 #include "util/u_screen.h"
 #include "util/u_string.h"
 
-#include "state_tracker/sw_winsys.h"
+#include "frontend/sw_winsys.h"
 
 static const struct debug_named_value
 debug_options[] = {
@@ -80,8 +80,11 @@ static int
 get_video_mem(struct zink_screen *screen)
 {
    VkDeviceSize size = 0;
-   for (uint32_t i = 0; i < screen->mem_props.memoryHeapCount; ++i)
-      size += screen->mem_props.memoryHeaps[i].size;
+   for (uint32_t i = 0; i < screen->mem_props.memoryHeapCount; ++i) {
+      if (screen->mem_props.memoryHeaps[i].flags &
+          VK_MEMORY_HEAP_DEVICE_LOCAL_BIT)
+         size += screen->mem_props.memoryHeaps[i].size;
+   }
    return (int)(size >> 20);
 }
 
@@ -113,6 +116,9 @@ zink_get_param(struct pipe_screen *pscreen, enum pipe_cap param)
       return 1;
 #endif
 
+   case PIPE_CAP_TEXTURE_MULTISAMPLE:
+      return 1;
+
    case PIPE_CAP_TEXTURE_SWIZZLE:
       return 1;
 
@@ -154,9 +160,12 @@ zink_get_param(struct pipe_screen *pscreen, enum pipe_cap param)
    case PIPE_CAP_VERTEX_COLOR_UNCLAMPED:
       return 1;
 
+   case PIPE_CAP_CONDITIONAL_RENDER:
+     return screen->have_EXT_conditional_rendering;
+
    case PIPE_CAP_GLSL_FEATURE_LEVEL:
    case PIPE_CAP_GLSL_FEATURE_LEVEL_COMPATIBILITY:
-      return 120;
+      return 130;
 
 #if 0 /* TODO: Enable me */
    case PIPE_CAP_COMPUTE:
@@ -193,7 +202,7 @@ zink_get_param(struct pipe_screen *pscreen, enum pipe_cap param)
       return PIPE_ENDIAN_NATIVE; /* unsure */
 
    case PIPE_CAP_MAX_VIEWPORTS:
-      return screen->props.limits.maxViewports;
+      return 1; /* TODO: When GS is supported, use screen->props.limits.maxViewports */
 
    case PIPE_CAP_MIXED_FRAMEBUFFER_SIZES:
       return 1;
@@ -261,10 +270,8 @@ zink_get_param(struct pipe_screen *pscreen, enum pipe_cap param)
    case PIPE_CAP_PCI_FUNCTION:
       return 0; /* TODO: figure these out */
 
-#if 0 /* TODO: Enable me */
    case PIPE_CAP_CULL_DISTANCE:
       return screen->feats.shaderCullDistance;
-#endif
 
    case PIPE_CAP_VIEWPORT_SUBPIXEL_BITS:
       return screen->props.limits.viewportSubPixelBits;
@@ -298,6 +305,9 @@ zink_get_param(struct pipe_screen *pscreen, enum pipe_cap param)
    case PIPE_CAP_TGSI_FS_FACE_IS_INTEGER_SYSVAL:
       return 1;
 
+   case PIPE_CAP_VIEWPORT_TRANSFORM_LOWERED:
+      return 1;
+
    case PIPE_CAP_FLATSHADE:
    case PIPE_CAP_ALPHA_TEST:
    case PIPE_CAP_CLIP_PLANES:
@@ -386,9 +396,15 @@ zink_get_shader_param(struct pipe_screen *pscreen,
       }
 
    case PIPE_SHADER_CAP_MAX_TEXTURE_SAMPLERS:
-      /* this might be a bit simplistic... */
-      return MIN2(screen->props.limits.maxPerStageDescriptorSamplers,
-                  PIPE_MAX_SAMPLERS);
+      switch (shader) {
+      case PIPE_SHADER_VERTEX:
+      case PIPE_SHADER_FRAGMENT:
+         /* this might be a bit simplistic... */
+         return MIN2(screen->props.limits.maxPerStageDescriptorSamplers,
+                     PIPE_MAX_SAMPLERS);
+      default:
+         return 0; /* unsupported stage */
+      }
 
    case PIPE_SHADER_CAP_MAX_CONST_BUFFER_SIZE:
       return MIN2(screen->props.limits.maxUniformBufferRange, INT_MAX);
@@ -409,6 +425,8 @@ zink_get_shader_param(struct pipe_screen *pscreen,
    case PIPE_SHADER_CAP_SUBROUTINES:
    case PIPE_SHADER_CAP_INT64_ATOMICS:
    case PIPE_SHADER_CAP_FP16:
+   case PIPE_SHADER_CAP_FP16_DERIVATIVES:
+   case PIPE_SHADER_CAP_INT16:
       return 0; /* not implemented */
 
    case PIPE_SHADER_CAP_PREFERRED_IR:
@@ -440,8 +458,12 @@ zink_get_shader_param(struct pipe_screen *pscreen,
       return (1 << PIPE_SHADER_IR_NIR) | (1 << PIPE_SHADER_IR_TGSI);
 
    case PIPE_SHADER_CAP_MAX_SHADER_IMAGES:
+#if 0 /* TODO: needs compiler support */
       return MIN2(screen->props.limits.maxPerStageDescriptorStorageImages,
                   PIPE_MAX_SHADER_IMAGES);
+#else
+      return 0;
+#endif
 
    case PIPE_SHADER_CAP_LOWER_IF_THRESHOLD:
    case PIPE_SHADER_CAP_TGSI_SKIP_MERGE_REGISTERS:
@@ -698,10 +720,40 @@ zink_flush_frontbuffer(struct pipe_screen *pscreen,
       winsys->displaytarget_display(winsys, res->dt, winsys_drawable_handle, sub_box);
 }
 
+static bool
+load_device_extensions(struct zink_screen *screen)
+{
+#define GET_PROC_ADDR(x) do {                                               \
+      screen->vk_##x = (PFN_vk##x)vkGetDeviceProcAddr(screen->dev, "vk"#x); \
+      if (!screen->vk_##x)                                                  \
+         return false;                                                      \
+   } while (0)
+   if (screen->have_EXT_transform_feedback) {
+      GET_PROC_ADDR(CmdBindTransformFeedbackBuffersEXT);
+      GET_PROC_ADDR(CmdBeginTransformFeedbackEXT);
+      GET_PROC_ADDR(CmdEndTransformFeedbackEXT);
+      GET_PROC_ADDR(CmdBeginQueryIndexedEXT);
+      GET_PROC_ADDR(CmdEndQueryIndexedEXT);
+      GET_PROC_ADDR(CmdDrawIndirectByteCountEXT);
+   }
+   if (screen->have_KHR_external_memory_fd)
+      GET_PROC_ADDR(GetMemoryFdKHR);
+
+   if (screen->have_EXT_conditional_rendering) {
+      GET_PROC_ADDR(CmdBeginConditionalRenderingEXT);
+      GET_PROC_ADDR(CmdEndConditionalRenderingEXT);
+   }
+
+#undef GET_PROC_ADDR
+
+   return true;
+}
+
 static struct pipe_screen *
 zink_internal_create_screen(struct sw_winsys *winsys, int fd)
 {
    struct zink_screen *screen = CALLOC_STRUCT(zink_screen);
+   bool have_cond_render_ext = false;
    if (!screen)
       return NULL;
 
@@ -711,8 +763,6 @@ zink_internal_create_screen(struct sw_winsys *winsys, int fd)
    screen->pdev = choose_pdev(screen->instance);
    screen->gfx_queue = find_gfx_queue(screen->pdev);
 
-   vkGetPhysicalDeviceProperties(screen->pdev, &screen->props);
-   vkGetPhysicalDeviceFeatures(screen->pdev, &screen->feats);
    vkGetPhysicalDeviceMemoryProperties(screen->pdev, &screen->mem_props);
 
    screen->have_X8_D24_UNORM_PACK32 = zink_is_depth_format_supported(screen,
@@ -736,10 +786,32 @@ zink_internal_create_screen(struct sw_winsys *winsys, int fd)
             if (!strcmp(extensions[i].extensionName,
                         VK_KHR_EXTERNAL_MEMORY_FD_EXTENSION_NAME))
                screen->have_KHR_external_memory_fd = true;
+            if (!strcmp(extensions[i].extensionName,
+                        VK_EXT_CONDITIONAL_RENDERING_EXTENSION_NAME))
+               have_cond_render_ext = true;
+
          }
          FREE(extensions);
       }
    }
+   VkPhysicalDeviceFeatures2 feats = {};
+   VkPhysicalDeviceConditionalRenderingFeaturesEXT cond_render_feats = {};
+
+   feats.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FEATURES_2;
+   if (have_cond_render_ext) {
+      cond_render_feats.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_CONDITIONAL_RENDERING_FEATURES_EXT;
+      cond_render_feats.pNext = feats.pNext;
+      feats.pNext = &cond_render_feats;
+   }
+   vkGetPhysicalDeviceFeatures2(screen->pdev, &feats);
+   memcpy(&screen->feats, &feats.features, sizeof(screen->feats));
+   if (have_cond_render_ext && cond_render_feats.conditionalRendering)
+      screen->have_EXT_conditional_rendering = true;
+
+   VkPhysicalDeviceProperties2 props = {};
+   props.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROPERTIES_2;
+   vkGetPhysicalDeviceProperties2(screen->pdev, &props);
+   memcpy(&screen->props, &props.properties, sizeof(screen->props));
 
    if (!screen->have_KHR_maintenance1) {
       debug_printf("ZINK: VK_KHR_maintenance1 required!\n");
@@ -757,8 +829,11 @@ zink_internal_create_screen(struct sw_winsys *winsys, int fd)
    dci.sType = VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO;
    dci.queueCreateInfoCount = 1;
    dci.pQueueCreateInfos = &qci;
-   dci.pEnabledFeatures = &screen->feats;
-   const char *extensions[3] = {
+   /* extensions don't have bool members in pEnabledFeatures.
+    * this requires us to pass the whole VkPhysicalDeviceFeatures2 struct
+    */
+   dci.pNext = &feats;
+   const char *extensions[4] = {
       VK_KHR_MAINTENANCE1_EXTENSION_NAME,
    };
    num_extensions = 1;
@@ -772,6 +847,10 @@ zink_internal_create_screen(struct sw_winsys *winsys, int fd)
       extensions[num_extensions++] = VK_KHR_EXTERNAL_MEMORY_EXTENSION_NAME;
       extensions[num_extensions++] = VK_KHR_EXTERNAL_MEMORY_FD_EXTENSION_NAME;
    }
+
+   if (screen->have_EXT_conditional_rendering)
+      extensions[num_extensions++] = VK_EXT_CONDITIONAL_RENDERING_EXTENSION_NAME;
+
    assert(num_extensions <= ARRAY_SIZE(extensions));
 
    dci.ppEnabledExtensionNames = extensions;
@@ -779,6 +858,9 @@ zink_internal_create_screen(struct sw_winsys *winsys, int fd)
    if (vkCreateDevice(screen->pdev, &dci, NULL, &screen->dev) != VK_SUCCESS)
       goto fail;
 
+   if (!load_device_extensions(screen))
+      goto fail;
+
    screen->winsys = winsys;
 
    screen->base.get_name = zink_get_name;