From a577be8a6d7e294afea20db0fa59db2585edc3c1 Mon Sep 17 00:00:00 2001 From: niki Date: Tue, 23 Aug 2022 01:38:47 +0200 Subject: [PATCH] vulkan: fix a few bugs in Shader --- src/modules/graphics/vulkan/Graphics.h | 2 +- src/modules/graphics/vulkan/Shader.cpp | 62 +++++++++++++++++++------- src/modules/graphics/vulkan/Shader.h | 1 + 3 files changed, 49 insertions(+), 16 deletions(-) diff --git a/src/modules/graphics/vulkan/Graphics.h b/src/modules/graphics/vulkan/Graphics.h index e390a0c24..3aafceff0 100644 --- a/src/modules/graphics/vulkan/Graphics.h +++ b/src/modules/graphics/vulkan/Graphics.h @@ -262,7 +262,7 @@ private: std::vector swapChainImageViews; VkPipeline currentGraphicsPipeline = VK_NULL_HANDLE; VkRenderPass currentRenderPass = VK_NULL_HANDLE; - VkSampleCountFlagBits msaaSamples; + VkSampleCountFlagBits msaaSamples = VK_SAMPLE_COUNT_1_BIT; VkImage colorImage = VK_NULL_HANDLE; VkImageView colorImageView = VK_NULL_HANDLE; VmaAllocation colorImageAllocation = VK_NULL_HANDLE; diff --git a/src/modules/graphics/vulkan/Shader.cpp b/src/modules/graphics/vulkan/Shader.cpp index 8125d76ea..07e57ec9a 100644 --- a/src/modules/graphics/vulkan/Shader.cpp +++ b/src/modules/graphics/vulkan/Shader.cpp @@ -207,9 +207,9 @@ const VkPipelineLayout Shader::getGraphicsPipelineLayout() const { } static VkDescriptorImageInfo* createDescriptorImageInfo(graphics::Texture* texture) { - Texture* vkTexture = (Texture*)texture; + auto vkTexture = (Texture*)texture; - VkDescriptorImageInfo* imageInfo = new VkDescriptorImageInfo(); + auto imageInfo = new VkDescriptorImageInfo(); imageInfo->imageLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL; imageInfo->imageView = (VkImageView)vkTexture->getRenderTargetHandle(); @@ -219,7 +219,7 @@ static VkDescriptorImageInfo* createDescriptorImageInfo(graphics::Texture* textu } void Shader::cmdPushDescriptorSets(VkCommandBuffer commandBuffer, uint32_t frameIndex) { - // detect wether a new frame has begun + // detect whether a new frame has begun if (currentFrame != frameIndex) { currentFrame = frameIndex; @@ -259,14 +259,14 @@ void Shader::cmdPushDescriptorSets(VkCommandBuffer commandBuffer, uint32_t frame auto currentStreamBuffer = streamBuffers.at(currentFrame).back(); auto mapInfo = currentStreamBuffer->map(uniformBufferSizeAligned); - memcpy(mapInfo.data, localUniformStagingData.data(), uniformBufferSizeAligned); + memcpy(mapInfo.data, localUniformStagingData.data(), localUniformStagingData.size()); currentStreamBuffer->unmap(uniformBufferSizeAligned); currentStreamBuffer->markUsed(uniformBufferSizeAligned); VkDescriptorBufferInfo bufferInfo{}; bufferInfo.buffer = (VkBuffer)currentStreamBuffer->getHandle(); bufferInfo.offset = currentUsedUniformStreamBuffersCount * uniformBufferSizeAligned; - bufferInfo.range = sizeof(BuiltinUniformData); + bufferInfo.range = localUniformStagingData.size(); VkDescriptorSet currentDescriptorSet = descriptorSetsVector.at(currentFrame).at(currentUsedDescriptorSetsCount); @@ -414,7 +414,17 @@ void Shader::buildLocalUniforms(spirv_cross::Compiler& comp, const spirv_cross:: u.matrix.columns = memberType.columns; } - // fixme: initializer values + const auto& reflectionIt = validationReflection.localUniforms.find(u.name); + if (reflectionIt != validationReflection.localUniforms.end()) { + const auto& localUniform = reflectionIt->second; + const auto& values = localUniform.initializerValues; + if (!values.empty()) { + memcpy( + u.data, + values.data(), + std::min(u.dataSize, values.size() * sizeof(LocalUniformValue))); + } + } uniformInfos[u.name] = u; @@ -434,7 +444,7 @@ void Shader::compileShaders() { std::vector glslangShaders; - TProgram* program = new TProgram(); + auto program = new TProgram(); gfx = Module::getInstance(Module::ModuleType::M_GRAPHICS); auto vgfx = (Graphics*)gfx; @@ -450,7 +460,7 @@ void Shader::compileShaders() { tshader->setEnvInput(EShSourceGlsl, glslangShaderStage, EShClientVulkan, 450); tshader->setEnvClient(EShClientVulkan, EShTargetVulkan_1_2); - tshader->setEnvTarget(EshTargetSpv, EShTargetSpv_1_5); + tshader->setEnvTarget(EshTargetSpv, EShTargetSpv_1_0); tshader->setAutoMapLocations(true); tshader->setAutoMapBindings(true); tshader->setEnvInputVulkanRulesRelaxed(); @@ -541,6 +551,7 @@ void Shader::compileShaders() { size_t uniformBufferObjectSize = comp.get_declared_struct_size(type); auto defaultUniformBlockSize = comp.get_declared_struct_size(type); localUniformStagingData.resize(defaultUniformBlockSize); + uniformLocation = comp.get_decoration(resource.id, spv::DecorationBinding); memset(localUniformStagingData.data(), 0, defaultUniformBlockSize); @@ -630,15 +641,26 @@ void Shader::createDescriptorSetLayout() { std::vector bindings; for (auto const& [key, val] : uniformInfos) { - VkDescriptorSetLayoutBinding layoutBinding{}; - layoutBinding.binding = val.location; - layoutBinding.descriptorType = val.baseType == UNIFORM_SAMPLER ? VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER : VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER; - layoutBinding.descriptorCount = 1; // is this correct? - layoutBinding.stageFlags = VK_SHADER_STAGE_VERTEX_BIT | VK_SHADER_STAGE_FRAGMENT_BIT | VK_SHADER_STAGE_COMPUTE_BIT; // fixme: can we determine in what shader it got used? + auto type = Vulkan::getDescriptorType(val.baseType); + if (type != VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER) { + VkDescriptorSetLayoutBinding layoutBinding{}; - bindings.push_back(layoutBinding); + layoutBinding.binding = val.location; + layoutBinding.descriptorType = val.baseType == UNIFORM_SAMPLER ? VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER : VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER; + layoutBinding.descriptorCount = val.count; + layoutBinding.stageFlags = VK_SHADER_STAGE_VERTEX_BIT | VK_SHADER_STAGE_FRAGMENT_BIT | VK_SHADER_STAGE_COMPUTE_BIT; // fixme: can we determine in what shader it got used? + + bindings.push_back(layoutBinding); + } } + VkDescriptorSetLayoutBinding uniformBinding{}; + uniformBinding.binding = uniformLocation; + uniformBinding.descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER; + uniformBinding.descriptorCount = 1; + uniformBinding.stageFlags = VK_SHADER_STAGE_VERTEX_BIT | VK_SHADER_STAGE_FRAGMENT_BIT; + bindings.push_back(uniformBinding); + VkDescriptorSetLayoutCreateInfo layoutInfo{}; layoutInfo.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO; layoutInfo.bindingCount = static_cast(bindings.size()); @@ -706,9 +728,19 @@ VkDescriptorSet Shader::allocateDescriptorSet() { // fixme: we can optimize this, since sizes should never change for a given shader. std::vector sizes; + VkDescriptorPoolSize size{}; + size.type = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER; + size.descriptorCount = 1; + + sizes.push_back(size); + for (const auto& [key, val] : uniformInfos) { VkDescriptorPoolSize size{}; - size.type = Vulkan::getDescriptorType(val.baseType); + auto type = Vulkan::getDescriptorType(val.baseType); + if (type == VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER) { + continue; + } + size.type = type; size.descriptorCount = 1; sizes.push_back(size); } diff --git a/src/modules/graphics/vulkan/Shader.h b/src/modules/graphics/vulkan/Shader.h index 382274c89..a343a27bb 100644 --- a/src/modules/graphics/vulkan/Shader.h +++ b/src/modules/graphics/vulkan/Shader.h @@ -95,6 +95,7 @@ private: std::unique_ptr uniformBufferObjectBuffer; std::vector localUniformStagingData; + uint32_t uniformLocation; size_t builtinUniformDataOffset; uint32_t currentFrame;