Skip to content

Commit 7cd6273

Browse files
committed
Introduce undefined and replacement resource types
Can now create resources as undefined types and replace them with the actual type when it is actually loaded instead of possibly creating the incorrect type ahead of time.
1 parent c9b9b9d commit 7cd6273

22 files changed

+822
-202
lines changed

libs/foe_graphics_resource/src/image_loader.cpp

Lines changed: 21 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -142,8 +142,23 @@ void foeImageLoader::gfxMaintenance() {
142142
new (pDst) foeImage(std::move(*pSrcData));
143143
};
144144

145-
it.pPostLoadFn(it.resource, to_foeResult(FOE_GRAPHICS_RESOURCE_SUCCESS), &it.data,
146-
moveFn, this, foeImageLoader::unloadResource);
145+
if (foeResourceGetType(it.resource) == FOE_RESOURCE_RESOURCE_TYPE_UNDEFINED) {
146+
// Need to replace the placeholder with the actual resource
147+
foeResource newResource = foeResourcePoolLoadedReplace(
148+
mResourcePool, foeResourceGetID(it.resource),
149+
FOE_GRAPHICS_RESOURCE_STRUCTURE_TYPE_IMAGE, sizeof(foeImage), &it.data,
150+
moveFn, this, foeImageLoader::unloadResource);
151+
152+
if (newResource == FOE_NULL_HANDLE)
153+
// @TODO - Handle failure
154+
std::abort();
155+
156+
foeResourceDecrementRefCount(it.resource);
157+
foeResourceDecrementRefCount(newResource);
158+
} else {
159+
it.pPostLoadFn(it.resource, to_foeResult(FOE_GRAPHICS_RESOURCE_SUCCESS),
160+
&it.data, moveFn, this, foeImageLoader::unloadResource);
161+
}
147162
} else {
148163
// Destroy the data immediately
149164
VkDevice device = foeGfxVkGetDevice(mGfxSession);
@@ -208,10 +223,12 @@ void foeImageLoader::load(foeResource resource,
208223
nullptr, nullptr, nullptr, nullptr);
209224
foeResourceCreateInfoDecrementRefCount(createInfo);
210225
return;
211-
} else if (foeResourceGetType(resource) != FOE_GRAPHICS_RESOURCE_STRUCTURE_TYPE_IMAGE) {
226+
} else if (foeResourceType type = foeResourceGetType(resource);
227+
type != FOE_GRAPHICS_RESOURCE_STRUCTURE_TYPE_IMAGE &&
228+
type != FOE_RESOURCE_RESOURCE_TYPE_UNDEFINED) {
212229
FOE_LOG(foeGraphicsResource, FOE_LOG_LEVEL_ERROR,
213230
"foeImageLoader - Cannot load {} as it is an incompatible type: {}",
214-
foeIdToString(foeResourceGetID(resource)), foeResourceGetType(resource));
231+
foeIdToString(foeResourceGetID(resource)), type);
215232

216233
pPostLoadFn(resource, to_foeResult(FOE_GRAPHICS_RESOURCE_ERROR_INCOMPATIBLE_RESOURCE_TYPE),
217234
nullptr, nullptr, nullptr, nullptr);

libs/foe_graphics_resource/src/material_loader.cpp

Lines changed: 139 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -107,6 +107,31 @@ bool foeMaterialLoader::initializedGraphics() const noexcept {
107107
return mGfxSession != FOE_NULL_HANDLE;
108108
}
109109

110+
namespace {
111+
112+
bool processResourceReplacement(foeResource *pResource) {
113+
bool replaced = false;
114+
115+
if (*pResource == FOE_NULL_HANDLE)
116+
return false;
117+
118+
while (foeResourceGetType(*pResource) == FOE_RESOURCE_RESOURCE_TYPE_REPLACED) {
119+
foeResource replacement = foeResourceGetReplacement(*pResource);
120+
121+
foeResourceIncrementUseCount(replacement);
122+
123+
foeResourceDecrementUseCount(*pResource);
124+
foeResourceDecrementRefCount(*pResource);
125+
126+
*pResource = replacement;
127+
replaced = true;
128+
}
129+
130+
return replaced;
131+
}
132+
133+
} // namespace
134+
110135
void foeMaterialLoader::gfxMaintenance() {
111136
// Process Delayed Data Destruction
112137
mDestroySync.lock();
@@ -144,45 +169,110 @@ void foeMaterialLoader::gfxMaintenance() {
144169
std::vector<LoadData> stillLoading;
145170

146171
for (auto &it : toLoad) {
147-
// Check to see if what we need has been loaded yet
148-
std::array<foeResource, 2> subResources = {
149-
it.data.fragmentShader,
150-
it.data.image,
151-
};
172+
bool replacement;
173+
foeResourceLoadState subResLoadState;
174+
175+
do {
176+
// Check to see if what we need has been loaded yet
177+
std::array<foeResource, 2> subResources = {
178+
it.data.fragmentShader,
179+
it.data.image,
180+
};
181+
subResLoadState = worstResourceLoadState(subResources.size(), subResources.data());
182+
183+
// Then perform any replacements after retreiving the load state
184+
replacement = false;
185+
replacement = replacement || processResourceReplacement(&it.data.fragmentShader);
186+
replacement = replacement || processResourceReplacement(&it.data.image);
187+
188+
// Repeat as long as replacements are occurring
189+
} while (replacement);
190+
191+
// Verify the sub-resources are/have expected type
192+
if (it.data.fragmentShader != FOE_NULL_HANDLE) {
193+
if (foeResourceType type = foeResourceGetType(it.data.fragmentShader);
194+
type != FOE_GRAPHICS_RESOURCE_STRUCTURE_TYPE_SHADER &&
195+
type != FOE_RESOURCE_RESOURCE_TYPE_REPLACED &&
196+
type != FOE_RESOURCE_RESOURCE_TYPE_UNDEFINED &&
197+
!foeResourceHasType(it.data.fragmentShader,
198+
FOE_GRAPHICS_RESOURCE_STRUCTURE_TYPE_SHADER)) {
199+
subResLoadState = FOE_RESOURCE_LOAD_STATE_FAILED;
200+
}
201+
}
152202

153-
auto subResLoadState = worstResourceLoadState(subResources.size(), subResources.data());
203+
if (it.data.image != FOE_NULL_HANDLE) {
204+
if (foeResourceType type = foeResourceGetType(it.data.fragmentShader);
205+
type != FOE_GRAPHICS_RESOURCE_STRUCTURE_TYPE_IMAGE &&
206+
type != FOE_RESOURCE_RESOURCE_TYPE_REPLACED &&
207+
type != FOE_RESOURCE_RESOURCE_TYPE_UNDEFINED &&
208+
!foeResourceHasType(it.data.fragmentShader,
209+
FOE_GRAPHICS_RESOURCE_STRUCTURE_TYPE_IMAGE)) {
210+
subResLoadState = FOE_RESOURCE_LOAD_STATE_FAILED;
211+
}
212+
}
154213

155214
if (subResLoadState == FOE_RESOURCE_LOAD_STATE_LOADED) {
156-
{ // Using the sub-resources that are loaded, and definition data, create the resource
157-
foeGfxShader fragShader =
158-
(it.data.fragmentShader != FOE_NULL_HANDLE)
159-
? ((foeShader const *)foeResourceGetData(it.data.fragmentShader))->shader
160-
: FOE_NULL_HANDLE;
161-
162-
auto const *pMaterialCI =
163-
(foeMaterialCreateInfo const *)foeResourceCreateInfoGetData(it.createInfo);
164-
165-
it.data.pGfxFragDescriptor = foeGfxVkGetFragmentDescriptor(
166-
mGfxFragmentDescriptorPool, pMaterialCI->pRasterizationSCI,
167-
pMaterialCI->pDepthStencilSCI, pMaterialCI->pColourBlendSCI, fragShader);
168-
}
215+
// Using the sub-resources that are loaded, and definition data, create the resource
216+
foeGfxShader fragShader =
217+
(it.data.fragmentShader != FOE_NULL_HANDLE)
218+
? ((foeShader const *)foeResourceGetTypeData(
219+
it.data.fragmentShader, FOE_GRAPHICS_RESOURCE_STRUCTURE_TYPE_SHADER))
220+
->shader
221+
: FOE_NULL_HANDLE;
169222

170-
VkResult vkResult = createDescriptorSet(&it.data);
171-
if (vkResult != VK_SUCCESS)
172-
goto DESCRIPTOR_CREATE_FAILED;
223+
auto const *pMaterialCI =
224+
(foeMaterialCreateInfo const *)foeResourceCreateInfoGetData(it.createInfo);
173225

174-
// Everything's ready, load the resource
175-
auto moveFn = [](void *pSrc, void *pDst) {
176-
auto *pSrcData = (foeMaterial *)pSrc;
177-
new (pDst) foeMaterial(std::move(*pSrcData));
178-
};
226+
it.data.pGfxFragDescriptor = foeGfxVkGetFragmentDescriptor(
227+
mGfxFragmentDescriptorPool, pMaterialCI->pRasterizationSCI,
228+
pMaterialCI->pDepthStencilSCI, pMaterialCI->pColourBlendSCI, fragShader);
179229

180-
it.pPostLoadFn(it.resource, {}, &it.data, moveFn, this,
181-
foeMaterialLoader::unloadResource);
182-
foeResourceCreateInfoDecrementRefCount(it.createInfo);
230+
VkResult vkResult = createDescriptorSet(&it.data);
231+
if (vkResult != VK_SUCCESS) {
232+
// Failed to load
233+
it.pPostLoadFn(
234+
it.resource,
235+
to_foeResult(FOE_GRAPHICS_RESOURCE_ERROR_MATERIAL_SUBRESOURCE_FAILED_TO_LOAD),
236+
nullptr, nullptr, nullptr, nullptr);
237+
foeResourceCreateInfoDecrementRefCount(it.createInfo);
238+
239+
// Unload the data we did get
240+
if (it.data.fragmentShader != nullptr) {
241+
foeResourceDecrementUseCount(it.data.fragmentShader);
242+
foeResourceDecrementRefCount(it.data.fragmentShader);
243+
}
244+
if (it.data.image != FOE_NULL_HANDLE) {
245+
foeResourceDecrementUseCount(it.data.image);
246+
foeResourceDecrementRefCount(it.data.image);
247+
}
248+
} else {
249+
// Everything's ready, load the resource
250+
auto moveFn = [](void *pSrc, void *pDst) {
251+
auto *pSrcData = (foeMaterial *)pSrc;
252+
new (pDst) foeMaterial(std::move(*pSrcData));
253+
};
254+
255+
if (foeResourceGetType(it.resource) == FOE_RESOURCE_RESOURCE_TYPE_UNDEFINED) {
256+
// Need to replace the placeholder with the actual resource
257+
foeResource newResource = foeResourcePoolLoadedReplace(
258+
mResourcePool, foeResourceGetID(it.resource),
259+
FOE_GRAPHICS_RESOURCE_STRUCTURE_TYPE_MATERIAL, sizeof(foeMaterial),
260+
&it.data, moveFn, this, foeMaterialLoader::unloadResource);
261+
262+
if (newResource == FOE_NULL_HANDLE)
263+
// @TODO - Handle failure
264+
std::abort();
265+
266+
foeResourceDecrementRefCount(it.resource);
267+
foeResourceDecrementRefCount(newResource);
268+
} else {
269+
it.pPostLoadFn(it.resource, {}, &it.data, moveFn, this,
270+
foeMaterialLoader::unloadResource);
271+
}
272+
273+
foeResourceCreateInfoDecrementRefCount(it.createInfo);
274+
}
183275
} else if (subResLoadState == FOE_RESOURCE_LOAD_STATE_FAILED) {
184-
DESCRIPTOR_CREATE_FAILED:
185-
// One of them failed to load, we're not proceeding with this resource
186276
it.pPostLoadFn(
187277
it.resource,
188278
to_foeResult(FOE_GRAPHICS_RESOURCE_ERROR_MATERIAL_SUBRESOURCE_FAILED_TO_LOAD),
@@ -242,10 +332,12 @@ void foeMaterialLoader::load(foeResource resource,
242332
nullptr, nullptr, nullptr, nullptr);
243333
foeResourceCreateInfoDecrementRefCount(createInfo);
244334
return;
245-
} else if (foeResourceGetType(resource) != FOE_GRAPHICS_RESOURCE_STRUCTURE_TYPE_MATERIAL) {
335+
} else if (foeResourceType type = foeResourceGetType(resource);
336+
type != FOE_GRAPHICS_RESOURCE_STRUCTURE_TYPE_MATERIAL &&
337+
type != FOE_RESOURCE_RESOURCE_TYPE_UNDEFINED) {
246338
FOE_LOG(foeGraphicsResource, FOE_LOG_LEVEL_ERROR,
247339
"foeMaterialLoader - Cannot load {} as it is an incompatible type: {}",
248-
foeIdToString(foeResourceGetID(resource)), foeResourceGetType(resource));
340+
foeIdToString(foeResourceGetID(resource)), type);
249341

250342
pPostLoadFn(resource, to_foeResult(FOE_GRAPHICS_RESOURCE_ERROR_INCOMPATIBLE_RESOURCE_TYPE),
251343
nullptr, nullptr, nullptr, nullptr);
@@ -266,13 +358,15 @@ void foeMaterialLoader::load(foeResource resource,
266358
data.fragmentShader = foeResourcePoolFind(mResourcePool, pMaterialCI->fragmentShader);
267359

268360
if (data.fragmentShader == FOE_NULL_HANDLE)
269-
data.fragmentShader = foeResourcePoolAdd(
270-
mResourcePool, pMaterialCI->fragmentShader,
271-
FOE_GRAPHICS_RESOURCE_STRUCTURE_TYPE_SHADER, sizeof(foeShader));
361+
data.fragmentShader =
362+
foeResourcePoolAdd(mResourcePool, pMaterialCI->fragmentShader);
272363
}
273364

274-
if (foeResourceGetType(data.fragmentShader) !=
275-
FOE_GRAPHICS_RESOURCE_STRUCTURE_TYPE_SHADER) {
365+
if (foeResourceType type = foeResourceGetType(data.fragmentShader);
366+
type != FOE_GRAPHICS_RESOURCE_STRUCTURE_TYPE_SHADER &&
367+
type != FOE_RESOURCE_RESOURCE_TYPE_REPLACED &&
368+
type != FOE_RESOURCE_RESOURCE_TYPE_UNDEFINED &&
369+
!foeResourceHasType(data.fragmentShader, FOE_GRAPHICS_RESOURCE_STRUCTURE_TYPE_SHADER)) {
276370
result = to_foeResult(FOE_GRAPHICS_RESOURCE_ERROR_MATERIAL_SUBRESOURCE_INCOMPATIBLE);
277371
goto LOAD_FAILED;
278372
}
@@ -283,12 +377,14 @@ void foeMaterialLoader::load(foeResource resource,
283377
data.image = foeResourcePoolFind(mResourcePool, pMaterialCI->image);
284378

285379
if (data.image == FOE_NULL_HANDLE)
286-
data.image = foeResourcePoolAdd(mResourcePool, pMaterialCI->image,
287-
FOE_GRAPHICS_RESOURCE_STRUCTURE_TYPE_IMAGE,
288-
sizeof(foeImage));
380+
data.image = foeResourcePoolAdd(mResourcePool, pMaterialCI->image);
289381
}
290382

291-
if (foeResourceGetType(data.image) != FOE_GRAPHICS_RESOURCE_STRUCTURE_TYPE_IMAGE) {
383+
if (foeResourceType type = foeResourceGetType(data.image);
384+
type != FOE_GRAPHICS_RESOURCE_STRUCTURE_TYPE_IMAGE &&
385+
type != FOE_RESOURCE_RESOURCE_TYPE_REPLACED &&
386+
type != FOE_RESOURCE_RESOURCE_TYPE_UNDEFINED &&
387+
!foeResourceHasType(data.image, FOE_GRAPHICS_RESOURCE_STRUCTURE_TYPE_IMAGE)) {
292388
result = to_foeResult(FOE_GRAPHICS_RESOURCE_ERROR_MATERIAL_SUBRESOURCE_INCOMPATIBLE);
293389
goto LOAD_FAILED;
294390
}

libs/foe_graphics_resource/src/material_loader.hpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
#define MATERIAL_LOADER_HPP
77

88
#include <foe/graphics/resource/material.hpp>
9+
#include <foe/graphics/resource/result.h>
910
#include <foe/graphics/session.h>
1011
#include <foe/graphics/type_defs.h>
1112
#include <foe/graphics/vk/fragment_descriptor_pool.h>

libs/foe_graphics_resource/src/mesh_loader.cpp

Lines changed: 20 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -134,8 +134,22 @@ void foeMeshLoader::gfxMaintenance() {
134134
new (pDst) foeMesh(std::move(*pSrcData));
135135
};
136136

137-
it.pPostLoadFn(it.resource, to_foeResult(FOE_GRAPHICS_RESOURCE_SUCCESS), &it.data,
138-
moveFn, this, foeMeshLoader::unloadResource);
137+
if (foeResourceGetType(it.resource) == FOE_RESOURCE_RESOURCE_TYPE_UNDEFINED) {
138+
foeResource newResource = foeResourcePoolLoadedReplace(
139+
mResourcePool, foeResourceGetID(it.resource),
140+
FOE_GRAPHICS_RESOURCE_STRUCTURE_TYPE_MESH, sizeof(foeMesh), &it.data,
141+
moveFn, this, foeMeshLoader::unloadResource);
142+
143+
if (newResource == FOE_NULL_HANDLE)
144+
// @TODO - Handle failure
145+
std::abort();
146+
147+
foeResourceDecrementRefCount(it.resource);
148+
foeResourceDecrementRefCount(newResource);
149+
} else {
150+
it.pPostLoadFn(it.resource, to_foeResult(FOE_GRAPHICS_RESOURCE_SUCCESS),
151+
&it.data, moveFn, this, foeMeshLoader::unloadResource);
152+
}
139153
} else {
140154
// No target resource, this is to be discarded
141155
if (it.data.gfxData != FOE_NULL_HANDLE)
@@ -196,10 +210,12 @@ void foeMeshLoader::load(foeResource resource,
196210
nullptr, nullptr, nullptr, nullptr);
197211
foeResourceCreateInfoDecrementRefCount(createInfo);
198212
return;
199-
} else if (foeResourceGetType(resource) != FOE_GRAPHICS_RESOURCE_STRUCTURE_TYPE_MESH) {
213+
} else if (foeResourceType type = foeResourceGetType(resource);
214+
type != FOE_GRAPHICS_RESOURCE_STRUCTURE_TYPE_MESH &&
215+
type != FOE_RESOURCE_RESOURCE_TYPE_UNDEFINED) {
200216
FOE_LOG(foeGraphicsResource, FOE_LOG_LEVEL_ERROR,
201217
"foeMeshLoader - Cannot load {} as it is an incompatible type: {}",
202-
foeIdToString(foeResourceGetID(resource)), foeResourceGetType(resource));
218+
foeIdToString(foeResourceGetID(resource)), type);
203219

204220
pPostLoadFn(resource, to_foeResult(FOE_GRAPHICS_RESOURCE_ERROR_INCOMPATIBLE_RESOURCE_TYPE),
205221
nullptr, nullptr, nullptr, nullptr);

libs/foe_graphics_resource/src/shader_loader.cpp

Lines changed: 24 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -102,12 +102,29 @@ void foeShaderLoader::gfxMaintenance() {
102102

103103
for (auto &it : toLoad) {
104104
auto moveFn = [](void *pSrc, void *pDst) {
105-
auto *pSrcData = (foeShader *)pSrc;
105+
foeShader *pSrcData = (foeShader *)pSrc;
106106
new (pDst) foeShader(std::move(*pSrcData));
107107
};
108108

109-
it.pPostLoadFn(it.resource, to_foeResult(FOE_GRAPHICS_RESOURCE_SUCCESS), &it.data, moveFn,
110-
this, foeShaderLoader::unloadResource);
109+
if (foeResourceGetType(it.resource) == FOE_RESOURCE_RESOURCE_TYPE_UNDEFINED) {
110+
// We need to replace this placeholder with the actual resource
111+
foeResource newResource = foeResourcePoolLoadedReplace(
112+
mResourcePool, foeResourceGetID(it.resource),
113+
FOE_GRAPHICS_RESOURCE_STRUCTURE_TYPE_SHADER, sizeof(foeShader), &it.data, moveFn,
114+
this, foeShaderLoader::unloadResource);
115+
116+
if (newResource == FOE_NULL_HANDLE)
117+
// @TODO - Handle failure
118+
std::abort();
119+
120+
// Decrement references we no longer need/use
121+
foeResourceDecrementRefCount(it.resource);
122+
foeResourceDecrementRefCount(newResource);
123+
} else {
124+
// The resource handle is of the desired type already, use the regular load function
125+
it.pPostLoadFn(it.resource, to_foeResult(FOE_GRAPHICS_RESOURCE_SUCCESS), &it.data,
126+
moveFn, this, foeShaderLoader::unloadResource);
127+
}
111128
}
112129
}
113130

@@ -137,10 +154,12 @@ void foeShaderLoader::load(foeResource resource,
137154
nullptr, nullptr, nullptr, nullptr);
138155
foeResourceCreateInfoDecrementRefCount(createInfo);
139156
return;
140-
} else if (foeResourceGetType(resource) != FOE_GRAPHICS_RESOURCE_STRUCTURE_TYPE_SHADER) {
157+
} else if (foeResourceType type = foeResourceGetType(resource);
158+
type != FOE_GRAPHICS_RESOURCE_STRUCTURE_TYPE_SHADER &&
159+
type != FOE_RESOURCE_RESOURCE_TYPE_UNDEFINED) {
141160
FOE_LOG(foeGraphicsResource, FOE_LOG_LEVEL_ERROR,
142161
"foeShaderLoader - Cannot load {} as it is an incompatible type: {}",
143-
foeIdToString(foeResourceGetID(resource)), foeResourceGetType(resource));
162+
foeIdToString(foeResourceGetID(resource)), type);
144163

145164
pPostLoadFn(resource, to_foeResult(FOE_GRAPHICS_RESOURCE_ERROR_INCOMPATIBLE_RESOURCE_TYPE),
146165
nullptr, nullptr, nullptr, nullptr);

0 commit comments

Comments
 (0)