Make vk-unittests use VulkanWrapper

This change moves the VulkanBenchmark and DrawBenchmark classes to VulkanWrapper so that they can be used from other unit tests -- namely, vk-unittests. In doing so, it became clear that using these as base classes wasn't great for writing googletests, as text fixtures are classes themselves, and this resulted in messy multiple inheritance. So I modified the two classes to use callback registration instead of virtual functions. Apart from reworking existing tests (e.g. see TriangleBenchmark.cpp), I also added a new DrawTests.cpp to vk-unittests with a unit test to make sure we don't crash when leaving out "gl_Position", a bug that sugoi@ fixed in swiftshader-cl/51808. This is a good example of how easy it can be to write such unit tests now. List of changes: * Moved VulkanBenchmark and DrawBenchmark to VulkanWrapper, and renamed VulkanTester and DrawTester respectively. * ClearImageBenchmark refactored to aggregate a VulkanTester. This is an example where using a class is fine as we can still use the testers via aggregation. * TriangleBenchmark tests refactored to use DrawTester and register callbacks. * Moved compute tests to a ComputeTests.cpp. * Moved the other tests to BasicTests.cpp. * Added DrawTests.cpp with new DrawTests.VertexShaderNoPositionOutput test. * CMake: add VulkanWrapper target for unittests as well as benchmarks. * CMake: change FOLDER to better organize the tests and benchmarks for VS. Bug: b/176981107 Change-Id: Ib1a0b85b3df787d2e39da08930414f9a14954a73 Reviewed-on: https://swiftshader-review.googlesource.com/c/SwiftShader/+/52348 Kokoro-Result: kokoro <noreply+kokoro@google.com> Reviewed-by: 's avatarAlexis Hétu <sugoi@google.com> Tested-by: 's avatarAntonio Maiorano <amaiorano@google.com> Commit-Queue: Antonio Maiorano <amaiorano@google.com>
parent 266614a3
......@@ -243,13 +243,20 @@ function(InitSubmodule target submodule_dir)
endif()
endfunction()
if (SWIFTSHADER_BUILD_TESTS OR SWIFTSHADER_BUILD_BENCHMARKS)
set(BUILD_VULKAN_WRAPPER TRUE)
endif()
if (BUILD_VULKAN_WRAPPER)
InitSubmodule(glslang ${THIRD_PARTY_DIR}/glslang)
endif()
if (SWIFTSHADER_BUILD_TESTS)
InitSubmodule(gtest ${THIRD_PARTY_DIR}/googletest)
endif()
if(SWIFTSHADER_BUILD_BENCHMARKS)
InitSubmodule(benchmark::benchmark ${THIRD_PARTY_DIR}/benchmark)
InitSubmodule(glslang ${THIRD_PARTY_DIR}/glslang)
endif()
if(REACTOR_EMIT_DEBUG_INFO)
......@@ -992,6 +999,13 @@ if(HAVE_PVR_SUBMODULE AND SWIFTSHADER_BUILD_PVR)
endif()
endif()
if(BUILD_VULKAN_WRAPPER)
if (NOT TARGET glslang)
add_subdirectory(${THIRD_PARTY_DIR}/glslang)
endif()
add_subdirectory(${TESTS_DIR}/VulkanWrapper) # Add VulkanWrapper target
endif()
if(SWIFTSHADER_BUILD_TESTS)
add_subdirectory(${TESTS_DIR}/ReactorUnitTests) # Add ReactorUnitTests target
add_subdirectory(${TESTS_DIR}/GLESUnitTests) # Add gles-unittests target
......@@ -1000,11 +1014,6 @@ if(SWIFTSHADER_BUILD_TESTS)
endif()
if(SWIFTSHADER_BUILD_BENCHMARKS)
if (NOT TARGET glslang)
add_subdirectory(${THIRD_PARTY_DIR}/glslang)
endif()
add_subdirectory(${TESTS_DIR}/VulkanWrapper) # Add VulkanWrapper target
if (NOT TARGET benchmark::benchmark)
set(BENCHMARK_ENABLE_TESTING FALSE CACHE BOOL FALSE FORCE)
add_subdirectory(${THIRD_PARTY_DIR}/benchmark)
......
......@@ -31,7 +31,7 @@ add_executable(ReactorBenchmarks
)
set_target_properties(ReactorBenchmarks PROPERTIES
FOLDER "Benchmarks"
FOLDER "Tests/Benchmarks"
RUNTIME_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}"
)
......
......@@ -32,7 +32,7 @@ add_executable(system-benchmarks
)
set_target_properties(system-benchmarks PROPERTIES
FOLDER "Benchmarks"
FOLDER "Tests/Benchmarks"
RUNTIME_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}"
)
......
......@@ -23,12 +23,8 @@ set(ROOT_PROJECT_LINK_LIBRARIES
set(VULKAN_BENCHMARKS_SRC_FILES
ClearImageBenchmarks.cpp
DrawBenchmark.cpp
DrawBenchmark.hpp
main.cpp
TriangleBenchmarks.cpp
VulkanBenchmark.cpp
VulkanBenchmark.hpp
)
add_executable(VulkanBenchmarks
......@@ -48,7 +44,7 @@ add_dependencies(VulkanBenchmarks
)
set_target_properties(VulkanBenchmarks PROPERTIES
FOLDER "Benchmarks"
FOLDER "Tests/Benchmarks"
RUNTIME_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}"
)
......
......@@ -12,17 +12,18 @@
// See the License for the specific language governing permissions and
// limitations under the License.
#include "VulkanBenchmark.hpp"
#include "VulkanTester.hpp"
#include "benchmark/benchmark.h"
#include <cassert>
class ClearImageBenchmark : public VulkanBenchmark
class ClearImageBenchmark
{
public:
void initialize(vk::Format clearFormat, vk::ImageAspectFlagBits clearAspect)
{
VulkanBenchmark::initialize();
tester.initialize();
auto &device = tester.getDevice();
vk::ImageCreateInfo imageInfo;
imageInfo.imageType = vk::ImageType::e2D;
......@@ -48,7 +49,7 @@ public:
device.bindImageMemory(image, memory, 0);
vk::CommandPoolCreateInfo commandPoolCreateInfo;
commandPoolCreateInfo.queueFamilyIndex = queueFamilyIndex;
commandPoolCreateInfo.queueFamilyIndex = tester.getQueueFamilyIndex();
commandPool = device.createCommandPool(commandPoolCreateInfo);
......@@ -96,6 +97,7 @@ public:
~ClearImageBenchmark()
{
auto &device = tester.getDevice();
device.freeCommandBuffers(commandPool, 1, &commandBuffer);
device.destroyCommandPool(commandPool, nullptr);
device.freeMemory(memory, nullptr);
......@@ -104,6 +106,8 @@ public:
void clear()
{
auto &queue = tester.getQueue();
vk::SubmitInfo submitInfo;
submitInfo.commandBufferCount = 1;
submitInfo.pCommandBuffers = &commandBuffer;
......@@ -113,6 +117,7 @@ public:
}
private:
VulkanTester tester;
vk::Image image; // Owning handle
vk::DeviceMemory memory; // Owning handle
vk::CommandPool commandPool; // Owning handle
......
......@@ -13,22 +13,33 @@
// limitations under the License.
#include "Buffer.hpp"
#include "DrawBenchmark.hpp"
#include "DrawTester.hpp"
#include "benchmark/benchmark.h"
#include <cassert>
#include <vector>
class TriangleSolidColorBenchmark : public DrawBenchmark
template<typename T>
static void RunBenchmark(benchmark::State &state, T &tester)
{
public:
TriangleSolidColorBenchmark(Multisample multisample)
: DrawBenchmark(multisample)
{}
tester.initialize();
if(false) tester.show(); // Enable for visual verification.
// Warmup
tester.renderFrame();
protected:
void doCreateVertexBuffers() override
for(auto _ : state)
{
tester.renderFrame();
}
}
static void TriangleSolidColor(benchmark::State &state, Multisample multisample)
{
DrawTester tester(multisample);
tester.onCreateVertexBuffers([](DrawTester &tester) {
struct Vertex
{
float position[3];
......@@ -43,11 +54,10 @@ protected:
std::vector<vk::VertexInputAttributeDescription> inputAttributes;
inputAttributes.push_back(vk::VertexInputAttributeDescription(0, 0, vk::Format::eR32G32B32Sfloat, offsetof(Vertex, position)));
addVertexBuffer(vertexBufferData, sizeof(vertexBufferData), std::move(inputAttributes));
}
tester.addVertexBuffer(vertexBufferData, sizeof(vertexBufferData), std::move(inputAttributes));
});
vk::ShaderModule doCreateVertexShader() override
{
tester.onCreateVertexShader([](DrawTester &tester) {
const char *vertexShader = R"(#version 310 es
layout(location = 0) in vec3 inPos;
......@@ -56,11 +66,10 @@ protected:
gl_Position = vec4(inPos.xyz, 1.0);
})";
return createShaderModule(vertexShader, EShLanguage::EShLangVertex);
}
return tester.createShaderModule(vertexShader, EShLanguage::EShLangVertex);
});
vk::ShaderModule doCreateFragmentShader() override
{
tester.onCreateFragmentShader([](DrawTester &tester) {
const char *fragmentShader = R"(#version 310 es
precision highp float;
......@@ -71,20 +80,17 @@ protected:
outColor = vec4(1.0, 1.0, 1.0, 1.0);
})";
return createShaderModule(fragmentShader, EShLanguage::EShLangFragment);
}
};
return tester.createShaderModule(fragmentShader, EShLanguage::EShLangFragment);
});
RunBenchmark(state, tester);
}
class TriangleInterpolateColorBenchmark : public DrawBenchmark
static void TriangleInterpolateColor(benchmark::State &state, Multisample multisample)
{
public:
TriangleInterpolateColorBenchmark(Multisample multisample)
: DrawBenchmark(multisample)
{}
DrawTester tester(multisample);
protected:
void doCreateVertexBuffers() override
{
tester.onCreateVertexBuffers([](DrawTester &tester) {
struct Vertex
{
float position[3];
......@@ -101,11 +107,10 @@ protected:
inputAttributes.push_back(vk::VertexInputAttributeDescription(0, 0, vk::Format::eR32G32B32Sfloat, offsetof(Vertex, position)));
inputAttributes.push_back(vk::VertexInputAttributeDescription(1, 0, vk::Format::eR32G32B32Sfloat, offsetof(Vertex, color)));
addVertexBuffer(vertexBufferData, sizeof(vertexBufferData), std::move(inputAttributes));
}
tester.addVertexBuffer(vertexBufferData, sizeof(vertexBufferData), std::move(inputAttributes));
});
vk::ShaderModule doCreateVertexShader() override
{
tester.onCreateVertexShader([](DrawTester &tester) {
const char *vertexShader = R"(#version 310 es
layout(location = 0) in vec3 inPos;
layout(location = 1) in vec3 inColor;
......@@ -118,11 +123,10 @@ protected:
gl_Position = vec4(inPos.xyz, 1.0);
})";
return createShaderModule(vertexShader, EShLanguage::EShLangVertex);
}
return tester.createShaderModule(vertexShader, EShLanguage::EShLangVertex);
});
vk::ShaderModule doCreateFragmentShader() override
{
tester.onCreateFragmentShader([](DrawTester &tester) {
const char *fragmentShader = R"(#version 310 es
precision highp float;
......@@ -135,20 +139,17 @@ protected:
outColor = vec4(inColor, 1.0);
})";
return createShaderModule(fragmentShader, EShLanguage::EShLangFragment);
}
};
return tester.createShaderModule(fragmentShader, EShLanguage::EShLangFragment);
});
RunBenchmark(state, tester);
}
class TriangleSampleTextureBenchmark : public DrawBenchmark
static void TriangleSampleTexture(benchmark::State &state, Multisample multisample)
{
public:
TriangleSampleTextureBenchmark(Multisample multisample)
: DrawBenchmark(multisample)
{}
DrawTester tester(multisample);
protected:
void doCreateVertexBuffers() override
{
tester.onCreateVertexBuffers([](DrawTester &tester) {
struct Vertex
{
float position[3];
......@@ -167,11 +168,10 @@ protected:
inputAttributes.push_back(vk::VertexInputAttributeDescription(1, 0, vk::Format::eR32G32B32Sfloat, offsetof(Vertex, color)));
inputAttributes.push_back(vk::VertexInputAttributeDescription(2, 0, vk::Format::eR32G32Sfloat, offsetof(Vertex, texCoord)));
addVertexBuffer(vertexBufferData, sizeof(vertexBufferData), std::move(inputAttributes));
}
tester.addVertexBuffer(vertexBufferData, sizeof(vertexBufferData), std::move(inputAttributes));
});
vk::ShaderModule doCreateVertexShader() override
{
tester.onCreateVertexShader([](DrawTester &tester) {
const char *vertexShader = R"(#version 310 es
layout(location = 0) in vec3 inPos;
layout(location = 1) in vec3 inColor;
......@@ -186,11 +186,10 @@ protected:
fragTexCoord = inPos.xy;
})";
return createShaderModule(vertexShader, EShLanguage::EShLangVertex);
}
return tester.createShaderModule(vertexShader, EShLanguage::EShLangVertex);
});
vk::ShaderModule doCreateFragmentShader() override
{
tester.onCreateFragmentShader([](DrawTester &tester) {
const char *fragmentShader = R"(#version 310 es
precision highp float;
......@@ -206,11 +205,10 @@ protected:
outColor = texture(texSampler, fragTexCoord) * vec4(inColor, 1.0);
})";
return createShaderModule(fragmentShader, EShLanguage::EShLangFragment);
}
return tester.createShaderModule(fragmentShader, EShLanguage::EShLangFragment);
});
std::vector<vk::DescriptorSetLayoutBinding> doCreateDescriptorSetLayouts() override
{
tester.onCreateDescriptorSetLayouts([](DrawTester &tester) -> std::vector<vk::DescriptorSetLayoutBinding> {
vk::DescriptorSetLayoutBinding samplerLayoutBinding;
samplerLayoutBinding.binding = 1;
samplerLayoutBinding.descriptorCount = 1;
......@@ -219,11 +217,13 @@ protected:
samplerLayoutBinding.stageFlags = vk::ShaderStageFlagBits::eFragment;
return { samplerLayoutBinding };
}
});
void doUpdateDescriptorSet(vk::CommandPool &commandPool, vk::DescriptorSet &descriptorSet) override
{
auto &texture = addImage(device, 16, 16, vk::Format::eR8G8B8A8Unorm).obj;
tester.onUpdateDescriptorSet([](DrawTester &tester, vk::CommandPool &commandPool, vk::DescriptorSet &descriptorSet) {
auto &device = tester.getDevice();
auto &queue = tester.getQueue();
auto &texture = tester.addImage(device, 16, 16, vk::Format::eR8G8B8A8Unorm).obj;
// Fill texture with white
vk::DeviceSize bufferSize = 16 * 16 * 4;
......@@ -249,7 +249,7 @@ protected:
samplerInfo.minLod = 0.0f;
samplerInfo.maxLod = 0.0f;
auto sampler = addSampler(samplerInfo);
auto sampler = tester.addSampler(samplerInfo);
vk::DescriptorImageInfo imageInfo;
imageInfo.imageLayout = vk::ImageLayout::eShaderReadOnlyOptimal;
......@@ -266,41 +266,9 @@ protected:
descriptorWrites[0].pImageInfo = &imageInfo;
device.updateDescriptorSets(static_cast<uint32_t>(descriptorWrites.size()), descriptorWrites.data(), 0, nullptr);
}
};
template<typename T>
static void RunBenchmark(benchmark::State &state, T &benchmark)
{
benchmark.initialize();
if(false) benchmark.show(); // Enable for visual verification.
// Warmup
benchmark.renderFrame();
});
for(auto _ : state)
{
benchmark.renderFrame();
}
}
static void TriangleSolidColor(benchmark::State &state, Multisample multisample)
{
TriangleSolidColorBenchmark benchmark(multisample);
RunBenchmark(state, benchmark);
}
static void TriangleInterpolateColor(benchmark::State &state, Multisample multisample)
{
TriangleInterpolateColorBenchmark benchmark(multisample);
RunBenchmark(state, benchmark);
}
static void TriangleSampleTexture(benchmark::State &state, Multisample multisample)
{
TriangleSampleTextureBenchmark benchmark(multisample);
RunBenchmark(state, benchmark);
RunBenchmark(state, tester);
}
BENCHMARK_CAPTURE(TriangleSolidColor, TriangleSolidColor, Multisample::False)->Unit(benchmark::kMillisecond);
......
// Copyright 2021 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 "VulkanBenchmark.hpp"
VulkanBenchmark::~VulkanBenchmark()
{
device.waitIdle();
device.destroy(nullptr);
instance.destroy(nullptr);
}
void VulkanBenchmark::initialize()
{
// TODO(b/158231104): Other platforms
#if defined(_WIN32)
dl = std::make_unique<vk::DynamicLoader>("./vk_swiftshader.dll");
#elif defined(__linux__)
dl = std::make_unique<vk::DynamicLoader>("./libvk_swiftshader.so");
#else
# error Unimplemented platform
#endif
assert(dl->success());
PFN_vkGetInstanceProcAddr vkGetInstanceProcAddr = dl->getProcAddress<PFN_vkGetInstanceProcAddr>("vkGetInstanceProcAddr");
VULKAN_HPP_DEFAULT_DISPATCHER.init(vkGetInstanceProcAddr);
instance = vk::createInstance({}, nullptr);
VULKAN_HPP_DEFAULT_DISPATCHER.init(instance);
std::vector<vk::PhysicalDevice> physicalDevices = instance.enumeratePhysicalDevices();
assert(!physicalDevices.empty());
physicalDevice = physicalDevices[0];
const float defaultQueuePriority = 0.0f;
vk::DeviceQueueCreateInfo queueCreatInfo;
queueCreatInfo.queueFamilyIndex = queueFamilyIndex;
queueCreatInfo.queueCount = 1;
queueCreatInfo.pQueuePriorities = &defaultQueuePriority;
vk::DeviceCreateInfo deviceCreateInfo;
deviceCreateInfo.queueCreateInfoCount = 1;
deviceCreateInfo.pQueueCreateInfos = &queueCreatInfo;
device = physicalDevice.createDevice(deviceCreateInfo, nullptr);
queue = device.getQueue(queueFamilyIndex, 0);
}
......@@ -26,9 +26,12 @@ test("swiftshader_vulkan_unittests") {
sources = [
"//gpu/swiftshader_tests_main.cc",
"Device.cpp",
"Driver.cpp",
"unittests.cpp",
"BasicTests.cpp"
"ComputeTests.cpp"
"Device.cpp"
"DrawTests.cpp"
"Driver.cpp"
"main.cpp"
]
include_dirs = [
......
// Copyright 2018 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.
// Vulkan unit tests that provide coverage for functionality not tested by
// the dEQP test suite. Also used as a smoke test.
#include "Device.hpp"
#include "Driver.hpp"
#include "gmock/gmock.h"
#include "gtest/gtest.h"
class BasicTest : public testing::Test
{
protected:
static Driver driver;
void SetUp() override
{
ASSERT_TRUE(driver.loadSwiftShader());
}
void TearDown() override
{
driver.unload();
}
};
Driver BasicTest::driver;
TEST_F(BasicTest, ICD_Check)
{
auto createInstance = driver.vk_icdGetInstanceProcAddr(VK_NULL_HANDLE, "vkCreateInstance");
EXPECT_NE(createInstance, nullptr);
auto enumerateInstanceExtensionProperties =
driver.vk_icdGetInstanceProcAddr(VK_NULL_HANDLE, "vkEnumerateInstanceExtensionProperties");
EXPECT_NE(enumerateInstanceExtensionProperties, nullptr);
auto enumerateInstanceLayerProperties =
driver.vk_icdGetInstanceProcAddr(VK_NULL_HANDLE, "vkEnumerateInstanceLayerProperties");
EXPECT_NE(enumerateInstanceLayerProperties, 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(BasicTest, Version)
{
uint32_t apiVersion = 0;
VkResult result = driver.vkEnumerateInstanceVersion(&apiVersion);
EXPECT_EQ(apiVersion, (uint32_t)VK_API_VERSION_1_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);
ASSERT_TRUE(driver.resolve(instance));
uint32_t pPhysicalDeviceCount = 0;
result = driver.vkEnumeratePhysicalDevices(instance, &pPhysicalDeviceCount, nullptr);
EXPECT_EQ(result, VK_SUCCESS);
EXPECT_EQ(pPhysicalDeviceCount, 1U);
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_NE(strstr(physicalDeviceProperties.deviceName, "SwiftShader Device"), 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);
}
/*
TEST_F(BasicTest, UnsupportedDeviceExtension_DISABLED)
{
uint32_t apiVersion = 0;
VkResult result = driver.vkEnumerateInstanceVersion(&apiVersion);
EXPECT_EQ(apiVersion, (uint32_t)VK_API_VERSION_1_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);
ASSERT_TRUE(driver.resolve(instance));
VkBaseInStructure unsupportedExt = { VK_STRUCTURE_TYPE_SHADER_MODULE_VALIDATION_CACHE_CREATE_INFO_EXT, nullptr };
// Gather all physical devices
std::vector<VkPhysicalDevice> physicalDevices;
result = Device::GetPhysicalDevices(&driver, instance, physicalDevices);
EXPECT_EQ(result, VK_SUCCESS);
// Inspect each physical device's queue families for compute support.
for(auto physicalDevice : physicalDevices)
{
int queueFamilyIndex = Device::GetComputeQueueFamilyIndex(&driver, physicalDevice);
if(queueFamilyIndex < 0)
{
continue;
}
const float queuePrioritory = 1.0f;
const VkDeviceQueueCreateInfo deviceQueueCreateInfo = {
VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO, // sType
nullptr, // pNext
0, // flags
(uint32_t)queueFamilyIndex, // queueFamilyIndex
1, // queueCount
&queuePrioritory, // pQueuePriorities
};
const VkDeviceCreateInfo deviceCreateInfo = {
VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO, // sType
&unsupportedExt, // pNext
0, // flags
1, // queueCreateInfoCount
&deviceQueueCreateInfo, // pQueueCreateInfos
0, // enabledLayerCount
nullptr, // ppEnabledLayerNames
0, // enabledExtensionCount
nullptr, // ppEnabledExtensionNames
nullptr, // pEnabledFeatures
};
VkDevice device;
result = driver.vkCreateDevice(physicalDevice, &deviceCreateInfo, nullptr, &device);
EXPECT_EQ(result, VK_SUCCESS);
driver.vkDestroyDevice(device, nullptr);
}
driver.vkDestroyInstance(instance, nullptr);
}
*/
......@@ -13,7 +13,6 @@
# limitations under the License.
set(ROOT_PROJECT_COMPILE_OPTIONS
${SWIFTSHADER_COMPILE_OPTIONS}
${WARNINGS_AS_ERRORS}
)
......@@ -23,14 +22,16 @@ set(ROOT_PROJECT_LINK_LIBRARIES
)
set(VULKAN_UNIT_TESTS_SRC_FILES
BasicTests.cpp
ComputeTests.cpp
Device.cpp
Device.hpp
DrawTests.cpp
Driver.cpp
Driver.hpp
main.cpp
VkGlobalFuncs.hpp
VkInstanceFuncs.hpp
Device.cpp
Driver.cpp
main.cpp
unittests.cpp
)
add_executable(vk-unittests
......@@ -72,5 +73,6 @@ target_link_libraries(vk-unittests
gtest
gmock
SPIRV-Tools
VulkanWrapper
${ROOT_PROJECT_LINK_LIBRARIES}
)
This source diff could not be displayed because it is too large. You can view the blob instead.
......@@ -333,7 +333,7 @@ void Device::UpdateStorageBufferDescriptorSets(
});
}
driver->vkUpdateDescriptorSets(device, writes.size(), writes.data(), 0, nullptr);
driver->vkUpdateDescriptorSets(device, (uint32_t)writes.size(), writes.data(), 0, nullptr);
}
VkResult Device::AllocateMemory(size_t size, VkMemoryPropertyFlags flags, VkDeviceMemory *out) const
......
// Copyright 2021 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 "DrawTester.hpp"
#include "gmock/gmock.h"
#include "gtest/gtest.h"
class DrawTest : public testing::Test
{
};
// Test that a vertex shader with no gl_Position works.
// This was fixed in swiftshader-cl/51808
TEST_F(DrawTest, VertexShaderNoPositionOutput)
{
DrawTester tester;
tester.onCreateVertexBuffers([](DrawTester &tester) {
struct Vertex
{
float position[3];
};
Vertex vertexBufferData[] = {
{ { 1.0f, 1.0f, 0.5f } },
{ { -1.0f, 1.0f, 0.5f } },
{ { 0.0f, -1.0f, 0.5f } }
};
std::vector<vk::VertexInputAttributeDescription> inputAttributes;
inputAttributes.push_back(vk::VertexInputAttributeDescription(0, 0, vk::Format::eR32G32B32Sfloat, offsetof(Vertex, position)));
tester.addVertexBuffer(vertexBufferData, sizeof(vertexBufferData), std::move(inputAttributes));
});
tester.onCreateVertexShader([](DrawTester &tester) {
const char *vertexShader = R"(#version 310 es
layout(location = 0) in vec3 inPos;
void main()
{
// Remove gl_Position on purpose for the test
//gl_Position = vec4(inPos.xyz, 1.0);
})";
return tester.createShaderModule(vertexShader, EShLanguage::EShLangVertex);
});
tester.onCreateFragmentShader([](DrawTester &tester) {
const char *fragmentShader = R"(#version 310 es
precision highp float;
layout(location = 0) out vec4 outColor;
void main()
{
outColor = vec4(1.0, 1.0, 1.0, 1.0);
})";
return tester.createShaderModule(fragmentShader, EShLanguage::EShLangFragment);
});
tester.initialize();
tester.renderFrame();
}
......@@ -17,20 +17,24 @@ set(ROOT_PROJECT_COMPILE_OPTIONS
)
set(VULKAN_WRAPPER_SRC_FILES
Buffer.hpp
Framebuffer.hpp
Image.hpp
Swapchain.hpp
Util.hpp
VulkanHeaders.hpp
Window.hpp
Buffer.cpp
Buffer.hpp
DrawTester.cpp
DrawTester.hpp
Framebuffer.cpp
Framebuffer.hpp
Image.cpp
Image.hpp
Swapchain.cpp
Swapchain.hpp
Util.cpp
Util.hpp
VulkanHeaders.cpp
VulkanHeaders.hpp
VulkanTester.cpp
VulkanTester.hpp
Window.cpp
Window.hpp
)
add_library(VulkanWrapper STATIC
......@@ -50,7 +54,7 @@ if (NOT TARGET SPIRV)
endif()
set_target_properties(VulkanWrapper PROPERTIES
FOLDER "Benchmarks"
FOLDER "Tests"
RUNTIME_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}"
)
......@@ -60,6 +64,11 @@ target_include_directories(VulkanWrapper
"${SWIFTSHADER_DIR}/include"
)
target_compile_definitions(VulkanWrapper
PUBLIC
"STANDALONE"
)
target_compile_options(VulkanWrapper
PRIVATE
${ROOT_PROJECT_COMPILE_OPTIONS}
......
......@@ -12,16 +12,16 @@
// See the License for the specific language governing permissions and
// limitations under the License.
#include "DrawBenchmark.hpp"
#include "DrawTester.hpp"
#define ARRAY_SIZE(arr) (sizeof(arr) / sizeof(arr[0]))
DrawBenchmark::DrawBenchmark(Multisample multisample)
DrawTester::DrawTester(Multisample multisample)
: multisample(multisample == Multisample::True)
{
}
DrawBenchmark::~DrawBenchmark()
DrawTester::~DrawTester()
{
device.freeCommandBuffers(commandPool, commandBuffers);
......@@ -59,9 +59,9 @@ DrawBenchmark::~DrawBenchmark()
window.reset();
}
void DrawBenchmark::initialize()
void DrawTester::initialize()
{
VulkanBenchmark::initialize();
VulkanTester::initialize();
window.reset(new Window(instance, windowSize));
swapchain.reset(new Swapchain(physicalDevice, device, *window));
......@@ -78,7 +78,7 @@ void DrawBenchmark::initialize()
createCommandBuffers(renderPass);
}
void DrawBenchmark::renderFrame()
void DrawTester::renderFrame()
{
swapchain->acquireNextImage(presentCompleteSemaphore, currentFrameBuffer);
......@@ -101,12 +101,12 @@ void DrawBenchmark::renderFrame()
swapchain->queuePresent(queue, currentFrameBuffer, renderCompleteSemaphore);
}
void DrawBenchmark::show()
void DrawTester::show()
{
window->show();
}
vk::RenderPass DrawBenchmark::createRenderPass(vk::Format colorFormat)
vk::RenderPass DrawTester::createRenderPass(vk::Format colorFormat)
{
std::vector<vk::AttachmentDescription> attachments(multisample ? 2 : 1);
......@@ -187,7 +187,7 @@ vk::RenderPass DrawBenchmark::createRenderPass(vk::Format colorFormat)
return device.createRenderPass(renderPassInfo);
}
void DrawBenchmark::createFramebuffers(vk::RenderPass renderPass)
void DrawTester::createFramebuffers(vk::RenderPass renderPass)
{
framebuffers.resize(swapchain->imageCount());
......@@ -197,14 +197,14 @@ void DrawBenchmark::createFramebuffers(vk::RenderPass renderPass)
}
}
void DrawBenchmark::prepareVertices()
void DrawTester::prepareVertices()
{
doCreateVertexBuffers();
hooks.createVertexBuffers(*this);
}
vk::Pipeline DrawBenchmark::createGraphicsPipeline(vk::RenderPass renderPass)
vk::Pipeline DrawTester::createGraphicsPipeline(vk::RenderPass renderPass)
{
auto setLayoutBindings = doCreateDescriptorSetLayouts();
auto setLayoutBindings = hooks.createDescriptorSetLayout(*this);
std::vector<vk::DescriptorSetLayout> setLayouts;
if(!setLayoutBindings.empty())
......@@ -271,8 +271,8 @@ vk::Pipeline DrawBenchmark::createGraphicsPipeline(vk::RenderPass renderPass)
multisampleState.rasterizationSamples = multisample ? vk::SampleCountFlagBits::e4 : vk::SampleCountFlagBits::e1;
multisampleState.pSampleMask = nullptr;
vk::ShaderModule vertexModule = doCreateVertexShader();
vk::ShaderModule fragmentModule = doCreateFragmentShader();
vk::ShaderModule vertexModule = hooks.createVertexShader(*this);
vk::ShaderModule fragmentModule = hooks.createFragmentShader(*this);
assert(vertexModule); // TODO: if nullptr, use a default
assert(fragmentModule); // TODO: if nullptr, use a default
......@@ -307,7 +307,7 @@ vk::Pipeline DrawBenchmark::createGraphicsPipeline(vk::RenderPass renderPass)
return pipeline;
}
void DrawBenchmark::createSynchronizationPrimitives()
void DrawTester::createSynchronizationPrimitives()
{
vk::SemaphoreCreateInfo semaphoreCreateInfo;
presentCompleteSemaphore = device.createSemaphore(semaphoreCreateInfo);
......@@ -322,7 +322,7 @@ void DrawBenchmark::createSynchronizationPrimitives()
}
}
void DrawBenchmark::createCommandBuffers(vk::RenderPass renderPass)
void DrawTester::createCommandBuffers(vk::RenderPass renderPass)
{
vk::CommandPoolCreateInfo commandPoolCreateInfo;
commandPoolCreateInfo.queueFamilyIndex = queueFamilyIndex;
......@@ -351,7 +351,7 @@ void DrawBenchmark::createCommandBuffers(vk::RenderPass renderPass)
descriptorSets = device.allocateDescriptorSets(allocInfo);
doUpdateDescriptorSet(commandPool, descriptorSets[0]);
hooks.updateDescriptorSet(*this, commandPool, descriptorSets[0]);
}
vk::CommandBufferAllocateInfo commandBufferAllocateInfo;
......@@ -402,7 +402,7 @@ void DrawBenchmark::createCommandBuffers(vk::RenderPass renderPass)
}
}
void DrawBenchmark::addVertexBuffer(void *vertexBufferData, size_t vertexBufferDataSize, size_t vertexSize, std::vector<vk::VertexInputAttributeDescription> inputAttributes)
void DrawTester::addVertexBuffer(void *vertexBufferData, size_t vertexBufferDataSize, size_t vertexSize, std::vector<vk::VertexInputAttributeDescription> inputAttributes)
{
assert(!vertices.buffer); // For now, only support adding once
......@@ -437,7 +437,7 @@ void DrawBenchmark::addVertexBuffer(void *vertexBufferData, size_t vertexBufferD
vertices.numVertices = static_cast<uint32_t>(vertexBufferDataSize / vertexSize);
}
vk::ShaderModule DrawBenchmark::createShaderModule(const char *glslSource, EShLanguage glslLanguage)
vk::ShaderModule DrawTester::createShaderModule(const char *glslSource, EShLanguage glslLanguage)
{
auto spirv = Util::compileGLSLtoSPIRV(glslSource, glslLanguage);
......
......@@ -12,14 +12,14 @@
// See the License for the specific language governing permissions and
// limitations under the License.
#ifndef DRAW_BENCHMARK_HPP_
#define DRAW_BENCHMARK_HPP_
#ifndef DRAW_TESTER_HPP_
#define DRAW_TESTER_HPP_
#include "Framebuffer.hpp"
#include "Image.hpp"
#include "Swapchain.hpp"
#include "Util.hpp"
#include "VulkanBenchmark.hpp"
#include "VulkanTester.hpp"
#include "Window.hpp"
enum class Multisample
......@@ -28,62 +28,43 @@ enum class Multisample
True
};
class DrawBenchmark : public VulkanBenchmark
class DrawTester : public VulkanTester
{
public:
DrawBenchmark(Multisample multisample);
~DrawBenchmark();
using ThisType = DrawTester;
DrawTester(Multisample multisample = Multisample::False);
~DrawTester();
void initialize();
void renderFrame();
void show();
private:
void createSynchronizationPrimitives();
void createCommandBuffers(vk::RenderPass renderPass);
void prepareVertices();
void createFramebuffers(vk::RenderPass renderPass);
vk::RenderPass createRenderPass(vk::Format colorFormat);
vk::Pipeline createGraphicsPipeline(vk::RenderPass renderPass);
void addVertexBuffer(void *vertexBufferData, size_t vertexBufferDataSize, size_t vertexSize, std::vector<vk::VertexInputAttributeDescription> inputAttributes);
protected:
/////////////////////////
// Hooks
/////////////////////////
// Called from prepareVertices.
// Child type may call addVertexBuffer() from this function.
virtual void doCreateVertexBuffers() {}
// Callback may call tester.addVertexBuffer() from this function.
void onCreateVertexBuffers(std::function<void(ThisType &tester)> callback);
// Called from createGraphicsPipeline.
// Child type may return vector of DescriptorSetLayoutBindings for which a DescriptorSetLayout
// Callback must return vector of DescriptorSetLayoutBindings for which a DescriptorSetLayout
// will be created and stored in this->descriptorSetLayout.
virtual std::vector<vk::DescriptorSetLayoutBinding> doCreateDescriptorSetLayouts()
{
return {};
}
void onCreateDescriptorSetLayouts(std::function<std::vector<vk::DescriptorSetLayoutBinding>(ThisType &tester)> callback);
// Called from createGraphicsPipeline.
// Child type may call createShaderModule() and return the result.
virtual vk::ShaderModule doCreateVertexShader()
{
return nullptr;
}
// Callback should call tester.createShaderModule() and return the result.
void onCreateVertexShader(std::function<vk::ShaderModule(ThisType &tester)> callback);
// Called from createGraphicsPipeline.
// Child type may call createShaderModule() and return the result.
virtual vk::ShaderModule doCreateFragmentShader()
{
return nullptr;
}
// Callback should call tester.createShaderModule() and return the result.
void onCreateFragmentShader(std::function<vk::ShaderModule(ThisType &tester)> callback);
// Called from createCommandBuffers.
// Child type may create resources (addImage, addSampler, etc.), and make sure to
// call device.updateDescriptorSets.
virtual void doUpdateDescriptorSet(vk::CommandPool &commandPool, vk::DescriptorSet &descriptorSet)
{
}
// Callback may create resources (tester.addImage, tester.addSampler, etc.), and make sure to
// call tester.device().updateDescriptorSets.
void onUpdateDescriptorSet(std::function<void(ThisType &tester, vk::CommandPool &commandPool, vk::DescriptorSet &descriptorSet)> callback);
/////////////////////////
// Resource Management
......@@ -122,7 +103,7 @@ protected:
{
auto sampler = device.createSampler(samplerCreateInfo);
samplers.push_back(sampler);
return { samplers.size() - 1, sampler };
return { samplers.size() - 1, samplers.back() };
}
vk::Sampler &getSamplerById(size_t id)
......@@ -131,6 +112,23 @@ protected:
}
private:
void createSynchronizationPrimitives();
void createCommandBuffers(vk::RenderPass renderPass);
void prepareVertices();
void createFramebuffers(vk::RenderPass renderPass);
vk::RenderPass createRenderPass(vk::Format colorFormat);
vk::Pipeline createGraphicsPipeline(vk::RenderPass renderPass);
void addVertexBuffer(void *vertexBufferData, size_t vertexBufferDataSize, size_t vertexSize, std::vector<vk::VertexInputAttributeDescription> inputAttributes);
struct Hook
{
std::function<void(ThisType &tester)> createVertexBuffers = [](auto &) {};
std::function<std::vector<vk::DescriptorSetLayoutBinding>(ThisType &tester)> createDescriptorSetLayout = [](auto &) { return std::vector<vk::DescriptorSetLayoutBinding>{}; };
std::function<vk::ShaderModule(ThisType &tester)> createVertexShader = [](auto &) { return vk::ShaderModule{}; };
std::function<vk::ShaderModule(ThisType &tester)> createFragmentShader = [](auto &) { return vk::ShaderModule{}; };
std::function<void(ThisType &tester, vk::CommandPool &commandPool, vk::DescriptorSet &descriptorSet)> updateDescriptorSet = [](auto &, auto &, auto &) {};
} hooks;
const vk::Extent2D windowSize = { 1280, 720 };
const bool multisample;
......@@ -171,4 +169,29 @@ private:
std::vector<vk::CommandBuffer> commandBuffers; // Owning handles
};
#endif // DRAW_BENCHMARK_HPP_
inline void DrawTester::onCreateVertexBuffers(std::function<void(ThisType &tester)> callback)
{
hooks.createVertexBuffers = std::move(callback);
}
inline void DrawTester::onCreateDescriptorSetLayouts(std::function<std::vector<vk::DescriptorSetLayoutBinding>(ThisType &tester)> callback)
{
hooks.createDescriptorSetLayout = std::move(callback);
}
inline void DrawTester::onCreateVertexShader(std::function<vk::ShaderModule(ThisType &tester)> callback)
{
hooks.createVertexShader = std::move(callback);
}
inline void DrawTester::onCreateFragmentShader(std::function<vk::ShaderModule(ThisType &tester)> callback)
{
hooks.createFragmentShader = std::move(callback);
}
inline void DrawTester::onUpdateDescriptorSet(std::function<void(ThisType &tester, vk::CommandPool &commandPool, vk::DescriptorSet &descriptorSet)> callback)
{
hooks.updateDescriptorSet = std::move(callback);
}
#endif // DRAW_TESTER_HPP_
......@@ -70,7 +70,7 @@ Swapchain::~Swapchain()
device.destroySwapchainKHR(swapchain, nullptr);
}
void Swapchain::acquireNextImage(VkSemaphore presentCompleteSemaphore, uint32_t &imageIndex)
void Swapchain::acquireNextImage(vk::Semaphore presentCompleteSemaphore, uint32_t &imageIndex)
{
auto result = device.acquireNextImageKHR(swapchain, UINT64_MAX, presentCompleteSemaphore, vk::Fence());
imageIndex = result.value;
......
......@@ -26,7 +26,7 @@ public:
Swapchain(vk::PhysicalDevice physicalDevice, vk::Device device, Window &window);
~Swapchain();
void acquireNextImage(VkSemaphore presentCompleteSemaphore, uint32_t &imageIndex);
void acquireNextImage(vk::Semaphore presentCompleteSemaphore, uint32_t &imageIndex);
void queuePresent(vk::Queue queue, uint32_t imageIndex, vk::Semaphore waitSemaphore);
size_t imageCount() const
......
......@@ -157,7 +157,7 @@ std::vector<uint32_t> compileGLSLtoSPIRV(const char *glslSource, EShLanguage gls
{
std::string debugLog = glslangShader->getInfoDebugLog();
std::string infoLog = glslangShader->getInfoLog();
assert(false);
assert(false && "Failed to parse shader");
}
glslang::TIntermediate *intermediateRepresentation = glslangShader->getIntermediate();
......
// Copyright 2021 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 "VulkanTester.hpp"
#include <fstream>
#if defined(_WIN32)
# define OS_WINDOWS 1
#elif defined(__APPLE__)
# define OS_MAC 1
#elif defined(__ANDROID__)
# define OS_ANDROID 1
#elif defined(__linux__)
# define OS_LINUX 1
#elif defined(__Fuchsia__)
# define OS_FUCHSIA 1
#else
# error Unimplemented platform
#endif
namespace {
std::vector<const char *> getDriverPaths()
{
#if OS_WINDOWS
# if !defined(STANDALONE)
// The DLL is delay loaded (see BUILD.gn), so we can load
// the correct ones from Chrome's swiftshader subdirectory.
// HMODULE libvulkan = LoadLibraryA("swiftshader\\libvulkan.dll");
// EXPECT_NE((HMODULE)NULL, libvulkan);
// return true;
# error TODO: !STANDALONE
# elif defined(NDEBUG)
# if defined(_WIN64)
return { "./build/Release_x64/vk_swiftshader.dll",
"./build/Release/vk_swiftshader.dll",
"./vk_swiftshader.dll" };
# else
return { "./build/Release_Win32/vk_swiftshader.dll",
"./build/Release/vk_swiftshader.dll",
"./vk_swiftshader.dll" };
# endif
# else
# if defined(_WIN64)
return { "./build/Debug_x64/vk_swiftshader.dll",
"./build/Debug/vk_swiftshader.dll",
"./vk_swiftshader.dll" };
# else
return { "./build/Debug_Win32/vk_swiftshader.dll",
"./build/Debug/vk_swiftshader.dll",
"./vk_swiftshader.dll" };
# endif
# endif
#elif OS_MAC
return { "./build/Darwin/libvk_swiftshader.dylib",
"swiftshader/libvk_swiftshader.dylib",
"libvk_swiftshader.dylib" };
#elif OS_LINUX
return { "./build/Linux/libvk_swiftshader.so",
"swiftshader/libvk_swiftshader.so",
"./libvk_swiftshader.so",
"libvk_swiftshader.so" };
#elif OS_ANDROID || OS_FUCHSIA
return
{
"libvk_swiftshader.so"
}
#else
# error Unimplemented platform
return {};
#endif
}
bool fileExists(const char *path)
{
std::ifstream f(path);
return f.good();
}
std::unique_ptr<vk::DynamicLoader> loadDriver()
{
for(auto &p : getDriverPaths())
{
if(!fileExists(p))
continue;
return std::make_unique<vk::DynamicLoader>(p);
}
return {};
}
} // namespace
VulkanTester::~VulkanTester()
{
device.waitIdle();
device.destroy(nullptr);
instance.destroy(nullptr);
}
void VulkanTester::initialize()
{
dl = loadDriver();
assert(dl && dl->success());
PFN_vkGetInstanceProcAddr vkGetInstanceProcAddr = dl->getProcAddress<PFN_vkGetInstanceProcAddr>("vkGetInstanceProcAddr");
VULKAN_HPP_DEFAULT_DISPATCHER.init(vkGetInstanceProcAddr);
instance = vk::createInstance({}, nullptr);
VULKAN_HPP_DEFAULT_DISPATCHER.init(instance);
std::vector<vk::PhysicalDevice> physicalDevices = instance.enumeratePhysicalDevices();
assert(!physicalDevices.empty());
physicalDevice = physicalDevices[0];
const float defaultQueuePriority = 0.0f;
vk::DeviceQueueCreateInfo queueCreateInfo;
queueCreateInfo.queueFamilyIndex = queueFamilyIndex;
queueCreateInfo.queueCount = 1;
queueCreateInfo.pQueuePriorities = &defaultQueuePriority;
vk::DeviceCreateInfo deviceCreateInfo;
deviceCreateInfo.queueCreateInfoCount = 1;
deviceCreateInfo.pQueueCreateInfos = &queueCreateInfo;
device = physicalDevice.createDevice(deviceCreateInfo, nullptr);
queue = device.getQueue(queueFamilyIndex, 0);
}
......@@ -12,20 +12,25 @@
// See the License for the specific language governing permissions and
// limitations under the License.
#ifndef VULKAN_BENCHMARK_HPP_
#define VULKAN_BENCHMARK_HPP_
#ifndef VULKAN_TESTER_HPP_
#define VULKAN_TESTER_HPP_
#include "VulkanHeaders.hpp"
class VulkanBenchmark
class VulkanTester
{
public:
VulkanBenchmark() = default;
virtual ~VulkanBenchmark();
VulkanTester() = default;
virtual ~VulkanTester();
// Call once after construction so that virtual functions may be called during init
void initialize();
const vk::DynamicLoader &dynamicLoader() const { return *dl; }
vk::Device &getDevice() { return this->device; }
vk::Queue &getQueue() { return this->queue; }
uint32_t getQueueFamilyIndex() const { return queueFamilyIndex; }
private:
std::unique_ptr<vk::DynamicLoader> dl;
......@@ -38,4 +43,4 @@ protected:
vk::Queue queue;
};
#endif // VULKAN_BENCHMARK_HPP_
#endif // VULKAN_TESTER_HPP_
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment