Merge changes Ic33110f9,I538566c6

* changes:
  Update Marl to 12872a0df
  Squashed 'third_party/marl/' changes from 5f31df137..12872a0df
diff --git a/README.md b/README.md
index 8be32f2..32975ce 100644
--- a/README.md
+++ b/README.md
@@ -5,7 +5,7 @@
 Introduction

 ------------

 

-SwiftShader is a high-performance CPU-based implementation of the OpenGL ES and Direct3D 9 graphics APIs<sup>1</sup><sup>2</sup>. Its goal is to provide hardware independence for advanced 3D graphics.

+SwiftShader is a high-performance CPU-based implementation of the Vulkan, OpenGL ES, and Direct3D 9 graphics APIs<sup>1</sup><sup>2</sup>. Its goal is to provide hardware independence for advanced 3D graphics.

 

 Building

 --------

@@ -109,5 +109,5 @@
 ----------

 

 1. Trademarks are the property of their respective owners.

-2. We do not claim official conformance with any graphics APIs at this moment.

+2. We do not claim official conformance with the Direct3D and OpenGL graphics APIs at this moment.

 3. This is not an official Google product.

diff --git a/src/Vulkan/VkConfig.h b/src/Vulkan/VkConfig.h
index 8d0b57d..905fcf2 100644
--- a/src/Vulkan/VkConfig.h
+++ b/src/Vulkan/VkConfig.h
@@ -31,8 +31,8 @@
 {
 	API_VERSION = VK_API_VERSION_1_1,
 	DRIVER_VERSION = VK_MAKE_VERSION(MAJOR_VERSION, MINOR_VERSION, PATCH_VERSION),
-	VENDOR_ID = 0x1AE0, // Google
-	DEVICE_ID = 0xC0DE, // SwiftShader
+	VENDOR_ID = 0x1AE0, // Google, Inc.: https://pcisig.com/google-inc-1
+	DEVICE_ID = 0xC0DE, // SwiftShader (placeholder)
 };
 
 enum
diff --git a/src/Vulkan/VkPhysicalDevice.cpp b/src/Vulkan/VkPhysicalDevice.cpp
index 69d1107..67bb70d 100644
--- a/src/Vulkan/VkPhysicalDevice.cpp
+++ b/src/Vulkan/VkPhysicalDevice.cpp
@@ -16,9 +16,6 @@
 
 #include "VkConfig.h"
 #include "Pipeline/SpirvShader.hpp" // sw::SIMD::Width
-#include "System/CPUID.hpp"
-
-#include "marl/thread.h"
 
 #include <limits>
 #include <cstring>
@@ -26,13 +23,8 @@
 namespace vk
 {
 
-PhysicalDevice::PhysicalDevice(const void*, void* mem) : scheduler(new marl::Scheduler())
+PhysicalDevice::PhysicalDevice(const void*, void* mem)
 {
-	scheduler->setThreadInitializer([] {
-		sw::CPUID::setFlushToZero(true);
-		sw::CPUID::setDenormalsAreZero(true);
-	});
-	scheduler->setWorkerThreadCount(std::min<size_t>(marl::Thread::numLogicalCPUs(), 16));
 }
 
 const VkPhysicalDeviceFeatures& PhysicalDevice::getFeatures() const
@@ -370,6 +362,14 @@
 	pExternalSemaphoreProperties->externalSemaphoreFeatures = 0;
 }
 
+void PhysicalDevice::getProperties(VkPhysicalDeviceDriverPropertiesKHR* properties) const
+{
+	properties->driverID = VK_DRIVER_ID_GOOGLE_SWIFTSHADER_KHR;
+	strcpy(properties->driverName, "SwiftShader driver");
+	strcpy(properties->driverInfo, "");
+	properties->conformanceVersion = {1, 1, 3, 3};
+}
+
 bool PhysicalDevice::hasFeatures(const VkPhysicalDeviceFeatures& requestedFeatures) const
 {
 	const VkPhysicalDeviceFeatures& supportedFeatures = getFeatures();
@@ -803,9 +803,4 @@
 	return properties;
 }
 
-marl::Scheduler* PhysicalDevice::getScheduler() const
-{
-	return scheduler.get();
-}
-
 } // namespace vk
diff --git a/src/Vulkan/VkPhysicalDevice.hpp b/src/Vulkan/VkPhysicalDevice.hpp
index f824851..7f6d05b 100644
--- a/src/Vulkan/VkPhysicalDevice.hpp
+++ b/src/Vulkan/VkPhysicalDevice.hpp
@@ -18,8 +18,6 @@
 #include "VkObject.hpp"
 #include "VkFormat.h"
 
-#include "marl/scheduler.h"
-
 #ifdef VK_USE_PLATFORM_ANDROID_KHR
 #include <vulkan/vk_android_native_buffer.h>
 #endif
@@ -62,6 +60,7 @@
 	void getProperties(const VkPhysicalDeviceExternalBufferInfo* pExternalBufferInfo, VkExternalBufferProperties* pExternalBufferProperties) const;
 	void getProperties(const VkPhysicalDeviceExternalFenceInfo* pExternalFenceInfo, VkExternalFenceProperties* pExternalFenceProperties) const;
 	void getProperties(const VkPhysicalDeviceExternalSemaphoreInfo* pExternalSemaphoreInfo, VkExternalSemaphoreProperties* pExternalSemaphoreProperties) const;
+	void getProperties(VkPhysicalDeviceDriverPropertiesKHR* properties) const;
 
 	void getFormatProperties(Format format, VkFormatProperties* pFormatProperties) const;
 	void getImageFormatProperties(Format format, VkImageType type, VkImageTiling tiling,
@@ -72,13 +71,9 @@
 	                              VkQueueFamilyProperties* pQueueFamilyProperties) const;
 	const VkPhysicalDeviceMemoryProperties& getMemoryProperties() const;
 
-	marl::Scheduler *getScheduler() const;
-
 private:
 	const VkPhysicalDeviceLimits& getLimits() const;
 	VkSampleCountFlags getSampleCounts() const;
-
-	std::unique_ptr<marl::Scheduler> scheduler;
 };
 
 using DispatchablePhysicalDevice = DispatchableObject<PhysicalDevice, VkPhysicalDevice>;
diff --git a/src/Vulkan/libVulkan.cpp b/src/Vulkan/libVulkan.cpp
index 996cfd3..bea662a 100644
--- a/src/Vulkan/libVulkan.cpp
+++ b/src/Vulkan/libVulkan.cpp
@@ -68,6 +68,9 @@
 
 #include "Reactor/Nucleus.hpp"
 
+#include "marl/scheduler.h"
+#include "marl/thread.h"
+
 #include "System/CPUID.hpp"
 
 #include <algorithm>
@@ -117,6 +120,17 @@
 	sw::CPUID::setEnableSSE(true);
 }
 
+marl::Scheduler* getOrCreateScheduler()
+{
+	static auto scheduler = std::unique_ptr<marl::Scheduler>(new marl::Scheduler());
+	scheduler->setThreadInitializer([] {
+		sw::CPUID::setFlushToZero(true);
+		sw::CPUID::setDenormalsAreZero(true);
+	});
+	scheduler->setWorkerThreadCount(std::min<size_t>(marl::Thread::numLogicalCPUs(), 16));
+	return scheduler.get();
+}
+
 // initializeLibrary() is called by vkCreateInstance() to perform one-off global
 // initialization of the swiftshader driver.
 void initializeLibrary()
@@ -172,6 +186,8 @@
 
 static const VkExtensionProperties deviceExtensionProperties[] =
 {
+	{ VK_KHR_DRIVER_PROPERTIES_EXTENSION_NAME, VK_KHR_DRIVER_PROPERTIES_SPEC_VERSION },
+	// Vulkan 1.1 promoted extensions
 	{ VK_KHR_16BIT_STORAGE_EXTENSION_NAME, VK_KHR_16BIT_STORAGE_SPEC_VERSION },
 	{ VK_KHR_BIND_MEMORY_2_EXTENSION_NAME, VK_KHR_BIND_MEMORY_2_SPEC_VERSION },
 	{ VK_KHR_DEDICATED_ALLOCATION_EXTENSION_NAME, VK_KHR_DEDICATED_ALLOCATION_SPEC_VERSION },
@@ -588,7 +604,7 @@
 		(void)queueFamilyPropertyCount; // Silence unused variable warning
 	}
 
-	auto scheduler = vk::Cast(physicalDevice)->getScheduler();
+	auto scheduler = getOrCreateScheduler();
 	return vk::DispatchableDevice::Create(pAllocator, pCreateInfo, pDevice, vk::Cast(physicalDevice), enabledFeatures, scheduler);
 }
 
@@ -2404,6 +2420,12 @@
 			ASSERT(!HasExtensionProperty(VK_EXT_EXTERNAL_MEMORY_HOST_EXTENSION_NAME, deviceExtensionProperties,
 			                             sizeof(deviceExtensionProperties) / sizeof(deviceExtensionProperties[0])));
 			break;
+		case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DRIVER_PROPERTIES_KHR:
+			{
+				auto& properties = *reinterpret_cast<VkPhysicalDeviceDriverPropertiesKHR*>(extensionProperties);
+				vk::Cast(physicalDevice)->getProperties(&properties);
+			}
+			break;
 #ifdef __ANDROID__
 		case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PRESENTATION_PROPERTIES_ANDROID:
 			{
diff --git a/src/WSI/MacOSSurfaceMVK.mm b/src/WSI/MacOSSurfaceMVK.mm
index 090cc20..7db42c1 100644
--- a/src/WSI/MacOSSurfaceMVK.mm
+++ b/src/WSI/MacOSSurfaceMVK.mm
@@ -44,6 +44,7 @@
             if ([obj isKindOfClass: [CAMetalLayer class]])
             {
                 layer = (CAMetalLayer*)[obj retain];
+                layer.framebufferOnly = false;
             }
             else
             {
diff --git a/tests/VulkanUnitTests/VkInstanceFuncs.hpp b/tests/VulkanUnitTests/VkInstanceFuncs.hpp
index a8ba8f5..ffdb1c9 100644
--- a/tests/VulkanUnitTests/VkInstanceFuncs.hpp
+++ b/tests/VulkanUnitTests/VkInstanceFuncs.hpp
@@ -58,6 +58,7 @@
 VK_INSTANCE(vkGetDeviceQueue, void, VkDevice, uint32_t, uint32_t, VkQueue*);
 VK_INSTANCE(vkGetPhysicalDeviceMemoryProperties, void, VkPhysicalDevice, VkPhysicalDeviceMemoryProperties*);
 VK_INSTANCE(vkGetPhysicalDeviceProperties, void, VkPhysicalDevice, VkPhysicalDeviceProperties*);
+VK_INSTANCE(vkGetPhysicalDeviceProperties2, void, VkPhysicalDevice, VkPhysicalDeviceProperties2*);
 VK_INSTANCE(vkGetPhysicalDeviceQueueFamilyProperties, void, VkPhysicalDevice, uint32_t*, VkQueueFamilyProperties*);
 VK_INSTANCE(vkMapMemory, VkResult, VkDevice, VkDeviceMemory, VkDeviceSize, VkDeviceSize, VkMemoryMapFlags, void**);
 VK_INSTANCE(vkQueueSubmit, VkResult, VkQueue, uint32_t, const VkSubmitInfo*, VkFence);
diff --git a/tests/VulkanUnitTests/unittests.cpp b/tests/VulkanUnitTests/unittests.cpp
index f7868e4..1203a50 100644
--- a/tests/VulkanUnitTests/unittests.cpp
+++ b/tests/VulkanUnitTests/unittests.cpp
@@ -104,7 +104,17 @@
 

     EXPECT_EQ(strncmp(physicalDeviceProperties.deviceName, "SwiftShader Device", VK_MAX_PHYSICAL_DEVICE_NAME_SIZE), 0);

 

-    driver.vkDestroyInstance(instance, nullptr);

+	VkPhysicalDeviceProperties2 physicalDeviceProperties2;

+	VkPhysicalDeviceDriverPropertiesKHR physicalDeviceDriverProperties;

+	physicalDeviceProperties2.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROPERTIES_2;

+	physicalDeviceProperties2.pNext = &physicalDeviceDriverProperties;

+	physicalDeviceDriverProperties.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DRIVER_PROPERTIES_KHR;

+	physicalDeviceDriverProperties.pNext = nullptr;

+	physicalDeviceDriverProperties.driverID = (VkDriverIdKHR)0;

+	driver.vkGetPhysicalDeviceProperties2(pPhysicalDevice, &physicalDeviceProperties2);

+	EXPECT_EQ(physicalDeviceDriverProperties.driverID, VK_DRIVER_ID_GOOGLE_SWIFTSHADER_KHR);

+

+	driver.vkDestroyInstance(instance, nullptr);

 }

 

 std::vector<uint32_t> compileSpirv(const char* assembly)