blob: 9728f84c6205dfab98f52331f38a170ad331436a [file] [log] [blame]
// Copyright (C) 2019 The Android Open Source Project
//
// 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 "goldfish_vk_baseprotodefs.pb.h"
#include "android/base/BumpPool.h"
#include "common/goldfish_vk_baseprotoconversion.h"
#include "common/goldfish_vk_testing.h"
#include "VulkanHandleMapping.h"
#include <gtest/gtest.h>
#include <vector>
#include <string.h>
#include <vulkan.h>
using android::base::BumpPool;
namespace goldfish_vk {
// Tests that a simple Vulkan struct works through protobuf API.
TEST(VulkanProtobuf, Basic) {
VkExtent2D testStruct = {
1, 2,
};
goldfish_vk_proto::VkExtent2D testProto;
testProto.set_width(testStruct.width);
testProto.set_height(testStruct.height);
EXPECT_EQ(testStruct.width, testProto.width());
EXPECT_EQ(testStruct.height, testProto.height());
}
// Tests that a Vulkan struct with strings works through protobuf API.
TEST(VulkanProtobuf, String) {
constexpr char testAppName[] = "testAppName";
constexpr char testEngineName[] = "testEngineName";
VkApplicationInfo appInfo = {
VK_STRUCTURE_TYPE_APPLICATION_INFO, 0,
testAppName, 1,
testEngineName, 2,
3,
};
goldfish_vk_proto::VkApplicationInfo appInfoProto;
appInfoProto.set_papplicationname(appInfo.pApplicationName);
appInfoProto.set_penginename(appInfo.pEngineName);
EXPECT_STREQ(appInfoProto.papplicationname().c_str(), appInfo.pApplicationName);
EXPECT_STREQ(appInfoProto.penginename().c_str(), appInfo.pEngineName);
}
// Tests that a Vulkan struct with string arrays works through protobuf API.
TEST(VulkanProtobuf, StringArray) {
const char* const testExtensionNames[] = {
"VK_KHR_get_physical_device_properties2",
"VK_KHR_external_memory_capabilities",
};
VkInstanceCreateInfo instCi = {
VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO, 0, 0,
nullptr,
0, nullptr,
2, testExtensionNames,
};
goldfish_vk_proto::VkInstanceCreateInfo instCiProto;
for (uint32_t i = 0; i < instCi.enabledExtensionCount; ++i) {
*(instCiProto.add_ppenabledextensionnames()) =
instCi.ppEnabledExtensionNames[i];
}
for (uint32_t i = 0; i < instCi.enabledExtensionCount; ++i) {
EXPECT_STREQ(instCiProto.ppenabledextensionnames(i).c_str(),
instCi.ppEnabledExtensionNames[i]);
}
}
// Tests that a Vulkan struct containing another struct works through protobuf API.
TEST(VulkanProtobuf, NestedStruct) {
constexpr char testAppName[] = "testAppName";
constexpr char testEngineName[] = "testEngineName";
const char* const testExtensionNames[] = {
"VK_KHR_get_physical_device_properties2",
"VK_KHR_external_memory_capabilities",
};
VkApplicationInfo appInfo = {
VK_STRUCTURE_TYPE_APPLICATION_INFO, 0,
testAppName, 1,
testEngineName, 2,
3,
};
VkInstanceCreateInfo instCi = {
VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO, 0, 0,
&appInfo,
0, nullptr,
2, testExtensionNames,
};
goldfish_vk_proto::VkInstanceCreateInfo instCiProto;
for (uint32_t i = 0; i < instCi.enabledExtensionCount; ++i) {
*(instCiProto.add_ppenabledextensionnames()) =
instCi.ppEnabledExtensionNames[i];
}
for (uint32_t i = 0; i < instCi.enabledExtensionCount; ++i) {
EXPECT_STREQ(instCiProto.ppenabledextensionnames(i).c_str(),
instCi.ppEnabledExtensionNames[i]);
}
EXPECT_FALSE(instCiProto.has_papplicationinfo());
auto appInfoProtoPtr =
instCiProto.mutable_papplicationinfo();
EXPECT_TRUE(instCiProto.has_papplicationinfo());
appInfoProtoPtr->set_papplicationname(appInfo.pApplicationName);
appInfoProtoPtr->set_penginename(appInfo.pEngineName);
EXPECT_STREQ(appInfoProtoPtr->papplicationname().c_str(), appInfo.pApplicationName);
EXPECT_STREQ(appInfoProtoPtr->penginename().c_str(), appInfo.pEngineName);
}
// Tests that a Vulkan struct containing another repeated struct works through protobuf API.
TEST(VulkanProtobuf, NestedRepeatedStruct) {
std::vector<VkDescriptorPoolSize> poolSizes = {
{ VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, 1 },
{ VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, 2 },
{ VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, 3 },
};
VkDescriptorPoolCreateInfo poolCi = {
VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO, 0, 0, 1,
(uint32_t)poolSizes.size(),
poolSizes.data(),
};
goldfish_vk_proto::VkDescriptorPoolCreateInfo poolCiProto;
for (uint32_t i = 0; i < poolCi.poolSizeCount; ++i) {
auto size = poolCiProto.add_ppoolsizes();
size->set_type(poolCi.pPoolSizes[i].type);
size->set_descriptorcount(poolCi.pPoolSizes[i].descriptorCount);
}
for (uint32_t i = 0; i < poolCi.poolSizeCount; ++i) {
EXPECT_EQ(poolCi.pPoolSizes[i].type,
poolCiProto.ppoolsizes(i).type());
EXPECT_EQ(poolCi.pPoolSizes[i].descriptorCount,
poolCiProto.ppoolsizes(i).descriptorcount());
}
}
// Tests that static string structs work via the protobuf api.
TEST(VulkanProtobuf, StaticString) {
VkExtensionProperties extProps = {
"VK_KHR_dedicated_allocation", 1,
};
goldfish_vk_proto::VkExtensionProperties extPropsProto;
extPropsProto.set_extensionname(extProps.extensionName);
extPropsProto.set_specversion(extProps.specVersion);
EXPECT_STREQ(
extProps.extensionName,
extPropsProto.extensionname().c_str());
}
// Tests that extension structs work via the protobuf api.
TEST(VulkanProtobuf, ExtensionStruct) {
VkMemoryDedicatedAllocateInfo dedicatedAi = {
VK_STRUCTURE_TYPE_MEMORY_DEDICATED_ALLOCATE_INFO, 0,
(VkImage)0,
(VkBuffer)1,
};
VkMemoryAllocateInfo allocInfo = {
VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO,
&dedicatedAi,
4096,
1,
};
goldfish_vk_proto::VkMemoryAllocateInfo allocInfoProto;
auto ext = allocInfoProto.mutable_pnext();
EXPECT_FALSE(ext->has_extension_vkmemorydedicatedallocateinfo());
EXPECT_FALSE(ext->has_extension_vkexportmemoryallocateinfo());
auto dedicatedAiProto =
ext->mutable_extension_vkmemorydedicatedallocateinfo();
// Check we don't step on and set any other extension.
EXPECT_TRUE(ext->has_extension_vkmemorydedicatedallocateinfo());
EXPECT_FALSE(ext->has_extension_vkexportmemoryallocateinfo());
dedicatedAiProto->set_stype(dedicatedAi.sType);
dedicatedAiProto->set_image((uint64_t)dedicatedAi.image);
dedicatedAiProto->set_buffer((uint64_t)dedicatedAi.buffer);
EXPECT_EQ(dedicatedAi.sType,
allocInfoProto.pnext()
.extension_vkmemorydedicatedallocateinfo()
.stype());
}
static void onFailCompareFunc(const char* errMsg) {
fprintf(stderr, "Failed to match: [%s]\n", errMsg);
FAIL();
}
// Tests the protobuf conversion API at a basic level.
TEST(VulkanProtobuf, ConversionSimple) {
BumpPool pool;
DefaultHandleMapping mapping;
VkExtent2D extent = { 1, 2, };
VkExtent2D extentReturn;
goldfish_vk_proto::VkExtent2D extentProto;
to_proto_VkExtent2D(
&mapping, &extent, &extentProto);
from_proto_VkExtent2D(
&pool, &mapping, &extentProto, &extentReturn);
EXPECT_EQ(extent.width, extentReturn.width);
EXPECT_EQ(extent.height, extentReturn.height);
// Test the testing API as well.
checkEqual_VkExtent2D(&extent, &extentReturn, onFailCompareFunc);
}
// Tests the protobuf conversion API when strings are involved.
TEST(VulkanProtobuf, ConversionStrings) {
BumpPool pool;
DefaultHandleMapping mapping;
constexpr char testAppName[] = "testAppName";
constexpr char testEngineName[] = "testEngineName";
VkApplicationInfo testStruct = {
VK_STRUCTURE_TYPE_APPLICATION_INFO, 0,
testAppName, 1,
testEngineName, 2,
3,
};
VkApplicationInfo testStructReturn;
goldfish_vk_proto::VkApplicationInfo testProto;
to_proto_VkApplicationInfo(
&mapping, &testStruct, &testProto);
from_proto_VkApplicationInfo(
&pool, &mapping, &testProto, &testStructReturn);
EXPECT_STREQ(
testStruct.pApplicationName,
testStructReturn.pApplicationName);
checkEqual_VkApplicationInfo(
&testStruct, &testStructReturn, onFailCompareFunc);
}
// Tests the protobuf conversion API with arrays of strings.
TEST(VulkanProtobuf, ConversionStringArrays) {
BumpPool pool;
DefaultHandleMapping mapping;
const char* const testExtensionNames[] = {
"VK_KHR_get_physical_device_properties2",
"VK_KHR_external_memory_capabilities",
};
VkInstanceCreateInfo testStruct = {
VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO, 0, 0,
nullptr,
0, nullptr,
2, testExtensionNames,
};
VkInstanceCreateInfo testStructReturn;
goldfish_vk_proto::VkInstanceCreateInfo testProto;
to_proto_VkInstanceCreateInfo(
&mapping, &testStruct, &testProto);
EXPECT_FALSE(testProto.has_papplicationinfo());
from_proto_VkInstanceCreateInfo(
&pool, &mapping, &testProto, &testStructReturn);
EXPECT_EQ(testStruct.enabledExtensionCount,
testStructReturn.enabledExtensionCount);
for (uint32_t i = 0; i < testStruct.enabledExtensionCount; ++i) {
EXPECT_STREQ(
testStruct.ppEnabledExtensionNames[i],
testStructReturn.ppEnabledExtensionNames[i]);
}
checkEqual_VkInstanceCreateInfo(
&testStruct, &testStructReturn, onFailCompareFunc);
}
// Tests the protobuf conversion API for nested structs.
TEST(VulkanProtobuf, ConversionNestedStruct) {
BumpPool pool;
DefaultHandleMapping mapping;
constexpr char testAppName[] = "testAppName";
constexpr char testEngineName[] = "testEngineName";
VkApplicationInfo appInfo = {
VK_STRUCTURE_TYPE_APPLICATION_INFO, 0,
testAppName, 1,
testEngineName, 2,
3,
};
const char* const testExtensionNames[] = {
"VK_KHR_get_physical_device_properties2",
"VK_KHR_external_memory_capabilities",
};
VkInstanceCreateInfo testStruct = {
VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO, 0, 0,
&appInfo,
0, nullptr,
2, testExtensionNames,
};
VkInstanceCreateInfo testStructReturn;
goldfish_vk_proto::VkInstanceCreateInfo testProto;
to_proto_VkInstanceCreateInfo(
&mapping, &testStruct, &testProto);
EXPECT_TRUE(testProto.has_papplicationinfo());
from_proto_VkInstanceCreateInfo(
&pool, &mapping, &testProto, &testStructReturn);
EXPECT_EQ(testStruct.enabledExtensionCount,
testStructReturn.enabledExtensionCount);
EXPECT_NE(nullptr, testStructReturn.pApplicationInfo);
checkEqual_VkInstanceCreateInfo(
&testStruct, &testStructReturn, onFailCompareFunc);
}
// Tests that protobuf conversion API can work with nested repeated structs.
TEST(VulkanProtobuf, ConversionNestedRepeatedStruct) {
BumpPool pool;
DefaultHandleMapping mapping;
std::vector<VkDescriptorPoolSize> poolSizes = {
{ VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, 1 },
{ VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, 2 },
{ VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, 3 },
};
VkDescriptorPoolCreateInfo testStruct = {
VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO, 0, 0, 1,
(uint32_t)poolSizes.size(),
poolSizes.data(),
};
VkDescriptorPoolCreateInfo testStructReturn;
goldfish_vk_proto::VkDescriptorPoolCreateInfo testProto;
to_proto_VkDescriptorPoolCreateInfo(
&mapping, &testStruct, &testProto);
from_proto_VkDescriptorPoolCreateInfo(
&pool, &mapping, &testProto, &testStructReturn);
EXPECT_EQ(testStruct.poolSizeCount, testStructReturn.poolSizeCount);
checkEqual_VkDescriptorPoolCreateInfo(
&testStruct, &testStructReturn, onFailCompareFunc);
}
// Tests the protobuf conversion API for structs that have static strings.
TEST(VulkanProtobuf, ConversionStaticString) {
BumpPool pool;
DefaultHandleMapping mapping;
VkExtensionProperties extProps = {
"VK_KHR_dedicated_allocation", 1,
};
VkExtensionProperties extPropsReturn;
goldfish_vk_proto::VkExtensionProperties extPropsProto;
to_proto_VkExtensionProperties(&mapping, &extProps, &extPropsProto);
from_proto_VkExtensionProperties(&pool, &mapping, &extPropsProto, &extPropsReturn);
EXPECT_STREQ(extPropsReturn.extensionName, extProps.extensionName);
checkEqual_VkExtensionProperties(&extProps, &extPropsReturn, onFailCompareFunc);
}
// Tests that protobuf conversion API can work with extension structs.
TEST(VulkanProtobuf, ConversionExtensionStruct) {
BumpPool pool;
DefaultHandleMapping mapping;
VkMemoryDedicatedAllocateInfo dedicatedAi = {
VK_STRUCTURE_TYPE_MEMORY_DEDICATED_ALLOCATE_INFO, 0,
(VkImage)0,
(VkBuffer)1,
};
VkMemoryAllocateInfo testStruct = {
VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO,
&dedicatedAi,
4096,
1,
};
VkMemoryAllocateInfo testStructReturn;
goldfish_vk_proto::VkMemoryAllocateInfo testProto;
to_proto_VkMemoryAllocateInfo(&mapping, &testStruct, &testProto);
from_proto_VkMemoryAllocateInfo(&pool, &mapping, &testProto, &testStructReturn);
EXPECT_TRUE(testProto.has_pnext());
checkEqual_VkMemoryAllocateInfo(
&testStruct, &testStructReturn, onFailCompareFunc);
}
} // namespace goldfish_vk