BsVulkanGpuProgram.cpp 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668
  1. //********************************** Banshee Engine (www.banshee3d.com) **************************************************//
  2. //**************** Copyright (c) 2016 Marko Pintera ([email protected]). All rights reserved. **********************//
  3. #include "BsVulkanGpuProgram.h"
  4. #include "BsVulkanRenderAPI.h"
  5. #include "BsVulkanDevice.h"
  6. #include "BsVulkanUtility.h"
  7. #include "BsGpuParams.h"
  8. #include "BsGpuParamDesc.h"
  9. #include "BsGpuProgramManager.h"
  10. #include "BsVertexDeclaration.h"
  11. #include "BsHardwareBufferManager.h"
  12. #include "BsRenderStats.h"
  13. #include "BsFileSystem.h"
  14. #include "BsDataStream.h"
  15. #include "glslang/Public/ShaderLang.h"
  16. #include "glslang/Include/Types.h"
  17. #include "SPIRV/GlslangToSpv.h"
  18. #include "SPIRV/Logger.h"
  19. namespace bs
  20. {
  21. const TBuiltInResource DefaultTBuiltInResource = {
  22. /* .MaxLights = */ 32,
  23. /* .MaxClipPlanes = */ 6,
  24. /* .MaxTextureUnits = */ 32,
  25. /* .MaxTextureCoords = */ 32,
  26. /* .MaxVertexAttribs = */ 64,
  27. /* .MaxVertexUniformComponents = */ 4096,
  28. /* .MaxVaryingFloats = */ 64,
  29. /* .MaxVertexTextureImageUnits = */ 32,
  30. /* .MaxCombinedTextureImageUnits = */ 80,
  31. /* .MaxTextureImageUnits = */ 32,
  32. /* .MaxFragmentUniformComponents = */ 4096,
  33. /* .MaxDrawBuffers = */ 32,
  34. /* .MaxVertexUniformVectors = */ 128,
  35. /* .MaxVaryingVectors = */ 8,
  36. /* .MaxFragmentUniformVectors = */ 16,
  37. /* .MaxVertexOutputVectors = */ 16,
  38. /* .MaxFragmentInputVectors = */ 15,
  39. /* .MinProgramTexelOffset = */ -8,
  40. /* .MaxProgramTexelOffset = */ 7,
  41. /* .MaxClipDistances = */ 8,
  42. /* .MaxComputeWorkGroupCountX = */ 65535,
  43. /* .MaxComputeWorkGroupCountY = */ 65535,
  44. /* .MaxComputeWorkGroupCountZ = */ 65535,
  45. /* .MaxComputeWorkGroupSizeX = */ 1024,
  46. /* .MaxComputeWorkGroupSizeY = */ 1024,
  47. /* .MaxComputeWorkGroupSizeZ = */ 64,
  48. /* .MaxComputeUniformComponents = */ 1024,
  49. /* .MaxComputeTextureImageUnits = */ 16,
  50. /* .MaxComputeImageUniforms = */ 8,
  51. /* .MaxComputeAtomicCounters = */ 8,
  52. /* .MaxComputeAtomicCounterBuffers = */ 1,
  53. /* .MaxVaryingComponents = */ 60,
  54. /* .MaxVertexOutputComponents = */ 64,
  55. /* .MaxGeometryInputComponents = */ 64,
  56. /* .MaxGeometryOutputComponents = */ 128,
  57. /* .MaxFragmentInputComponents = */ 128,
  58. /* .MaxImageUnits = */ 8,
  59. /* .MaxCombinedImageUnitsAndFragmentOutputs = */ 8,
  60. /* .MaxCombinedShaderOutputResources = */ 8,
  61. /* .MaxImageSamples = */ 0,
  62. /* .MaxVertexImageUniforms = */ 0,
  63. /* .MaxTessControlImageUniforms = */ 0,
  64. /* .MaxTessEvaluationImageUniforms = */ 0,
  65. /* .MaxGeometryImageUniforms = */ 0,
  66. /* .MaxFragmentImageUniforms = */ 8,
  67. /* .MaxCombinedImageUniforms = */ 8,
  68. /* .MaxGeometryTextureImageUnits = */ 16,
  69. /* .MaxGeometryOutputVertices = */ 256,
  70. /* .MaxGeometryTotalOutputComponents = */ 1024,
  71. /* .MaxGeometryUniformComponents = */ 1024,
  72. /* .MaxGeometryVaryingComponents = */ 64,
  73. /* .MaxTessControlInputComponents = */ 128,
  74. /* .MaxTessControlOutputComponents = */ 128,
  75. /* .MaxTessControlTextureImageUnits = */ 16,
  76. /* .MaxTessControlUniformComponents = */ 1024,
  77. /* .MaxTessControlTotalOutputComponents = */ 4096,
  78. /* .MaxTessEvaluationInputComponents = */ 128,
  79. /* .MaxTessEvaluationOutputComponents = */ 128,
  80. /* .MaxTessEvaluationTextureImageUnits = */ 16,
  81. /* .MaxTessEvaluationUniformComponents = */ 1024,
  82. /* .MaxTessPatchComponents = */ 120,
  83. /* .MaxPatchVertices = */ 32,
  84. /* .MaxTessGenLevel = */ 64,
  85. /* .MaxViewports = */ 16,
  86. /* .MaxVertexAtomicCounters = */ 0,
  87. /* .MaxTessControlAtomicCounters = */ 0,
  88. /* .MaxTessEvaluationAtomicCounters = */ 0,
  89. /* .MaxGeometryAtomicCounters = */ 0,
  90. /* .MaxFragmentAtomicCounters = */ 8,
  91. /* .MaxCombinedAtomicCounters = */ 8,
  92. /* .MaxAtomicCounterBindings = */ 1,
  93. /* .MaxVertexAtomicCounterBuffers = */ 0,
  94. /* .MaxTessControlAtomicCounterBuffers = */ 0,
  95. /* .MaxTessEvaluationAtomicCounterBuffers = */ 0,
  96. /* .MaxGeometryAtomicCounterBuffers = */ 0,
  97. /* .MaxFragmentAtomicCounterBuffers = */ 1,
  98. /* .MaxCombinedAtomicCounterBuffers = */ 1,
  99. /* .MaxAtomicCounterBufferSize = */ 16384,
  100. /* .MaxTransformFeedbackBuffers = */ 4,
  101. /* .MaxTransformFeedbackInterleavedComponents = */ 64,
  102. /* .MaxCullDistances = */ 8,
  103. /* .MaxCombinedClipAndCullDistances = */ 8,
  104. /* .MaxSamples = */ 4,
  105. /* .limits = */{
  106. /* .nonInductiveForLoops = */ 1,
  107. /* .whileLoops = */ 1,
  108. /* .doWhileLoops = */ 1,
  109. /* .generalUniformIndexing = */ 1,
  110. /* .generalAttributeMatrixVectorIndexing = */ 1,
  111. /* .generalVaryingIndexing = */ 1,
  112. /* .generalSamplerIndexing = */ 1,
  113. /* .generalVariableIndexing = */ 1,
  114. /* .generalConstantMatrixVectorIndexing = */ 1,
  115. } };
  116. VertexElementType mapGLSLangToVertexElemType(const glslang::TType& type)
  117. {
  118. if (type.isVector())
  119. {
  120. UINT32 vectorSize = type.getVectorSize();
  121. switch (type.getBasicType())
  122. {
  123. case glslang::EbtFloat:
  124. switch(vectorSize)
  125. {
  126. case 2: return VET_FLOAT2;
  127. case 3: return VET_FLOAT3;
  128. case 4: return VET_FLOAT4;
  129. default: return VET_UNKNOWN;
  130. }
  131. case glslang::EbtInt:
  132. switch (vectorSize)
  133. {
  134. case 2: return VET_INT2;
  135. case 3: return VET_INT3;
  136. case 4: return VET_INT4;
  137. default: return VET_UNKNOWN;
  138. }
  139. case glslang::EbtUint:
  140. switch (vectorSize)
  141. {
  142. case 2: return VET_UINT2;
  143. case 3: return VET_UINT3;
  144. case 4: return VET_UINT4;
  145. default: return VET_UNKNOWN;
  146. }
  147. default:
  148. return VET_UNKNOWN;
  149. }
  150. }
  151. if (type.getVectorSize() == 1)
  152. {
  153. switch (type.getBasicType())
  154. {
  155. case glslang::EbtFloat: return VET_FLOAT1;
  156. case glslang::EbtInt: return VET_INT1;
  157. case glslang::EbtUint: return VET_UINT1;
  158. default: return VET_UNKNOWN;
  159. }
  160. }
  161. return VET_UNKNOWN;
  162. }
  163. GpuParamDataType mapGLSLangToGpuParamDataType(const glslang::TType& type)
  164. {
  165. if (type.getBasicType() == glslang::EbtStruct)
  166. return GPDT_STRUCT;
  167. if (type.isVector())
  168. {
  169. UINT32 vectorSize = type.getVectorSize();
  170. switch (type.getBasicType())
  171. {
  172. case glslang::EbtFloat:
  173. switch (vectorSize)
  174. {
  175. case 2: return GPDT_FLOAT2;
  176. case 3: return GPDT_FLOAT3;
  177. case 4: return GPDT_FLOAT4;
  178. default: return GPDT_UNKNOWN;
  179. }
  180. case glslang::EbtInt:
  181. switch (vectorSize)
  182. {
  183. case 2: return GPDT_INT2;
  184. case 3: return GPDT_INT3;
  185. case 4: return GPDT_INT4;
  186. default: return GPDT_UNKNOWN;
  187. }
  188. default:
  189. return GPDT_UNKNOWN;
  190. }
  191. }
  192. if (type.isMatrix())
  193. {
  194. switch (type.getBasicType())
  195. {
  196. case glslang::EbtFloat:
  197. switch (type.getMatrixCols())
  198. {
  199. case 2:
  200. switch (type.getMatrixRows())
  201. {
  202. case 2: return GPDT_MATRIX_2X2;
  203. case 3: return GPDT_MATRIX_3X2;
  204. case 4: return GPDT_MATRIX_4X2;
  205. default: return GPDT_UNKNOWN;
  206. }
  207. case 3:
  208. switch (type.getMatrixRows())
  209. {
  210. case 2: return GPDT_MATRIX_2X3;
  211. case 3: return GPDT_MATRIX_3X3;
  212. case 4: return GPDT_MATRIX_4X3;
  213. default: return GPDT_UNKNOWN;
  214. }
  215. case 4:
  216. switch (type.getMatrixRows())
  217. {
  218. case 2: return GPDT_MATRIX_2X4;
  219. case 3: return GPDT_MATRIX_3X4;
  220. case 4: return GPDT_MATRIX_4X4;
  221. default: return GPDT_UNKNOWN;
  222. }
  223. }
  224. default:
  225. return GPDT_UNKNOWN;
  226. }
  227. }
  228. if (type.getVectorSize() == 1)
  229. {
  230. switch (type.getBasicType())
  231. {
  232. case glslang::EbtFloat: return GPDT_FLOAT1;
  233. case glslang::EbtInt: return GPDT_INT1;
  234. case glslang::EbtBool: return GPDT_BOOL;
  235. default: return GPDT_UNKNOWN;
  236. }
  237. }
  238. return GPDT_UNKNOWN;
  239. }
  240. /** Holds a GLSL program input attribute used in vertex programs. */
  241. struct GLSLAttribute
  242. {
  243. /** Constructs a new attribute from a name and a semantic that represents in which way is the attribute used. */
  244. GLSLAttribute(const String& name, VertexElementSemantic semantic)
  245. :mName(name), mSemantic(semantic)
  246. { }
  247. /**
  248. * Return true if attribute name matches the specified name and returns optional semantic index if it exists. Start
  249. * of the two compared strings must match, and the remaining non-matching bit will be assumed to be the semantic
  250. * index. Returns -1 if no match is made.
  251. */
  252. INT32 matchesName(const String& name) const
  253. {
  254. if (!StringUtil::startsWith(name, mName, false))
  255. return -1;
  256. UINT32 length = (UINT32)mName.size();
  257. return parseINT32(name.substr(length));
  258. }
  259. /** Returns the semantic of this attribute. */
  260. VertexElementSemantic getSemantic() const { return mSemantic; }
  261. private:
  262. String mName;
  263. VertexElementSemantic mSemantic;
  264. };
  265. bool attribNameToElementSemantic(const String& name, VertexElementSemantic& semantic, UINT16& index)
  266. {
  267. static GLSLAttribute attributes[] =
  268. {
  269. GLSLAttribute("bs_position", VES_POSITION),
  270. GLSLAttribute("bs_normal", VES_NORMAL),
  271. GLSLAttribute("bs_tangent", VES_TANGENT),
  272. GLSLAttribute("bs_bitangent", VES_BITANGENT),
  273. GLSLAttribute("bs_texcoord", VES_TEXCOORD),
  274. GLSLAttribute("bs_color", VES_COLOR),
  275. GLSLAttribute("bs_blendweights", VES_BLEND_WEIGHTS),
  276. GLSLAttribute("bs_blendindices", VES_BLEND_INDICES)
  277. };
  278. static const UINT32 numAttribs = sizeof(attributes) / sizeof(attributes[0]);
  279. for (UINT32 i = 0; i < numAttribs; i++)
  280. {
  281. INT32 attribIndex = attributes[i].matchesName(name);
  282. if (attribIndex != -1)
  283. {
  284. index = attribIndex;
  285. semantic = attributes[i].getSemantic();
  286. return true;
  287. }
  288. }
  289. return false;
  290. }
  291. bool parseVertexAttributes(const glslang::TProgram* program, List<VertexElement>& elementList, String& log)
  292. {
  293. int numAttributes = program->getNumLiveAttributes();
  294. for (int i = 0; i < numAttributes; i++)
  295. {
  296. const glslang::TType* ttype = program->getAttributeTType(i);
  297. UINT32 location = ttype->getQualifier().layoutLocation;
  298. if (location == -1)
  299. {
  300. log = "Vertex attribute parsing error: Found a vertex attribute without a location "
  301. "qualifier. Each attribute must have an explicitly defined location number.";
  302. return false;
  303. }
  304. const char* attribName = program->getAttributeName(i);
  305. VertexElementSemantic semantic = VES_POSITION;
  306. UINT16 index = 0;
  307. if (attribNameToElementSemantic(attribName, semantic, index))
  308. {
  309. VertexElementType type = mapGLSLangToVertexElemType(*ttype);
  310. if (type == VET_UNKNOWN)
  311. LOGERR("Cannot determine vertex input attribute type for attribute: " + String(attribName));
  312. elementList.push_back(VertexElement(0, location, type, semantic, index));
  313. }
  314. else
  315. {
  316. // Ignore built-in attributes
  317. if (memcmp(attribName, "gl_", 3) != 0)
  318. LOGERR("Cannot determine vertex input attribute semantic for attribute: " + String(attribName));
  319. }
  320. }
  321. return true;
  322. }
  323. bool parseUniforms(const glslang::TProgram* program, GpuParamDesc& desc, String& log)
  324. {
  325. // Parse uniform blocks
  326. UnorderedMap<UINT32, String> uniformBlockMap;
  327. int numBlocks = program->getNumLiveUniformBlocks();
  328. for (int i = 0; i < numBlocks; i++)
  329. {
  330. const glslang::TType* ttype = program->getUniformBlockTType(i);
  331. if (!ttype->getQualifier().hasBinding())
  332. {
  333. log = "Uniform parsing error: Found a uniform block without a binding qualifier. Each uniform block must "
  334. " have an explicitly defined binding number.";
  335. return false;
  336. }
  337. const char* name = program->getUniformBlockName(i);
  338. int size = program->getUniformBlockSize(i);
  339. int index = program->getUniformBlockIndex(i);
  340. GpuParamBlockDesc param;
  341. param.name = name;
  342. param.blockSize = size / 4;
  343. param.isShareable = true;
  344. param.slot = ttype->getQualifier().layoutBinding;
  345. param.set = ttype->getQualifier().layoutSet;
  346. if (param.set == glslang::TQualifier::layoutSetEnd)
  347. param.set = 0;
  348. desc.paramBlocks[name] = param;
  349. uniformBlockMap[index] = name;
  350. }
  351. // Parse individual uniforms
  352. int numUniforms = program->getNumLiveUniformVariables();
  353. for (int i = 0; i < numUniforms; i++)
  354. {
  355. const glslang::TType* ttype = program->getUniformTType(i);
  356. const char* name = program->getUniformName(i);
  357. if (ttype->getBasicType() == glslang::EbtSampler) // Object type
  358. {
  359. // Note: Even though the type is named EbtSampler, all object types are categorized under it (including non
  360. // sampled images and buffers)
  361. if (!ttype->getQualifier().hasBinding())
  362. {
  363. log = "Uniform parsing error: Found an uniform without a binding qualifier. Each uniform must have an "
  364. "explicitly defined binding number.";
  365. return false;
  366. }
  367. const glslang::TSampler& sampler = ttype->getSampler();
  368. GpuParamObjectDesc param;
  369. param.name = name;
  370. param.slot = ttype->getQualifier().layoutBinding;
  371. param.set = ttype->getQualifier().layoutSet;
  372. if (param.set == glslang::TQualifier::layoutSetEnd)
  373. param.set = 0;
  374. if (sampler.isImage())
  375. {
  376. switch (sampler.dim)
  377. {
  378. case glslang::Esd1D: param.type = GPOT_RWTEXTURE1D; break;
  379. case glslang::Esd2D: param.type = sampler.isMultiSample() ? GPOT_RWTEXTURE2DMS : GPOT_RWTEXTURE2D; break;
  380. case glslang::Esd3D: param.type = GPOT_RWTEXTURE3D; break;
  381. case glslang::EsdBuffer: param.type = GPOT_RWSTRUCTURED_BUFFER; break;
  382. }
  383. if(sampler.dim != glslang::EsdBuffer)
  384. desc.loadStoreTextures[name] = param;
  385. else
  386. desc.buffers[name] = param;
  387. }
  388. else
  389. {
  390. switch (sampler.dim)
  391. {
  392. case glslang::Esd1D: param.type = GPOT_SAMPLER1D; break;
  393. case glslang::Esd2D: param.type = sampler.isMultiSample() ? GPOT_SAMPLER2DMS : GPOT_SAMPLER2D; break;
  394. case glslang::Esd3D: param.type = GPOT_SAMPLER3D; break;
  395. case glslang::EsdCube: param.type = GPOT_SAMPLERCUBE; break;
  396. }
  397. desc.samplers[name] = param;
  398. if (!sampler.isPureSampler())
  399. {
  400. switch (sampler.dim)
  401. {
  402. case glslang::Esd1D: param.type = GPOT_TEXTURE1D; break;
  403. case glslang::Esd2D: param.type = sampler.isMultiSample() ? GPOT_TEXTURE2DMS : GPOT_TEXTURE2D; break;
  404. case glslang::Esd3D: param.type = GPOT_TEXTURE3D; break;
  405. case glslang::EsdCube: param.type = GPOT_TEXTURECUBE; break;
  406. case glslang::EsdBuffer: param.type = GPOT_STRUCTURED_BUFFER; break;
  407. }
  408. if (sampler.dim != glslang::EsdBuffer)
  409. desc.textures[name] = param;
  410. else
  411. desc.buffers[name] = param;
  412. }
  413. }
  414. if(param.type == GPOT_UNKNOWN)
  415. LOGERR("Cannot determine type for uniform: " + String(name));
  416. }
  417. else
  418. {
  419. if(ttype->getBasicType() == glslang::EbtStruct)
  420. {
  421. // Not handling structs at the moment
  422. }
  423. else
  424. {
  425. GpuParamDataType paramType = mapGLSLangToGpuParamDataType(*ttype);
  426. if (paramType == GPDT_UNKNOWN)
  427. {
  428. LOGWRN("Cannot determine type for uniform: " + String(name));
  429. continue;
  430. }
  431. int blockIdx = program->getUniformBlockIndex(i);
  432. auto iterFind = uniformBlockMap.find(blockIdx);
  433. if (iterFind == uniformBlockMap.end())
  434. LOGERR("Uniform is referencing a uniform block that doesn't exist: " + String(name));
  435. const GpuParamBlockDesc& paramBlockDesc = desc.paramBlocks[iterFind->second];
  436. const GpuParamDataTypeInfo& typeInfo = GpuParams::PARAM_SIZES.lookup[paramType];
  437. int bufferOffset = program->getUniformBufferOffset(i) / 4;
  438. GpuParamDataDesc param;
  439. param.name = name;
  440. param.type = paramType;
  441. param.paramBlockSet = paramBlockDesc.set;
  442. param.paramBlockSlot = paramBlockDesc.slot;
  443. param.elementSize = typeInfo.size / 4;
  444. param.arrayElementStride = param.elementSize;
  445. param.arraySize = program->getUniformArraySize(i);
  446. param.cpuMemOffset = bufferOffset;
  447. param.gpuMemOffset = bufferOffset;
  448. desc.params[name] = param;
  449. }
  450. }
  451. }
  452. return true;
  453. }
  454. VulkanShaderModule::VulkanShaderModule(VulkanResourceManager* owner, VkShaderModule module)
  455. :VulkanResource(owner, true), mModule(module)
  456. { }
  457. VulkanShaderModule::~VulkanShaderModule()
  458. {
  459. vkDestroyShaderModule(mOwner->getDevice().getLogical(), mModule, gVulkanAllocator);
  460. }
  461. VulkanGpuProgramCore::VulkanGpuProgramCore(const GPU_PROGRAM_DESC& desc, GpuDeviceFlags deviceMask)
  462. : GpuProgramCore(desc, deviceMask), mDeviceMask(deviceMask), mModules()
  463. {
  464. }
  465. VulkanGpuProgramCore::~VulkanGpuProgramCore()
  466. {
  467. for (UINT32 i = 0; i < BS_MAX_DEVICES; i++)
  468. {
  469. if (mModules[i] != nullptr)
  470. mModules[i]->destroy();
  471. }
  472. BS_INC_RENDER_STAT_CAT(ResDestroyed, RenderStatObject_GpuProgram);
  473. }
  474. void VulkanGpuProgramCore::initialize()
  475. {
  476. if (!isSupported())
  477. {
  478. mIsCompiled = false;
  479. mCompileError = "Specified program is not supported by the current render system.";
  480. GpuProgramCore::initialize();
  481. return;
  482. }
  483. glslang::InitializeProcess();
  484. TBuiltInResource resources = DefaultTBuiltInResource;
  485. glslang::TProgram* program = new glslang::TProgram;
  486. EShLanguage glslType;
  487. switch(mProperties.getType())
  488. {
  489. case GPT_FRAGMENT_PROGRAM:
  490. glslType = EShLangFragment;
  491. break;
  492. case GPT_HULL_PROGRAM:
  493. glslType = EShLangTessControl;
  494. break;
  495. case GPT_DOMAIN_PROGRAM:
  496. glslType = EShLangTessEvaluation;
  497. break;
  498. case GPT_GEOMETRY_PROGRAM:
  499. glslType = EShLangGeometry;
  500. break;
  501. case GPT_VERTEX_PROGRAM:
  502. glslType = EShLangVertex;
  503. break;
  504. case GPT_COMPUTE_PROGRAM:
  505. glslType = EShLangCompute;
  506. break;
  507. }
  508. std::vector<UINT32> spirv;
  509. spv::SpvBuildLogger logger;
  510. std::string compileLog;
  511. const String& source = mProperties.getSource();
  512. const char* sourceBytes = source.c_str();
  513. glslang::TShader* shader = new glslang::TShader(glslType);
  514. shader->setStrings(&sourceBytes, 1);
  515. shader->setEntryPoint("main");
  516. if (!shader->parse(&resources, 450, false, EShMsgDefault))
  517. {
  518. mIsCompiled = false;
  519. mCompileError = "Compile error: " + String(shader->getInfoLog());
  520. goto cleanup;
  521. }
  522. program->addShader(shader);
  523. if (!program->link(EShMsgDefault))
  524. {
  525. mIsCompiled = false;
  526. mCompileError = "Link error: " + String(program->getInfoLog());
  527. goto cleanup;
  528. }
  529. program->mapIO();
  530. program->buildReflection();
  531. // Compile to SPIR-V
  532. GlslangToSpv(*program->getIntermediate(glslType), spirv, &logger);
  533. // Parse uniforms
  534. if(!parseUniforms(program, *mParametersDesc, mCompileError))
  535. {
  536. mIsCompiled = false;
  537. goto cleanup;
  538. }
  539. // If vertex program, retrieve information about vertex inputs
  540. if (mProperties.getType() == GPT_VERTEX_PROGRAM)
  541. {
  542. List<VertexElement> elementList;
  543. if (parseVertexAttributes(program, elementList, mCompileError))
  544. mInputDeclaration = HardwareBufferCoreManager::instance().createVertexDeclaration(elementList, mDeviceMask);
  545. else
  546. {
  547. mIsCompiled = false;
  548. goto cleanup;
  549. }
  550. }
  551. // Create Vulkan module
  552. VkShaderModuleCreateInfo moduleCI;
  553. moduleCI.sType = VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO;
  554. moduleCI.pNext = nullptr;
  555. moduleCI.flags = 0;
  556. moduleCI.codeSize = spirv.size() * sizeof(UINT32);
  557. moduleCI.pCode = spirv.data();
  558. VulkanRenderAPI& rapi = static_cast<VulkanRenderAPI&>(RenderAPICore::instance());
  559. VulkanDevice* devices[BS_MAX_DEVICES];
  560. VulkanUtility::getDevices(rapi, mDeviceMask, devices);
  561. for (UINT32 i = 0; i < BS_MAX_DEVICES; i++)
  562. {
  563. if (devices[i] != nullptr)
  564. {
  565. VkDevice vkDevice = devices[i]->getLogical();
  566. VulkanResourceManager& rescManager = devices[i]->getResourceManager();
  567. VkShaderModule shaderModule;
  568. VkResult result = vkCreateShaderModule(vkDevice, &moduleCI, gVulkanAllocator, &shaderModule);
  569. assert(result == VK_SUCCESS);
  570. mModules[i] = rescManager.create<VulkanShaderModule>(shaderModule);
  571. }
  572. }
  573. cleanup:
  574. delete program;
  575. delete shader;
  576. glslang::FinalizeProcess();
  577. BS_INC_RENDER_STAT_CAT(ResCreated, RenderStatObject_GpuProgram);
  578. GpuProgramCore::initialize();
  579. }
  580. }