Lugdunum  0.1.0
ShaderModule.cpp
Go to the documentation of this file.
2 
3 #include <fstream>
4 
5 #if defined(LUG_SYSTEM_ANDROID)
6  #include <android/asset_manager.h>
7 
9  #include <lug/Window/Window.hpp>
10 #endif
11 
14 
15 namespace lug {
16 namespace Graphics {
17 namespace Vulkan {
18 namespace API {
19 namespace Builder {
20 
21 ShaderModule::ShaderModule(const API::Device& device) : _device{device} {}
22 
23 bool ShaderModule::loadFromFile(const std::string& filename) {
24 #if defined(LUG_SYSTEM_ANDROID)
25  // Load shader from compressed asset
26  AAsset* asset = AAssetManager_open((lug::Window::priv::WindowImpl::activity)->assetManager, filename.c_str(), AASSET_MODE_STREAMING);
27 
28  if (!asset) {
29  LUG_LOG.error("Builder::ShaderModule: Can't open Android asset \"{}\"", filename);
30  return false;
31  }
32 
33  _codeSize = AAsset_getLength(asset);
34 
35  if (_codeSize <= 0) {
36  LUG_LOG.error("Builder::ShaderModule: Android asset \"{}\" is empty", filename);
37  return false;
38  }
39 
40  _data.resize(_codeSize % 4 ? (_codeSize + 4 - _codeSize % 4) : (_codeSize));
41 
42  AAsset_read(asset, reinterpret_cast<char*>(_data.data()), _codeSize);
43  AAsset_close(asset);
44 #else
45  std::ifstream shaderFile(filename, std::ios::binary);
46 
47  if (!shaderFile.good()) {
48  LUG_LOG.error("Builder::ShaderModule: Can't open file \"{}\"", filename);
49  return false;
50  }
51 
52  shaderFile.seekg(0, shaderFile.end);
53  _codeSize = shaderFile.tellg();
54  shaderFile.seekg(0, shaderFile.beg);
55 
56  _data.resize(_codeSize % 4 ? (_codeSize + 4 - _codeSize % 4) : (_codeSize));
57 
58  shaderFile.read(reinterpret_cast<char*>(_data.data()), _codeSize);
59  shaderFile.close();
60 #endif
61 
62  return true;
63 }
64 
65 void ShaderModule::loadFromData(const std::vector<uint32_t>& data) {
66  _codeSize = data.size() * sizeof(uint32_t);
67  _data = data;
68 }
69 
70 bool ShaderModule::build(API::ShaderModule& shaderModule, VkResult* returnResult) {
71  const VkShaderModuleCreateInfo createInfo{
72  /* createInfo.sType */ VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO,
73  /* createInfo.pNext */ nullptr,
74  /* createInfo.flags */ 0,
75  /* createInfo.codeSize */ _codeSize,
76  /* createInfo.pCode */ _data.data()
77  };
78 
79  VkShaderModule vkShaderModule = VK_NULL_HANDLE;
80  VkResult result = vkCreateShaderModule(static_cast<VkDevice>(_device), &createInfo, nullptr, &vkShaderModule);
81 
82  if (returnResult) {
83  *returnResult = result;
84  }
85 
86  if (result != VK_SUCCESS) {
87  return false;
88  }
89 
90  shaderModule = API::ShaderModule(vkShaderModule, &_device);
91 
92  return true;
93 }
94 
95 std::unique_ptr<API::ShaderModule> ShaderModule::build(VkResult* returnResult) {
96  std::unique_ptr<API::ShaderModule> shaderModule = std::make_unique<API::ShaderModule>();
97  return build(*shaderModule, returnResult) ? std::move(shaderModule) : nullptr;
98 }
99 
100 } // Builder
101 } // API
102 } // Vulkan
103 } // Graphics
104 } // lug
bool loadFromFile(const std::string &filename)
static ANativeActivity * activity
#define LUG_LOG
Definition: Logger.hpp:73
bool build(API::ShaderModule &instance, VkResult *returnResult=nullptr)
void loadFromData(const std::vector< uint32_t > &data)