tests: Add a Driver class to abstract the vulkan implementation

The idea here is that we can build a number of fine granularity SPIR-V tests, which we can also verify against any optional system Vulkan hardware.

This CL adds support for building and running the Vulkan unit tests on mac and linux.

Bug: b/123749916
Change-Id: I01a4e2a914ffd5473d271013957fa3dddbc43645
Reviewed-on: https://swiftshader-review.googlesource.com/c/SwiftShader/+/24328
Presubmit-Ready: Ben Clayton <bclayton@google.com>
Tested-by: Ben Clayton <bclayton@google.com>
Reviewed-by: Chris Forbes <chrisforbes@google.com>
Kokoro-Presubmit: kokoro <noreply+kokoro@google.com>
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 965f7dd..6850639 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -2326,6 +2326,7 @@
     endif()
 endif()
 
+# GLES unit tests. TODO: Rename 'unittests' to 'gles-unittests'?
 if(BUILD_TESTS)
     set(UNITTESTS_LIST
         ${CMAKE_CURRENT_SOURCE_DIR}/tests/GLESUnitTests/main.cpp
@@ -2349,3 +2350,28 @@
 
     target_link_libraries(unittests libEGL libGLESv2 ${OS_LIBS})
 endif()
+
+if(BUILD_TESTS AND BUILD_VULKAN)
+    set(UNITTESTS_LIST
+        ${CMAKE_CURRENT_SOURCE_DIR}/tests/VulkanUnitTests/Driver.cpp
+        ${CMAKE_CURRENT_SOURCE_DIR}/tests/VulkanUnitTests/main.cpp
+        ${CMAKE_CURRENT_SOURCE_DIR}/tests/VulkanUnitTests/unittests.cpp
+        ${CMAKE_CURRENT_SOURCE_DIR}/third_party/googletest/googletest/src/gtest-all.cc
+    )
+
+    set(UNITTESTS_INCLUDE_DIR
+        ${CMAKE_CURRENT_SOURCE_DIR}/third_party/googletest/googletest/include/
+        ${CMAKE_CURRENT_SOURCE_DIR}/third_party/googletest/googlemock/include/
+        ${CMAKE_CURRENT_SOURCE_DIR}/third_party/googletest/googletest/
+        ${CMAKE_CURRENT_SOURCE_DIR}/include/
+    )
+
+    add_executable(vk-unittests ${UNITTESTS_LIST})
+    set_target_properties(vk-unittests PROPERTIES
+        INCLUDE_DIRECTORIES "${UNITTESTS_INCLUDE_DIR}"
+        FOLDER "Tests"
+        COMPILE_DEFINITIONS "STANDALONE"
+    )
+
+    target_link_libraries(vk-unittests ${OS_LIBS})
+endif()
diff --git a/tests/VulkanUnitTests/Driver.cpp b/tests/VulkanUnitTests/Driver.cpp
new file mode 100644
index 0000000..cb2645c
--- /dev/null
+++ b/tests/VulkanUnitTests/Driver.cpp
@@ -0,0 +1,165 @@
+// Copyright 2019 The SwiftShader Authors. All Rights Reserved.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//    http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#include "Driver.hpp"
+
+#if defined(_WIN64)
+#    include "Windows.h"
+#    define OS_WINDOWS 1
+#elif defined(__APPLE__)
+#    include "dlfcn.h"
+#    define OS_MAC 1
+#elif defined(__linux__)
+#    include "dlfcn.h"
+#    define OS_LINUX 1
+#else
+#    error Unimplemented platform
+#endif
+
+Driver::Driver() : vk_icdGetInstanceProcAddr(nullptr), dll(nullptr)
+{
+#define VK_GLOBAL(N, R, ...) N = nullptr;
+#include "VkGlobalFuncs.hpp"
+#undef VK_GLOBAL
+
+#define VK_INSTANCE(N, R, ...) N = nullptr;
+#include "VkInstanceFuncs.hpp"
+#undef VK_INSTANCE
+}
+
+Driver::~Driver()
+{
+    unload();
+}
+
+bool Driver::loadSwiftShader()
+{
+#if OS_WINDOWS
+#    if defined(NDEBUG)
+    return load("../../out/Release_x64/vk_swiftshader.dll");
+#    else
+    return load("../../out/Debug_x64/vk_swiftshader.dll");
+#    endif
+#elif OS_MAC
+    return load("./out/Darwin/libvk_swiftshader.dylib");
+#elif OS_LINUX
+    return load("./out/Linux/libvk_swiftshader.so");
+#else
+#    error Unimplemented platform
+#endif
+}
+
+bool Driver::loadSystem()
+{
+#if OS_LINUX
+    return load("libvulkan.so.1");
+#else
+    return false;
+#endif
+}
+
+bool Driver::load(const char* path)
+{
+#if OS_WINDOWS
+    dll = LoadLibraryA(path);
+#elif(OS_MAC || OS_LINUX)
+    dll = dlopen(path, RTLD_LAZY | RTLD_LOCAL);
+#else
+    return false;
+#endif
+    if(dll == nullptr)
+    {
+        return false;
+    }
+
+    // Is the driver an ICD?
+    if(!lookup(&vk_icdGetInstanceProcAddr, "vk_icdGetInstanceProcAddr"))
+    {
+        // Nope, attempt to use the loader version.
+        if(!lookup(&vk_icdGetInstanceProcAddr, "vkGetInstanceProcAddr"))
+        {
+            return false;
+        }
+    }
+
+#define VK_GLOBAL(N, R, ...)                                             \
+    if(auto pfn = vk_icdGetInstanceProcAddr(nullptr, #N))                \
+    {                                                                    \
+        N = reinterpret_cast<decltype(N)>(pfn);                          \
+    }
+#include "VkGlobalFuncs.hpp"
+#undef VK_GLOBAL
+
+    return true;
+}
+
+void Driver::unload()
+{
+    if(!isLoaded())
+    {
+        return;
+    }
+
+#if OS_WINDOWS
+    FreeLibrary((HMODULE)dll);
+#elif OS_LINUX
+    dlclose(dll);
+#endif
+
+#define VK_GLOBAL(N, R, ...) N = nullptr;
+#include "VkGlobalFuncs.hpp"
+#undef VK_GLOBAL
+
+#define VK_INSTANCE(N, R, ...) N = nullptr;
+#include "VkInstanceFuncs.hpp"
+#undef VK_INSTANCE
+}
+
+bool Driver::isLoaded() const
+{
+    return dll != nullptr;
+}
+
+bool Driver::resolve(VkInstance instance)
+{
+    if(!isLoaded())
+    {
+        return false;
+    }
+
+#define VK_INSTANCE(N, R, ...)                             \
+    if(auto pfn = vk_icdGetInstanceProcAddr(instance, #N)) \
+    {                                                      \
+        N = reinterpret_cast<decltype(N)>(pfn);            \
+    }                                                      \
+    else                                                   \
+    {                                                      \
+        return false;                                      \
+    }
+#include "VkInstanceFuncs.hpp"
+#undef VK_INSTANCE
+
+    return true;
+}
+
+void* Driver::lookup(const char* name)
+{
+#if OS_WINDOWS
+    return GetProcAddress((HMODULE)dll, name);
+#elif(OS_MAC || OS_LINUX)
+    return dlsym(dll, name);
+#else
+    return nullptr;
+#endif
+}
diff --git a/tests/VulkanUnitTests/Driver.hpp b/tests/VulkanUnitTests/Driver.hpp
new file mode 100644
index 0000000..f602d72
--- /dev/null
+++ b/tests/VulkanUnitTests/Driver.hpp
@@ -0,0 +1,88 @@
+// Copyright 2019 The SwiftShader Authors. All Rights Reserved.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//    http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#include <vulkan/vulkan_core.h>
+
+// Driver is used to load a Vulkan graphics driver and expose its functions.
+// It is used by the unit tests to test the SwiftShader driver and optionally
+// load a system vulkan driver to test against.
+class Driver
+{
+public:
+    Driver();
+    ~Driver();
+
+    // loadSwiftShader attempts to load the SwiftShader vulkan driver.
+    // returns true on success, false on failure.
+    bool loadSwiftShader();
+
+    // loadSystem attempts to load the system's vulkan driver.
+    // returns true on success, false on failure.
+    bool loadSystem();
+
+    // load attempts to load the vulkan driver from the given path.
+    // returns true on success, false on failure.
+    bool load(const char* path);
+
+    // unloads the currently loaded driver.
+    // No-op if no driver is currently loaded.
+    void unload();
+
+    // isLoaded returns true if the driver is currently loaded.
+    bool isLoaded() const;
+
+    // resolve all the functions for the given VkInstance.
+    bool resolve(VkInstance);
+
+    VKAPI_ATTR PFN_vkVoidFunction(VKAPI_CALL* vk_icdGetInstanceProcAddr)(VkInstance instance, const char* pName);
+
+    // Global vulkan function pointers.
+#define VK_GLOBAL(N, R, ...) R (*N)(__VA_ARGS__);
+#include "VkGlobalFuncs.hpp"
+#undef VK_GLOBAL
+
+    // Per-instance vulkan function pointers.
+#define VK_INSTANCE(N, R, ...) R (*N)(__VA_ARGS__);
+#include "VkInstanceFuncs.hpp"
+#undef VK_INSTANCE
+
+private:
+    Driver(const Driver&) = delete;
+    Driver(Driver&&) = delete;
+    Driver& operator=(const Driver&) = delete;
+
+    // lookup searches the loaded driver for a symbol with the given name,
+    // returning the address of this symbol if found, otherwise nullptr.
+    void* lookup(const char* name);
+
+    // Helper function to lookup a symbol and cast it to the appropriate type.
+    // Returns true if the symbol was found and assigned to ptr, otherwise
+    // returns false.
+    template<typename T>
+    inline bool lookup(T* ptr, const char* name);
+
+    void* dll;
+};
+
+template<typename T>
+bool Driver::lookup(T* ptr, const char* name)
+{
+    void* sym = lookup(name);
+    if(sym == nullptr)
+    {
+        return false;
+    }
+    *ptr = reinterpret_cast<T>(sym);
+    return true;
+}
\ No newline at end of file
diff --git a/tests/VulkanUnitTests/VkGlobalFuncs.hpp b/tests/VulkanUnitTests/VkGlobalFuncs.hpp
new file mode 100644
index 0000000..1a0c0aa
--- /dev/null
+++ b/tests/VulkanUnitTests/VkGlobalFuncs.hpp
@@ -0,0 +1,21 @@
+// Copyright 2019 The SwiftShader Authors. All Rights Reserved.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//    http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+// VkGlobalFuncs.h lists the vulkan driver global exposed functions.
+//
+// TODO: Generate this list.
+
+// VK_GLOBAL(<function name>, <return type>, <arguments>...)
+VK_GLOBAL(vkCreateInstance, VkResult, const VkInstanceCreateInfo*, const VkAllocationCallbacks*, VkInstance*)
+VK_GLOBAL(vkEnumerateInstanceVersion, VkResult, uint32_t*)
diff --git a/tests/VulkanUnitTests/VkInstanceFuncs.hpp b/tests/VulkanUnitTests/VkInstanceFuncs.hpp
new file mode 100644
index 0000000..5efb525
--- /dev/null
+++ b/tests/VulkanUnitTests/VkInstanceFuncs.hpp
@@ -0,0 +1,56 @@
+// Copyright 2019 The SwiftShader Authors. All Rights Reserved.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//    http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+// VkInstanceFuncs.h lists the vulkan driver per-instance functions.
+//
+// TODO: Generate this list.
+
+// VK_INSTANCE(<function name>, <return type>, <arguments>...)
+VK_INSTANCE(vkAllocateCommandBuffers, VkResult, VkDevice, const VkCommandBufferAllocateInfo*, VkCommandBuffer*);
+VK_INSTANCE(vkAllocateDescriptorSets, VkResult, VkDevice, const VkDescriptorSetAllocateInfo*, VkDescriptorSet*);
+VK_INSTANCE(vkAllocateMemory, VkResult, VkDevice, const VkMemoryAllocateInfo*, const VkAllocationCallbacks*,
+            VkDeviceMemory*);
+VK_INSTANCE(vkBeginCommandBuffer, VkResult, VkCommandBuffer, const VkCommandBufferBeginInfo*);
+VK_INSTANCE(vkBindBufferMemory, VkResult, VkDevice, VkBuffer, VkDeviceMemory, VkDeviceSize);
+VK_INSTANCE(vkCmdBindDescriptorSets, void, VkCommandBuffer, VkPipelineBindPoint, VkPipelineLayout, uint32_t, uint32_t,
+            const VkDescriptorSet*, uint32_t, const uint32_t*);
+VK_INSTANCE(vkCmdBindPipeline, void, VkCommandBuffer, VkPipelineBindPoint, VkPipeline);
+VK_INSTANCE(vkCmdDispatch, void, VkCommandBuffer, uint32_t, uint32_t, uint32_t);
+VK_INSTANCE(vkCreateBuffer, VkResult, VkDevice, const VkBufferCreateInfo*, const VkAllocationCallbacks*, VkBuffer*);
+VK_INSTANCE(vkCreateCommandPool, VkResult, VkDevice, const VkCommandPoolCreateInfo*, const VkAllocationCallbacks*,
+            VkCommandPool*);
+VK_INSTANCE(vkCreateComputePipelines, VkResult, VkDevice, VkPipelineCache, uint32_t, const VkComputePipelineCreateInfo*,
+            const VkAllocationCallbacks*, VkPipeline*);
+VK_INSTANCE(vkCreateDescriptorPool, VkResult, VkDevice, const VkDescriptorPoolCreateInfo*, const VkAllocationCallbacks*,
+            VkDescriptorPool*);
+VK_INSTANCE(vkCreateDescriptorSetLayout, VkResult, VkDevice, const VkDescriptorSetLayoutCreateInfo*,
+            const VkAllocationCallbacks*, VkDescriptorSetLayout*);
+VK_INSTANCE(vkCreateDevice, VkResult, VkPhysicalDevice, const VkDeviceCreateInfo*, const VkAllocationCallbacks*,
+            VkDevice*);
+VK_INSTANCE(vkCreatePipelineLayout, VkResult, VkDevice, const VkPipelineLayoutCreateInfo*, const VkAllocationCallbacks*,
+            VkPipelineLayout*);
+VK_INSTANCE(vkCreateShaderModule, VkResult, VkDevice, const VkShaderModuleCreateInfo*, const VkAllocationCallbacks*,
+            VkShaderModule*);
+VK_INSTANCE(vkEndCommandBuffer, VkResult, VkCommandBuffer);
+VK_INSTANCE(vkEnumeratePhysicalDevices, VkResult, VkInstance, uint32_t*, VkPhysicalDevice*)
+VK_INSTANCE(vkGetDeviceQueue, void, VkDevice, uint32_t, uint32_t, VkQueue*);
+VK_INSTANCE(vkGetPhysicalDeviceMemoryProperties, void, VkPhysicalDevice, VkPhysicalDeviceMemoryProperties*);
+VK_INSTANCE(vkGetPhysicalDeviceProperties, void, VkPhysicalDevice, VkPhysicalDeviceProperties*)
+VK_INSTANCE(vkGetPhysicalDeviceQueueFamilyProperties, void, VkPhysicalDevice, uint32_t*, VkQueueFamilyProperties*);
+VK_INSTANCE(vkMapMemory, VkResult, VkDevice, VkDeviceMemory, VkDeviceSize, VkDeviceSize, VkMemoryMapFlags, void**);
+VK_INSTANCE(vkUnmapMemory, void, VkDevice, VkDeviceMemory);
+VK_INSTANCE(vkUpdateDescriptorSets, void, VkDevice, uint32_t, const VkWriteDescriptorSet*, uint32_t,
+            const VkCopyDescriptorSet*);
+VK_INSTANCE(vkQueueSubmit, VkResult, VkQueue, uint32_t, const VkSubmitInfo*, VkFence);
+VK_INSTANCE(vkQueueWaitIdle, VkResult, VkQueue);
\ No newline at end of file
diff --git a/tests/VulkanUnitTests/VulkanUnitTests.vcxproj b/tests/VulkanUnitTests/VulkanUnitTests.vcxproj
index 943821b..ebef195 100644
--- a/tests/VulkanUnitTests/VulkanUnitTests.vcxproj
+++ b/tests/VulkanUnitTests/VulkanUnitTests.vcxproj
@@ -98,6 +98,7 @@
   </ItemDefinitionGroup>

   <ItemGroup>

     <ClCompile Include="..\..\third_party\googletest\googletest\src\gtest-all.cc" />

+    <ClCompile Include="Driver.cpp" />

     <ClCompile Include="main.cpp" />

     <ClCompile Include="unittests.cpp" />

   </ItemGroup>

@@ -106,6 +107,11 @@
       <Project>{e1c34b66-c942-4b9a-b8c3-9a12625650d3}</Project>

     </ProjectReference>

   </ItemGroup>

+  <ItemGroup>

+    <ClInclude Include="Driver.hpp" />

+    <ClInclude Include="VkGlobalFuncs.hpp" />

+    <ClInclude Include="VkInstanceFuncs.hpp" />

+  </ItemGroup>

   <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />

   <ImportGroup Label="ExtensionTargets">

   </ImportGroup>

diff --git a/tests/VulkanUnitTests/VulkanUnitTests.vcxproj.filters b/tests/VulkanUnitTests/VulkanUnitTests.vcxproj.filters
index 1044d65..ea4f8f0 100644
--- a/tests/VulkanUnitTests/VulkanUnitTests.vcxproj.filters
+++ b/tests/VulkanUnitTests/VulkanUnitTests.vcxproj.filters
@@ -5,6 +5,10 @@
       <UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>

       <Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions>

     </Filter>

+    <Filter Include="Header Files">

+      <UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>

+      <Extensions>h;hpp;hxx;hm;inl;inc;xsd</Extensions>

+    </Filter>

     <Filter Include="Resource Files">

       <UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier>

       <Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms</Extensions>

@@ -20,5 +24,19 @@
     <ClCompile Include="main.cpp">

       <Filter>Source Files</Filter>

     </ClCompile>

+    <ClCompile Include="Driver.cpp">

+      <Filter>Source Files</Filter>

+    </ClCompile>

   </ItemGroup>

-</Project>

+  <ItemGroup>

+    <ClInclude Include="Driver.hpp">

+      <Filter>Header Files</Filter>

+    </ClInclude>

+    <ClInclude Include="VkGlobalFuncs.hpp">

+      <Filter>Header Files</Filter>

+    </ClInclude>

+    <ClInclude Include="VkInstanceFuncs.hpp">

+      <Filter>Header Files</Filter>

+    </ClInclude>

+  </ItemGroup>

+</Project>
\ No newline at end of file
diff --git a/tests/VulkanUnitTests/unittests.cpp b/tests/VulkanUnitTests/unittests.cpp
index eb3c8bd..be2d924 100644
--- a/tests/VulkanUnitTests/unittests.cpp
+++ b/tests/VulkanUnitTests/unittests.cpp
@@ -15,106 +15,80 @@
 // Vulkan unit tests that provide coverage for functionality not tested by

 // the dEQP test suite. Also used as a smoke test.

 

-#include "gtest/gtest.h"

-#include "gmock/gmock.h"

+#include "Driver.hpp"

 

-#include <vulkan/vulkan_core.h>

-#include <vulkan/vk_icd.h>

+#include "gmock/gmock.h"

+#include "gtest/gtest.h"

 

 #include <cstring>

 

-typedef PFN_vkVoidFunction(__stdcall *vk_icdGetInstanceProcAddrPtr)(VkInstance, const char*);

-

-#if defined(_WIN32)

-#include <Windows.h>

-#endif

-

 class SwiftShaderVulkanTest : public testing::Test

 {

-protected:

-	void SetUp() override

-	{

-		HMODULE libVulkan = nullptr;

-		const char* libVulkanName = nullptr;

-

-		#if defined(_WIN64)

-			#if defined(NDEBUG)

-				libVulkanName = "../../out/Release_x64/vk_swiftshader.dll";

-			#else

-				libVulkanName = "../../out/Debug_x64/vk_swiftshader.dll";

-			#endif

-		#else

-			#error Unimplemented platform

-		#endif

-

-		#if defined(_WIN32)

-			libVulkan = LoadLibraryA(libVulkanName);

-			EXPECT_NE((HMODULE)NULL, libVulkan);

-			vk_icdGetInstanceProcAddr = (vk_icdGetInstanceProcAddrPtr)GetProcAddress(libVulkan, "vk_icdGetInstanceProcAddr");

-			EXPECT_NE((vk_icdGetInstanceProcAddrPtr)nullptr, vk_icdGetInstanceProcAddr);

-		#endif

-	}

-

-	vk_icdGetInstanceProcAddrPtr vk_icdGetInstanceProcAddr = nullptr;

 };

 

 TEST_F(SwiftShaderVulkanTest, ICD_Check)

 {

-	if(vk_icdGetInstanceProcAddr)

-	{

-		auto createInstance = vk_icdGetInstanceProcAddr(VK_NULL_HANDLE, "vkCreateInstance");

-		EXPECT_NE(createInstance, nullptr);

+    Driver driver;

+    ASSERT_TRUE(driver.loadSwiftShader());

 

-		auto enumerateInstanceExtensionProperties = vk_icdGetInstanceProcAddr(VK_NULL_HANDLE, "vkEnumerateInstanceExtensionProperties");

-		EXPECT_NE(enumerateInstanceExtensionProperties, nullptr);

+    auto createInstance = driver.vk_icdGetInstanceProcAddr(VK_NULL_HANDLE, "vkCreateInstance");

+    EXPECT_NE(createInstance, nullptr);

 

-		auto enumerateInstanceLayerProperties = vk_icdGetInstanceProcAddr(VK_NULL_HANDLE, "vkEnumerateInstanceLayerProperties");

-		EXPECT_NE(enumerateInstanceLayerProperties, nullptr);

+    auto enumerateInstanceExtensionProperties =

+        driver.vk_icdGetInstanceProcAddr(VK_NULL_HANDLE, "vkEnumerateInstanceExtensionProperties");

+    EXPECT_NE(enumerateInstanceExtensionProperties, nullptr);

 

-		auto enumerateInstanceVersion = vk_icdGetInstanceProcAddr(VK_NULL_HANDLE, "vkEnumerateInstanceVersion");

-		EXPECT_NE(enumerateInstanceVersion, nullptr);

+    auto enumerateInstanceLayerProperties =

+        driver.vk_icdGetInstanceProcAddr(VK_NULL_HANDLE, "vkEnumerateInstanceLayerProperties");

+    EXPECT_NE(enumerateInstanceLayerProperties, nullptr);

 

-		auto bad_function = vk_icdGetInstanceProcAddr(VK_NULL_HANDLE, "bad_function");

-		EXPECT_EQ(bad_function, nullptr);

-	}

+    auto enumerateInstanceVersion = driver.vk_icdGetInstanceProcAddr(VK_NULL_HANDLE, "vkEnumerateInstanceVersion");

+    EXPECT_NE(enumerateInstanceVersion, nullptr);

+

+    auto bad_function = driver.vk_icdGetInstanceProcAddr(VK_NULL_HANDLE, "bad_function");

+    EXPECT_EQ(bad_function, nullptr);

 }

 

 TEST_F(SwiftShaderVulkanTest, Version)

 {

-	uint32_t apiVersion = 0;

-	VkResult result = vkEnumerateInstanceVersion(&apiVersion);

-	EXPECT_EQ(apiVersion, VK_API_VERSION_1_1);

+    Driver driver;

+    ASSERT_TRUE(driver.loadSwiftShader());

 

-	const VkInstanceCreateInfo createInfo =

-	{

-		VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO, // sType

-		nullptr, // pNext

-		0,       // flags

-		nullptr, // pApplicationInfo

-		0,       // enabledLayerCount

-		nullptr, // ppEnabledLayerNames

-		0,       // enabledExtensionCount

-		nullptr, // ppEnabledExtensionNames

-	};

-	VkInstance instance = VK_NULL_HANDLE;

-	result = vkCreateInstance(&createInfo, nullptr, &instance);

-	EXPECT_EQ(result, VK_SUCCESS);

+    uint32_t apiVersion = 0;

+    VkResult result = driver.vkEnumerateInstanceVersion(&apiVersion);

+    EXPECT_EQ(apiVersion, (uint32_t)VK_API_VERSION_1_1);

 

-	uint32_t pPhysicalDeviceCount = 0;

-	result = vkEnumeratePhysicalDevices(instance, &pPhysicalDeviceCount, nullptr);

-	EXPECT_EQ(result, VK_SUCCESS);

-	EXPECT_EQ(pPhysicalDeviceCount, 1);

+    const VkInstanceCreateInfo createInfo = {

+        VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO,  // sType

+        nullptr,                                 // pNext

+        0,                                       // flags

+        nullptr,                                 // pApplicationInfo

+        0,                                       // enabledLayerCount

+        nullptr,                                 // ppEnabledLayerNames

+        0,                                       // enabledExtensionCount

+        nullptr,                                 // ppEnabledExtensionNames

+    };

+    VkInstance instance = VK_NULL_HANDLE;

+    result = driver.vkCreateInstance(&createInfo, nullptr, &instance);

+    EXPECT_EQ(result, VK_SUCCESS);

 

-	VkPhysicalDevice pPhysicalDevice = VK_NULL_HANDLE;

-	result = vkEnumeratePhysicalDevices(instance, &pPhysicalDeviceCount, &pPhysicalDevice);

-	EXPECT_EQ(result, VK_SUCCESS);

-	EXPECT_NE(pPhysicalDevice, (VkPhysicalDevice)VK_NULL_HANDLE);

+    ASSERT_TRUE(driver.resolve(instance));

 

-	VkPhysicalDeviceProperties physicalDeviceProperties;

-	vkGetPhysicalDeviceProperties(pPhysicalDevice, &physicalDeviceProperties);

-	EXPECT_EQ(physicalDeviceProperties.apiVersion, VK_API_VERSION_1_1);

-	EXPECT_EQ(physicalDeviceProperties.deviceID, 0xC0DE);

-	EXPECT_EQ(physicalDeviceProperties.deviceType, VK_PHYSICAL_DEVICE_TYPE_CPU);

+    uint32_t pPhysicalDeviceCount = 0;

+    result = driver.vkEnumeratePhysicalDevices(instance, &pPhysicalDeviceCount, nullptr);

+    EXPECT_EQ(result, VK_SUCCESS);

+    EXPECT_EQ(pPhysicalDeviceCount, 1U);

 

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

+    VkPhysicalDevice pPhysicalDevice = VK_NULL_HANDLE;

+    result = driver.vkEnumeratePhysicalDevices(instance, &pPhysicalDeviceCount, &pPhysicalDevice);

+    EXPECT_EQ(result, VK_SUCCESS);

+    EXPECT_NE(pPhysicalDevice, (VkPhysicalDevice)VK_NULL_HANDLE);

+

+    VkPhysicalDeviceProperties physicalDeviceProperties;

+    driver.vkGetPhysicalDeviceProperties(pPhysicalDevice, &physicalDeviceProperties);

+    EXPECT_EQ(physicalDeviceProperties.apiVersion, (uint32_t)VK_API_VERSION_1_1);

+    EXPECT_EQ(physicalDeviceProperties.deviceID, 0xC0DEU);

+    EXPECT_EQ(physicalDeviceProperties.deviceType, VK_PHYSICAL_DEVICE_TYPE_CPU);

+

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

 }