vulkan: fix video rendering

When rewriting the shader part rendering videos was broken.
This commit fixes that again.
This commit is contained in:
niki
2022-08-14 20:45:57 +02:00
parent f9ad1842b5
commit 84df8fee03
2 changed files with 55 additions and 19 deletions
+52 -15
View File
@@ -150,6 +150,10 @@ Shader::Shader(StrongRef<love::graphics::ShaderStage> 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<VkDescriptorImageInfo*> 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<uint32_t>(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<uint32_t>(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<TShader*> glslangShaders;
TProgram* program = new TProgram();
gfx = Module::getInstance<Graphics>(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
+3 -4
View File
@@ -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<uint8> 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;