ソースを参照

vulkan: Support VK_KHR_portability_subset extension (for MoltenVK)

Does not really work very well yet, validation also errors about zero stride which is apparently not supported, but some simple programs work.
rdb 2 年 前
コミット
606a6a4033

+ 3 - 0
panda/src/vulkandisplay/config_vulkandisplay.h

@@ -40,6 +40,9 @@ extern "C" EXPCL_VULKANDISPLAY int get_pipe_type_p3vulkandisplay();
 #define VK_USE_PLATFORM_XLIB_KHR
 #endif
 
+// Necessary for VK_KHR_portability_subset (MoltenVK)
+#define VK_ENABLE_BETA_EXTENSIONS
+
 #include <vulkan/vulkan.h>
 
 #ifdef HAVE_X11

+ 10 - 0
panda/src/vulkandisplay/vulkanGraphicsPipe.cxx

@@ -132,6 +132,12 @@ VulkanGraphicsPipe() : _max_allocation_size(0) {
     has_props2_ext = true;
   }
 
+  bool has_portability_enum_ext = false;
+  if (has_instance_extension(VK_KHR_PORTABILITY_ENUMERATION_EXTENSION_NAME)) {
+    extensions.push_back(VK_KHR_PORTABILITY_ENUMERATION_EXTENSION_NAME);
+    has_portability_enum_ext = true;
+  }
+
   VkApplicationInfo app_info;
   app_info.sType = VK_STRUCTURE_TYPE_APPLICATION_INFO;
   app_info.pNext = nullptr;
@@ -155,6 +161,10 @@ VulkanGraphicsPipe() : _max_allocation_size(0) {
   inst_info.enabledExtensionCount = extensions.size();
   inst_info.ppEnabledExtensionNames = &extensions[0];
 
+  if (has_portability_enum_ext) {
+    inst_info.flags |= VK_INSTANCE_CREATE_ENUMERATE_PORTABILITY_BIT_KHR;
+  }
+
   VkResult err = vkCreateInstance(&inst_info, nullptr, &_instance);
   if (err == VK_ERROR_INCOMPATIBLE_DRIVER) {
     vulkandisplay_cat.error()

+ 16 - 4
panda/src/vulkandisplay/vulkanGraphicsStateGuardian.cxx

@@ -124,6 +124,18 @@ VulkanGraphicsStateGuardian(GraphicsEngine *engine, VulkanGraphicsPipe *pipe,
     supports_null_descriptor = true;
   }
 
+  VkPhysicalDevicePortabilitySubsetFeaturesKHR portability_features = {
+    VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PORTABILITY_SUBSET_FEATURES_KHR,
+    enabled_features.pNext,
+  };
+  if (pipe->has_device_extension(VK_KHR_PORTABILITY_SUBSET_EXTENSION_NAME)) {
+    portability_features.imageViewFormatSwizzle = VK_TRUE;
+    portability_features.vertexAttributeAccessBeyondStride = VK_TRUE;
+    enabled_features.pNext = &portability_features;
+
+    extensions.push_back(VK_KHR_PORTABILITY_SUBSET_EXTENSION_NAME);
+  }
+
   // Create a queue in the given queue family.  For now, we assume NVIDIA,
   // which has only one queue family, but we want to separate this out for
   // the sake of AMD cards.
@@ -283,7 +295,7 @@ VulkanGraphicsStateGuardian(GraphicsEngine *engine, VulkanGraphicsPipe *pipe,
   }
 
   // Create a descriptor set layout for our LightAttrib descriptor set.
-  const uint32_t num_shadow_maps = 16;
+  const uint32_t num_shadow_maps = 8;
   {
     // The depth map is managed by Panda, so we can bake the sampler state into
     // the pipeline layout, which allows lower-latency samples on some cards.
@@ -341,7 +353,7 @@ VulkanGraphicsStateGuardian(GraphicsEngine *engine, VulkanGraphicsPipe *pipe,
   }
 
   // Create a descriptor set layout for our TextureAttrib descriptor set.
-  const uint32_t num_texture_stages = 16;
+  const uint32_t num_texture_stages = 8;
   {
     VkDescriptorSetLayoutBinding stage_bindings[num_texture_stages];
 
@@ -3870,7 +3882,7 @@ get_attrib_descriptor_set(VkDescriptorSet &out, VkDescriptorSetLayout layout, co
  */
 bool VulkanGraphicsStateGuardian::
 update_lattr_descriptor_set(VkDescriptorSet ds, const LightAttrib *attr) {
-  const size_t num_shadow_maps = 16;
+  const size_t num_shadow_maps = 8;
   VkWriteDescriptorSet *writes = (VkWriteDescriptorSet *)alloca(num_shadow_maps * sizeof(VkWriteDescriptorSet));
   VkDescriptorImageInfo *image_infos = (VkDescriptorImageInfo *)alloca(num_shadow_maps * sizeof(VkDescriptorImageInfo));
 
@@ -3926,7 +3938,7 @@ update_lattr_descriptor_set(VkDescriptorSet ds, const LightAttrib *attr) {
                    stage_flags, VK_ACCESS_SHADER_READ_BIT);
 
     VkDescriptorImageInfo &image_info = image_infos[i];
-    image_info.sampler = _shadow_sampler;
+    image_info.sampler = VK_NULL_HANDLE;
     image_info.imageView = tc->get_image_view(0);
     image_info.imageLayout = tc->_layout;