From 84df8fee034ba4381c0a5cdbe7f11ac921cf9142 Mon Sep 17 00:00:00 2001 From: niki Date: Sun, 14 Aug 2022 20:45:57 +0200 Subject: [PATCH] vulkan: fix video rendering When rewriting the shader part rendering videos was broken. This commit fixes that again. --- src/modules/graphics/vulkan/Shader.cpp | 67 ++++++++++++++++++++------ src/modules/graphics/vulkan/Shader.h | 7 ++- 2 files changed, 55 insertions(+), 19 deletions(-) diff --git a/src/modules/graphics/vulkan/Shader.cpp b/src/modules/graphics/vulkan/Shader.cpp index 35209cd7b..401b83696 100644 --- a/src/modules/graphics/vulkan/Shader.cpp +++ b/src/modules/graphics/vulkan/Shader.cpp @@ -150,6 +150,10 @@ Shader::Shader(StrongRef stages[]) } bool Shader::loadVolatile() { + for (int i = 0; i < BUILTIN_MAX_ENUM; i++) { + builtinUniformInfo[i] = nullptr; + } + compileShaders(); calculateUniformBufferSizeAligned(); createDescriptorSetLayout(); @@ -192,12 +196,15 @@ const VkPipelineLayout Shader::getGraphicsPipelineLayout() const { return pipelineLayout; } -static VkDescriptorImageInfo createDescriptorImageInfo(graphics::Texture* texture) { - VkDescriptorImageInfo imageInfo{}; - imageInfo.imageLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL; +static VkDescriptorImageInfo* createDescriptorImageInfo(graphics::Texture* texture) { Texture* vkTexture = (Texture*)texture; - imageInfo.imageView = (VkImageView)vkTexture->getRenderTargetHandle(); - imageInfo.sampler = (VkSampler)vkTexture->getSamplerHandle(); + + VkDescriptorImageInfo* imageInfo = new VkDescriptorImageInfo(); + + imageInfo->imageLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL; + imageInfo->imageView = (VkImageView)vkTexture->getRenderTargetHandle(); + imageInfo->sampler = (VkSampler)vkTexture->getSamplerHandle(); + return imageInfo; } @@ -259,6 +266,11 @@ void Shader::cmdPushDescriptorSets(VkCommandBuffer commandBuffer, uint32_t frame descriptorWrite.push_back(uniformWrite); + // Vulkan needs the image infos as a pointer. + // we collect them all here to properly free them up + // after the vulkan call. + std::vector imageInfos; + // update everything other than uniform buffers (since that's already taken care of. for (const auto& [key, val] : uniformInfos) { // fixme: other types. @@ -270,8 +282,13 @@ void Shader::cmdPushDescriptorSets(VkCommandBuffer commandBuffer, uint32_t frame write.dstArrayElement = 0; write.descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER; write.descriptorCount = 1; - const auto imageInfo = createDescriptorImageInfo(val.textures[0]); // fixme: arrays - write.pImageInfo = &imageInfo; + + uint32_t index = static_cast(imageInfos.size()); + + VkDescriptorImageInfo* imageInfo = createDescriptorImageInfo(val.textures[0]); // fixme: arrays + imageInfos.push_back(imageInfo); + + write.pImageInfo = imageInfo; descriptorWrite.push_back(write); } @@ -282,6 +299,10 @@ void Shader::cmdPushDescriptorSets(VkCommandBuffer commandBuffer, uint32_t frame pipelineLayout, 0, static_cast(descriptorWrite.size()), descriptorWrite.data()); + for (const auto imageInfo : imageInfos) { + delete imageInfo; + } + count++; } @@ -385,16 +406,14 @@ void Shader::compileShaders() { using namespace glslang; using namespace spirv_cross; + std::vector glslangShaders; + TProgram* program = new TProgram(); gfx = Module::getInstance(Module::ModuleType::M_GRAPHICS); auto vgfx = (Graphics*)gfx; device = vgfx->getDevice(); - ytexture = vgfx->getDefaultTexture(); - crtexture = vgfx->getDefaultTexture(); - cbtexture = vgfx->getDefaultTexture(); - for (int i = 0; i < SHADERSTAGE_MAX_ENUM; i++) { if (!stages[i]) continue; @@ -430,6 +449,7 @@ void Shader::compileShaders() { } program->addShader(tshader); + glslangShaders.push_back(tshader); } if (!program->link(EShMsgDefault)) { @@ -615,6 +635,11 @@ void Shader::compileShaders() { } } } + + delete program; + for (auto shader : glslangShaders) { + delete shader; + } } void Shader::createDescriptorSetLayout() { @@ -666,9 +691,17 @@ void Shader::createStreamBuffers() { } void Shader::setVideoTextures(graphics::Texture* ytexture, graphics::Texture* cbtexture, graphics::Texture* crtexture) { - this->ytexture = ytexture; - this->cbtexture = cbtexture; - this->crtexture = crtexture; + // if the shader doesn't actually use these textures they might get optimized out + // in that case this function becomes a noop. + if (builtinUniformInfo[BUILTIN_TEXTURE_VIDEO_Y] != nullptr) { + builtinUniformInfo[BUILTIN_TEXTURE_VIDEO_Y]->textures[0] = ytexture; + } + if (builtinUniformInfo[BUILTIN_TEXTURE_VIDEO_CB] != nullptr) { + builtinUniformInfo[BUILTIN_TEXTURE_VIDEO_CB]->textures[0] = cbtexture; + } + if (builtinUniformInfo[BUILTIN_TEXTURE_VIDEO_CR] != nullptr) { + builtinUniformInfo[BUILTIN_TEXTURE_VIDEO_CR]->textures[0] = crtexture; + } } void Shader::setUniformData(BuiltinUniformData& data) { @@ -677,7 +710,11 @@ void Shader::setUniformData(BuiltinUniformData& data) { } void Shader::setMainTex(graphics::Texture* texture) { - builtinUniformInfo[BUILTIN_TEXTURE_MAIN]->textures[0] = texture; + // if the shader doesn't actually use the texture it might get optimized out + // in that case this function becomes a noop. + if (builtinUniformInfo[BUILTIN_TEXTURE_MAIN] != nullptr) { + builtinUniformInfo[BUILTIN_TEXTURE_MAIN]->textures[0] = texture; + } } } // vulkan } // graphics diff --git a/src/modules/graphics/vulkan/Shader.h b/src/modules/graphics/vulkan/Shader.h index a23da784d..f91b7ccde 100644 --- a/src/modules/graphics/vulkan/Shader.h +++ b/src/modules/graphics/vulkan/Shader.h @@ -42,6 +42,9 @@ public: const UniformInfo* getUniformInfo(const std::string& name) const override { return nullptr; } const UniformInfo* getUniformInfo(BuiltinUniform builtin) const override { return nullptr; } + // Not needed right now, since the logic that links the values of the uniforms to the shader is done in cmdPushDescriptorSets + // which gets called from the vulkan::Graphics class whenever a draw call happens. + // I'll have to reevaluate the use of this function in the future though. void updateUniform(const UniformInfo* info, int count) override {} void sendTextures(const UniformInfo* info, graphics::Texture** textures, int count) override {} @@ -90,10 +93,6 @@ private: std::vector localUniformStagingData; size_t builtinUniformDataOffset; - graphics::Texture* ytexture; - graphics::Texture* cbtexture; - graphics::Texture* crtexture; - uint32_t currentFrame; // todo: give this variable a better name uint32_t count;