Shader.cpp 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517
  1. #include "Shader.h"
  2. #include "Graphics.h"
  3. #include "libraries/glslang/glslang/Public/ShaderLang.h"
  4. #include "libraries/glslang/SPIRV/GlslangToSpv.h"
  5. #include "libraries/spirv_cross/spirv_cross.hpp"
  6. #include <vector>
  7. namespace love {
  8. namespace graphics {
  9. namespace vulkan {
  10. static const TBuiltInResource defaultTBuiltInResource = {
  11. /* .MaxLights = */ 32,
  12. /* .MaxClipPlanes = */ 6,
  13. /* .MaxTextureUnits = */ 32,
  14. /* .MaxTextureCoords = */ 32,
  15. /* .MaxVertexAttribs = */ 64,
  16. /* .MaxVertexUniformComponents = */ 16384,
  17. /* .MaxVaryingFloats = */ 128,
  18. /* .MaxVertexTextureImageUnits = */ 32,
  19. /* .MaxCombinedTextureImageUnits = */ 80,
  20. /* .MaxTextureImageUnits = */ 32,
  21. /* .MaxFragmentUniformComponents = */ 16384,
  22. /* .MaxDrawBuffers = */ 8,
  23. /* .MaxVertexUniformVectors = */ 4096,
  24. /* .MaxVaryingVectors = */ 32,
  25. /* .MaxFragmentUniformVectors = */ 4096,
  26. /* .MaxVertexOutputVectors = */ 32,
  27. /* .MaxFragmentInputVectors = */ 31,
  28. /* .MinProgramTexelOffset = */ -8,
  29. /* .MaxProgramTexelOffset = */ 7,
  30. /* .MaxClipDistances = */ 8,
  31. /* .MaxComputeWorkGroupCountX = */ 65535,
  32. /* .MaxComputeWorkGroupCountY = */ 65535,
  33. /* .MaxComputeWorkGroupCountZ = */ 65535,
  34. /* .MaxComputeWorkGroupSizeX = */ 1024,
  35. /* .MaxComputeWorkGroupSizeY = */ 1024,
  36. /* .MaxComputeWorkGroupSizeZ = */ 64,
  37. /* .MaxComputeUniformComponents = */ 1024,
  38. /* .MaxComputeTextureImageUnits = */ 32,
  39. /* .MaxComputeImageUniforms = */ 16,
  40. /* .MaxComputeAtomicCounters = */ 4096,
  41. /* .MaxComputeAtomicCounterBuffers = */ 8,
  42. /* .MaxVaryingComponents = */ 128,
  43. /* .MaxVertexOutputComponents = */ 128,
  44. /* .MaxGeometryInputComponents = */ 128,
  45. /* .MaxGeometryOutputComponents = */ 128,
  46. /* .MaxFragmentInputComponents = */ 128,
  47. /* .MaxImageUnits = */ 192,
  48. /* .MaxCombinedImageUnitsAndFragmentOutputs = */ 144,
  49. /* .MaxCombinedShaderOutputResources = */ 144,
  50. /* .MaxImageSamples = */ 32,
  51. /* .MaxVertexImageUniforms = */ 16,
  52. /* .MaxTessControlImageUniforms = */ 16,
  53. /* .MaxTessEvaluationImageUniforms = */ 16,
  54. /* .MaxGeometryImageUniforms = */ 16,
  55. /* .MaxFragmentImageUniforms = */ 16,
  56. /* .MaxCombinedImageUniforms = */ 80,
  57. /* .MaxGeometryTextureImageUnits = */ 16,
  58. /* .MaxGeometryOutputVertices = */ 256,
  59. /* .MaxGeometryTotalOutputComponents = */ 1024,
  60. /* .MaxGeometryUniformComponents = */ 1024,
  61. /* .MaxGeometryVaryingComponents = */ 64,
  62. /* .MaxTessControlInputComponents = */ 128,
  63. /* .MaxTessControlOutputComponents = */ 128,
  64. /* .MaxTessControlTextureImageUnits = */ 16,
  65. /* .MaxTessControlUniformComponents = */ 1024,
  66. /* .MaxTessControlTotalOutputComponents = */ 4096,
  67. /* .MaxTessEvaluationInputComponents = */ 128,
  68. /* .MaxTessEvaluationOutputComponents = */ 128,
  69. /* .MaxTessEvaluationTextureImageUnits = */ 16,
  70. /* .MaxTessEvaluationUniformComponents = */ 1024,
  71. /* .MaxTessPatchComponents = */ 120,
  72. /* .MaxPatchVertices = */ 32,
  73. /* .MaxTessGenLevel = */ 64,
  74. /* .MaxViewports = */ 16,
  75. /* .MaxVertexAtomicCounters = */ 4096,
  76. /* .MaxTessControlAtomicCounters = */ 4096,
  77. /* .MaxTessEvaluationAtomicCounters = */ 4096,
  78. /* .MaxGeometryAtomicCounters = */ 4096,
  79. /* .MaxFragmentAtomicCounters = */ 4096,
  80. /* .MaxCombinedAtomicCounters = */ 4096,
  81. /* .MaxAtomicCounterBindings = */ 8,
  82. /* .MaxVertexAtomicCounterBuffers = */ 8,
  83. /* .MaxTessControlAtomicCounterBuffers = */ 8,
  84. /* .MaxTessEvaluationAtomicCounterBuffers = */ 8,
  85. /* .MaxGeometryAtomicCounterBuffers = */ 8,
  86. /* .MaxFragmentAtomicCounterBuffers = */ 8,
  87. /* .MaxCombinedAtomicCounterBuffers = */ 8,
  88. /* .MaxAtomicCounterBufferSize = */ 16384,
  89. /* .MaxTransformFeedbackBuffers = */ 4,
  90. /* .MaxTransformFeedbackInterleavedComponents = */ 64,
  91. /* .MaxCullDistances = */ 8,
  92. /* .MaxCombinedClipAndCullDistances = */ 8,
  93. /* .MaxSamples = */ 32,
  94. /* .maxMeshOutputVerticesNV = */ 256,
  95. /* .maxMeshOutputPrimitivesNV = */ 512,
  96. /* .maxMeshWorkGroupSizeX_NV = */ 32,
  97. /* .maxMeshWorkGroupSizeY_NV = */ 1,
  98. /* .maxMeshWorkGroupSizeZ_NV = */ 1,
  99. /* .maxTaskWorkGroupSizeX_NV = */ 32,
  100. /* .maxTaskWorkGroupSizeY_NV = */ 1,
  101. /* .maxTaskWorkGroupSizeZ_NV = */ 1,
  102. /* .maxMeshViewCountNV = */ 4,
  103. /* .maxDualSourceDrawBuffersEXT = */ 1,
  104. /* .limits = */ {
  105. /* .nonInductiveForLoops = */ 1,
  106. /* .whileLoops = */ 1,
  107. /* .doWhileLoops = */ 1,
  108. /* .generalUniformIndexing = */ 1,
  109. /* .generalAttributeMatrixVectorIndexing = */ 1,
  110. /* .generalVaryingIndexing = */ 1,
  111. /* .generalSamplerIndexing = */ 1,
  112. /* .generalVariableIndexing = */ 1,
  113. /* .generalConstantMatrixVectorIndexing = */ 1,
  114. }
  115. };
  116. static const uint32_t STREAMBUFFER_DEFAULT_SIZE = 16;
  117. static VkShaderStageFlagBits getStageBit(ShaderStageType type) {
  118. switch (type) {
  119. case SHADERSTAGE_VERTEX:
  120. return VK_SHADER_STAGE_VERTEX_BIT;
  121. case SHADERSTAGE_PIXEL:
  122. return VK_SHADER_STAGE_FRAGMENT_BIT;
  123. case SHADERSTAGE_COMPUTE:
  124. return VK_SHADER_STAGE_COMPUTE_BIT;
  125. }
  126. throw love::Exception("invalid type");
  127. }
  128. static EShLanguage getGlslShaderType(ShaderStageType stage) {
  129. switch (stage) {
  130. case SHADERSTAGE_VERTEX:
  131. return EShLangVertex;
  132. case SHADERSTAGE_PIXEL:
  133. return EShLangFragment;
  134. case SHADERSTAGE_COMPUTE:
  135. return EShLangCompute;
  136. default:
  137. throw love::Exception("unkonwn shader stage type");
  138. }
  139. }
  140. Shader::Shader(StrongRef<love::graphics::ShaderStage> stages[])
  141. : graphics::Shader(stages) {
  142. loadVolatile();
  143. }
  144. bool Shader::loadVolatile() {
  145. calculateUniformBufferSizeAligned();
  146. compileShaders();
  147. createDescriptorSetLayout();
  148. createPipelineLayout();
  149. createStreamBuffers();
  150. currentImage = 0;
  151. count = 0;
  152. return true;
  153. }
  154. void Shader::unloadVolatile() {
  155. if (shaderModules.size() == 0) {
  156. return;
  157. }
  158. auto gfx = Module::getInstance<Graphics>(Module::M_GRAPHICS);
  159. gfx->queueCleanUp([shaderModules = std::move(shaderModules), device = device, descriptorSetLayout = descriptorSetLayout, pipelineLayout = pipelineLayout](){
  160. for (const auto shaderModule : shaderModules) {
  161. vkDestroyShaderModule(device, shaderModule, nullptr);
  162. }
  163. vkDestroyDescriptorSetLayout(device, descriptorSetLayout, nullptr);
  164. vkDestroyPipelineLayout(device, pipelineLayout, nullptr);
  165. });
  166. for (const auto &streamBufferVector : streamBuffers) {
  167. for (const auto streamBuffer : streamBufferVector) {
  168. delete streamBuffer;
  169. }
  170. }
  171. shaderModules.clear();
  172. shaderStages.clear();
  173. streamBuffers.clear();
  174. }
  175. const std::vector<VkPipelineShaderStageCreateInfo>& Shader::getShaderStages() const {
  176. return shaderStages;
  177. }
  178. const VkPipelineLayout Shader::getGraphicsPipelineLayout() const {
  179. return pipelineLayout;
  180. }
  181. static VkDescriptorImageInfo createDescriptorImageInfo(graphics::Texture* texture) {
  182. VkDescriptorImageInfo imageInfo{};
  183. imageInfo.imageLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL;
  184. Texture* vkTexture = (Texture*)texture;
  185. imageInfo.imageView = (VkImageView)vkTexture->getRenderTargetHandle();
  186. imageInfo.sampler = (VkSampler)vkTexture->getSamplerHandle();
  187. return imageInfo;
  188. }
  189. void Shader::cmdPushDescriptorSets(VkCommandBuffer commandBuffer, uint32_t imageIndex) {
  190. // detect wether a new frame has begun
  191. if (currentImage != imageIndex) {
  192. currentImage = imageIndex;
  193. count = 0;
  194. // we needed more memory last frame, let's collapse all buffers into a single one.
  195. if (streamBuffers.at(currentImage).size() > 1) {
  196. size_t newSize = 0;
  197. for (auto streamBuffer : streamBuffers.at(currentImage)) {
  198. newSize += streamBuffer->getSize();
  199. delete streamBuffer;
  200. }
  201. streamBuffers.at(currentImage).clear();
  202. streamBuffers.at(currentImage).push_back(new StreamBuffer(gfx, BUFFERUSAGE_UNIFORM, newSize));
  203. }
  204. // no collapse necessary, can just call nextFrame to reset the current (only) streambuffer
  205. else {
  206. streamBuffers.at(currentImage).at(0)->nextFrame();
  207. }
  208. }
  209. // still the same frame
  210. else {
  211. auto usedStreamBufferMemory = count * uniformBufferSizeAligned;
  212. if (usedStreamBufferMemory >= streamBuffers.at(currentImage).back()->getSize()) {
  213. // we ran out of memory in the current frame, need to allocate more.
  214. streamBuffers.at(currentImage).push_back(new StreamBuffer(gfx, BUFFERUSAGE_UNIFORM, STREAMBUFFER_DEFAULT_SIZE * uniformBufferSizeAligned));
  215. count = 0;
  216. }
  217. }
  218. // additional data is always added onto the last stream buffer in the current frame
  219. auto currentStreamBuffer = streamBuffers.at(currentImage).back();
  220. auto mapInfo = currentStreamBuffer->map(uniformBufferSizeAligned);
  221. memcpy(mapInfo.data, &uniformData, uniformBufferSizeAligned);
  222. currentStreamBuffer->unmap(uniformBufferSizeAligned);
  223. currentStreamBuffer->markUsed(uniformBufferSizeAligned);
  224. VkDescriptorBufferInfo bufferInfo{};
  225. bufferInfo.buffer = (VkBuffer)currentStreamBuffer->getHandle();
  226. bufferInfo.offset = count * uniformBufferSizeAligned;
  227. bufferInfo.range = sizeof(BuiltinUniformData);
  228. auto mainTexImageInfo = createDescriptorImageInfo(mainTex);
  229. auto ytextureImageInfo = createDescriptorImageInfo(ytexture);
  230. auto cbtextureImageInfo = createDescriptorImageInfo(cbtexture);
  231. auto crtextureImageInfo = createDescriptorImageInfo(crtexture);
  232. std::array<VkWriteDescriptorSet, 5> descriptorWrite{};
  233. descriptorWrite[0].sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
  234. descriptorWrite[0].dstSet = 0;
  235. descriptorWrite[0].dstBinding = 0;
  236. descriptorWrite[0].dstArrayElement = 0;
  237. descriptorWrite[0].descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
  238. descriptorWrite[0].descriptorCount = 1;
  239. descriptorWrite[0].pBufferInfo = &bufferInfo;
  240. descriptorWrite[1].sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
  241. descriptorWrite[1].dstSet = 0;
  242. descriptorWrite[1].dstBinding = 1;
  243. descriptorWrite[1].dstArrayElement = 0;
  244. descriptorWrite[1].descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER;
  245. descriptorWrite[1].descriptorCount = 1;
  246. descriptorWrite[1].pImageInfo = &mainTexImageInfo;
  247. descriptorWrite[2].sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
  248. descriptorWrite[2].dstSet = 0;
  249. descriptorWrite[2].dstBinding = 2;
  250. descriptorWrite[2].dstArrayElement = 0;
  251. descriptorWrite[2].descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER;
  252. descriptorWrite[2].descriptorCount = 1;
  253. descriptorWrite[2].pImageInfo = &ytextureImageInfo;
  254. descriptorWrite[3].sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
  255. descriptorWrite[3].dstSet = 0;
  256. descriptorWrite[3].dstBinding = 3;
  257. descriptorWrite[3].dstArrayElement = 0;
  258. descriptorWrite[3].descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER;
  259. descriptorWrite[3].descriptorCount = 1;
  260. descriptorWrite[3].pImageInfo = &cbtextureImageInfo;
  261. descriptorWrite[4].sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
  262. descriptorWrite[4].dstSet = 0;
  263. descriptorWrite[4].dstBinding = 4;
  264. descriptorWrite[4].dstArrayElement = 0;
  265. descriptorWrite[4].descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER;
  266. descriptorWrite[4].descriptorCount = 1;
  267. descriptorWrite[4].pImageInfo = &crtextureImageInfo;
  268. vkCmdPushDescriptorSet(commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, pipelineLayout, 0, static_cast<uint32_t>(descriptorWrite.size()), descriptorWrite.data());
  269. count++;
  270. }
  271. Shader::~Shader() {
  272. unloadVolatile();
  273. }
  274. void Shader::attach() {
  275. if (Shader::current != this) {
  276. Graphics::flushBatchedDrawsGlobal();
  277. Shader::current = this;
  278. Vulkan::shaderSwitch();
  279. }
  280. }
  281. int Shader::getVertexAttributeIndex(const std::string& name) {
  282. return vertexAttributeIndices.at(name);
  283. }
  284. void Shader::calculateUniformBufferSizeAligned() {
  285. gfx = Module::getInstance<Graphics>(Module::ModuleType::M_GRAPHICS);
  286. auto vgfx = (Graphics*)gfx;
  287. auto minAlignment = vgfx->getMinUniformBufferOffsetAlignment();
  288. uniformBufferSizeAligned =
  289. static_cast<VkDeviceSize>(
  290. std::ceil(
  291. static_cast<float>(sizeof(BuiltinUniformData)) / static_cast<float>(minAlignment)
  292. )
  293. )
  294. * minAlignment;
  295. }
  296. void Shader::compileShaders() {
  297. using namespace glslang;
  298. using namespace spirv_cross;
  299. TProgram* program = new TProgram();
  300. gfx = Module::getInstance<Graphics>(Module::ModuleType::M_GRAPHICS);
  301. auto vgfx = (Graphics*)gfx;
  302. device = vgfx->getDevice();
  303. mainTex = vgfx->getDefaultTexture();
  304. ytexture = vgfx->getDefaultTexture();
  305. crtexture = vgfx->getDefaultTexture();
  306. cbtexture = vgfx->getDefaultTexture();
  307. for (int i = 0; i < SHADERSTAGE_MAX_ENUM; i++) {
  308. if (!stages[i])
  309. continue;
  310. auto stage = (ShaderStageType)i;
  311. auto glslangShaderStage = getGlslShaderType(stage);
  312. auto tshader = new TShader(glslangShaderStage);
  313. tshader->setEnvInput(EShSourceGlsl, glslangShaderStage, EShClientVulkan, 450);
  314. tshader->setEnvClient(EShClientVulkan, EShTargetVulkan_1_2);
  315. tshader->setEnvTarget(EshTargetSpv, EShTargetSpv_1_5);
  316. tshader->setAutoMapLocations(true);
  317. tshader->setAutoMapBindings(true);
  318. tshader->setEnvInputVulkanRulesRelaxed();
  319. tshader->setGlobalUniformBinding(0);
  320. tshader->setGlobalUniformSet(0);
  321. auto& glsl = stages[i]->getSource();
  322. const char* csrc = glsl.c_str();
  323. const int sourceLength = static_cast<int>(glsl.length());
  324. tshader->setStringsWithLengths(&csrc, &sourceLength, 1);
  325. int defaultVersio = 450;
  326. EProfile defaultProfile = ECoreProfile;
  327. bool forceDefault = false;
  328. bool forwardCompat = true;
  329. if (!tshader->parse(&defaultTBuiltInResource, defaultVersio, defaultProfile, forceDefault, forwardCompat, EShMsgSuppressWarnings)) {
  330. const char* msg1 = tshader->getInfoLog();
  331. const char* msg2 = tshader->getInfoDebugLog();
  332. throw love::Exception("error while parsing shader");
  333. }
  334. program->addShader(tshader);
  335. }
  336. if (!program->link(EShMsgDefault)) {
  337. throw love::Exception("link failed! %s\n", program->getInfoLog());
  338. }
  339. if (!program->mapIO()) {
  340. throw love::Exception("mapIO failed");
  341. }
  342. for (int i = 0; i < SHADERSTAGE_MAX_ENUM; i++) {
  343. auto glslangStage = getGlslShaderType((ShaderStageType)i);
  344. auto intermediate = program->getIntermediate(glslangStage);
  345. if (intermediate == nullptr) {
  346. continue;
  347. }
  348. spv::SpvBuildLogger logger;
  349. glslang::SpvOptions opt;
  350. opt.validate = true;
  351. std::vector<uint32_t> spirv;
  352. GlslangToSpv(*intermediate, spirv, &logger, &opt);
  353. std::string msgs = logger.getAllMessages();
  354. VkShaderModuleCreateInfo createInfo{};
  355. createInfo.sType = VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO;
  356. createInfo.codeSize = spirv.size() * sizeof(uint32_t);
  357. createInfo.pCode = spirv.data();
  358. Graphics* vkGfx = (Graphics*)gfx;
  359. auto device = vkGfx->getDevice();
  360. VkShaderModule shaderModule;
  361. if (vkCreateShaderModule(device, &createInfo, nullptr, &shaderModule) != VK_SUCCESS) {
  362. throw love::Exception("failed to create shader module");
  363. }
  364. shaderModules.push_back(shaderModule);
  365. VkPipelineShaderStageCreateInfo shaderStageInfo{};
  366. shaderStageInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO;
  367. shaderStageInfo.stage = getStageBit((ShaderStageType)i);
  368. shaderStageInfo.module = shaderModule;
  369. shaderStageInfo.pName = "main";
  370. shaderStages.push_back(shaderStageInfo);
  371. }
  372. }
  373. // fixme: should generate this dynamically.
  374. void Shader::createDescriptorSetLayout() {
  375. auto vgfx = (Graphics*)gfx;
  376. vkCmdPushDescriptorSet = vgfx->getVkCmdPushDescriptorSetKHRFunctionPointer();
  377. VkDescriptorSetLayoutBinding uboLayoutBinding{};
  378. uboLayoutBinding.binding = 0;
  379. uboLayoutBinding.descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
  380. uboLayoutBinding.descriptorCount = 1;
  381. uboLayoutBinding.stageFlags = VK_SHADER_STAGE_VERTEX_BIT | VK_SHADER_STAGE_FRAGMENT_BIT;
  382. VkDescriptorSetLayoutBinding samplerLayoutBinding{};
  383. samplerLayoutBinding.binding = 1;
  384. samplerLayoutBinding.descriptorCount = 1;
  385. samplerLayoutBinding.descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER;
  386. samplerLayoutBinding.pImmutableSamplers = nullptr;
  387. samplerLayoutBinding.stageFlags = VK_SHADER_STAGE_FRAGMENT_BIT;
  388. VkDescriptorSetLayoutBinding videoYBinding{};
  389. videoYBinding.binding = 2;
  390. videoYBinding.descriptorCount = 1;
  391. videoYBinding.descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER;
  392. videoYBinding.pImmutableSamplers = nullptr;
  393. videoYBinding.stageFlags = VK_SHADER_STAGE_FRAGMENT_BIT;
  394. VkDescriptorSetLayoutBinding videoCBBinding{};
  395. videoCBBinding.binding = 3;
  396. videoCBBinding.descriptorCount = 1;
  397. videoCBBinding.descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER;
  398. videoCBBinding.pImmutableSamplers = nullptr;
  399. videoCBBinding.stageFlags = VK_SHADER_STAGE_FRAGMENT_BIT;
  400. VkDescriptorSetLayoutBinding videoCRinding{};
  401. videoCRinding.binding = 4;
  402. videoCRinding.descriptorCount = 1;
  403. videoCRinding.descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER;
  404. videoCRinding.pImmutableSamplers = nullptr;
  405. videoCRinding.stageFlags = VK_SHADER_STAGE_FRAGMENT_BIT;
  406. std::array<VkDescriptorSetLayoutBinding, 5> bindings = { uboLayoutBinding, samplerLayoutBinding, videoYBinding, videoCBBinding, videoCRinding };
  407. VkDescriptorSetLayoutCreateInfo layoutInfo{};
  408. layoutInfo.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO;
  409. layoutInfo.flags = VK_DESCRIPTOR_SET_LAYOUT_CREATE_PUSH_DESCRIPTOR_BIT_KHR;
  410. layoutInfo.bindingCount = static_cast<uint32_t>(bindings.size());
  411. layoutInfo.pBindings = bindings.data();
  412. if (vkCreateDescriptorSetLayout(device, &layoutInfo, nullptr, &descriptorSetLayout) != VK_SUCCESS) {
  413. throw love::Exception("failed to create descriptor set layout");
  414. }
  415. }
  416. void Shader::createPipelineLayout() {
  417. VkPipelineLayoutCreateInfo pipelineLayoutInfo{};
  418. pipelineLayoutInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO;
  419. pipelineLayoutInfo.setLayoutCount = 1;
  420. pipelineLayoutInfo.pSetLayouts = &descriptorSetLayout;
  421. pipelineLayoutInfo.pushConstantRangeCount = 0;
  422. if (vkCreatePipelineLayout(device, &pipelineLayoutInfo, nullptr, &pipelineLayout) != VK_SUCCESS) {
  423. throw love::Exception("failed to create pipeline layout");
  424. }
  425. }
  426. void Shader::createStreamBuffers() {
  427. auto vgfx = (Graphics*)gfx;
  428. const auto numImagesInFlight = vgfx->getNumImagesInFlight();
  429. streamBuffers.resize(numImagesInFlight);
  430. for (uint32_t i = 0; i < numImagesInFlight; i++) {
  431. streamBuffers[i].push_back(new StreamBuffer(gfx, BUFFERUSAGE_UNIFORM, STREAMBUFFER_DEFAULT_SIZE * uniformBufferSizeAligned));
  432. }
  433. }
  434. void Shader::setVideoTextures(graphics::Texture* ytexture, graphics::Texture* cbtexture, graphics::Texture* crtexture) {
  435. this->ytexture = ytexture;
  436. this->cbtexture = cbtexture;
  437. this->crtexture = crtexture;
  438. }
  439. void Shader::setUniformData(BuiltinUniformData& data) {
  440. uniformData = data;
  441. }
  442. void Shader::setMainTex(graphics::Texture* texture) {
  443. mainTex = texture;
  444. }
  445. } // vulkan
  446. } // graphics
  447. } // love