1 /*
2 * Copyright (c) 2024 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16 #include "loader/shader_loader.h"
17
18 #include <cstring>
19 #include <set>
20
21 #include <base/containers/array_view.h>
22 #include <base/containers/vector.h>
23 #include <core/io/intf_file_manager.h>
24 #include <render/device/gpu_resource_desc.h>
25 #include <render/device/pipeline_layout_desc.h>
26 #include <render/namespace.h>
27
28 #include "device/shader_manager.h"
29 #include "loader/json_util.h"
30 #include "loader/pipeline_layout_loader.h"
31 #include "loader/shader_data_loader.h"
32 #include "loader/shader_state_loader.h"
33 #include "loader/vertex_input_declaration_loader.h"
34 #include "util/log.h"
35
36 using namespace BASE_NS;
37 using namespace CORE_NS;
38
39 RENDER_BEGIN_NAMESPACE()
40 namespace {
41 enum ShaderDataFileType : uint32_t {
42 UNDEFINED = 0,
43 SHADER = 1,
44 SHADER_STATE = 2,
45 VERTEX_INPUT_DECLARATION = 3,
46 PIPELINE_LAYOUT = 4,
47 };
48
49 constexpr string_view ShaderDataFileExtensions[] {
50 "",
51 ".shader",
52 ".shadergs",
53 ".shadervid",
54 ".shaderpl",
55 };
56
HasExtension(const char * ext,const string_view fileUri)57 bool HasExtension(const char* ext, const string_view fileUri)
58 {
59 if (auto const pos = fileUri.rfind(ext); pos != string_view::npos) {
60 return std::strlen(ext) == (fileUri.length() - pos);
61 }
62 return false;
63 }
64
GetShaderDataFileType(IFileManager & fileMgr,const string_view fullFilename)65 ShaderDataFileType GetShaderDataFileType(IFileManager& fileMgr, const string_view fullFilename)
66 {
67 if (HasExtension(ShaderDataFileExtensions[ShaderDataFileType::SHADER].data(), fullFilename)) {
68 return ShaderDataFileType::SHADER;
69 } else if (HasExtension(ShaderDataFileExtensions[ShaderDataFileType::SHADER_STATE].data(), fullFilename)) {
70 return ShaderDataFileType::SHADER_STATE;
71 } else if (HasExtension(ShaderDataFileExtensions[ShaderDataFileType::PIPELINE_LAYOUT].data(), fullFilename)) {
72 return ShaderDataFileType::PIPELINE_LAYOUT;
73 } else if (HasExtension(
74 ShaderDataFileExtensions[ShaderDataFileType::VERTEX_INPUT_DECLARATION].data(), fullFilename)) {
75 return ShaderDataFileType::VERTEX_INPUT_DECLARATION;
76 }
77 return ShaderDataFileType::UNDEFINED;
78 }
79
ReadFile(IFile & file)80 vector<uint8_t> ReadFile(IFile& file)
81 {
82 auto fileData = vector<uint8_t>(static_cast<std::size_t>(file.GetLength()));
83 file.Read(fileData.data(), fileData.size());
84 return fileData;
85 }
86 } // namespace
87
ShaderLoader(IFileManager & fileManager,ShaderManager & shaderManager,const DeviceBackendType type)88 ShaderLoader::ShaderLoader(IFileManager& fileManager, ShaderManager& shaderManager, const DeviceBackendType type)
89 : fileManager_(fileManager), shaderMgr_(shaderManager), type_(type)
90 {}
91
Load(const ShaderManager::ShaderFilePathDesc & desc)92 void ShaderLoader::Load(const ShaderManager::ShaderFilePathDesc& desc)
93 {
94 if (!desc.shaderStatePath.empty()) {
95 auto const shaderStatesPath = fileManager_.OpenDirectory(desc.shaderStatePath);
96 if (shaderStatesPath) {
97 LoadShaderStates(desc.shaderStatePath, *shaderStatesPath);
98 } else {
99 PLUGIN_LOG_W("graphics state path (%s) not found.", desc.shaderStatePath.data());
100 }
101 }
102 if (!desc.vertexInputDeclarationPath.empty()) {
103 auto const vidsPath = fileManager_.OpenDirectory(desc.vertexInputDeclarationPath);
104 if (vidsPath) {
105 LoadVids(desc.vertexInputDeclarationPath, *vidsPath);
106 } else {
107 PLUGIN_LOG_W("vertex input declaration path (%s) not found.", desc.vertexInputDeclarationPath.data());
108 }
109 }
110 if (!desc.pipelineLayoutPath.empty()) {
111 auto const pipelineLayoutsPath = fileManager_.OpenDirectory(desc.pipelineLayoutPath);
112 if (pipelineLayoutsPath) {
113 LoadPipelineLayouts(desc.pipelineLayoutPath, *pipelineLayoutsPath);
114 } else {
115 PLUGIN_LOG_W("pipeline layout path (%s) not found.", desc.pipelineLayoutPath.data());
116 }
117 }
118 if (!desc.shaderPath.empty()) {
119 auto const shadersPath = fileManager_.OpenDirectory(desc.shaderPath);
120 if (shadersPath) {
121 RecurseDirectory(desc.shaderPath, *shadersPath);
122 } else {
123 PLUGIN_LOG_W("shader path (%s) not found.", desc.shaderPath.data());
124 }
125 }
126 }
127
LoadFile(const string_view uri,const bool forceReload)128 void ShaderLoader::LoadFile(const string_view uri, const bool forceReload)
129 {
130 const IDirectory::Entry entry = fileManager_.GetEntry(uri);
131 if (entry.type == IDirectory::Entry::FILE) {
132 // NOTE: currently there's no info within the shader json files
133 // we do type evaluation based on some key names in the json
134 const ShaderDataFileType shaderDataFileType = GetShaderDataFileType(fileManager_, uri);
135 switch (shaderDataFileType) {
136 case ShaderDataFileType::SHADER: {
137 // Force re-loads the shader module creation
138 HandleShaderFile(uri, entry, forceReload);
139 break;
140 }
141 case ShaderDataFileType::SHADER_STATE: {
142 HandleShaderStateFile(uri, entry);
143 break;
144 }
145 case ShaderDataFileType::PIPELINE_LAYOUT: {
146 HandlePipelineLayoutFile(uri, entry);
147 break;
148 }
149 case ShaderDataFileType::VERTEX_INPUT_DECLARATION: {
150 HandleVertexInputDeclarationFile(uri, entry);
151 break;
152 }
153 default: {
154 break;
155 }
156 }
157 }
158 }
159
HandleShaderFile(const string_view fullFileName,const IDirectory::Entry & entry,const bool forceReload)160 void ShaderLoader::HandleShaderFile(
161 const string_view fullFileName, const IDirectory::Entry& entry, const bool forceReload)
162 {
163 if (HasExtension(ShaderDataFileExtensions[ShaderDataFileType::SHADER].data(), entry.name)) {
164 ShaderDataLoader loader;
165 const auto result = loader.Load(fileManager_, fullFileName);
166 if (result.success) {
167 auto const handle = CreateShader(loader, forceReload);
168 #if (RENDER_DEV_ENABLED == 1)
169 const auto shaderVariants = loader.GetShaderVariants();
170 for (const auto& shaderVariant : shaderVariants) {
171 // Dev related book-keeping for reloading of spv files
172 auto const handleType = handle.GetHandleType();
173 if (handleType == RenderHandleType::COMPUTE_SHADER_STATE_OBJECT) {
174 string compShader = shaderVariant.computeShader;
175 PLUGIN_ASSERT(!compShader.empty());
176
177 auto& ref = fileToShaderNames_[move(compShader)];
178 ref.shaderStageFlags = ShaderStageFlagBits::CORE_SHADER_STAGE_COMPUTE_BIT;
179 ref.shaderNames.emplace_back(fullFileName);
180 } else if (handleType == RenderHandleType::SHADER_STATE_OBJECT) {
181 string vertShader = shaderVariant.vertexShader;
182 string fragShader = shaderVariant.fragmentShader;
183 PLUGIN_ASSERT_MSG(
184 (!vertShader.empty()) && (!fragShader.empty()), "shader name: %s", fullFileName.data());
185
186 auto& refVert = fileToShaderNames_[move(vertShader)];
187 refVert.shaderStageFlags = ShaderStageFlagBits::CORE_SHADER_STAGE_VERTEX_BIT;
188 refVert.shaderNames.emplace_back(fullFileName);
189 auto& refFrag = fileToShaderNames_[move(fragShader)];
190 refFrag.shaderStageFlags = ShaderStageFlagBits::CORE_SHADER_STAGE_FRAGMENT_BIT;
191 refFrag.shaderNames.emplace_back(fullFileName);
192 }
193 }
194 #endif
195 } else {
196 PLUGIN_LOG_E("unable to load shader json %s : %s", fullFileName.data(), result.error.c_str());
197 }
198 }
199 }
200
HandleShaderStateFile(const string_view fullFileName,const IDirectory::Entry & entry)201 void ShaderLoader::HandleShaderStateFile(const string_view fullFileName, const IDirectory::Entry& entry)
202 {
203 if (HasExtension(ShaderDataFileExtensions[ShaderDataFileType::SHADER_STATE].data(), entry.name)) {
204 ShaderStateLoader loader;
205 const auto result = loader.Load(fileManager_, fullFileName);
206 if (result.success) {
207 CreateShaderStates(loader.GetUri(), loader.GetGraphicsStateVariantData(), loader.GetGraphicsStates());
208 } else {
209 PLUGIN_LOG_E("unable to load shader state json %s : %s", fullFileName.data(), result.error.c_str());
210 }
211 }
212 }
213
HandlePipelineLayoutFile(const string_view fullFileName,const IDirectory::Entry & entry)214 void ShaderLoader::HandlePipelineLayoutFile(const string_view fullFileName, const IDirectory::Entry& entry)
215 {
216 if (HasExtension(ShaderDataFileExtensions[ShaderDataFileType::PIPELINE_LAYOUT].data(), entry.name)) {
217 PipelineLayoutLoader loader;
218 const auto result = loader.Load(fileManager_, fullFileName);
219 if (result.success) {
220 auto const handle = CreatePipelineLayout(loader);
221 if (!handle) {
222 PLUGIN_LOG_E(
223 "pipeline layout could not be created (%s) (%s)", fullFileName.data(), loader.GetUri().data());
224 }
225 } else {
226 PLUGIN_LOG_E("unable to load pipeline layout json %s : %s", fullFileName.data(), result.error.c_str());
227 }
228 }
229 }
230
HandleVertexInputDeclarationFile(const string_view fullFileName,const IDirectory::Entry & entry)231 void ShaderLoader::HandleVertexInputDeclarationFile(const string_view fullFileName, const IDirectory::Entry& entry)
232 {
233 if (HasExtension(ShaderDataFileExtensions[ShaderDataFileType::VERTEX_INPUT_DECLARATION].data(), entry.name)) {
234 VertexInputDeclarationLoader loader;
235 const auto result = loader.Load(fileManager_, fullFileName);
236 if (result.success) {
237 auto const vidName = loader.GetUri();
238 auto const handle = CreateVertexInputDeclaration(loader);
239 if (!handle) {
240 PLUGIN_LOG_E(
241 "vertex input declaration could not be created (%s) (%s)", fullFileName.data(), vidName.data());
242 }
243 } else {
244 PLUGIN_LOG_E(
245 "unable to load vertex input declaration json %s : %s", fullFileName.data(), result.error.c_str());
246 }
247 }
248 }
249
RecurseDirectory(const string_view currentPath,const IDirectory & directory)250 void ShaderLoader::RecurseDirectory(const string_view currentPath, const IDirectory& directory)
251 {
252 for (auto const& entry : directory.GetEntries()) {
253 switch (entry.type) {
254 default:
255 case IDirectory::Entry::Type::UNKNOWN:
256 break;
257 case IDirectory::Entry::Type::FILE: {
258 // does not force the shader module re-creations
259 HandleShaderFile(currentPath + entry.name, entry, false);
260 break;
261 }
262 case IDirectory::Entry::Type::DIRECTORY: {
263 if (entry.name == "." || entry.name == "..") {
264 continue;
265 }
266 auto nextDirectory = currentPath + entry.name + '/';
267 auto dir = fileManager_.OpenDirectory(nextDirectory);
268 if (dir) {
269 RecurseDirectory(nextDirectory, *dir);
270 }
271 break;
272 }
273 }
274 }
275 }
276
LoadShaderFile(const string_view shader,const ShaderStageFlags stageBits)277 ShaderLoader::ShaderFile ShaderLoader::LoadShaderFile(const string_view shader, const ShaderStageFlags stageBits)
278 {
279 ShaderLoader::ShaderFile info;
280 IFile::Ptr shaderFile;
281 switch (type_) {
282 case DeviceBackendType::VULKAN:
283 shaderFile = fileManager_.OpenFile(shader);
284 break;
285 case DeviceBackendType::OPENGLES:
286 shaderFile = fileManager_.OpenFile(shader + ".gles");
287 break;
288 case DeviceBackendType::OPENGL:
289 shaderFile = fileManager_.OpenFile(shader + ".gl");
290 break;
291 default:
292 break;
293 }
294 if (shaderFile) {
295 info.data = ReadFile(*shaderFile);
296
297 if (IFile::Ptr reflectionFile = fileManager_.OpenFile(shader + ".lsb"); reflectionFile) {
298 info.reflectionData = ReadFile(*reflectionFile);
299 }
300 info.info = { stageBits, info.data, { info.reflectionData } };
301 } else {
302 PLUGIN_LOG_E("shader file not found (%s)", shader.data());
303 }
304 return info;
305 }
306
CreateComputeShader(const ShaderDataLoader & dataLoader,const bool forceReload)307 RenderHandleReference ShaderLoader::CreateComputeShader(const ShaderDataLoader& dataLoader, const bool forceReload)
308 {
309 RenderHandleReference firstShaderVariantRhr;
310 const array_view<const ShaderDataLoader::ShaderVariant> shaderVariants = dataLoader.GetShaderVariants();
311 for (const auto& shaderVariant : shaderVariants) {
312 const string_view computeShader = shaderVariant.computeShader;
313 uint32_t index = INVALID_SM_INDEX;
314 if (!forceReload) {
315 index = shaderMgr_.GetShaderModuleIndex(computeShader);
316 }
317 if (index == INVALID_SM_INDEX) {
318 const auto shaderFile = LoadShaderFile(computeShader, ShaderStageFlagBits::CORE_SHADER_STAGE_COMPUTE_BIT);
319 if (!shaderFile.data.empty()) {
320 index = shaderMgr_.CreateShaderModule(computeShader, shaderFile.info);
321 } else {
322 PLUGIN_LOG_E("shader file not found (%s)", computeShader.data());
323 }
324 }
325 if (index != INVALID_SM_INDEX) {
326 const string_view uri = dataLoader.GetUri();
327 const string_view baseShaderPath = dataLoader.GetBaseShader();
328 const string_view baseCategory = dataLoader.GetBaseCategory();
329 const string_view variantName = shaderVariant.variantName;
330 const string_view displayName = shaderVariant.displayName;
331 const string_view pipelineLayout = shaderVariant.pipelineLayout;
332 const string_view renderSlot = shaderVariant.renderSlot;
333 const string_view shaderFileStr = shaderVariant.shaderFileStr;
334 const string_view matMetadataStr = shaderVariant.materialMetadata;
335 const uint32_t rsId = shaderMgr_.CreateRenderSlotId(renderSlot);
336 const uint32_t catId = shaderMgr_.CreateCategoryId(baseCategory);
337 const uint32_t plIndex =
338 (pipelineLayout.empty())
339 ? INVALID_SM_INDEX
340 : RenderHandleUtil::GetIndexPart(shaderMgr_.GetPipelineLayoutHandle(pipelineLayout).GetHandle());
341 // if many variants, the first is shader created without variant name
342 // it will have additional name for searching though
343 RenderHandleReference rhr;
344 if (!firstShaderVariantRhr) {
345 // NOTE: empty variant name
346 rhr = shaderMgr_.Create(
347 ComputeShaderCreateData { uri, rsId, catId, plIndex, index, shaderFileStr, matMetadataStr },
348 { baseShaderPath, {}, displayName });
349 firstShaderVariantRhr = rhr;
350 // add additional fullname with variant for the base shader
351 if (!variantName.empty()) {
352 shaderMgr_.AddAdditionalNameForHandle(rhr, uri);
353 }
354 } else {
355 rhr = shaderMgr_.Create(
356 ComputeShaderCreateData { uri, rsId, catId, plIndex, index, shaderFileStr, matMetadataStr },
357 { baseShaderPath, variantName, displayName });
358 }
359 if (shaderVariant.renderSlotDefaultShader) {
360 shaderMgr_.SetRenderSlotData(rsId, rhr, {});
361 }
362 } else {
363 PLUGIN_LOG_E("Failed to load shader : %s", computeShader.data());
364 }
365 }
366 return firstShaderVariantRhr;
367 }
368
CreateGraphicsShader(const ShaderDataLoader & dataLoader,const bool forceReload)369 RenderHandleReference ShaderLoader::CreateGraphicsShader(const ShaderDataLoader& dataLoader, const bool forceReload)
370 {
371 RenderHandleReference firstShaderVariantRhr;
372 const array_view<const ShaderDataLoader::ShaderVariant> shaderVariants = dataLoader.GetShaderVariants();
373 for (const auto& svRef : shaderVariants) {
374 const string_view vertexShader = svRef.vertexShader;
375 const string_view fragmentShader = svRef.fragmentShader;
376 uint32_t vertIndex = (forceReload) ? INVALID_SM_INDEX : shaderMgr_.GetShaderModuleIndex(vertexShader);
377 if (vertIndex == INVALID_SM_INDEX) {
378 const auto shaderFile = LoadShaderFile(vertexShader, ShaderStageFlagBits::CORE_SHADER_STAGE_VERTEX_BIT);
379 if (!shaderFile.data.empty()) {
380 vertIndex = shaderMgr_.CreateShaderModule(vertexShader, shaderFile.info);
381 }
382 }
383 uint32_t fragIndex = (forceReload) ? INVALID_SM_INDEX : shaderMgr_.GetShaderModuleIndex(fragmentShader);
384 if (fragIndex == INVALID_SM_INDEX) {
385 const auto shaderFile = LoadShaderFile(fragmentShader, ShaderStageFlagBits::CORE_SHADER_STAGE_FRAGMENT_BIT);
386 if (!shaderFile.data.empty()) {
387 fragIndex = shaderMgr_.CreateShaderModule(fragmentShader, shaderFile.info);
388 }
389 }
390 if ((vertIndex != INVALID_SM_INDEX) && (fragIndex != INVALID_SM_INDEX)) {
391 const string_view uri = dataLoader.GetUri();
392 // creating the default graphics state with full name
393 const string fullName = uri + svRef.variantName;
394 // default graphics state is created beforehand
395 const RenderHandleReference defaultGfxState = shaderMgr_.CreateGraphicsState(
396 { fullName, svRef.graphicsState }, { svRef.renderSlot, {}, {}, {}, svRef.stateFlags });
397 const uint32_t rsId = shaderMgr_.CreateRenderSlotId(svRef.renderSlot);
398 const uint32_t catId = shaderMgr_.CreateCategoryId(dataLoader.GetBaseCategory());
399 const uint32_t plIndex = svRef.pipelineLayout.empty()
400 ? INVALID_SM_INDEX
401 : RenderHandleUtil::GetIndexPart(
402 shaderMgr_.GetPipelineLayoutHandle(svRef.pipelineLayout).GetHandle());
403 const uint32_t vidIndex =
404 svRef.vertexInputDeclaration.empty()
405 ? INVALID_SM_INDEX
406 : RenderHandleUtil::GetIndexPart(
407 shaderMgr_.GetVertexInputDeclarationHandle(svRef.vertexInputDeclaration).GetHandle());
408 const uint32_t stateIndex = RenderHandleUtil::GetIndexPart(defaultGfxState.GetHandle());
409 const string_view shaderStr = svRef.shaderFileStr;
410 const string_view matMeta = svRef.materialMetadata;
411 // if many variants, the first is shader created without variant name
412 // it will have additional name for searching though
413 RenderHandleReference rhr;
414 if (!firstShaderVariantRhr) {
415 // NOTE: empty variant name
416 rhr = shaderMgr_.Create(
417 { uri, rsId, catId, vidIndex, plIndex, stateIndex, vertIndex, fragIndex, shaderStr, matMeta },
418 { dataLoader.GetBaseShader(), {}, svRef.displayName });
419 firstShaderVariantRhr = rhr;
420 // add additional fullname with variant for the base shader
421 if (!svRef.variantName.empty()) {
422 shaderMgr_.AddAdditionalNameForHandle(firstShaderVariantRhr, fullName);
423 }
424 } else {
425 rhr = shaderMgr_.Create(
426 { uri, rsId, catId, vidIndex, plIndex, stateIndex, vertIndex, fragIndex, shaderStr, matMeta },
427 { dataLoader.GetBaseShader(), svRef.variantName, svRef.displayName });
428 }
429 if (svRef.renderSlotDefaultShader) {
430 shaderMgr_.SetRenderSlotData(rsId, rhr, {});
431 }
432 } else {
433 PLUGIN_LOG_E("Failed to load shader : %s %s", vertexShader.data(), fragmentShader.data());
434 }
435 }
436 return firstShaderVariantRhr;
437 }
438
CreateShader(const ShaderDataLoader & dataLoader,const bool forceReload)439 RenderHandleReference ShaderLoader::CreateShader(const ShaderDataLoader& dataLoader, const bool forceReload)
440 {
441 const array_view<const ShaderDataLoader::ShaderVariant> shaderVariants = dataLoader.GetShaderVariants();
442 if (shaderVariants.empty()) {
443 return {};
444 }
445
446 const string_view compShader = shaderVariants[0].computeShader;
447 if (!compShader.empty()) {
448 return CreateComputeShader(dataLoader, forceReload);
449 } else {
450 const string_view vertShader = shaderVariants[0].vertexShader;
451 const string_view fragShader = shaderVariants[0].fragmentShader;
452 if (!vertShader.empty() && !fragShader.empty()) {
453 return CreateGraphicsShader(dataLoader, forceReload);
454 }
455 }
456 return {};
457 }
458
LoadShaderStates(const string_view currentPath,const IDirectory & directory)459 void ShaderLoader::LoadShaderStates(const string_view currentPath, const IDirectory& directory)
460 {
461 for (auto const& entry : directory.GetEntries()) {
462 switch (entry.type) {
463 default:
464 case IDirectory::Entry::Type::UNKNOWN:
465 break;
466 case IDirectory::Entry::Type::FILE: {
467 HandleShaderStateFile(currentPath + entry.name, entry);
468 break;
469 }
470 case IDirectory::Entry::Type::DIRECTORY: {
471 PLUGIN_LOG_I("recursive vertex input declarations directories not supported");
472 break;
473 }
474 }
475 }
476 }
477
CreateShaderStates(const string_view uri,const array_view<const ShaderStateLoaderVariantData> & variantData,const array_view<const GraphicsState> & states)478 void ShaderLoader::CreateShaderStates(const string_view uri,
479 const array_view<const ShaderStateLoaderVariantData>& variantData, const array_view<const GraphicsState>& states)
480 {
481 for (size_t stateIdx = 0; stateIdx < states.size(); ++stateIdx) {
482 const ShaderManager::GraphicsStateCreateInfo createInfo { uri, states[stateIdx] };
483 const auto& variant = variantData[stateIdx];
484 const ShaderManager::GraphicsStateVariantCreateInfo variantCreateInfo { variant.renderSlot, variant.variantName,
485 variant.baseShaderState, variant.baseVariantName, variant.stateFlags };
486 const RenderHandleReference handle = shaderMgr_.CreateGraphicsState(createInfo, variantCreateInfo);
487 if (variant.renderSlotDefaultState && (!variant.renderSlot.empty())) {
488 const uint32_t renderSlotId = shaderMgr_.GetRenderSlotId(variant.renderSlot);
489 shaderMgr_.SetRenderSlotData(renderSlotId, {}, handle);
490 }
491 if (!handle) {
492 PLUGIN_LOG_E(
493 "error creating graphics state (name: %s, variant: %s)", uri.data(), variant.variantName.data());
494 }
495 }
496 }
497
LoadVids(const string_view currentPath,const IDirectory & directory)498 void ShaderLoader::LoadVids(const string_view currentPath, const IDirectory& directory)
499 {
500 for (auto const& entry : directory.GetEntries()) {
501 switch (entry.type) {
502 default:
503 case IDirectory::Entry::Type::UNKNOWN:
504 break;
505 case IDirectory::Entry::Type::FILE: {
506 HandleVertexInputDeclarationFile(currentPath + entry.name, entry);
507 break;
508 }
509 case IDirectory::Entry::Type::DIRECTORY: {
510 PLUGIN_LOG_I("recursive vertex input declarations directories not supported");
511 break;
512 }
513 }
514 }
515 }
516
CreateVertexInputDeclaration(const VertexInputDeclarationLoader & loader)517 RenderHandleReference ShaderLoader::CreateVertexInputDeclaration(const VertexInputDeclarationLoader& loader)
518 {
519 const string_view uri = loader.GetUri();
520 VertexInputDeclarationView dataView = loader.GetVertexInputDeclarationView();
521 return shaderMgr_.CreateVertexInputDeclaration({ uri, dataView });
522 }
523
LoadPipelineLayouts(const string_view currentPath,const IDirectory & directory)524 void ShaderLoader::LoadPipelineLayouts(const string_view currentPath, const IDirectory& directory)
525 {
526 for (auto const& entry : directory.GetEntries()) {
527 switch (entry.type) {
528 default:
529 case IDirectory::Entry::Type::UNKNOWN:
530 break;
531 case IDirectory::Entry::Type::FILE: {
532 HandlePipelineLayoutFile(currentPath + entry.name, entry);
533 break;
534 }
535 case IDirectory::Entry::Type::DIRECTORY: {
536 PLUGIN_LOG_I("recursive pipeline layout directories not supported");
537 break;
538 }
539 }
540 }
541 }
542
CreatePipelineLayout(const PipelineLayoutLoader & loader)543 RenderHandleReference ShaderLoader::CreatePipelineLayout(const PipelineLayoutLoader& loader)
544 {
545 const string_view uri = loader.GetUri();
546 const PipelineLayout& pipelineLayout = loader.GetPipelineLayout();
547 return shaderMgr_.CreatePipelineLayout({ uri, pipelineLayout });
548 }
549 RENDER_END_NAMESPACE()
550