Move code around in prep for CacheKey -> Stream refactor
Moves code around to simplify viewing the diff for Change If7594c4ff7117454c1ab3d0afaeee5653120add8 Bug: dawn:1480, dawn:1481 Change-Id: Iecfe4356b1a933a46741cec185008ca1d927c0a6 Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/96903 Kokoro: Kokoro <noreply+kokoro@google.com> Reviewed-by: Loko Kung <lokokung@google.com> Reviewed-by: Corentin Wallez <cwallez@chromium.org> Commit-Queue: Austin Eng <enga@chromium.org>
This commit is contained in:
parent
290b3f5926
commit
ce8876074f
|
@ -334,6 +334,7 @@ source_set("sources") {
|
||||||
"VertexFormat.cpp",
|
"VertexFormat.cpp",
|
||||||
"VertexFormat.h",
|
"VertexFormat.h",
|
||||||
"dawn_platform.h",
|
"dawn_platform.h",
|
||||||
|
"stream/Stream.h",
|
||||||
"utils/WGPUHelpers.cpp",
|
"utils/WGPUHelpers.cpp",
|
||||||
"utils/WGPUHelpers.h",
|
"utils/WGPUHelpers.h",
|
||||||
"webgpu_absl_format.cpp",
|
"webgpu_absl_format.cpp",
|
||||||
|
@ -604,7 +605,6 @@ source_set("sources") {
|
||||||
"vulkan/BufferVk.cpp",
|
"vulkan/BufferVk.cpp",
|
||||||
"vulkan/BufferVk.h",
|
"vulkan/BufferVk.h",
|
||||||
"vulkan/CacheKeyVk.cpp",
|
"vulkan/CacheKeyVk.cpp",
|
||||||
"vulkan/CacheKeyVk.h",
|
|
||||||
"vulkan/CommandBufferVk.cpp",
|
"vulkan/CommandBufferVk.cpp",
|
||||||
"vulkan/CommandBufferVk.h",
|
"vulkan/CommandBufferVk.h",
|
||||||
"vulkan/CommandRecordingContext.h",
|
"vulkan/CommandRecordingContext.h",
|
||||||
|
|
|
@ -193,6 +193,7 @@ target_sources(dawn_native PRIVATE
|
||||||
"dawn_platform.h"
|
"dawn_platform.h"
|
||||||
"webgpu_absl_format.cpp"
|
"webgpu_absl_format.cpp"
|
||||||
"webgpu_absl_format.h"
|
"webgpu_absl_format.h"
|
||||||
|
"stream/Stream.h"
|
||||||
"utils/WGPUHelpers.cpp"
|
"utils/WGPUHelpers.cpp"
|
||||||
"utils/WGPUHelpers.h"
|
"utils/WGPUHelpers.h"
|
||||||
)
|
)
|
||||||
|
@ -486,7 +487,6 @@ if (DAWN_ENABLE_VULKAN)
|
||||||
"vulkan/BufferVk.cpp"
|
"vulkan/BufferVk.cpp"
|
||||||
"vulkan/BufferVk.h"
|
"vulkan/BufferVk.h"
|
||||||
"vulkan/CacheKeyVk.cpp"
|
"vulkan/CacheKeyVk.cpp"
|
||||||
"vulkan/CacheKeyVk.h"
|
|
||||||
"vulkan/CommandBufferVk.cpp"
|
"vulkan/CommandBufferVk.cpp"
|
||||||
"vulkan/CommandBufferVk.h"
|
"vulkan/CommandBufferVk.h"
|
||||||
"vulkan/CommandRecordingContext.h"
|
"vulkan/CommandRecordingContext.h"
|
||||||
|
|
|
@ -111,151 +111,10 @@ CacheKey::UnsafeUnkeyedValue<T> UnsafeUnkeyedValue(T&& value) {
|
||||||
return CacheKey::UnsafeUnkeyedValue<T>(std::forward<T>(value));
|
return CacheKey::UnsafeUnkeyedValue<T>(std::forward<T>(value));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Specialized overload for CacheKey::UnsafeIgnoredValue which does nothing.
|
|
||||||
template <typename T>
|
|
||||||
class CacheKeySerializer<CacheKey::UnsafeUnkeyedValue<T>> {
|
|
||||||
public:
|
|
||||||
constexpr static void Serialize(CacheKey* key, const CacheKey::UnsafeUnkeyedValue<T>&) {}
|
|
||||||
};
|
|
||||||
|
|
||||||
// Specialized overload for fundamental types.
|
|
||||||
template <typename T>
|
|
||||||
class CacheKeySerializer<T, std::enable_if_t<std::is_fundamental_v<T>>> {
|
|
||||||
public:
|
|
||||||
static void Serialize(CacheKey* key, const T t) {
|
|
||||||
const char* it = reinterpret_cast<const char*>(&t);
|
|
||||||
key->insert(key->end(), it, (it + sizeof(T)));
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
// Specialized overload for bitsets that are smaller than 64.
|
|
||||||
template <size_t N>
|
|
||||||
class CacheKeySerializer<std::bitset<N>, std::enable_if_t<(N <= 64)>> {
|
|
||||||
public:
|
|
||||||
static void Serialize(CacheKey* key, const std::bitset<N>& t) { key->Record(t.to_ullong()); }
|
|
||||||
};
|
|
||||||
|
|
||||||
// Specialized overload for bitsets since using the built-in to_ullong have a size limit.
|
|
||||||
template <size_t N>
|
|
||||||
class CacheKeySerializer<std::bitset<N>, std::enable_if_t<(N > 64)>> {
|
|
||||||
public:
|
|
||||||
static void Serialize(CacheKey* key, const std::bitset<N>& t) {
|
|
||||||
// Serializes the bitset into series of uint8_t, along with recording the size.
|
|
||||||
static_assert(N > 0);
|
|
||||||
key->Record(static_cast<size_t>(N));
|
|
||||||
uint8_t value = 0;
|
|
||||||
for (size_t i = 0; i < N; i++) {
|
|
||||||
value <<= 1;
|
|
||||||
// Explicitly convert to numeric since MSVC doesn't like mixing of bools.
|
|
||||||
value |= t[i] ? 1 : 0;
|
|
||||||
if (i % 8 == 7) {
|
|
||||||
// Whenever we fill an 8 bit value, record it and zero it out.
|
|
||||||
key->Record(value);
|
|
||||||
value = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// Serialize the last value if we are not a multiple of 8.
|
|
||||||
if (N % 8 != 0) {
|
|
||||||
key->Record(value);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
// Specialized overload for enums.
|
|
||||||
template <typename T>
|
|
||||||
class CacheKeySerializer<T, std::enable_if_t<std::is_enum_v<T>>> {
|
|
||||||
public:
|
|
||||||
static void Serialize(CacheKey* key, const T t) {
|
|
||||||
CacheKeySerializer<std::underlying_type_t<T>>::Serialize(
|
|
||||||
key, static_cast<std::underlying_type_t<T>>(t));
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
// Specialized overload for TypedInteger.
|
|
||||||
template <typename Tag, typename Integer>
|
|
||||||
class CacheKeySerializer<::detail::TypedIntegerImpl<Tag, Integer>> {
|
|
||||||
public:
|
|
||||||
static void Serialize(CacheKey* key, const ::detail::TypedIntegerImpl<Tag, Integer> t) {
|
|
||||||
CacheKeySerializer<Integer>::Serialize(key, static_cast<Integer>(t));
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
// Specialized overload for pointers. Since we are serializing for a cache key, we always
|
|
||||||
// serialize via value, not by pointer. To handle nullptr scenarios, we always serialize whether
|
|
||||||
// the pointer was nullptr followed by the contents if applicable.
|
|
||||||
template <typename T>
|
|
||||||
class CacheKeySerializer<T, std::enable_if_t<std::is_pointer_v<T>>> {
|
|
||||||
public:
|
|
||||||
static void Serialize(CacheKey* key, const T t) {
|
|
||||||
key->Record(t == nullptr);
|
|
||||||
if (t != nullptr) {
|
|
||||||
CacheKeySerializer<std::remove_cv_t<std::remove_pointer_t<T>>>::Serialize(key, *t);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
// Specialized overload for fixed arrays of primitives.
|
|
||||||
template <typename T, size_t N>
|
|
||||||
class CacheKeySerializer<T[N], std::enable_if_t<std::is_fundamental_v<T>>> {
|
|
||||||
public:
|
|
||||||
static void Serialize(CacheKey* key, const T (&t)[N]) {
|
|
||||||
static_assert(N > 0);
|
|
||||||
key->Record(static_cast<size_t>(N));
|
|
||||||
const char* it = reinterpret_cast<const char*>(t);
|
|
||||||
key->insert(key->end(), it, it + sizeof(t));
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
// Specialized overload for fixed arrays of non-primitives.
|
|
||||||
template <typename T, size_t N>
|
|
||||||
class CacheKeySerializer<T[N], std::enable_if_t<!std::is_fundamental_v<T>>> {
|
|
||||||
public:
|
|
||||||
static void Serialize(CacheKey* key, const T (&t)[N]) {
|
|
||||||
static_assert(N > 0);
|
|
||||||
key->Record(static_cast<size_t>(N));
|
|
||||||
for (size_t i = 0; i < N; i++) {
|
|
||||||
key->Record(t[i]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
// Specialized overload for CachedObjects.
|
|
||||||
template <typename T>
|
|
||||||
class CacheKeySerializer<T, std::enable_if_t<std::is_base_of_v<CachedObject, T>>> {
|
|
||||||
public:
|
|
||||||
static void Serialize(CacheKey* key, const T& t) { key->Record(t.GetCacheKey()); }
|
|
||||||
};
|
|
||||||
|
|
||||||
// Specialized overload for std::vector.
|
|
||||||
template <typename T>
|
|
||||||
class CacheKeySerializer<std::vector<T>> {
|
|
||||||
public:
|
|
||||||
static void Serialize(CacheKey* key, const std::vector<T>& t) { key->RecordIterable(t); }
|
|
||||||
};
|
|
||||||
|
|
||||||
// Specialized overload for std::pair<A, B>
|
|
||||||
template <typename A, typename B>
|
|
||||||
class CacheKeySerializer<std::pair<A, B>> {
|
|
||||||
public:
|
|
||||||
static void Serialize(CacheKey* key, const std::pair<A, B>& p) {
|
|
||||||
key->Record(p.first, p.second);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
// Specialized overload for std::unordered_map<K, V>
|
|
||||||
template <typename K, typename V>
|
|
||||||
class CacheKeySerializer<std::unordered_map<K, V>> {
|
|
||||||
public:
|
|
||||||
static void Serialize(CacheKey* key, const std::unordered_map<K, V>& m) {
|
|
||||||
std::vector<std::pair<K, V>> ordered(m.begin(), m.end());
|
|
||||||
std::sort(ordered.begin(), ordered.end(),
|
|
||||||
[](const std::pair<K, V>& a, const std::pair<K, V>& b) {
|
|
||||||
return std::less<K>{}(a.first, b.first);
|
|
||||||
});
|
|
||||||
key->RecordIterable(ordered);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
} // namespace dawn::native
|
} // namespace dawn::native
|
||||||
|
|
||||||
|
// CacheKeySerializer implementation temporarily moved to stream/Stream.h to
|
||||||
|
// simplify the diff in the refactor to stream::Stream.
|
||||||
|
#include "dawn/native/stream/Stream.h"
|
||||||
|
|
||||||
#endif // SRC_DAWN_NATIVE_CACHEKEY_H_
|
#endif // SRC_DAWN_NATIVE_CACHEKEY_H_
|
||||||
|
|
|
@ -0,0 +1,181 @@
|
||||||
|
// 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_STREAM_STREAM_H_
|
||||||
|
#define SRC_DAWN_NATIVE_STREAM_STREAM_H_
|
||||||
|
|
||||||
|
#include <algorithm>
|
||||||
|
#include <bitset>
|
||||||
|
#include <functional>
|
||||||
|
#include <unordered_map>
|
||||||
|
#include <utility>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
#include "dawn/common/Platform.h"
|
||||||
|
#include "dawn/common/TypedInteger.h"
|
||||||
|
#include "dawn/native/CacheKey.h"
|
||||||
|
#include "dawn/native/Error.h"
|
||||||
|
|
||||||
|
namespace dawn::native {
|
||||||
|
|
||||||
|
class CacheKey;
|
||||||
|
|
||||||
|
// Specialized overload for CacheKey::UnsafeIgnoredValue which does nothing.
|
||||||
|
template <typename T>
|
||||||
|
class CacheKeySerializer<CacheKey::UnsafeUnkeyedValue<T>> {
|
||||||
|
public:
|
||||||
|
constexpr static void Serialize(CacheKey* key, const CacheKey::UnsafeUnkeyedValue<T>&) {}
|
||||||
|
};
|
||||||
|
|
||||||
|
// Specialized overload for fundamental types.
|
||||||
|
template <typename T>
|
||||||
|
class CacheKeySerializer<T, std::enable_if_t<std::is_fundamental_v<T>>> {
|
||||||
|
public:
|
||||||
|
static void Serialize(CacheKey* key, const T t) {
|
||||||
|
const char* it = reinterpret_cast<const char*>(&t);
|
||||||
|
key->insert(key->end(), it, (it + sizeof(T)));
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// Specialized overload for bitsets that are smaller than 64.
|
||||||
|
template <size_t N>
|
||||||
|
class CacheKeySerializer<std::bitset<N>, std::enable_if_t<(N <= 64)>> {
|
||||||
|
public:
|
||||||
|
static void Serialize(CacheKey* key, const std::bitset<N>& t) { key->Record(t.to_ullong()); }
|
||||||
|
};
|
||||||
|
|
||||||
|
// Specialized overload for bitsets since using the built-in to_ullong have a size limit.
|
||||||
|
template <size_t N>
|
||||||
|
class CacheKeySerializer<std::bitset<N>, std::enable_if_t<(N > 64)>> {
|
||||||
|
public:
|
||||||
|
static void Serialize(CacheKey* key, const std::bitset<N>& t) {
|
||||||
|
// Serializes the bitset into series of uint8_t, along with recording the size.
|
||||||
|
static_assert(N > 0);
|
||||||
|
key->Record(static_cast<size_t>(N));
|
||||||
|
uint8_t value = 0;
|
||||||
|
for (size_t i = 0; i < N; i++) {
|
||||||
|
value <<= 1;
|
||||||
|
// Explicitly convert to numeric since MSVC doesn't like mixing of bools.
|
||||||
|
value |= t[i] ? 1 : 0;
|
||||||
|
if (i % 8 == 7) {
|
||||||
|
// Whenever we fill an 8 bit value, record it and zero it out.
|
||||||
|
key->Record(value);
|
||||||
|
value = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Serialize the last value if we are not a multiple of 8.
|
||||||
|
if (N % 8 != 0) {
|
||||||
|
key->Record(value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// Specialized overload for enums.
|
||||||
|
template <typename T>
|
||||||
|
class CacheKeySerializer<T, std::enable_if_t<std::is_enum_v<T>>> {
|
||||||
|
public:
|
||||||
|
static void Serialize(CacheKey* key, const T t) {
|
||||||
|
CacheKeySerializer<std::underlying_type_t<T>>::Serialize(
|
||||||
|
key, static_cast<std::underlying_type_t<T>>(t));
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// Specialized overload for TypedInteger.
|
||||||
|
template <typename Tag, typename Integer>
|
||||||
|
class CacheKeySerializer<::detail::TypedIntegerImpl<Tag, Integer>> {
|
||||||
|
public:
|
||||||
|
static void Serialize(CacheKey* key, const ::detail::TypedIntegerImpl<Tag, Integer> t) {
|
||||||
|
CacheKeySerializer<Integer>::Serialize(key, static_cast<Integer>(t));
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// Specialized overload for pointers. Since we are serializing for a cache key, we always
|
||||||
|
// serialize via value, not by pointer. To handle nullptr scenarios, we always serialize whether
|
||||||
|
// the pointer was nullptr followed by the contents if applicable.
|
||||||
|
template <typename T>
|
||||||
|
class CacheKeySerializer<T, std::enable_if_t<std::is_pointer_v<T>>> {
|
||||||
|
public:
|
||||||
|
static void Serialize(CacheKey* key, const T t) {
|
||||||
|
key->Record(t == nullptr);
|
||||||
|
if (t != nullptr) {
|
||||||
|
CacheKeySerializer<std::remove_cv_t<std::remove_pointer_t<T>>>::Serialize(key, *t);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// Specialized overload for fixed arrays of primitives.
|
||||||
|
template <typename T, size_t N>
|
||||||
|
class CacheKeySerializer<T[N], std::enable_if_t<std::is_fundamental_v<T>>> {
|
||||||
|
public:
|
||||||
|
static void Serialize(CacheKey* key, const T (&t)[N]) {
|
||||||
|
static_assert(N > 0);
|
||||||
|
key->Record(static_cast<size_t>(N));
|
||||||
|
const char* it = reinterpret_cast<const char*>(t);
|
||||||
|
key->insert(key->end(), it, it + sizeof(t));
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// Specialized overload for fixed arrays of non-primitives.
|
||||||
|
template <typename T, size_t N>
|
||||||
|
class CacheKeySerializer<T[N], std::enable_if_t<!std::is_fundamental_v<T>>> {
|
||||||
|
public:
|
||||||
|
static void Serialize(CacheKey* key, const T (&t)[N]) {
|
||||||
|
static_assert(N > 0);
|
||||||
|
key->Record(static_cast<size_t>(N));
|
||||||
|
for (size_t i = 0; i < N; i++) {
|
||||||
|
key->Record(t[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// Specialized overload for CachedObjects.
|
||||||
|
template <typename T>
|
||||||
|
class CacheKeySerializer<T, std::enable_if_t<std::is_base_of_v<CachedObject, T>>> {
|
||||||
|
public:
|
||||||
|
static void Serialize(CacheKey* key, const T& t) { key->Record(t.GetCacheKey()); }
|
||||||
|
};
|
||||||
|
|
||||||
|
// Specialized overload for std::vector.
|
||||||
|
template <typename T>
|
||||||
|
class CacheKeySerializer<std::vector<T>> {
|
||||||
|
public:
|
||||||
|
static void Serialize(CacheKey* key, const std::vector<T>& t) { key->RecordIterable(t); }
|
||||||
|
};
|
||||||
|
|
||||||
|
// Specialized overload for std::pair<A, B>
|
||||||
|
template <typename A, typename B>
|
||||||
|
class CacheKeySerializer<std::pair<A, B>> {
|
||||||
|
public:
|
||||||
|
static void Serialize(CacheKey* key, const std::pair<A, B>& p) {
|
||||||
|
key->Record(p.first, p.second);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// Specialized overload for std::unordered_map<K, V>
|
||||||
|
template <typename K, typename V>
|
||||||
|
class CacheKeySerializer<std::unordered_map<K, V>> {
|
||||||
|
public:
|
||||||
|
static void Serialize(CacheKey* key, const std::unordered_map<K, V>& m) {
|
||||||
|
std::vector<std::pair<K, V>> ordered(m.begin(), m.end());
|
||||||
|
std::sort(ordered.begin(), ordered.end(),
|
||||||
|
[](const std::pair<K, V>& a, const std::pair<K, V>& b) {
|
||||||
|
return std::less<K>{}(a.first, b.first);
|
||||||
|
});
|
||||||
|
key->RecordIterable(ordered);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace dawn::native
|
||||||
|
|
||||||
|
#endif // SRC_DAWN_NATIVE_STREAM_STREAM_H_
|
|
@ -14,11 +14,89 @@
|
||||||
|
|
||||||
#include <cstring>
|
#include <cstring>
|
||||||
|
|
||||||
#include "dawn/native/vulkan/CacheKeyVk.h"
|
#include "dawn/common/Assert.h"
|
||||||
|
#include "dawn/common/vulkan_platform.h"
|
||||||
|
#include "dawn/native/CacheKey.h"
|
||||||
#include "dawn/native/vulkan/RenderPassCache.h"
|
#include "dawn/native/vulkan/RenderPassCache.h"
|
||||||
|
|
||||||
|
#include "icd/generated/vk_typemap_helper.h"
|
||||||
|
|
||||||
namespace dawn::native {
|
namespace dawn::native {
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename VK_STRUCT_TYPE>
|
||||||
|
const VkBaseOutStructure* ToVkBaseOutStructure(const VK_STRUCT_TYPE* t) {
|
||||||
|
// Checks to ensure proper type safety.
|
||||||
|
static_assert(offsetof(VK_STRUCT_TYPE, sType) == offsetof(VkBaseOutStructure, sType) &&
|
||||||
|
offsetof(VK_STRUCT_TYPE, pNext) == offsetof(VkBaseOutStructure, pNext),
|
||||||
|
"Argument type is not a proper Vulkan structure type");
|
||||||
|
return reinterpret_cast<const VkBaseOutStructure*>(t);
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace detail
|
||||||
|
|
||||||
|
template <typename... VK_STRUCT_TYPES,
|
||||||
|
typename VK_STRUCT_TYPE,
|
||||||
|
typename = std::enable_if_t<(sizeof...(VK_STRUCT_TYPES) > 0)>>
|
||||||
|
void SerializePnext(CacheKey* key, const VK_STRUCT_TYPE* t) {
|
||||||
|
const VkBaseOutStructure* root = detail::ToVkBaseOutStructure(t);
|
||||||
|
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 <typename VK_STRUCT_TYPE>
|
||||||
|
void SerializePnext(CacheKey* key, const VK_STRUCT_TYPE* t) {
|
||||||
|
const VkBaseOutStructure* root = detail::ToVkBaseOutStructure(t);
|
||||||
|
detail::ValidatePnextImpl<>(root);
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace
|
||||||
|
|
||||||
template <>
|
template <>
|
||||||
void CacheKeySerializer<VkDescriptorSetLayoutBinding>::Serialize(
|
void CacheKeySerializer<VkDescriptorSetLayoutBinding>::Serialize(
|
||||||
CacheKey* key,
|
CacheKey* key,
|
||||||
|
@ -31,7 +109,7 @@ void CacheKeySerializer<VkDescriptorSetLayoutCreateInfo>::Serialize(
|
||||||
CacheKey* key,
|
CacheKey* key,
|
||||||
const VkDescriptorSetLayoutCreateInfo& t) {
|
const VkDescriptorSetLayoutCreateInfo& t) {
|
||||||
key->Record(t.flags).RecordIterable(t.pBindings, t.bindingCount);
|
key->Record(t.flags).RecordIterable(t.pBindings, t.bindingCount);
|
||||||
vulkan::SerializePnext<>(key, &t);
|
SerializePnext(key, &t);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <>
|
template <>
|
||||||
|
@ -47,7 +125,7 @@ void CacheKeySerializer<VkPipelineLayoutCreateInfo>::Serialize(
|
||||||
// The set layouts are not serialized here because they are pointers to backend objects.
|
// The set layouts are not serialized here because they are pointers to backend objects.
|
||||||
// They need to be cross-referenced with the frontend objects and serialized from there.
|
// They need to be cross-referenced with the frontend objects and serialized from there.
|
||||||
key->Record(t.flags).RecordIterable(t.pPushConstantRanges, t.pushConstantRangeCount);
|
key->Record(t.flags).RecordIterable(t.pPushConstantRanges, t.pushConstantRangeCount);
|
||||||
vulkan::SerializePnext<>(key, &t);
|
SerializePnext(key, &t);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <>
|
template <>
|
||||||
|
@ -85,7 +163,7 @@ void CacheKeySerializer<VkPipelineShaderStageCreateInfo>::Serialize(
|
||||||
key->Record(t.flags, t.stage)
|
key->Record(t.flags, t.stage)
|
||||||
.RecordIterable(t.pName, strlen(t.pName))
|
.RecordIterable(t.pName, strlen(t.pName))
|
||||||
.Record(t.pSpecializationInfo);
|
.Record(t.pSpecializationInfo);
|
||||||
vulkan::SerializePnext<VkPipelineShaderStageRequiredSubgroupSizeCreateInfoEXT>(key, &t);
|
SerializePnext<VkPipelineShaderStageRequiredSubgroupSizeCreateInfoEXT>(key, &t);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <>
|
template <>
|
||||||
|
@ -121,7 +199,7 @@ void CacheKeySerializer<VkPipelineVertexInputStateCreateInfo>::Serialize(
|
||||||
key->Record(t.flags)
|
key->Record(t.flags)
|
||||||
.RecordIterable(t.pVertexBindingDescriptions, t.vertexBindingDescriptionCount)
|
.RecordIterable(t.pVertexBindingDescriptions, t.vertexBindingDescriptionCount)
|
||||||
.RecordIterable(t.pVertexAttributeDescriptions, t.vertexAttributeDescriptionCount);
|
.RecordIterable(t.pVertexAttributeDescriptions, t.vertexAttributeDescriptionCount);
|
||||||
vulkan::SerializePnext<>(key, &t);
|
SerializePnext(key, &t);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <>
|
template <>
|
||||||
|
@ -129,7 +207,7 @@ void CacheKeySerializer<VkPipelineInputAssemblyStateCreateInfo>::Serialize(
|
||||||
CacheKey* key,
|
CacheKey* key,
|
||||||
const VkPipelineInputAssemblyStateCreateInfo& t) {
|
const VkPipelineInputAssemblyStateCreateInfo& t) {
|
||||||
key->Record(t.flags, t.topology, t.primitiveRestartEnable);
|
key->Record(t.flags, t.topology, t.primitiveRestartEnable);
|
||||||
vulkan::SerializePnext<>(key, &t);
|
SerializePnext(key, &t);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <>
|
template <>
|
||||||
|
@ -137,7 +215,7 @@ void CacheKeySerializer<VkPipelineTessellationStateCreateInfo>::Serialize(
|
||||||
CacheKey* key,
|
CacheKey* key,
|
||||||
const VkPipelineTessellationStateCreateInfo& t) {
|
const VkPipelineTessellationStateCreateInfo& t) {
|
||||||
key->Record(t.flags, t.patchControlPoints);
|
key->Record(t.flags, t.patchControlPoints);
|
||||||
vulkan::SerializePnext<>(key, &t);
|
SerializePnext(key, &t);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <>
|
template <>
|
||||||
|
@ -167,7 +245,7 @@ void CacheKeySerializer<VkPipelineViewportStateCreateInfo>::Serialize(
|
||||||
key->Record(t.flags)
|
key->Record(t.flags)
|
||||||
.RecordIterable(t.pViewports, t.viewportCount)
|
.RecordIterable(t.pViewports, t.viewportCount)
|
||||||
.RecordIterable(t.pScissors, t.scissorCount);
|
.RecordIterable(t.pScissors, t.scissorCount);
|
||||||
vulkan::SerializePnext<>(key, &t);
|
SerializePnext(key, &t);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <>
|
template <>
|
||||||
|
@ -177,7 +255,7 @@ void CacheKeySerializer<VkPipelineRasterizationStateCreateInfo>::Serialize(
|
||||||
key->Record(t.flags, t.depthClampEnable, t.rasterizerDiscardEnable, t.polygonMode, t.cullMode,
|
key->Record(t.flags, t.depthClampEnable, t.rasterizerDiscardEnable, t.polygonMode, t.cullMode,
|
||||||
t.frontFace, t.depthBiasEnable, t.depthBiasConstantFactor, t.depthBiasClamp,
|
t.frontFace, t.depthBiasEnable, t.depthBiasConstantFactor, t.depthBiasClamp,
|
||||||
t.depthBiasSlopeFactor, t.lineWidth);
|
t.depthBiasSlopeFactor, t.lineWidth);
|
||||||
vulkan::SerializePnext<VkPipelineRasterizationDepthClipStateCreateInfoEXT>(key, &t);
|
SerializePnext<VkPipelineRasterizationDepthClipStateCreateInfoEXT>(key, &t);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <>
|
template <>
|
||||||
|
@ -186,7 +264,7 @@ void CacheKeySerializer<VkPipelineMultisampleStateCreateInfo>::Serialize(
|
||||||
const VkPipelineMultisampleStateCreateInfo& t) {
|
const VkPipelineMultisampleStateCreateInfo& t) {
|
||||||
key->Record(t.flags, t.rasterizationSamples, t.sampleShadingEnable, t.minSampleShading,
|
key->Record(t.flags, t.rasterizationSamples, t.sampleShadingEnable, t.minSampleShading,
|
||||||
t.pSampleMask, t.alphaToCoverageEnable, t.alphaToOneEnable);
|
t.pSampleMask, t.alphaToCoverageEnable, t.alphaToOneEnable);
|
||||||
vulkan::SerializePnext<>(key, &t);
|
SerializePnext(key, &t);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <>
|
template <>
|
||||||
|
@ -202,7 +280,7 @@ void CacheKeySerializer<VkPipelineDepthStencilStateCreateInfo>::Serialize(
|
||||||
key->Record(t.flags, t.depthTestEnable, t.depthWriteEnable, t.depthCompareOp,
|
key->Record(t.flags, t.depthTestEnable, t.depthWriteEnable, t.depthCompareOp,
|
||||||
t.depthBoundsTestEnable, t.stencilTestEnable, t.front, t.back, t.minDepthBounds,
|
t.depthBoundsTestEnable, t.stencilTestEnable, t.front, t.back, t.minDepthBounds,
|
||||||
t.maxDepthBounds);
|
t.maxDepthBounds);
|
||||||
vulkan::SerializePnext<>(key, &t);
|
SerializePnext(key, &t);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <>
|
template <>
|
||||||
|
@ -220,7 +298,7 @@ void CacheKeySerializer<VkPipelineColorBlendStateCreateInfo>::Serialize(
|
||||||
key->Record(t.flags, t.logicOpEnable, t.logicOp)
|
key->Record(t.flags, t.logicOpEnable, t.logicOp)
|
||||||
.RecordIterable(t.pAttachments, t.attachmentCount)
|
.RecordIterable(t.pAttachments, t.attachmentCount)
|
||||||
.Record(t.blendConstants);
|
.Record(t.blendConstants);
|
||||||
vulkan::SerializePnext<>(key, &t);
|
SerializePnext(key, &t);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <>
|
template <>
|
||||||
|
@ -228,7 +306,7 @@ void CacheKeySerializer<VkPipelineDynamicStateCreateInfo>::Serialize(
|
||||||
CacheKey* key,
|
CacheKey* key,
|
||||||
const VkPipelineDynamicStateCreateInfo& t) {
|
const VkPipelineDynamicStateCreateInfo& t) {
|
||||||
key->Record(t.flags).RecordIterable(t.pDynamicStates, t.dynamicStateCount);
|
key->Record(t.flags).RecordIterable(t.pDynamicStates, t.dynamicStateCount);
|
||||||
vulkan::SerializePnext<>(key, &t);
|
SerializePnext(key, &t);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <>
|
template <>
|
||||||
|
@ -266,7 +344,7 @@ void CacheKeySerializer<VkGraphicsPipelineCreateInfo>::Serialize(
|
||||||
.Record(t.pVertexInputState, t.pInputAssemblyState, t.pTessellationState, t.pViewportState,
|
.Record(t.pVertexInputState, t.pInputAssemblyState, t.pTessellationState, t.pViewportState,
|
||||||
t.pRasterizationState, t.pMultisampleState, t.pDepthStencilState,
|
t.pRasterizationState, t.pMultisampleState, t.pDepthStencilState,
|
||||||
t.pColorBlendState, t.pDynamicState, t.subpass);
|
t.pColorBlendState, t.pDynamicState, t.subpass);
|
||||||
vulkan::SerializePnext<>(key, &t);
|
SerializePnext(key, &t);
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace dawn::native
|
} // namespace dawn::native
|
||||||
|
|
|
@ -1,100 +0,0 @@
|
||||||
// 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 <map>
|
|
||||||
|
|
||||||
#include "dawn/common/Assert.h"
|
|
||||||
#include "dawn/common/vulkan_platform.h"
|
|
||||||
#include "dawn/native/CacheKey.h"
|
|
||||||
|
|
||||||
#include "icd/generated/vk_typemap_helper.h"
|
|
||||||
|
|
||||||
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);
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename VK_STRUCT_TYPE>
|
|
||||||
const VkBaseOutStructure* ToVkBaseOutStructure(const VK_STRUCT_TYPE* t) {
|
|
||||||
// Checks to ensure proper type safety.
|
|
||||||
static_assert(offsetof(VK_STRUCT_TYPE, sType) == offsetof(VkBaseOutStructure, sType) &&
|
|
||||||
offsetof(VK_STRUCT_TYPE, pNext) == offsetof(VkBaseOutStructure, pNext),
|
|
||||||
"Argument type is not a proper Vulkan structure type");
|
|
||||||
return reinterpret_cast<const VkBaseOutStructure*>(t);
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace detail
|
|
||||||
|
|
||||||
template <typename... VK_STRUCT_TYPES,
|
|
||||||
typename VK_STRUCT_TYPE,
|
|
||||||
typename = std::enable_if_t<(sizeof...(VK_STRUCT_TYPES) > 0)>>
|
|
||||||
void SerializePnext(CacheKey* key, const VK_STRUCT_TYPE* t) {
|
|
||||||
const VkBaseOutStructure* root = detail::ToVkBaseOutStructure(t);
|
|
||||||
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 <typename VK_STRUCT_TYPE>
|
|
||||||
void SerializePnext(CacheKey* key, const VK_STRUCT_TYPE* t) {
|
|
||||||
const VkBaseOutStructure* root = detail::ToVkBaseOutStructure(t);
|
|
||||||
detail::ValidatePnextImpl<>(root);
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace dawn::native::vulkan
|
|
||||||
|
|
||||||
#endif // SRC_DAWN_NATIVE_VULKAN_CACHEKEYVK_H_
|
|
Loading…
Reference in New Issue