/* * This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ #include "VulkanShader.hpp" #include "Vulkan/Context.hpp" #include "Scene/Vertex.hpp" #include "Scene/Shader.hpp" #include "Vulkan/Resources/IShaderOwner.hpp" namespace openVulkanoCpp::Vulkan { void VulkanShader::Init(Context* context, Scene::Shader* shader, IShaderOwner* owner) { this->device = context->device->device; this->shader = shader; this->owner = owner; this->context = context; shaderModules.reserve(shader->shaderPrograms.size()); shaderStageCreateInfo.resize(shader->shaderPrograms.size()); int i = 0; for(const auto& shaderProgram : shader->shaderPrograms) { const auto shaderModule = context->device->CreateShaderModule(shaderProgram.GetShaderNameVulkan()); shaderModules.push_back(shaderModule); shaderStageCreateInfo[i] = {{}, static_cast(static_cast(shaderProgram.type)), shaderModule, "main"}; i++; } BuildPipeline(); } void VulkanShader::BuildPipeline() { vk::VertexInputBindingDescription vertexBindDesc(0, sizeof(Vertex), vk::VertexInputRate::eVertex); std::vector attributeDescriptions; attributeDescriptions.emplace_back(0, 0, vk::Format::eR32G32B32Sfloat, offsetof(Vertex, position)); attributeDescriptions.emplace_back(1, 0, vk::Format::eR32G32B32Sfloat, offsetof(Vertex, normal)); attributeDescriptions.emplace_back(2, 0, vk::Format::eR32G32B32Sfloat, offsetof(Vertex, tangent)); attributeDescriptions.emplace_back(3, 0, vk::Format::eR32G32B32Sfloat, offsetof(Vertex, biTangent)); attributeDescriptions.emplace_back(4, 0, vk::Format::eR32G32B32Sfloat, offsetof(Vertex, textureCoordinates)); attributeDescriptions.emplace_back(5, 0, vk::Format::eR32G32B32A32Sfloat, offsetof(Vertex, color)); vk::PipelineViewportStateCreateInfo viewportStateCreateInfo = { {}, 1, &context->swapChain.GetFullscreenViewport(), 1, &context->swapChain.GetFullscreenScissor() }; vk::PipelineVertexInputStateCreateInfo pipelineVertexInputStateCreateInfo = { {}, 1, &vertexBindDesc, static_cast(attributeDescriptions.size()), attributeDescriptions.data() }; vk::PipelineInputAssemblyStateCreateInfo inputAssembly = { {}, static_cast(shader->topology), 0 }; vk::PipelineRasterizationStateCreateInfo rasterizer = {}; rasterizer.cullMode = vk::CullModeFlagBits::eBack; vk::PipelineMultisampleStateCreateInfo msaa = {}; vk::PipelineDepthStencilStateCreateInfo depth = { {}, 1, 1, vk::CompareOp::eLess }; depth.maxDepthBounds = 1; vk::PipelineColorBlendAttachmentState colorBlendAttachment = {}; colorBlendAttachment.colorWriteMask = vk::ColorComponentFlagBits::eA | vk::ColorComponentFlagBits::eB | vk::ColorComponentFlagBits::eG | vk::ColorComponentFlagBits::eR; vk::PipelineColorBlendStateCreateInfo colorInfo = {}; colorInfo.attachmentCount = 1; colorInfo.pAttachments = &colorBlendAttachment; vk::GraphicsPipelineCreateInfo pipelineCreateInfo = { {}, static_cast(shaderStageCreateInfo.size()), shaderStageCreateInfo.data(), &pipelineVertexInputStateCreateInfo, &inputAssembly, nullptr, &viewportStateCreateInfo, &rasterizer, &msaa, &depth, &colorInfo, nullptr, context->pipeline.pipelineLayout, context->swapChainRenderPass.renderPass }; pipeline = this->device.createGraphicsPipeline({}, pipelineCreateInfo).value; } void VulkanShader::Resize() { device.destroyPipeline(pipeline); BuildPipeline(); } void VulkanShader::Record(vk::CommandBuffer& cmdBuffer, uint32_t bufferId) { cmdBuffer.bindPipeline(vk::PipelineBindPoint::eGraphics, pipeline); } void VulkanShader::Close() { owner->RemoveShader(this); shader = nullptr; device.destroyPipeline(pipeline); for(auto& shaderModule : shaderModules) { device.destroyShaderModule(shaderModule); } } }