1
+ // Copyright (C) 2024-2024 - DevSH Graphics Programming Sp. z O.O.
2
+ // This file is part of the "Nabla Engine".
3
+ #include " CAssetConverter.h"
4
+
5
+
6
+ namespace nbl ::video
7
+ {
8
+
9
+
10
+ struct dep_gather_hash
11
+ {
12
+ template <asset::Asset AssetType>
13
+ inline size_t operator ()(const CAssetConverter::root_t <AssetType>& in) const
14
+ {
15
+ return std::hash<const void *>{}(in.asset )^(in.unique ? (~0x0ull ):0x0ull );
16
+ }
17
+ };
18
+ template <asset::Asset AssetType>
19
+ using dep_gather_cache_t = core::unordered_multimap<CAssetConverter::root_t <AssetType>,typename asset_traits<AssetType>::patch_t ,dep_gather_hash>;
20
+
21
+ auto CAssetConverter::reserve (const SInput& input) -> SResults
22
+ {
23
+ SResults retval = {};
24
+ if (input.readCache ->m_params .device !=m_params.device )
25
+ return retval;
26
+
27
+ core::tuple_transform_t <dep_gather_cache_t ,supported_asset_types> dep_gather_caches;
28
+ // gather all dependencies (DFS graph search) and patch
29
+ // do not deduplicate/merge assets at this stage, only patch GPU creation parameters
30
+ {
31
+ core::stack<const asset::IAsset*> dfsStack;
32
+ auto push = [&]<asset::Asset AssetType>(const CAssetConverter::input_t <AssetType>& in)->void
33
+ {
34
+ using cache_t = dep_gather_cache_t <AssetType>;
35
+ auto & cache = std::get<cache_t >(dep_gather_caches);
36
+ auto found = cache.equal_range (in);
37
+ if (found.first !=found.second )
38
+ {
39
+ #if 0
40
+ // found the thing, combine patches
41
+ const auto& cachedPatch = found->patch;
42
+ if (auto combined=in.patch; combined)
43
+ const_cast<asset_traits<AssetType>::patch_t&>(cachedPatch) = combined;
44
+ #endif
45
+ }
46
+ // insert a new entry
47
+ cache.insert (found.first ,{in,{}/* in.patch*/ });
48
+ };
49
+ core::visit ([&push]<asset::Asset AssetType>(const SInput::span_t <AssetType> assets)->void {
50
+ for (auto & asset : assets)
51
+ push (asset);
52
+ },input.assets );
53
+ /*
54
+ auto pushAll = [&push]()->void
55
+ {
56
+ };
57
+ while (!dfsStack.empty())
58
+ {
59
+ const auto* asset = dfsStack.top();
60
+ dfsStack.pop();
61
+
62
+ auto found = std::get<dep_gather_cache_t<asset::ICPUShader>>(dep_gather_caches).find(asset);
63
+ if (!=end())
64
+ {
65
+ }
66
+ }
67
+ */
68
+ }
69
+
70
+ // check whether the item is creatable after patching, else duplicate/de-alias
71
+
72
+ // now we have a list of gpu creation parameters we want to create resources with
73
+
74
+ #if 0
75
+ auto stuff = [&]<typename AssetType>(const input_t<AssetType>& key)->void
76
+ {
77
+ //
78
+ CCache::search_t<AssetType> s = key;
79
+ if (!s.patch.has_value())
80
+ s.patch = asset_traits<AssetType>::defaultPatch(key.asset);
81
+ const size_t hash = CCache::Hash{}(s);
82
+
83
+ // search by the {asset+patch} in read cache
84
+ if (auto found=input.readCache->find(s,hash); found!=input.readCache->end<AssetType>())
85
+ {
86
+ //
87
+ }
88
+
89
+ // reserve in write cache
90
+ };
91
+ #endif
92
+
93
+ // if read cache
94
+ // find deps in read cache
95
+ // mark deps as ready/found
96
+ // if not ready/found
97
+ // find dep in transient cache
98
+ // if not found, insert and recurse
99
+
100
+ // see what can be patched/combined
101
+
102
+ return retval;
103
+ }
104
+
105
+ bool CAssetConverter::convert (SResults& reservations, SConvertParams& params)
106
+ {
107
+ if (!reservations.reserveSuccess ())
108
+ return false ;
109
+
110
+ const auto reqQueueFlags = reservations.getRequiredQueueFlags ();
111
+ if (reqQueueFlags.hasFlags (IQueue::FAMILY_FLAGS::TRANSFER_BIT|IQueue::FAMILY_FLAGS::COMPUTE_BIT) && !params.utilities )
112
+ return false ;
113
+
114
+ auto invalidQueue = [reqQueueFlags](const IQueue::FAMILY_FLAGS flag, IQueue* queue)->bool
115
+ {
116
+ if (!reqQueueFlags.hasFlags (flag))
117
+ return false ;
118
+ if (!queue || queue->getFamilyIndex ())
119
+ return true ;
120
+ return false ;
121
+ };
122
+ if (reqQueueFlags.hasFlags (IQueue::FAMILY_FLAGS::TRANSFER_BIT) && (!params.transfer .queue || params.transfer .queue ->getFamilyIndex () || !params.utilities ))
123
+ return false ;
124
+ if (reqQueueFlags.hasFlags (IQueue::FAMILY_FLAGS::COMPUTE_BIT) && (!params.compute .queue || !params.utilities ))
125
+ return false ;
126
+
127
+ const core::string debugPrefix = " Created by Converter " +std::to_string (ptrdiff_t (this ))+" with hash " ;
128
+ auto setDebugName = [&debugPrefix](IBackendObject* obj, const size_t hashval)->void
129
+ {
130
+ if (obj)
131
+ obj->setObjectDebugName ((debugPrefix+std::to_string (hashval)).c_str ());
132
+ };
133
+
134
+ auto device = m_params.device ;
135
+ // create shaders
136
+ {
137
+ ILogicalDevice::SShaderCreationParameters params = {
138
+ .optimizer = m_params.optimizer .get (),
139
+ .readCache = m_params.compilerCache .get (),
140
+ .writeCache = m_params.compilerCache .get ()
141
+ };
142
+
143
+ {
144
+ params.cpushader = nullptr ; // TODO
145
+ reservations.get <asset::ICPUShader>().emplace_back (device->createShader (params));
146
+ }
147
+ }
148
+
149
+ return true ;
150
+ }
151
+
152
+ }
0 commit comments