I’m building a video game engine using C++ as the coding language and Vulkan for graphics. I am trying to set up a generic renderer using Vulkan that is flexible and will render objects based on a vector that is supplied to it. The renderer will also handle the creation of the window using GLFW and use GLM for all relevant math calls. I am using the ASSIMP library to load 3d models and animations.

I am in the process of converting the codebase from using vulkan.h to vulkan.hpp, as well as utilising RAII. Here is some of the code:

Pipeline.h:

#pragma once

#include <vulkan/vulkan.hpp>
#include <vector>
#include <array>
#include <stdexcept>
#include "Shader.h"

class Pipeline
{
public:
	Pipeline();
	~Pipeline();

	void CreateGraphicsPipeline(const std::vector<vk::VertexInputBindingDescription>& vertexBindingDescriptions,
		const std::vector<vk::VertexInputAttributeDescription>& vertexAttributeDescriptions,
		vk::Extent2D swapchainExtent,
		const std::vector<Shader*>& shaders,
		vk::RenderPass renderPass,
		vk::PipelineLayout pipelineLayout,
		vk::Device device);

	void Cleanup();

	vk::Pipeline GetPipeline() const;

	bool IsInitialized() const;

private:
	vk::Device device;
	vk::Pipeline pipeline;
	bool initialized;

	void CreateShaderStages(const std::vector<Shader*>& shaders, std::vector<vk::PipelineShaderStageCreateInfo>& shaderStages);
};

Pipeline.cpp:

#include "Pipeline.h"

Pipeline::Pipeline()
	: device(nullptr), pipeline(nullptr), initialized(false)
{
}

Pipeline::~Pipeline()
{
	Cleanup();
}

void Pipeline::CreateGraphicsPipeline(const std::vector<vk::VertexInputBindingDescription>& vertexBindingDescriptions,
	const std::vector<vk::VertexInputAttributeDescription>& vertexAttributeDescriptions,
	vk::Extent2D swapchainExtent,
	const std::vector<Shader*>& shaders,
	vk::RenderPass renderPass,
	vk::PipelineLayout pipelineLayout,
	vk::Device device)
{
	this->device = device;

	vk::PipelineVertexInputStateCreateInfo vertexInputInfo{};
	vertexInputInfo.vertexBindingDescriptionCount = static_cast<uint32_t>(vertexBindingDescriptions.size());
	vertexInputInfo.pVertexBindingDescriptions = vertexBindingDescriptions.data();
	vertexInputInfo.vertexAttributeDescriptionCount = static_cast<uint32_t>(vertexAttributeDescriptions.size());
	vertexInputInfo.pVertexAttributeDescriptions = vertexAttributeDescriptions.data();

	vk::PipelineInputAssemblyStateCreateInfo inputAssembly{};
	inputAssembly.topology = vk::PrimitiveTopology::eTriangleList;
	inputAssembly.primitiveRestartEnable = VK_FALSE;

	vk::Viewport viewport{};
	viewport.x = 0.0f;
	viewport.y = 0.0f;
	viewport.width = static_cast<float>(swapchainExtent.width);
	viewport.height = static_cast<float>(swapchainExtent.height);
	viewport.minDepth = 0.0f;
	viewport.maxDepth = 1.0f;

	vk::Rect2D scissor{};
	scissor.offset = { 0, 0 };
	scissor.extent = swapchainExtent;

	vk::PipelineViewportStateCreateInfo viewportState{};
	viewportState.viewportCount = 1;
	viewportState.pViewports = &viewport;
	viewportState.scissorCount = 1;
	viewportState.pScissors = &scissor;

	vk::PipelineRasterizationStateCreateInfo rasterizer{};
	rasterizer.depthClampEnable = VK_FALSE;
	rasterizer.rasterizerDiscardEnable = VK_FALSE;
	rasterizer.polygonMode = vk::PolygonMode::eFill;
	rasterizer.lineWidth = 1.0f;
	rasterizer.cullMode = vk::CullModeFlagBits::eBack;
	rasterizer.frontFace = vk::FrontFace::eCounterClockwise;
	rasterizer.depthBiasEnable = VK_FALSE;

	vk::PipelineMultisampleStateCreateInfo multisampling{};
	multisampling.sampleShadingEnable = VK_FALSE;
	multisampling.rasterizationSamples = vk::SampleCountFlagBits::e1;

	vk::PipelineColorBlendAttachmentState colorBlendAttachment{};
	colorBlendAttachment.colorWriteMask = vk::ColorComponentFlagBits::eR | vk::ColorComponentFlagBits::eG | vk::ColorComponentFlagBits::eB | vk::ColorComponentFlagBits::eA;
	colorBlendAttachment.blendEnable = VK_FALSE;

	vk::PipelineColorBlendStateCreateInfo colorBlending{};
	colorBlending.logicOpEnable = VK_FALSE;
	colorBlending.logicOp = vk::LogicOp::eCopy;
	colorBlending.attachmentCount = 1;
	colorBlending.pAttachments = &colorBlendAttachment;
	colorBlending.blendConstants[0] = 0.0f;
	colorBlending.blendConstants[1] = 0.0f;
	colorBlending.blendConstants[2] = 0.0f;
	colorBlending.blendConstants[3] = 0.0f;

	std::vector<vk::PipelineShaderStageCreateInfo> shaderStages;
	CreateShaderStages(shaders, shaderStages);

	vk::GraphicsPipelineCreateInfo pipelineCreateInfo{};
	pipelineCreateInfo.stageCount = static_cast<uint32_t>(shaderStages.size());
	pipelineCreateInfo.pStages = shaderStages.data();
	pipelineCreateInfo.pVertexInputState = &vertexInputInfo;
	pipelineCreateInfo.pInputAssemblyState = &inputAssembly;
	pipelineCreateInfo.pViewportState = &viewportState;
	pipelineCreateInfo.pRasterizationState = &rasterizer;
	pipelineCreateInfo.pMultisampleState = &multisampling;
	pipelineCreateInfo.pColorBlendState = &colorBlending;
	pipelineCreateInfo.layout = pipelineLayout;
	pipelineCreateInfo.renderPass = renderPass;
	pipelineCreateInfo.subpass = 0;

	pipeline = device.createGraphicsPipeline(nullptr, pipelineCreateInfo);

	initialized = true;
}

bool Pipeline::IsInitialized() const
{
	return initialized;
}

void Pipeline::Cleanup()
{
	if (pipeline != nullptr && initialized)
	{
		device.destroyPipeline(pipeline, nullptr);
		pipeline = nullptr;
		initialized = false;
	}
}

vk::Pipeline Pipeline::GetPipeline() const
{
	return pipeline;
}

void Pipeline::CreateShaderStages(const std::vector<Shader*>& shaders, std::vector<vk::PipelineShaderStageCreateInfo>& shaderStages)
{
	for (auto shader : shaders)
	{
		shaderStages.push_back(shader->GetPipelineShaderStageCreateInfo());
	}
}


I am getting some errors in the following part of the Pipeline::CreateGraphicsPipeline function:

scissor.offset = { 0, 0 };

pipeline = device.createGraphicsPipeline(nullptr, pipelineCreateInfo);

It says more than one operator "=" matches these operands. How can these issues be fixed?