浏览代码

Vulkan: support 1.0.11 SDK, fix vertex colors, pre-clear swapchain images

rdb 9 年之前
父节点
当前提交
1232210050

+ 12 - 3
makepanda/makepandacore.py

@@ -2215,11 +2215,20 @@ def SdkLocateVulkan():
 
     path = 'C:/VulkanSDK'
     if os.path.isdir(path):
+        # Enumerate the available Vulkan SDK versions.
+        versions = []
+        for dir in os.listdir(path):
+            try:
+                versions.append(tuple([int(i) for i in dir.split('.')]))
+            except ValueError:
+                pass
+
         # Use the latest version.
-        versions = os.listdir(path)
         versions.sort()
-        print("Using Vulkan SDK %s" % (versions[-1]))
-        SDK["VULKAN"] = path + '/' + versions[-1]
+        version = '.'.join([str(i) for i in versions[-1]])
+
+        print("Using Vulkan SDK %s" % (version))
+        SDK["VULKAN"] = path + '/' + version
 
 ########################################################################
 ##

+ 28 - 6
panda/src/vulkandisplay/vulkanGraphicsStateGuardian.cxx

@@ -1964,16 +1964,26 @@ make_pipeline(const RenderState *state, const GeomVertexFormat *format,
     attrib_desc[i].binding = array_index;
     attrib_desc[i].offset = column->get_start();
 
+    bool normalized = (column->get_contents() == GeomEnums::C_color);
+
     // Determine which Vulkan format to map this column to.  The formats are
     // laid out somewhat (though not entirely) consistently, so we can use a
     // trick to jump to the format for the right number of components.
     int fmt_jump = column->get_num_components() - 1;
     switch (column->get_numeric_type()) {
     case GeomEnums::NT_uint8:
-      if (fmt_jump < 3) {
-        attrib_desc[i].format = (VkFormat)(VK_FORMAT_R8_UINT + 7 * fmt_jump);
+      if (normalized) {
+        if (fmt_jump < 3) {
+          attrib_desc[i].format = (VkFormat)(VK_FORMAT_R8_UNORM + 7 * fmt_jump);
+        } else {
+          attrib_desc[i].format = VK_FORMAT_R8G8B8A8_UNORM;
+        }
       } else {
-        attrib_desc[i].format = VK_FORMAT_R8G8B8A8_UINT;
+        if (fmt_jump < 3) {
+          attrib_desc[i].format = (VkFormat)(VK_FORMAT_R8_UINT + 7 * fmt_jump);
+        } else {
+          attrib_desc[i].format = VK_FORMAT_R8G8B8A8_UINT;
+        }
       }
       break;
     case GeomEnums::NT_uint16:
@@ -1983,16 +1993,28 @@ make_pipeline(const RenderState *state, const GeomVertexFormat *format,
       attrib_desc[i].format = (VkFormat)(VK_FORMAT_R32_UINT + 3 * fmt_jump);
       break;
     case GeomEnums::NT_packed_dcba:
-      attrib_desc[i].format = VK_FORMAT_B8G8R8A8_UINT;
+      if (normalized) {
+        attrib_desc[i].format = VK_FORMAT_B8G8R8A8_UNORM;
+      } else {
+        attrib_desc[i].format = VK_FORMAT_B8G8R8A8_UINT;
+      }
       break;
     case GeomEnums::NT_packed_dabc:
-      attrib_desc[i].format = VK_FORMAT_A8B8G8R8_UINT_PACK32;
+      if (normalized) {
+        attrib_desc[i].format = VK_FORMAT_A8B8G8R8_UNORM_PACK32;
+      } else {
+        attrib_desc[i].format = VK_FORMAT_A8B8G8R8_UINT_PACK32;
+      }
       break;
+#ifndef STDFLOAT_DOUBLE
     case GeomEnums::NT_stdfloat:
-      assert(false);
+#endif
     case GeomEnums::NT_float32:
       attrib_desc[i].format = (VkFormat)(VK_FORMAT_R32_SFLOAT + 3 * fmt_jump);
       break;
+#ifdef STDFLOAT_DOUBLE
+    case GeomEnums::NT_stdfloat:
+#endif
     case GeomEnums::NT_float64:
       attrib_desc[i].format = (VkFormat)(VK_FORMAT_R64_SFLOAT + 3 * fmt_jump);
       break;

+ 33 - 2
panda/src/vulkandisplay/vulkanGraphicsWindow.cxx

@@ -185,8 +185,39 @@ begin_frame(FrameMode mode, Thread *current_thread) {
   if (!buffer._layout_defined) {
     // If this is the first time we are using these images, they are still in
     // the UNDEFINED layout.
-    barriers[0].srcAccessMask = 0;
-    barriers[0].oldLayout = VK_IMAGE_LAYOUT_UNDEFINED;
+    if (!get_clear_color_active()) {
+      // If the attachment is set to LOAD, we need to clear it for the first
+      // time if we don't want the validation layer to yell at us.  This means
+      // we need to transition it to TRANSFER_DST_OPTIMAL first.
+      VkImageMemoryBarrier barrier;
+      barrier.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER;
+      barrier.pNext = NULL;
+      barrier.srcAccessMask = 0;
+      barrier.dstAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT;
+      barrier.oldLayout = VK_IMAGE_LAYOUT_UNDEFINED;
+      barrier.newLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
+      barrier.srcQueueFamilyIndex = vkgsg->_graphics_queue_family_index;
+      barrier.dstQueueFamilyIndex = vkgsg->_graphics_queue_family_index;
+      barrier.image = buffer._image;
+      barrier.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
+      barrier.subresourceRange.baseMipLevel = 0;
+      barrier.subresourceRange.levelCount = 1;
+      barrier.subresourceRange.baseArrayLayer = 0;
+      barrier.subresourceRange.layerCount = 1;
+      vkCmdPipelineBarrier(cmd, 0, VK_PIPELINE_STAGE_TRANSFER_BIT, 0,
+                           0, NULL, 0, NULL, 1, &barrier);
+
+      // Now clear the image to some arbitrary color.  We'll just pick the
+      // color returned by get_clear_color(), even if it is meaningless.
+      vkCmdClearColorImage(cmd, buffer._image, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
+                           &clears[0].color, 1, &barrier.subresourceRange);
+
+      barriers[0].srcAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT;
+      barriers[0].oldLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
+    } else {
+      barriers[0].srcAccessMask = 0;
+      barriers[0].oldLayout = VK_IMAGE_LAYOUT_UNDEFINED;
+    }
     buffer._layout_defined = true;
   }