blob: 0142a52def5378b33e13fa4c567c4251fe38cc1f [file] [log] [blame]
// Copyright 2022 The Dawn Authors
//
// 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.
#ifndef SRC_DAWN_NATIVE_VULKAN_CACHEKEYVK_H_
#define SRC_DAWN_NATIVE_VULKAN_CACHEKEYVK_H_
#include "dawn/common/Assert.h"
#include "dawn/common/vulkan_platform.h"
#include "dawn/native/CacheKey.h"
#include "icd/generated/vk_typemap_helper.h"
#include <map>
namespace dawn::native::vulkan {
namespace detail {
template <typename... VK_STRUCT_TYPES>
void ValidatePnextImpl(const VkBaseOutStructure* root) {
const VkBaseOutStructure* next =
reinterpret_cast<const VkBaseOutStructure*>(root->pNext);
while (next != nullptr) {
// Assert that the type of each pNext struct is exactly one of the specified
// templates.
ASSERT(((LvlTypeMap<VK_STRUCT_TYPES>::kSType == next->sType ? 1 : 0) + ... + 0) ==
1);
next = reinterpret_cast<const VkBaseOutStructure*>(next->pNext);
}
}
template <typename VK_STRUCT_TYPE>
void SerializePnextImpl(CacheKey* key, const VkBaseOutStructure* root) {
const VkBaseOutStructure* next =
reinterpret_cast<const VkBaseOutStructure*>(root->pNext);
const VK_STRUCT_TYPE* found = nullptr;
while (next != nullptr) {
if (LvlTypeMap<VK_STRUCT_TYPE>::kSType == next->sType) {
if (found == nullptr) {
found = reinterpret_cast<const VK_STRUCT_TYPE*>(next);
} else {
// Fail an assert here since that means that the chain had more than one of
// the same typed chained object.
ASSERT(false);
}
}
next = reinterpret_cast<const VkBaseOutStructure*>(next->pNext);
}
if (found != nullptr) {
key->Record(found);
}
}
template <typename VK_STRUCT_TYPE,
typename... VK_STRUCT_TYPES,
typename = std::enable_if_t<(sizeof...(VK_STRUCT_TYPES) > 0)>>
void SerializePnextImpl(CacheKey* key, const VkBaseOutStructure* root) {
SerializePnextImpl<VK_STRUCT_TYPE>(key, root);
SerializePnextImpl<VK_STRUCT_TYPES...>(key, root);
}
} // namespace detail
template <typename... VK_STRUCT_TYPES>
void SerializePnext(CacheKey* key, const VkBaseOutStructure* root) {
detail::ValidatePnextImpl<VK_STRUCT_TYPES...>(root);
detail::SerializePnextImpl<VK_STRUCT_TYPES...>(key, root);
}
// Empty template specialization so that we can put this in to ensure failures occur if new
// extensions are added without updating serialization.
template <>
void SerializePnext(CacheKey* key, const VkBaseOutStructure* root) {
detail::ValidatePnextImpl<>(root);
}
} // namespace dawn::native::vulkan
#endif // SRC_DAWN_NATIVE_VULKAN_CACHEKEYVK_H_