UDocumentation UE5.7 10.02.2026 (Source)
API documentation for Unreal Engine 5.7
D3D12BarriersFactory.h
Go to the documentation of this file.
1// Copyright Epic Games, Inc. All Rights Reserved.
2
3#pragma once
4
5#include "ID3D12Barriers.h"
6
8
9#include <type_traits>
10
17
18// Enforce that a parameter is a non-abstract implementation of a base class
19template <typename TBase, typename T>
21 std::is_base_of_v<TBase, T>
22 && !std::is_abstract_v<T>;
23
24// Must be a concrete implementation of ID3D12BarriersForAdapter or nullptr_t
25template <typename T>
28 || std::is_same_v<T, nullptr_t>;
29
30// Must be a concrete implementation of ID3D12BarriersForContext or nullptr_t
31template <typename T>
34 || std::is_same_v<T, nullptr_t>;
35
36// Type used to bring some structure (heh) to the template parameters for TD3D12BarriersFactory
37template <
47
48
49// Don't define any of the *ImplTypes in this case since it's a terminator only and meaningless
50// as a factory entry. If we try to use the ImplTypes, something has gone wrong anyway.
51template <>
53
54// Used for ending the list of TFactoryEntries in the template parameters for TD3D12BarriersFactory
57
58
59//
60// Check if a type is an instance of TD3D12BarriersFactoryEntry
61//
62// This is done by having a baseline struct template that accepts any type followed by
63// a template-template type which we default to TD3D12BarriersFactoryEntry. This
64// baseline produces a struct that inherits from std::false_type and is what all types
65// that don't follow the pattern of TTemplate<auto, typename...> will match. Template
66// types that do follow the pattern of TTemplate<auto, typename...> will match the
67// specialization. That's good, but also means it would match anytime that takes that
68// pattern of template parameters and specifically only want TD3D12BarriersFactoryEntry.
69// To further refine the result, we then conditionally switch on if putting the
70// template-template type back together with its parameters produces the same type as
71// gluing those same parameters together with TD3D12BarriersFactoryEntry. Whether the
72// resulting struct inherits from std::true_type or std::false_type depends on the result
73// of that equality and ultimately answers the question of if the provided type is an
74// instance of TD3D12BarriersFactoryEntry.
75//
76template<typename, template<auto, typename...> typename = TD3D12BarriersFactoryEntry>
78
79template<template<auto, typename...> typename TTemplate, auto InImplType, typename... TParams>
81 std::conditional_t<
82 std::is_same_v<
83 TTemplate<InImplType, TParams...>,
84 TD3D12BarriersFactoryEntry<InImplType, TParams...>
85 >,
86 std::true_type,
87 std::false_type
88 > {};
89
90// Must be an instance of the TD3D12BarriersFactoryEntry template
91template <typename T>
93
94
95//
96// This factory has the task of both creating the various barrier implementation
97// objects at runtime and also informing the Adapter and Context as to which types
98// they should use to refer to the implementation objects. If a given platform is
99// compiled with only a single implementation, then the types
100//
101// - TD3D12BarriersFactory::BarriersForAdapterType
102// - TD3D12BarriersFactory::BarriersForContextType
103//
104// will reflect the concrete types of that single implementation. Otherwise, if
105// multiple implementations are compiled in (and therefore selectable at runtime),
106// then the above types will be of the abstract interface types. This is to combat,
107// at least, MSVC not being intelligent enough to de-virtualize the functions calls
108// where appropriate. If you want something done...
109//
110// To implement a new platform, create a <PlatformPrefix>BarriersFactory.h file in
111// its D3D12RHI/Private folder. An Example would be
112// Engine/Source/Runtime/D3D12RHI/Private/Windows/WindowsD3D12BarriersFactory.h
113// This file needs to define the type FD3D12BarriersFactory as an instantiation
114// of the TD3D12BarriersFactory.
115//
116// In that type definition define each barrier implementation as a
117// TD3D12BarriersFactoryEntry in the template parameters passed to
118// TD3D12BarriersFactory. Note that this list must end with
119// FNullD3D12BarriersFactoryEntry. This is to solve the trailing ',' in the case
120// that a given platform can support multiple implementations. Those must also be
121// compile time controllable and dealing with that trailing ',' gets messy so
122// always having a trailing entry (that's ignored btw) comes in handy.
123//
124// This code also does its best to identify problems with its use during compile
125// time since usage may not be exactly intuitive.
126//
127
130{
131private:
132 template <typename TFirst, typename...>
133 struct TGetFirstTypeInPack { using Type = TFirst; };
134
135 // 2 accounts for 1 entry + terminator
136 static constexpr uint32 MinimumFactoryEntries = 2u;
137
138public:
139 template <CD3D12BarriersForAdapterImpl TAdapterImpl, CD3D12BarriersForContextImpl TContextImpl>
141
143 std::conditional_t<
144 (sizeof...(TFactoryEntries) > MinimumFactoryEntries),
146 typename TGetFirstTypeInPack<TFactoryEntries...>::Type::AdapterImplType>;
147
149 std::conditional_t<
150 (sizeof...(TFactoryEntries) > MinimumFactoryEntries),
152 typename TGetFirstTypeInPack<TFactoryEntries...>::Type::ContextImplType>;
153
154 [[nodiscard]]
157 {
158 return CreateBarriersInternal<EComponentType::Adapter, TFactoryEntries...>(PreferredType);
159 }
160
161 [[nodiscard]]
164 {
165 return CreateBarriersInternal<EComponentType::Context, TFactoryEntries...>(PreferredType);
166 }
167
168private:
169 enum class EComponentType
170 {
171 Adapter,
172 Context,
173 };
174
175 // If another component type is added, add a new specialization
176 // to use the same CreateBarriersInternal function for it
177 template <EComponentType InCompType>
178 struct CreateBarriersInternalReturnType { using Type = nullptr_t; };
179 template<>
180 struct CreateBarriersInternalReturnType<EComponentType::Adapter> { using Type = BarriersForAdapterType; };
181 template<>
182 struct CreateBarriersInternalReturnType<EComponentType::Context> { using Type = BarriersForContextType; };
183
184 template <
188 [[nodiscard]]
189 static CreateBarriersInternalReturnType<InComponentType>::Type* CreateBarriersInternal(
191 {
192 // TRest only contains the terminator
193 // Note that this also means the last entry in the list will
194 // be the default if the PreferredType cannot be be matched
195 if constexpr (sizeof...(TRest) == 1)
196 {
197 if constexpr (InComponentType == EComponentType::Adapter)
198 {
199 return new TFirst::AdapterImplType();
200 }
201 if constexpr (InComponentType == EComponentType::Context)
202 {
203 return new TFirst::ContextImplType();
204 }
205 }
206 else if (TFirst::ImplType == PreferredType)
207 {
208 if constexpr (InComponentType == EComponentType::Adapter)
209 {
210 return new TFirst::AdapterImplType();
211 }
212 if constexpr (InComponentType == EComponentType::Context)
213 {
214 return new TFirst::ContextImplType();
215 }
216 }
217 else
218 {
219 return CreateBarriersInternal<InComponentType, TRest...>(PreferredType);
220 }
221 }
222
223 template <typename T, typename TFirst, typename... TRest>
224 static consteval bool CheckThatLastTypeInPackIs()
225 {
226 if constexpr (sizeof...(TRest) == 0)
227 {
228 return std::is_same_v<TFirst, T>;
229 }
230 else
231 {
232 return CheckThatLastTypeInPackIs<T, TRest...>();
233 }
234 }
235
237 static consteval bool CheckThatNoImplTypeAppearsMoreThanOnce(
239 {
240 if constexpr (sizeof...(TRest) == 0)
241 {
242 return true;
243 }
244 else if (SeenTypes[static_cast<uint32>(TFirst::ImplType)])
245 {
246 return false;
247 }
248 else
249 {
250 SeenTypes[static_cast<uint32>(TFirst::ImplType)] = true;
251 return CheckThatNoImplTypeAppearsMoreThanOnce<TRest...>(SeenTypes);
252 }
253 }
254
255 static_assert(
256 CheckThatLastTypeInPackIs<FNullD3D12BarriersFactoryEntry, TFactoryEntries...>(),
257 "List of barrier implementations must end with FNullD3D12BarriersFactoryEntry!");
258
259 static_assert(sizeof...(TFactoryEntries) >= MinimumFactoryEntries,
260 "No list of barrier implementations provided!");
261
262 static_assert(
263 CheckThatNoImplTypeAppearsMoreThanOnce<TFactoryEntries...>(),
264 "More than one implementation for a given type is provided. "
265 "TD3D12BarriersFactory will always pick the first implementation of a given type!");
266};
UE_FORCEINLINE_HINT TSharedRef< CastToType, Mode > StaticCastSharedRef(TSharedRef< CastFromType, Mode > const &InSharedRef)
Definition SharedPointer.h:127
TD3D12BarriersFactoryEntry< ED3D12BarrierImplementationType::Invalid, nullptr_t, nullptr_t > FNullD3D12BarriersFactoryEntry
Definition D3D12BarriersFactory.h:56
ED3D12BarrierImplementationType
Definition D3D12BarriersFactory.h:12
uint32_t uint32
Definition binka_ue_file_header.h:6
Definition ID3D12Barriers.h:49
Definition ID3D12Barriers.h:96
Definition D3D12BarriersFactory.h:130
std::conditional_t<(sizeof...(TFactoryEntries) > MinimumFactoryEntries), ID3D12BarriersForAdapter, typename TGetFirstTypeInPack< TFactoryEntries... >::Type::AdapterImplType > BarriersForAdapterType
Definition D3D12BarriersFactory.h:146
std::conditional_t<(sizeof...(TFactoryEntries) > MinimumFactoryEntries), ID3D12BarriersForContext, typename TGetFirstTypeInPack< TFactoryEntries... >::Type::ContextImplType > BarriersForContextType
Definition D3D12BarriersFactory.h:152
static BarriersForContextType * CreateBarriersForContext(ED3D12BarrierImplementationType PreferredType)
Definition D3D12BarriersFactory.h:162
static BarriersForAdapterType * CreateBarriersForAdapter(ED3D12BarrierImplementationType PreferredType)
Definition D3D12BarriersFactory.h:155
Definition StaticArray.h:26
Definition D3D12BarriersFactory.h:92
Definition D3D12BarriersFactory.h:26
Definition D3D12BarriersFactory.h:32
Definition D3D12BarriersFactory.h:20
Definition AnimTypes.h:802
Type
Definition PawnAction_Move.h:11
Definition D3D12BarriersFactory.h:42
static constexpr ED3D12BarrierImplementationType ImplType
Definition D3D12BarriersFactory.h:43
TAdapterImpl AdapterImplType
Definition D3D12BarriersFactory.h:44
TContextImpl ContextImplType
Definition D3D12BarriersFactory.h:45
Definition D3D12BarriersFactory.h:77
Definition Tuple.h:652