88 lines
3.9 KiB
C++
88 lines
3.9 KiB
C++
/*
|
|
* 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<vk::ShaderStageFlagBits>(static_cast<uint32_t>(shaderProgram.type)), shaderModule, "main"};
|
|
i++;
|
|
}
|
|
BuildPipeline();
|
|
}
|
|
|
|
void VulkanShader::BuildPipeline()
|
|
{
|
|
vk::VertexInputBindingDescription vertexBindDesc(0, sizeof(Vertex), vk::VertexInputRate::eVertex);
|
|
std::vector<vk::VertexInputAttributeDescription> 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<uint32_t>(attributeDescriptions.size()), attributeDescriptions.data() };
|
|
vk::PipelineInputAssemblyStateCreateInfo inputAssembly = { {}, static_cast<vk::PrimitiveTopology>(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<uint32_t>(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);
|
|
}
|
|
}
|
|
} |