Add Device and Window abstraction
This commit is contained in:
@@ -1,4 +1,4 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||||
<ItemGroup Label="ProjectConfigurations">
|
<ItemGroup Label="ProjectConfigurations">
|
||||||
<ProjectConfiguration Include="Debug|Win32">
|
<ProjectConfiguration Include="Debug|Win32">
|
||||||
@@ -166,6 +166,9 @@
|
|||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ClCompile Include="src\copium\core\Application.cpp" />
|
<ClCompile Include="src\copium\core\Application.cpp" />
|
||||||
<ClCompile Include="src\copium\buffer\Buffer.cpp" />
|
<ClCompile Include="src\copium\buffer\Buffer.cpp" />
|
||||||
|
<ClCompile Include="src\copium\core\Device.cpp" />
|
||||||
|
<ClCompile Include="src\copium\core\Vulkan.cpp" />
|
||||||
|
<ClCompile Include="src\copium\core\Window.cpp" />
|
||||||
<ClCompile Include="src\copium\mesh\Mesh.cpp" />
|
<ClCompile Include="src\copium\mesh\Mesh.cpp" />
|
||||||
<ClCompile Include="src\copium\sampler\ColorAttachment.cpp" />
|
<ClCompile Include="src\copium\sampler\ColorAttachment.cpp" />
|
||||||
<ClCompile Include="src\copium\buffer\CommandBuffer.cpp" />
|
<ClCompile Include="src\copium\buffer\CommandBuffer.cpp" />
|
||||||
@@ -195,6 +198,10 @@
|
|||||||
<ClCompile Include="src\copium\mesh\VertexPassthrough.cpp" />
|
<ClCompile Include="src\copium\mesh\VertexPassthrough.cpp" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
|
<ClInclude Include="src\copium\core\VulkanCore.h" />
|
||||||
|
<ClInclude Include="src\copium\core\Device.h" />
|
||||||
|
<ClInclude Include="src\copium\core\Vulkan.h" />
|
||||||
|
<ClInclude Include="src\copium\core\Window.h" />
|
||||||
<ClInclude Include="src\copium\mesh\Mesh.h" />
|
<ClInclude Include="src\copium\mesh\Mesh.h" />
|
||||||
<ClInclude Include="src\copium\sampler\DepthAttachment.h" />
|
<ClInclude Include="src\copium\sampler\DepthAttachment.h" />
|
||||||
<ClInclude Include="src\copium\core\Application.h" />
|
<ClInclude Include="src\copium\core\Application.h" />
|
||||||
|
|||||||
@@ -102,6 +102,15 @@
|
|||||||
<ClCompile Include="src\copium\mesh\Mesh.cpp">
|
<ClCompile Include="src\copium\mesh\Mesh.cpp">
|
||||||
<Filter>Source Files</Filter>
|
<Filter>Source Files</Filter>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
|
<ClCompile Include="src\copium\core\Device.cpp">
|
||||||
|
<Filter>Source Files</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="src\copium\core\Window.cpp">
|
||||||
|
<Filter>Source Files</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="src\copium\core\Vulkan.cpp">
|
||||||
|
<Filter>Source Files</Filter>
|
||||||
|
</ClCompile>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ClInclude Include="src\copium\sampler\DepthAttachment.h">
|
<ClInclude Include="src\copium\sampler\DepthAttachment.h">
|
||||||
@@ -194,6 +203,18 @@
|
|||||||
<ClInclude Include="src\copium\mesh\Mesh.h">
|
<ClInclude Include="src\copium\mesh\Mesh.h">
|
||||||
<Filter>Header Files</Filter>
|
<Filter>Header Files</Filter>
|
||||||
</ClInclude>
|
</ClInclude>
|
||||||
|
<ClInclude Include="src\copium\core\Window.h">
|
||||||
|
<Filter>Header Files</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
<ClInclude Include="src\copium\core\Vulkan.h">
|
||||||
|
<Filter>Header Files</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
<ClInclude Include="src\copium\core\Device.h">
|
||||||
|
<Filter>Header Files</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
<ClInclude Include="src\copium\core\VulkanCore.h">
|
||||||
|
<Filter>Header Files</Filter>
|
||||||
|
</ClInclude>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<None Include="res\shaders\shader.frag" />
|
<None Include="res\shaders\shader.frag" />
|
||||||
|
|||||||
@@ -1,9 +1,12 @@
|
|||||||
#include "copium/buffer/Buffer.h"
|
#include "copium/buffer/Buffer.h"
|
||||||
|
|
||||||
|
#include "copium/core/Device.h"
|
||||||
|
#include "copium/core/Instance.h"
|
||||||
|
|
||||||
namespace Copium
|
namespace Copium
|
||||||
{
|
{
|
||||||
Buffer::Buffer(Instance& instance, VkBufferUsageFlags usage, VkMemoryPropertyFlags properties, VkDeviceSize size, int count)
|
Buffer::Buffer(Vulkan& vulkan, VkBufferUsageFlags usage, VkMemoryPropertyFlags properties, VkDeviceSize size, int count)
|
||||||
: instance{instance}, size{size}, count{count}
|
: vulkan{vulkan}, size{size}, count{count}
|
||||||
{
|
{
|
||||||
VkBufferCreateInfo createInfo{};
|
VkBufferCreateInfo createInfo{};
|
||||||
createInfo.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO;
|
createInfo.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO;
|
||||||
@@ -11,25 +14,25 @@ namespace Copium
|
|||||||
createInfo.usage = usage;
|
createInfo.usage = usage;
|
||||||
createInfo.sharingMode = VK_SHARING_MODE_EXCLUSIVE;
|
createInfo.sharingMode = VK_SHARING_MODE_EXCLUSIVE;
|
||||||
|
|
||||||
CP_VK_ASSERT(vkCreateBuffer(instance.GetDevice(), &createInfo, nullptr, &handle), "Buffer : Failed to initialize buffer");
|
CP_VK_ASSERT(vkCreateBuffer(vulkan.GetDevice(), &createInfo, nullptr, &handle), "Buffer : Failed to initialize buffer");
|
||||||
|
|
||||||
VkMemoryRequirements memoryRequirements;
|
VkMemoryRequirements memoryRequirements;
|
||||||
vkGetBufferMemoryRequirements(instance.GetDevice(), handle, &memoryRequirements);
|
vkGetBufferMemoryRequirements(vulkan.GetDevice(), handle, &memoryRequirements);
|
||||||
|
|
||||||
VkMemoryAllocateInfo allocateInfo{};
|
VkMemoryAllocateInfo allocateInfo{};
|
||||||
allocateInfo.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO;
|
allocateInfo.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO;
|
||||||
allocateInfo.allocationSize = memoryRequirements.size;
|
allocateInfo.allocationSize = memoryRequirements.size;
|
||||||
allocateInfo.memoryTypeIndex = instance.FindMemoryType(memoryRequirements.memoryTypeBits, properties);
|
allocateInfo.memoryTypeIndex = vulkan.GetDevice().FindMemoryType(memoryRequirements.memoryTypeBits, properties);
|
||||||
|
|
||||||
CP_VK_ASSERT(vkAllocateMemory(instance.GetDevice(), &allocateInfo, nullptr, &memory), "Buffer : Failed to allocate buffer memory");
|
CP_VK_ASSERT(vkAllocateMemory(vulkan.GetDevice(), &allocateInfo, nullptr, &memory), "Buffer : Failed to allocate buffer memory");
|
||||||
|
|
||||||
vkBindBufferMemory(instance.GetDevice(), handle, memory, 0);
|
vkBindBufferMemory(vulkan.GetDevice(), handle, memory, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
Buffer::~Buffer()
|
Buffer::~Buffer()
|
||||||
{
|
{
|
||||||
vkFreeMemory(instance.GetDevice(), memory, nullptr);
|
vkFreeMemory(vulkan.GetDevice(), memory, nullptr);
|
||||||
vkDestroyBuffer(instance.GetDevice(), handle, nullptr);
|
vkDestroyBuffer(vulkan.GetDevice(), handle, nullptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Buffer::Update(void* indexData, int index)
|
void Buffer::Update(void* indexData, int index)
|
||||||
@@ -39,9 +42,9 @@ namespace Copium
|
|||||||
if (mappedData == nullptr)
|
if (mappedData == nullptr)
|
||||||
{
|
{
|
||||||
void* data;
|
void* data;
|
||||||
vkMapMemory(instance.GetDevice(), memory, index * size, size, 0, &data);
|
vkMapMemory(vulkan.GetDevice(), memory, index * size, size, 0, &data);
|
||||||
memcpy(data, indexData, size);
|
memcpy(data, indexData, size);
|
||||||
vkUnmapMemory(instance.GetDevice(), memory);
|
vkUnmapMemory(vulkan.GetDevice(), memory);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@@ -52,26 +55,26 @@ namespace Copium
|
|||||||
void Buffer::UpdateStaging(void* data)
|
void Buffer::UpdateStaging(void* data)
|
||||||
{
|
{
|
||||||
VkDeviceSize bufferSize = size * count;
|
VkDeviceSize bufferSize = size * count;
|
||||||
Buffer stagingBuffer{instance, VK_BUFFER_USAGE_TRANSFER_SRC_BIT, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT, bufferSize, 1};
|
Buffer stagingBuffer{vulkan, VK_BUFFER_USAGE_TRANSFER_SRC_BIT, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT, bufferSize, 1};
|
||||||
|
|
||||||
stagingBuffer.Update(data, 0);
|
stagingBuffer.Update(data, 0);
|
||||||
|
|
||||||
CopyBuffer(instance, stagingBuffer, *this, 0, bufferSize);
|
CopyBuffer(vulkan, stagingBuffer, *this, 0, bufferSize);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Buffer::UpdateStaging(void* data, VkDeviceSize offset, VkDeviceSize size)
|
void Buffer::UpdateStaging(void* data, VkDeviceSize offset, VkDeviceSize size)
|
||||||
{
|
{
|
||||||
Buffer stagingBuffer{instance, VK_BUFFER_USAGE_TRANSFER_SRC_BIT, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT, size, 1};
|
Buffer stagingBuffer{vulkan, VK_BUFFER_USAGE_TRANSFER_SRC_BIT, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT, size, 1};
|
||||||
|
|
||||||
stagingBuffer.Update(data, 0);
|
stagingBuffer.Update(data, 0);
|
||||||
|
|
||||||
CopyBuffer(instance, stagingBuffer, *this, offset, size);
|
CopyBuffer(vulkan, stagingBuffer, *this, offset, size);
|
||||||
}
|
}
|
||||||
|
|
||||||
void* Buffer::Map()
|
void* Buffer::Map()
|
||||||
{
|
{
|
||||||
CP_ASSERT(mappedData == nullptr, "Map : Mapping an already mapped buffer");
|
CP_ASSERT(mappedData == nullptr, "Map : Mapping an already mapped buffer");
|
||||||
vkMapMemory(instance.GetDevice(), memory, 0, size * count, 0, &mappedData);
|
vkMapMemory(vulkan.GetDevice(), memory, 0, size * count, 0, &mappedData);
|
||||||
return mappedData;
|
return mappedData;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -79,7 +82,7 @@ namespace Copium
|
|||||||
{
|
{
|
||||||
CP_ASSERT(mappedData != nullptr, "Unmap : Unmapping an already unmapped buffer");
|
CP_ASSERT(mappedData != nullptr, "Unmap : Unmapping an already unmapped buffer");
|
||||||
|
|
||||||
vkUnmapMemory(instance.GetDevice(), memory);
|
vkUnmapMemory(vulkan.GetDevice(), memory);
|
||||||
mappedData = nullptr;
|
mappedData = nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -99,17 +102,17 @@ namespace Copium
|
|||||||
return size * (VkDeviceSize)index;
|
return size * (VkDeviceSize)index;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Buffer::CopyBuffer(Instance& instance, const Buffer& srcBuffer, const Buffer& dstBuffer, VkDeviceSize offset, VkDeviceSize size)
|
void Buffer::CopyBuffer(Vulkan& vulkan, const Buffer& srcBuffer, const Buffer& dstBuffer, VkDeviceSize offset, VkDeviceSize size)
|
||||||
{
|
{
|
||||||
VkCommandBufferAllocateInfo allocateInfo{};
|
VkCommandBufferAllocateInfo allocateInfo{};
|
||||||
|
|
||||||
allocateInfo.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO;
|
allocateInfo.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO;
|
||||||
allocateInfo.level = VK_COMMAND_BUFFER_LEVEL_PRIMARY;
|
allocateInfo.level = VK_COMMAND_BUFFER_LEVEL_PRIMARY;
|
||||||
allocateInfo.commandPool = instance.GetCommandPool();
|
allocateInfo.commandPool = vulkan.GetDevice().GetCommandPool();
|
||||||
allocateInfo.commandBufferCount = 1;
|
allocateInfo.commandBufferCount = 1;
|
||||||
|
|
||||||
VkCommandBuffer commandBuffer;
|
VkCommandBuffer commandBuffer;
|
||||||
CP_VK_ASSERT(vkAllocateCommandBuffers(instance.GetDevice(), &allocateInfo, &commandBuffer), "CopyBuffer : Failed to initialize command buffer");
|
CP_VK_ASSERT(vkAllocateCommandBuffers(vulkan.GetDevice(), &allocateInfo, &commandBuffer), "CopyBuffer : Failed to initialize command buffer");
|
||||||
|
|
||||||
VkCommandBufferBeginInfo beginInfo{};
|
VkCommandBufferBeginInfo beginInfo{};
|
||||||
beginInfo.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
|
beginInfo.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
|
||||||
@@ -131,9 +134,9 @@ namespace Copium
|
|||||||
submitInfo.commandBufferCount = 1;
|
submitInfo.commandBufferCount = 1;
|
||||||
submitInfo.pCommandBuffers = &commandBuffer;
|
submitInfo.pCommandBuffers = &commandBuffer;
|
||||||
|
|
||||||
vkQueueSubmit(instance.GetGraphicsQueue(), 1, &submitInfo, VK_NULL_HANDLE);
|
vkQueueSubmit(vulkan.GetDevice().GetGraphicsQueue(), 1, &submitInfo, VK_NULL_HANDLE);
|
||||||
vkQueueWaitIdle(instance.GetGraphicsQueue());
|
vkQueueWaitIdle(vulkan.GetDevice().GetGraphicsQueue());
|
||||||
|
|
||||||
vkFreeCommandBuffers(instance.GetDevice(), instance.GetCommandPool(), 1, &commandBuffer);
|
vkFreeCommandBuffers(vulkan.GetDevice(), vulkan.GetDevice().GetCommandPool(), 1, &commandBuffer);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "copium/core/Instance.h"
|
#include "copium/core/Vulkan.h"
|
||||||
#include "copium/util/Common.h"
|
#include "copium/util/Common.h"
|
||||||
|
|
||||||
#include <vulkan/vulkan.hpp>
|
#include <vulkan/vulkan.hpp>
|
||||||
@@ -11,7 +11,7 @@ namespace Copium
|
|||||||
{
|
{
|
||||||
CP_DELETE_COPY_AND_MOVE_CTOR(Buffer);
|
CP_DELETE_COPY_AND_MOVE_CTOR(Buffer);
|
||||||
protected:
|
protected:
|
||||||
Instance& instance;
|
Vulkan& vulkan;
|
||||||
|
|
||||||
VkDeviceMemory memory;
|
VkDeviceMemory memory;
|
||||||
VkBuffer handle;
|
VkBuffer handle;
|
||||||
@@ -21,7 +21,7 @@ namespace Copium
|
|||||||
void* mappedData = nullptr;
|
void* mappedData = nullptr;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
Buffer(Instance& instance, VkBufferUsageFlags usage, VkMemoryPropertyFlags properties, VkDeviceSize size, int count);
|
Buffer(Vulkan& vulkan, VkBufferUsageFlags usage, VkMemoryPropertyFlags properties, VkDeviceSize size, int count);
|
||||||
virtual ~Buffer();
|
virtual ~Buffer();
|
||||||
|
|
||||||
void Update(void* indexData, int index);
|
void Update(void* indexData, int index);
|
||||||
@@ -35,6 +35,6 @@ namespace Copium
|
|||||||
VkDeviceSize GetSize() const;
|
VkDeviceSize GetSize() const;
|
||||||
VkDeviceSize GetPosition(int index) const;
|
VkDeviceSize GetPosition(int index) const;
|
||||||
|
|
||||||
static void CopyBuffer(Instance& instance, const Buffer& srcBuffer, const Buffer& dstBuffer, VkDeviceSize offset, VkDeviceSize size);
|
static void CopyBuffer(Vulkan& vulkan, const Buffer& srcBuffer, const Buffer& dstBuffer, VkDeviceSize offset, VkDeviceSize size);
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,26 +1,37 @@
|
|||||||
#include "copium/buffer/CommandBuffer.h"
|
#include "copium/buffer/CommandBuffer.h"
|
||||||
|
|
||||||
|
#include "copium/core/Device.h"
|
||||||
|
#include "copium/core/Instance.h"
|
||||||
|
#include "copium/core/SwapChain.h"
|
||||||
|
|
||||||
namespace Copium
|
namespace Copium
|
||||||
{
|
{
|
||||||
CommandBuffer::CommandBuffer(Instance& instance, Type type)
|
CommandBuffer::CommandBuffer(Vulkan& vulkan, Type type)
|
||||||
: instance{instance}, type{type}
|
: vulkan{vulkan}, type{type}
|
||||||
{
|
{
|
||||||
if (type == Type::Dynamic)
|
switch (type)
|
||||||
commandBuffers.resize(instance.GetMaxFramesInFlight());
|
{
|
||||||
else
|
case Type::SingleUse:
|
||||||
commandBuffers.resize(1);
|
commandBuffers.resize(1);
|
||||||
|
break;
|
||||||
|
case Type::Dynamic:
|
||||||
|
commandBuffers.resize(SwapChain::MAX_FRAMES_IN_FLIGHT);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
CP_ABORT("CommandBuffer : Unreachable switch case");
|
||||||
|
}
|
||||||
|
|
||||||
VkCommandBufferAllocateInfo allocateInfo{};
|
VkCommandBufferAllocateInfo allocateInfo{};
|
||||||
allocateInfo.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO;
|
allocateInfo.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO;
|
||||||
allocateInfo.level = VK_COMMAND_BUFFER_LEVEL_PRIMARY;
|
allocateInfo.level = VK_COMMAND_BUFFER_LEVEL_PRIMARY;
|
||||||
allocateInfo.commandPool = instance.GetCommandPool();
|
allocateInfo.commandPool = vulkan.GetDevice().GetCommandPool();
|
||||||
allocateInfo.commandBufferCount = commandBuffers.size();
|
allocateInfo.commandBufferCount = commandBuffers.size();
|
||||||
CP_VK_ASSERT(vkAllocateCommandBuffers(instance.GetDevice(), &allocateInfo, commandBuffers.data()), "CommandBuffer : Failed to allocate CommandBuffer");
|
CP_VK_ASSERT(vkAllocateCommandBuffers(vulkan.GetDevice(), &allocateInfo, commandBuffers.data()), "CommandBuffer : Failed to allocate CommandBuffer");
|
||||||
}
|
}
|
||||||
|
|
||||||
CommandBuffer::~CommandBuffer()
|
CommandBuffer::~CommandBuffer()
|
||||||
{
|
{
|
||||||
vkFreeCommandBuffers(instance.GetDevice(), instance.GetCommandPool(), commandBuffers.size(), commandBuffers.data());
|
vkFreeCommandBuffers(vulkan.GetDevice(), vulkan.GetDevice().GetCommandPool(), commandBuffers.size(), commandBuffers.data());
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: Test as constexpr function to see if it avoids the switch case
|
// TODO: Test as constexpr function to see if it avoids the switch case
|
||||||
@@ -30,26 +41,25 @@ namespace Copium
|
|||||||
beginInfo.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
|
beginInfo.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
|
||||||
beginInfo.flags = 0;
|
beginInfo.flags = 0;
|
||||||
beginInfo.pInheritanceInfo = nullptr;
|
beginInfo.pInheritanceInfo = nullptr;
|
||||||
|
|
||||||
switch (type)
|
switch (type)
|
||||||
{
|
{
|
||||||
case Type::SingleUse:
|
case Type::SingleUse:
|
||||||
beginInfo.flags = VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT;
|
beginInfo.flags = VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT;
|
||||||
currentCommandBuffer = commandBuffers.front();
|
|
||||||
break;
|
break;
|
||||||
case Type::Dynamic:
|
case Type::Dynamic:
|
||||||
currentCommandBuffer = commandBuffers[instance.GetFlightIndex()];
|
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
CP_ABORT("Begin : Unreachable switch case");
|
CP_ABORT("Begin : Unreachable switch case");
|
||||||
}
|
}
|
||||||
|
|
||||||
vkResetCommandBuffer(currentCommandBuffer, 0);
|
vkResetCommandBuffer(commandBuffers[vulkan.GetSwapChain().GetFlightIndex()], 0);
|
||||||
CP_VK_ASSERT(vkBeginCommandBuffer(currentCommandBuffer, &beginInfo), "Begin : Failed to begin command buffer");
|
CP_VK_ASSERT(vkBeginCommandBuffer(commandBuffers[vulkan.GetSwapChain().GetFlightIndex()], &beginInfo), "Begin : Failed to begin command buffer");
|
||||||
}
|
}
|
||||||
|
|
||||||
void CommandBuffer::End()
|
void CommandBuffer::End()
|
||||||
{
|
{
|
||||||
vkEndCommandBuffer(currentCommandBuffer);
|
vkEndCommandBuffer(commandBuffers[vulkan.GetSwapChain().GetFlightIndex()]);
|
||||||
}
|
}
|
||||||
|
|
||||||
void CommandBuffer::Submit()
|
void CommandBuffer::Submit()
|
||||||
@@ -57,20 +67,15 @@ namespace Copium
|
|||||||
VkSubmitInfo submitInfo{};
|
VkSubmitInfo submitInfo{};
|
||||||
submitInfo.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
|
submitInfo.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
|
||||||
submitInfo.commandBufferCount = 1;
|
submitInfo.commandBufferCount = 1;
|
||||||
submitInfo.pCommandBuffers = ¤tCommandBuffer;
|
submitInfo.pCommandBuffers = &commandBuffers[vulkan.GetSwapChain().GetFlightIndex()];
|
||||||
|
|
||||||
vkQueueSubmit(instance.GetGraphicsQueue(), 1, &submitInfo, VK_NULL_HANDLE);
|
vkQueueSubmit(vulkan.GetDevice().GetGraphicsQueue(), 1, &submitInfo, VK_NULL_HANDLE);
|
||||||
// TODO: if singleUse?
|
// TODO: if singleUse?
|
||||||
vkQueueWaitIdle(instance.GetGraphicsQueue());
|
vkQueueWaitIdle(vulkan.GetDevice().GetGraphicsQueue());
|
||||||
}
|
|
||||||
|
|
||||||
void CommandBuffer::SubmitAsGraphicsQueue()
|
|
||||||
{
|
|
||||||
instance.SubmitGraphicsQueue({currentCommandBuffer});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
CommandBuffer::operator VkCommandBuffer() const
|
CommandBuffer::operator VkCommandBuffer() const
|
||||||
{
|
{
|
||||||
return currentCommandBuffer;
|
return commandBuffers[vulkan.GetSwapChain().GetFlightIndex()];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "copium/core/Instance.h"
|
#include "copium/core/Vulkan.h"
|
||||||
#include "copium/util/Common.h"
|
#include "copium/util/Common.h"
|
||||||
|
|
||||||
#include <vulkan/vulkan.hpp>
|
#include <vulkan/vulkan.hpp>
|
||||||
@@ -16,21 +16,18 @@ namespace Copium
|
|||||||
SingleUse, Dynamic
|
SingleUse, Dynamic
|
||||||
};
|
};
|
||||||
private:
|
private:
|
||||||
Instance& instance;
|
Vulkan& vulkan;
|
||||||
|
|
||||||
std::vector<VkCommandBuffer> commandBuffers;
|
std::vector<VkCommandBuffer> commandBuffers;
|
||||||
const Type type;
|
const Type type;
|
||||||
VkCommandBuffer currentCommandBuffer{VK_NULL_HANDLE};
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
CommandBuffer(Instance& instance, Type type);
|
CommandBuffer(Vulkan& vulkan, Type type);
|
||||||
|
|
||||||
virtual ~CommandBuffer();
|
virtual ~CommandBuffer();
|
||||||
|
|
||||||
void Begin();
|
void Begin();
|
||||||
void End();
|
void End();
|
||||||
void Submit();
|
void Submit();
|
||||||
void SubmitAsGraphicsQueue();
|
|
||||||
|
|
||||||
operator VkCommandBuffer() const;
|
operator VkCommandBuffer() const;
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -2,8 +2,8 @@
|
|||||||
|
|
||||||
namespace Copium
|
namespace Copium
|
||||||
{
|
{
|
||||||
CommandBufferScoped::CommandBufferScoped(Instance& instance)
|
CommandBufferScoped::CommandBufferScoped(Vulkan& vulkan)
|
||||||
: CommandBuffer{instance, Type::SingleUse}
|
: CommandBuffer{vulkan, Type::SingleUse}
|
||||||
{
|
{
|
||||||
CommandBuffer::Begin();
|
CommandBuffer::Begin();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "copium/buffer/CommandBuffer.h"
|
#include "copium/buffer/CommandBuffer.h"
|
||||||
#include "copium/core/Instance.h"
|
#include "copium/core/Vulkan.h"
|
||||||
#include "copium/util/Common.h"
|
#include "copium/util/Common.h"
|
||||||
|
|
||||||
namespace Copium
|
namespace Copium
|
||||||
@@ -10,7 +10,7 @@ namespace Copium
|
|||||||
{
|
{
|
||||||
CP_DELETE_COPY_AND_MOVE_CTOR(CommandBufferScoped);
|
CP_DELETE_COPY_AND_MOVE_CTOR(CommandBufferScoped);
|
||||||
public:
|
public:
|
||||||
CommandBufferScoped(Instance& instance);
|
CommandBufferScoped(Vulkan& vulkan);
|
||||||
|
|
||||||
~CommandBufferScoped() override;
|
~CommandBufferScoped() override;
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -1,12 +1,14 @@
|
|||||||
#include "copium/buffer/Framebuffer.h"
|
#include "copium/buffer/Framebuffer.h"
|
||||||
|
|
||||||
#include "copium/buffer/CommandBuffer.h"
|
#include "copium/buffer/CommandBuffer.h"
|
||||||
|
#include "copium/core/Device.h"
|
||||||
|
#include "copium/core/SwapChain.h"
|
||||||
#include "copium/sampler/Image.h"
|
#include "copium/sampler/Image.h"
|
||||||
|
|
||||||
namespace Copium
|
namespace Copium
|
||||||
{
|
{
|
||||||
Framebuffer::Framebuffer(Instance& instance, uint32_t width, uint32_t height)
|
Framebuffer::Framebuffer(Vulkan& vulkan, uint32_t width, uint32_t height)
|
||||||
: instance{instance}, width{width}, height{height}
|
: vulkan{vulkan}, width{width}, height{height}
|
||||||
{
|
{
|
||||||
InitializeImage();
|
InitializeImage();
|
||||||
InitializeDepthBuffer();
|
InitializeDepthBuffer();
|
||||||
@@ -17,19 +19,19 @@ namespace Copium
|
|||||||
Framebuffer::~Framebuffer()
|
Framebuffer::~Framebuffer()
|
||||||
{
|
{
|
||||||
for (auto& framebuffer : framebuffers)
|
for (auto& framebuffer : framebuffers)
|
||||||
vkDestroyFramebuffer(instance.GetDevice(), framebuffer, nullptr);
|
vkDestroyFramebuffer(vulkan.GetDevice(), framebuffer, nullptr);
|
||||||
vkDestroyRenderPass(instance.GetDevice(), renderPass, nullptr);
|
vkDestroyRenderPass(vulkan.GetDevice(), renderPass, nullptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Framebuffer::Resize(uint32_t width, uint32_t height)
|
void Framebuffer::Resize(uint32_t width, uint32_t height)
|
||||||
{
|
{
|
||||||
vkDeviceWaitIdle(instance.GetDevice());
|
vkDeviceWaitIdle(vulkan.GetDevice());
|
||||||
this->width = width;
|
this->width = width;
|
||||||
this->height = height;
|
this->height = height;
|
||||||
colorAttachment.reset();
|
colorAttachment.reset();
|
||||||
depthAttachment.reset();
|
depthAttachment.reset();
|
||||||
for (auto&& framebuffer : framebuffers)
|
for (auto&& framebuffer : framebuffers)
|
||||||
vkDestroyFramebuffer(instance.GetDevice(), framebuffer, nullptr);
|
vkDestroyFramebuffer(vulkan.GetDevice(), framebuffer, nullptr);
|
||||||
InitializeImage();
|
InitializeImage();
|
||||||
InitializeDepthBuffer();
|
InitializeDepthBuffer();
|
||||||
InitializeFramebuffers();
|
InitializeFramebuffers();
|
||||||
@@ -44,7 +46,8 @@ namespace Copium
|
|||||||
VkRenderPassBeginInfo renderPassBeginInfo{};
|
VkRenderPassBeginInfo renderPassBeginInfo{};
|
||||||
renderPassBeginInfo.sType = VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO;
|
renderPassBeginInfo.sType = VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO;
|
||||||
renderPassBeginInfo.renderPass = renderPass;
|
renderPassBeginInfo.renderPass = renderPass;
|
||||||
renderPassBeginInfo.framebuffer = framebuffers[instance.GetFlightIndex()];
|
renderPassBeginInfo.framebuffer = framebuffers[vulkan.GetSwapChain().GetFlightIndex()];
|
||||||
|
;
|
||||||
renderPassBeginInfo.renderArea.offset = {0, 0};
|
renderPassBeginInfo.renderArea.offset = {0, 0};
|
||||||
renderPassBeginInfo.renderArea.extent = {width, height};
|
renderPassBeginInfo.renderArea.extent = {width, height};
|
||||||
renderPassBeginInfo.clearValueCount = clearValues.size();
|
renderPassBeginInfo.clearValueCount = clearValues.size();
|
||||||
@@ -77,7 +80,7 @@ namespace Copium
|
|||||||
|
|
||||||
VkFramebuffer Framebuffer::GetFramebuffer() const
|
VkFramebuffer Framebuffer::GetFramebuffer() const
|
||||||
{
|
{
|
||||||
return framebuffers[instance.GetFlightIndex()];
|
return framebuffers[vulkan.GetSwapChain().GetFlightIndex()];
|
||||||
}
|
}
|
||||||
|
|
||||||
const ColorAttachment& Framebuffer::GetColorAttachment() const
|
const ColorAttachment& Framebuffer::GetColorAttachment() const
|
||||||
@@ -97,12 +100,12 @@ namespace Copium
|
|||||||
|
|
||||||
void Framebuffer::InitializeImage()
|
void Framebuffer::InitializeImage()
|
||||||
{
|
{
|
||||||
colorAttachment = std::make_unique<ColorAttachment>(instance, width, height);
|
colorAttachment = std::make_unique<ColorAttachment>(vulkan, width, height);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Framebuffer::InitializeDepthBuffer()
|
void Framebuffer::InitializeDepthBuffer()
|
||||||
{
|
{
|
||||||
depthAttachment = std::make_unique<DepthAttachment>(instance, width, height);
|
depthAttachment = std::make_unique<DepthAttachment>(vulkan, width, height);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Framebuffer::InitializeRenderPass()
|
void Framebuffer::InitializeRenderPass()
|
||||||
@@ -118,7 +121,7 @@ namespace Copium
|
|||||||
colorAttachment.finalLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL;
|
colorAttachment.finalLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL;
|
||||||
|
|
||||||
VkAttachmentDescription depthAttachment{};
|
VkAttachmentDescription depthAttachment{};
|
||||||
depthAttachment.format = Image::SelectDepthFormat(instance);
|
depthAttachment.format = Image::SelectDepthFormat(vulkan);
|
||||||
depthAttachment.samples = VK_SAMPLE_COUNT_1_BIT;
|
depthAttachment.samples = VK_SAMPLE_COUNT_1_BIT;
|
||||||
depthAttachment.loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR;
|
depthAttachment.loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR;
|
||||||
depthAttachment.storeOp = VK_ATTACHMENT_STORE_OP_STORE;
|
depthAttachment.storeOp = VK_ATTACHMENT_STORE_OP_STORE;
|
||||||
@@ -166,14 +169,13 @@ namespace Copium
|
|||||||
renderPassCreateInfo.dependencyCount = dependencies.size();
|
renderPassCreateInfo.dependencyCount = dependencies.size();
|
||||||
renderPassCreateInfo.pDependencies = dependencies.data();
|
renderPassCreateInfo.pDependencies = dependencies.data();
|
||||||
|
|
||||||
CP_VK_ASSERT(vkCreateRenderPass(instance.GetDevice(), &renderPassCreateInfo, nullptr, &renderPass), "InitializeRenderPass : Failed to initialze render pass");
|
CP_VK_ASSERT(vkCreateRenderPass(vulkan.GetDevice(), &renderPassCreateInfo, nullptr, &renderPass), "InitializeRenderPass : Failed to initialze render pass");
|
||||||
}
|
}
|
||||||
|
|
||||||
void Framebuffer::InitializeFramebuffers()
|
void Framebuffer::InitializeFramebuffers()
|
||||||
{
|
{
|
||||||
framebuffers.resize(instance.GetMaxFramesInFlight());
|
framebuffers.resize(SwapChain::MAX_FRAMES_IN_FLIGHT);
|
||||||
|
for (size_t i = 0; i < framebuffers.size(); ++i)
|
||||||
for (size_t i = 0; i < instance.GetMaxFramesInFlight(); ++i)
|
|
||||||
{
|
{
|
||||||
std::vector<VkImageView> attachments{colorAttachment->GetImageView(i), depthAttachment->GetImageView()};
|
std::vector<VkImageView> attachments{colorAttachment->GetImageView(i), depthAttachment->GetImageView()};
|
||||||
|
|
||||||
@@ -186,7 +188,7 @@ namespace Copium
|
|||||||
createInfo.height = height;
|
createInfo.height = height;
|
||||||
createInfo.layers = 1;
|
createInfo.layers = 1;
|
||||||
|
|
||||||
CP_VK_ASSERT(vkCreateFramebuffer(instance.GetDevice(), &createInfo, nullptr, &framebuffers[i]), "InitializeFramebuffers : Failed to initialize framebuffer");
|
CP_VK_ASSERT(vkCreateFramebuffer(vulkan.GetDevice(), &createInfo, nullptr, &framebuffers[i]), "InitializeFramebuffers : Failed to initialize framebuffer");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1,6 +1,7 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "copium/core/Instance.h"
|
#include "copium/buffer/CommandBuffer.h"
|
||||||
|
#include "copium/core/Vulkan.h"
|
||||||
#include "copium/sampler/ColorAttachment.h"
|
#include "copium/sampler/ColorAttachment.h"
|
||||||
#include "copium/sampler/DepthAttachment.h"
|
#include "copium/sampler/DepthAttachment.h"
|
||||||
#include "copium/util/Common.h"
|
#include "copium/util/Common.h"
|
||||||
@@ -13,7 +14,7 @@ namespace Copium
|
|||||||
{
|
{
|
||||||
CP_DELETE_COPY_AND_MOVE_CTOR(Framebuffer);
|
CP_DELETE_COPY_AND_MOVE_CTOR(Framebuffer);
|
||||||
private:
|
private:
|
||||||
Instance& instance;
|
Vulkan& vulkan;
|
||||||
|
|
||||||
std::unique_ptr<ColorAttachment> colorAttachment;
|
std::unique_ptr<ColorAttachment> colorAttachment;
|
||||||
std::unique_ptr<DepthAttachment> depthAttachment;
|
std::unique_ptr<DepthAttachment> depthAttachment;
|
||||||
@@ -23,7 +24,7 @@ namespace Copium
|
|||||||
uint32_t width;
|
uint32_t width;
|
||||||
uint32_t height;
|
uint32_t height;
|
||||||
public:
|
public:
|
||||||
Framebuffer(Instance& instance, uint32_t width, uint32_t height);
|
Framebuffer(Vulkan& vulkan, uint32_t width, uint32_t height);
|
||||||
~Framebuffer();
|
~Framebuffer();
|
||||||
|
|
||||||
void Resize(uint32_t width, uint32_t height);
|
void Resize(uint32_t width, uint32_t height);
|
||||||
|
|||||||
@@ -1,13 +1,11 @@
|
|||||||
#include "copium/buffer/IndexBuffer.h"
|
#include "copium/buffer/IndexBuffer.h"
|
||||||
|
|
||||||
#include "copium/buffer/CommandBuffer.h"
|
|
||||||
|
|
||||||
#include <vulkan/vulkan.hpp>
|
#include <vulkan/vulkan.hpp>
|
||||||
|
|
||||||
namespace Copium
|
namespace Copium
|
||||||
{
|
{
|
||||||
IndexBuffer::IndexBuffer(Instance& instance, int indexCount)
|
IndexBuffer::IndexBuffer(Vulkan& vulkan, int indexCount)
|
||||||
: Buffer{instance, VK_BUFFER_USAGE_TRANSFER_DST_BIT | VK_BUFFER_USAGE_INDEX_BUFFER_BIT, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT, indexCount * sizeof(uint16_t), 1},
|
: Buffer{vulkan, VK_BUFFER_USAGE_TRANSFER_DST_BIT | VK_BUFFER_USAGE_INDEX_BUFFER_BIT, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT, indexCount * sizeof(uint16_t), 1},
|
||||||
indexCount{indexCount}
|
indexCount{indexCount}
|
||||||
{}
|
{}
|
||||||
|
|
||||||
|
|||||||
@@ -1,7 +1,8 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "copium/buffer/Buffer.h"
|
#include "copium/buffer/Buffer.h"
|
||||||
#include "copium/core/Instance.h"
|
#include "copium/buffer/CommandBuffer.h"
|
||||||
|
#include "copium/core/Vulkan.h"
|
||||||
#include "copium/util/Common.h"
|
#include "copium/util/Common.h"
|
||||||
|
|
||||||
namespace Copium
|
namespace Copium
|
||||||
@@ -12,7 +13,7 @@ namespace Copium
|
|||||||
private:
|
private:
|
||||||
int indexCount;
|
int indexCount;
|
||||||
public:
|
public:
|
||||||
IndexBuffer(Instance& instance, int indexCount);
|
IndexBuffer(Vulkan& vulkan, int indexCount);
|
||||||
|
|
||||||
void Bind(const CommandBuffer& commandBuffer);
|
void Bind(const CommandBuffer& commandBuffer);
|
||||||
void Draw(const CommandBuffer& commandBuffer);
|
void Draw(const CommandBuffer& commandBuffer);
|
||||||
|
|||||||
@@ -1,9 +1,11 @@
|
|||||||
#include "copium/buffer/UniformBuffer.h"
|
#include "copium/buffer/UniformBuffer.h"
|
||||||
|
|
||||||
|
#include "copium/core/SwapChain.h"
|
||||||
|
|
||||||
namespace Copium
|
namespace Copium
|
||||||
{
|
{
|
||||||
UniformBuffer::UniformBuffer(Instance& instance, VkDeviceSize size)
|
UniformBuffer::UniformBuffer(Vulkan& vulkan, VkDeviceSize size)
|
||||||
: Buffer{instance, VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT, size, instance.GetMaxFramesInFlight()}
|
: Buffer{vulkan, VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT, size, SwapChain::MAX_FRAMES_IN_FLIGHT}
|
||||||
{}
|
{}
|
||||||
|
|
||||||
VkDescriptorBufferInfo UniformBuffer::GetDescriptorBufferInfo(int index) const
|
VkDescriptorBufferInfo UniformBuffer::GetDescriptorBufferInfo(int index) const
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "copium/buffer/Buffer.h"
|
#include "copium/buffer/Buffer.h"
|
||||||
#include "copium/core/Instance.h"
|
#include "copium/core/Vulkan.h"
|
||||||
#include "copium/util/Common.h"
|
#include "copium/util/Common.h"
|
||||||
|
|
||||||
#include <vulkan/vulkan.hpp>
|
#include <vulkan/vulkan.hpp>
|
||||||
@@ -13,18 +13,19 @@ namespace Copium
|
|||||||
CP_DELETE_COPY_AND_MOVE_CTOR(UniformBuffer);
|
CP_DELETE_COPY_AND_MOVE_CTOR(UniformBuffer);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
UniformBuffer(Instance& instance, VkDeviceSize size);
|
UniformBuffer(Vulkan& vulkan, VkDeviceSize size);
|
||||||
|
|
||||||
VkDescriptorBufferInfo GetDescriptorBufferInfo(int index) const;
|
VkDescriptorBufferInfo GetDescriptorBufferInfo(int index) const;
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
void Update(const T& t);
|
void Update(const T& t);
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
void UniformBuffer::Update(const T& t)
|
void UniformBuffer::Update(const T& t)
|
||||||
{
|
{
|
||||||
CP_ASSERT(sizeof(T) == Buffer::GetSize(), "Update : Template size is not the same as buffer size %u != %u", sizeof(T), Buffer::GetSize());
|
CP_ASSERT(sizeof(T) == Buffer::GetSize(), "Update : Template size is not the same as buffer size %u != %u", sizeof(T), Buffer::GetSize());
|
||||||
Buffer::Update((void*)&t, instance.GetFlightIndex());
|
Buffer::Update((void*)&t, vulkan.GetSwapChain().GetFlightIndex());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,8 +2,8 @@
|
|||||||
|
|
||||||
namespace Copium
|
namespace Copium
|
||||||
{
|
{
|
||||||
VertexBuffer::VertexBuffer(Instance& instance, const VertexDescriptor& descriptor, int vertexCount)
|
VertexBuffer::VertexBuffer(Vulkan& vulkan, const VertexDescriptor& descriptor, int vertexCount)
|
||||||
: Buffer{instance, VK_BUFFER_USAGE_TRANSFER_DST_BIT | VK_BUFFER_USAGE_VERTEX_BUFFER_BIT, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT, descriptor.GetVertexSize() * vertexCount, 1}
|
: Buffer{vulkan, VK_BUFFER_USAGE_TRANSFER_DST_BIT | VK_BUFFER_USAGE_VERTEX_BUFFER_BIT, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT, descriptor.GetVertexSize() * vertexCount, 1}
|
||||||
{
|
{
|
||||||
VkDeviceSize offset = 0;
|
VkDeviceSize offset = 0;
|
||||||
for (auto&& binding : descriptor.GetBindings())
|
for (auto&& binding : descriptor.GetBindings())
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
#include "copium/buffer/Buffer.h"
|
#include "copium/buffer/Buffer.h"
|
||||||
#include "copium/buffer/CommandBuffer.h"
|
#include "copium/buffer/CommandBuffer.h"
|
||||||
#include "copium/core/Instance.h"
|
#include "copium/core/Vulkan.h"
|
||||||
#include "copium/pipeline/VertexDescriptor.h"
|
#include "copium/pipeline/VertexDescriptor.h"
|
||||||
#include "copium/util/Common.h"
|
#include "copium/util/Common.h"
|
||||||
|
|
||||||
@@ -18,7 +18,7 @@ namespace Copium
|
|||||||
std::vector<VkDeviceSize> bindingOffsets;
|
std::vector<VkDeviceSize> bindingOffsets;
|
||||||
std::vector<VkDeviceSize> bindingSizes;
|
std::vector<VkDeviceSize> bindingSizes;
|
||||||
public:
|
public:
|
||||||
VertexBuffer(Instance& instance, const VertexDescriptor& descriptor, int vertexCount);
|
VertexBuffer(Vulkan& vulkan, const VertexDescriptor& descriptor, int vertexCount);
|
||||||
|
|
||||||
void Bind(const CommandBuffer& commandBuffer);
|
void Bind(const CommandBuffer& commandBuffer);
|
||||||
void UpdateStaging(uint32_t binding, void* data);
|
void UpdateStaging(uint32_t binding, void* data);
|
||||||
|
|||||||
@@ -2,6 +2,10 @@
|
|||||||
|
|
||||||
#include "copium/mesh/Vertex.h"
|
#include "copium/mesh/Vertex.h"
|
||||||
#include "copium/mesh/VertexPassthrough.h"
|
#include "copium/mesh/VertexPassthrough.h"
|
||||||
|
#include "copium/core/Device.h"
|
||||||
|
#include "copium/core/Instance.h"
|
||||||
|
#include "copium/core/SwapChain.h"
|
||||||
|
#include "copium/core/Window.h"
|
||||||
|
|
||||||
#include <glm/gtc/matrix_transform.hpp>
|
#include <glm/gtc/matrix_transform.hpp>
|
||||||
|
|
||||||
@@ -44,7 +48,7 @@ namespace Copium
|
|||||||
|
|
||||||
Application::Application()
|
Application::Application()
|
||||||
{
|
{
|
||||||
InitializeInstance();
|
InitializeVulkan();
|
||||||
InitializeFrameBuffer();
|
InitializeFrameBuffer();
|
||||||
InitializeGraphicsPipeline();
|
InitializeGraphicsPipeline();
|
||||||
InitializeTextureSampler();
|
InitializeTextureSampler();
|
||||||
@@ -56,56 +60,61 @@ namespace Copium
|
|||||||
|
|
||||||
Application::~Application()
|
Application::~Application()
|
||||||
{
|
{
|
||||||
vkDeviceWaitIdle(instance->GetDevice());
|
vkDeviceWaitIdle(vulkan->GetDevice());
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Application::Update()
|
bool Application::Update()
|
||||||
{
|
{
|
||||||
if (framebuffer->GetWidth() != instance->GetSwapChain().GetExtent().width || framebuffer->GetHeight() != instance->GetSwapChain().GetExtent().height)
|
if (framebuffer->GetWidth() != vulkan->GetSwapChain().GetExtent().width || framebuffer->GetHeight() != vulkan->GetSwapChain().GetExtent().height)
|
||||||
{
|
{
|
||||||
framebuffer->Resize(instance->GetSwapChain().GetExtent().width / 8, instance->GetSwapChain().GetExtent().height / 8);
|
framebuffer->Resize(vulkan->GetSwapChain().GetExtent().width / 8, vulkan->GetSwapChain().GetExtent().height / 8);
|
||||||
descriptorSetPassthrough->AddSampler(framebuffer->GetColorAttachment(), 0);
|
descriptorSetPassthrough->AddSampler(framebuffer->GetColorAttachment(), 0);
|
||||||
}
|
}
|
||||||
if (!instance->BeginPresent())
|
|
||||||
{
|
if (!vulkan->GetSwapChain().BeginPresent())
|
||||||
return true;
|
return true;
|
||||||
}
|
|
||||||
|
|
||||||
RecordCommandBuffer();
|
RecordCommandBuffer();
|
||||||
commandBuffer->SubmitAsGraphicsQueue();
|
vulkan->GetSwapChain().SubmitToGraphicsQueue(*commandBuffer);
|
||||||
|
|
||||||
return instance->EndPresent();
|
vulkan->GetSwapChain().EndPresent();
|
||||||
|
return !glfwWindowShouldClose(vulkan->GetWindow().GetWindow());
|
||||||
}
|
}
|
||||||
|
|
||||||
void Application::InitializeInstance()
|
void Application::InitializeVulkan()
|
||||||
{
|
{
|
||||||
instance = std::make_unique<Instance>("Copium Engine");
|
vulkan = std::make_unique<Vulkan>();
|
||||||
|
vulkan->SetInstance(std::make_unique<Instance>("Copium Engine"));
|
||||||
|
vulkan->SetWindow(std::make_unique<Window>(*vulkan, "Copium Engine", 1920, 1080, Window::Mode::Windowed));
|
||||||
|
vulkan->SetDevice(std::make_unique<Device>(*vulkan));
|
||||||
|
vulkan->SetSwapChain(std::make_unique<SwapChain>(*vulkan));
|
||||||
|
CP_ASSERT(vulkan->Valid(), "Vulkan Manager was not initialized correctly");
|
||||||
}
|
}
|
||||||
|
|
||||||
void Application::InitializeFrameBuffer()
|
void Application::InitializeFrameBuffer()
|
||||||
{
|
{
|
||||||
framebuffer = std::make_unique<Framebuffer>(*instance, instance->GetSwapChain().GetExtent().width, instance->GetSwapChain().GetExtent().height);
|
framebuffer = std::make_unique<Framebuffer>(*vulkan, vulkan->GetSwapChain().GetExtent().width, vulkan->GetSwapChain().GetExtent().height);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Application::InitializeTextureSampler()
|
void Application::InitializeTextureSampler()
|
||||||
{
|
{
|
||||||
texture2D = std::make_unique<Texture2D>(*instance, "res/textures/texture.png");
|
texture2D = std::make_unique<Texture2D>(*vulkan, "res/textures/texture.png");
|
||||||
}
|
}
|
||||||
|
|
||||||
void Application::InitializeUniformBuffer()
|
void Application::InitializeUniformBuffer()
|
||||||
{
|
{
|
||||||
shaderUniformBuffer = std::make_unique<UniformBuffer>(*instance, sizeof(ShaderUniform));
|
shaderUniformBuffer = std::make_unique<UniformBuffer>(*vulkan, sizeof(ShaderUniform));
|
||||||
}
|
}
|
||||||
|
|
||||||
void Application::InitializeDescriptorSets()
|
void Application::InitializeDescriptorSets()
|
||||||
{
|
{
|
||||||
descriptorPool = std::make_unique<DescriptorPool>(*instance);
|
descriptorPool = std::make_unique<DescriptorPool>(*vulkan);
|
||||||
|
|
||||||
descriptorSet = std::make_unique<DescriptorSet>(*instance, *descriptorPool, graphicsPipeline->GetDescriptorSetLayout(0));
|
descriptorSet = std::make_unique<DescriptorSet>(*vulkan, *descriptorPool, graphicsPipeline->GetDescriptorSetLayout(0));
|
||||||
descriptorSet->AddUniform(*shaderUniformBuffer, 0);
|
descriptorSet->AddUniform(*shaderUniformBuffer, 0);
|
||||||
descriptorSet->AddSampler(*texture2D, 1);
|
descriptorSet->AddSampler(*texture2D, 1);
|
||||||
|
|
||||||
descriptorSetPassthrough = std::make_unique<DescriptorSet>(*instance, *descriptorPool, graphicsPipelinePassthrough->GetDescriptorSetLayout(0));
|
descriptorSetPassthrough = std::make_unique<DescriptorSet>(*vulkan, *descriptorPool, graphicsPipelinePassthrough->GetDescriptorSetLayout(0));
|
||||||
descriptorSetPassthrough->AddSampler(framebuffer->GetColorAttachment(), 0);
|
descriptorSetPassthrough->AddSampler(framebuffer->GetColorAttachment(), 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -116,24 +125,24 @@ namespace Copium
|
|||||||
creator.AddDescriptorSetLayoutBinding(0, 1, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, 1, VK_SHADER_STAGE_FRAGMENT_BIT);
|
creator.AddDescriptorSetLayoutBinding(0, 1, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, 1, VK_SHADER_STAGE_FRAGMENT_BIT);
|
||||||
creator.SetVertexDescriptor(Vertex::GetDescriptor());
|
creator.SetVertexDescriptor(Vertex::GetDescriptor());
|
||||||
creator.SetCullMode(VK_CULL_MODE_NONE);
|
creator.SetCullMode(VK_CULL_MODE_NONE);
|
||||||
graphicsPipeline = std::make_unique<Pipeline>(*instance, creator);
|
graphicsPipeline = std::make_unique<Pipeline>(*vulkan, creator);
|
||||||
|
|
||||||
PipelineCreator creatorPassthrough{instance->GetSwapChain().GetRenderPass(), "res/shaders/passthrough.vert", "res/shaders/passthrough.frag"};
|
PipelineCreator creatorPassthrough{vulkan->GetSwapChain().GetRenderPass(), "res/shaders/passthrough.vert", "res/shaders/passthrough.frag"};
|
||||||
creatorPassthrough.AddDescriptorSetLayoutBinding(0, 0, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, 1, VK_SHADER_STAGE_FRAGMENT_BIT);
|
creatorPassthrough.AddDescriptorSetLayoutBinding(0, 0, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, 1, VK_SHADER_STAGE_FRAGMENT_BIT);
|
||||||
creatorPassthrough.SetVertexDescriptor(VertexPassthrough::GetDescriptor());
|
creatorPassthrough.SetVertexDescriptor(VertexPassthrough::GetDescriptor());
|
||||||
creatorPassthrough.SetCullMode(VK_CULL_MODE_NONE);
|
creatorPassthrough.SetCullMode(VK_CULL_MODE_NONE);
|
||||||
graphicsPipelinePassthrough = std::make_unique<Pipeline>(*instance, creatorPassthrough);
|
graphicsPipelinePassthrough = std::make_unique<Pipeline>(*vulkan, creatorPassthrough);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Application::InitializeMesh()
|
void Application::InitializeMesh()
|
||||||
{
|
{
|
||||||
mesh = std::make_unique<Mesh>(*instance, vertices, indices);
|
mesh = std::make_unique<Mesh>(*vulkan, vertices, indices);
|
||||||
meshPassthrough = std::make_unique<Mesh>(*instance, verticesPassthrough, indicesPassthrough);
|
meshPassthrough = std::make_unique<Mesh>(*vulkan, verticesPassthrough, indicesPassthrough);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Application::InitializeCommandBuffer()
|
void Application::InitializeCommandBuffer()
|
||||||
{
|
{
|
||||||
commandBuffer = std::make_unique<CommandBuffer>(*instance, CommandBuffer::Type::Dynamic);
|
commandBuffer = std::make_unique<CommandBuffer>(*vulkan, CommandBuffer::Type::Dynamic);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Application::RecordCommandBuffer()
|
void Application::RecordCommandBuffer()
|
||||||
@@ -153,7 +162,7 @@ namespace Copium
|
|||||||
|
|
||||||
framebuffer->Unbind(*commandBuffer);
|
framebuffer->Unbind(*commandBuffer);
|
||||||
|
|
||||||
instance->GetSwapChain().BeginFrameBuffer(*commandBuffer);
|
vulkan->GetSwapChain().BeginFrameBuffer(*commandBuffer);
|
||||||
|
|
||||||
graphicsPipelinePassthrough->Bind(*commandBuffer);
|
graphicsPipelinePassthrough->Bind(*commandBuffer);
|
||||||
graphicsPipelinePassthrough->SetDescriptorSet(0, *descriptorSetPassthrough);
|
graphicsPipelinePassthrough->SetDescriptorSet(0, *descriptorSetPassthrough);
|
||||||
@@ -162,7 +171,7 @@ namespace Copium
|
|||||||
meshPassthrough->Bind(*commandBuffer);
|
meshPassthrough->Bind(*commandBuffer);
|
||||||
meshPassthrough->Render(*commandBuffer);
|
meshPassthrough->Render(*commandBuffer);
|
||||||
|
|
||||||
instance->GetSwapChain().EndFrameBuffer(*commandBuffer);
|
vulkan->GetSwapChain().EndFrameBuffer(*commandBuffer);
|
||||||
commandBuffer->End();
|
commandBuffer->End();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -4,7 +4,9 @@
|
|||||||
#include "copium/buffer/IndexBuffer.h"
|
#include "copium/buffer/IndexBuffer.h"
|
||||||
#include "copium/buffer/UniformBuffer.h"
|
#include "copium/buffer/UniformBuffer.h"
|
||||||
#include "copium/buffer/VertexBuffer.h"
|
#include "copium/buffer/VertexBuffer.h"
|
||||||
|
#include "copium/core/Device.h"
|
||||||
#include "copium/core/Instance.h"
|
#include "copium/core/Instance.h"
|
||||||
|
#include "copium/core/Vulkan.h"
|
||||||
#include "copium/mesh/Mesh.h"
|
#include "copium/mesh/Mesh.h"
|
||||||
#include "copium/pipeline/DescriptorPool.h"
|
#include "copium/pipeline/DescriptorPool.h"
|
||||||
#include "copium/pipeline/DescriptorSet.h"
|
#include "copium/pipeline/DescriptorSet.h"
|
||||||
@@ -17,6 +19,7 @@ namespace Copium
|
|||||||
{
|
{
|
||||||
CP_DELETE_COPY_AND_MOVE_CTOR(Application);
|
CP_DELETE_COPY_AND_MOVE_CTOR(Application);
|
||||||
private:
|
private:
|
||||||
|
std::unique_ptr<Vulkan> vulkan;
|
||||||
std::unique_ptr<Instance> instance;
|
std::unique_ptr<Instance> instance;
|
||||||
std::unique_ptr<Framebuffer> framebuffer;
|
std::unique_ptr<Framebuffer> framebuffer;
|
||||||
std::unique_ptr<Texture2D> texture2D;
|
std::unique_ptr<Texture2D> texture2D;
|
||||||
@@ -30,14 +33,13 @@ namespace Copium
|
|||||||
std::unique_ptr<Mesh> meshPassthrough;
|
std::unique_ptr<Mesh> meshPassthrough;
|
||||||
std::unique_ptr<CommandBuffer> commandBuffer;
|
std::unique_ptr<CommandBuffer> commandBuffer;
|
||||||
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
Application();
|
Application();
|
||||||
~Application();
|
~Application();
|
||||||
|
|
||||||
bool Update();
|
bool Update();
|
||||||
private:
|
private:
|
||||||
void InitializeInstance();
|
void InitializeVulkan();
|
||||||
void InitializeFrameBuffer();
|
void InitializeFrameBuffer();
|
||||||
void InitializeTextureSampler();
|
void InitializeTextureSampler();
|
||||||
void InitializeUniformBuffer();
|
void InitializeUniformBuffer();
|
||||||
|
|||||||
@@ -0,0 +1,189 @@
|
|||||||
|
#include "Device.h"
|
||||||
|
|
||||||
|
#include "copium/core/Instance.h"
|
||||||
|
#include "copium/core/SwapChain.h"
|
||||||
|
#include "copium/core/Window.h"
|
||||||
|
|
||||||
|
namespace Copium
|
||||||
|
{
|
||||||
|
Device::Device(Vulkan& vulkan)
|
||||||
|
: vulkan{vulkan}
|
||||||
|
{
|
||||||
|
SelectPhysicalDevice();
|
||||||
|
InitializeLogicalDevice();
|
||||||
|
InitializeCommandPool();
|
||||||
|
}
|
||||||
|
Device::~Device()
|
||||||
|
{
|
||||||
|
vkDestroyCommandPool(device, commandPool, nullptr);
|
||||||
|
|
||||||
|
vkDestroyDevice(device, nullptr);
|
||||||
|
}
|
||||||
|
|
||||||
|
VkQueue Device::GetGraphicsQueue() const
|
||||||
|
{
|
||||||
|
return graphicsQueue;
|
||||||
|
}
|
||||||
|
|
||||||
|
VkQueue Device::GetPresentQueue() const
|
||||||
|
{
|
||||||
|
return presentQueue;
|
||||||
|
}
|
||||||
|
|
||||||
|
VkCommandPool Device::GetCommandPool() const
|
||||||
|
{
|
||||||
|
return commandPool;
|
||||||
|
}
|
||||||
|
|
||||||
|
VkPhysicalDevice Device::GetPhysicalDevice() const
|
||||||
|
{
|
||||||
|
return physicalDevice;
|
||||||
|
}
|
||||||
|
|
||||||
|
Device::operator VkDevice() const
|
||||||
|
{
|
||||||
|
return device;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t Device::FindMemoryType(uint32_t typeFilter, VkMemoryPropertyFlags properties)
|
||||||
|
{
|
||||||
|
VkPhysicalDeviceMemoryProperties memoryProperties;
|
||||||
|
vkGetPhysicalDeviceMemoryProperties(physicalDevice, &memoryProperties);
|
||||||
|
for (uint32_t i = 0; i < memoryProperties.memoryTypeCount; ++i)
|
||||||
|
{
|
||||||
|
if ((typeFilter & (1 << i)) && (memoryProperties.memoryTypes[i].propertyFlags & properties) == properties)
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
CP_ABORT("FindMemoryType : Failed to find suitable memory type");
|
||||||
|
}
|
||||||
|
|
||||||
|
void Device::SelectPhysicalDevice()
|
||||||
|
{
|
||||||
|
uint32_t deviceCount;
|
||||||
|
vkEnumeratePhysicalDevices(vulkan.GetInstance(), &deviceCount, nullptr);
|
||||||
|
CP_ASSERT(deviceCount != 0, "SelectPhysicaDevice : No available devices support Vulkan");
|
||||||
|
|
||||||
|
std::vector<VkPhysicalDevice> devices(deviceCount);
|
||||||
|
vkEnumeratePhysicalDevices(vulkan.GetInstance(), &deviceCount, devices.data());
|
||||||
|
CP_INFO("SelectPhysicaDevice : Available devices:");
|
||||||
|
for (auto&& device : devices)
|
||||||
|
{
|
||||||
|
VkPhysicalDeviceProperties deviceProperties;
|
||||||
|
vkGetPhysicalDeviceProperties(device, &deviceProperties);
|
||||||
|
CP_INFO_CONT("\t%s", deviceProperties.deviceName);
|
||||||
|
}
|
||||||
|
for (auto&& device : devices)
|
||||||
|
{
|
||||||
|
if (IsPhysicalDeviceSuitable(device))
|
||||||
|
{
|
||||||
|
VkPhysicalDeviceProperties deviceProperties;
|
||||||
|
vkGetPhysicalDeviceProperties(device, &deviceProperties);
|
||||||
|
physicalDevice = device;
|
||||||
|
CP_INFO("SelectPhysicaDevice : Selecting device: %s", deviceProperties.deviceName);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
CP_ASSERT(physicalDevice != VK_NULL_HANDLE, "SelectPhysicaDevice : Failed to find suitable GPU");
|
||||||
|
}
|
||||||
|
|
||||||
|
void Device::InitializeLogicalDevice()
|
||||||
|
{
|
||||||
|
QueueFamiliesQuery query{vulkan.GetWindow().GetSurface(), physicalDevice};
|
||||||
|
|
||||||
|
float queuePriority = 1.0f;
|
||||||
|
|
||||||
|
std::vector<VkDeviceQueueCreateInfo> queueCreateInfos{};
|
||||||
|
std::set<uint32_t> uniqueQueueFamilies{query.graphicsFamily.value(), query.presentFamily.value()};
|
||||||
|
for (auto&& queueFamily : uniqueQueueFamilies)
|
||||||
|
{
|
||||||
|
VkDeviceQueueCreateInfo queueCreateInfo{};
|
||||||
|
queueCreateInfo.sType = VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO;
|
||||||
|
queueCreateInfo.queueFamilyIndex = queueFamily;
|
||||||
|
queueCreateInfo.queueCount = 1;
|
||||||
|
queueCreateInfo.pQueuePriorities = &queuePriority;
|
||||||
|
queueCreateInfos.emplace_back(queueCreateInfo);
|
||||||
|
}
|
||||||
|
std::vector<const char*> deviceExtensions = GetRequiredDeviceExtensions();
|
||||||
|
VkPhysicalDeviceFeatures deviceFeatures{};
|
||||||
|
deviceFeatures.fillModeNonSolid = VK_TRUE;
|
||||||
|
deviceFeatures.samplerAnisotropy = VK_TRUE;
|
||||||
|
VkDeviceCreateInfo createInfo{};
|
||||||
|
createInfo.sType = VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO;
|
||||||
|
createInfo.pQueueCreateInfos = queueCreateInfos.data();
|
||||||
|
createInfo.queueCreateInfoCount = queueCreateInfos.size();
|
||||||
|
createInfo.pEnabledFeatures = &deviceFeatures;
|
||||||
|
createInfo.ppEnabledExtensionNames = deviceExtensions.data();
|
||||||
|
createInfo.enabledExtensionCount = deviceExtensions.size();
|
||||||
|
|
||||||
|
CP_VK_ASSERT(vkCreateDevice(physicalDevice, &createInfo, nullptr, &device), "InitializeLogicalDevice : Failed to initialize logical device");
|
||||||
|
|
||||||
|
graphicsQueueIndex = query.graphicsFamily.value();
|
||||||
|
presentQueueIndex = query.presentFamily.value();
|
||||||
|
vkGetDeviceQueue(device, graphicsQueueIndex, 0, &graphicsQueue);
|
||||||
|
vkGetDeviceQueue(device, presentQueueIndex, 0, &presentQueue);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Device::InitializeCommandPool()
|
||||||
|
{
|
||||||
|
VkCommandPoolCreateInfo createInfo{};
|
||||||
|
createInfo.sType = VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO;
|
||||||
|
createInfo.flags = VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT;
|
||||||
|
createInfo.queueFamilyIndex = graphicsQueueIndex;
|
||||||
|
CP_VK_ASSERT(vkCreateCommandPool(device, &createInfo, nullptr, &commandPool), "InitializeCommandPool : Failed to initialize command pool");
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Device::IsPhysicalDeviceSuitable(VkPhysicalDevice device)
|
||||||
|
{
|
||||||
|
VkPhysicalDeviceProperties deviceProperties;
|
||||||
|
vkGetPhysicalDeviceProperties(device, &deviceProperties);
|
||||||
|
if (deviceProperties.deviceType != VK_PHYSICAL_DEVICE_TYPE_DISCRETE_GPU)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
VkPhysicalDeviceFeatures deviceFeatures;
|
||||||
|
vkGetPhysicalDeviceFeatures(device, &deviceFeatures);
|
||||||
|
if (!deviceFeatures.fillModeNonSolid || !deviceFeatures.samplerAnisotropy)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
QueueFamiliesQuery query{vulkan.GetWindow().GetSurface(), device};
|
||||||
|
if (!query.AllRequiredFamiliesSupported())
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if (!CheckDeviceExtensionSupport(device))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
SwapChainSupportDetails details{vulkan.GetWindow().GetSurface(), device};
|
||||||
|
if (!details.Valid())
|
||||||
|
return false;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Device::CheckDeviceExtensionSupport(VkPhysicalDevice device)
|
||||||
|
{
|
||||||
|
uint32_t extensionCount;
|
||||||
|
vkEnumerateDeviceExtensionProperties(device, nullptr, &extensionCount, nullptr);
|
||||||
|
std::vector<VkExtensionProperties> extensions{extensionCount};
|
||||||
|
vkEnumerateDeviceExtensionProperties(device, nullptr, &extensionCount, extensions.data());
|
||||||
|
|
||||||
|
for (auto&& requiredExtension : GetRequiredDeviceExtensions())
|
||||||
|
{
|
||||||
|
bool found = false;
|
||||||
|
for (auto&& extension : extensions)
|
||||||
|
{
|
||||||
|
if (std::strcmp(requiredExtension, extension.extensionName) == 0)
|
||||||
|
{
|
||||||
|
found = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!found)
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<const char*> Device::GetRequiredDeviceExtensions()
|
||||||
|
{
|
||||||
|
return {VK_KHR_SWAPCHAIN_EXTENSION_NAME};
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,48 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "copium/core/QueueFamilies.h"
|
||||||
|
#include "copium/core/Vulkan.h"
|
||||||
|
#include "copium/util/Common.h"
|
||||||
|
|
||||||
|
#include <vulkan/vulkan.hpp>
|
||||||
|
|
||||||
|
namespace Copium
|
||||||
|
{
|
||||||
|
class Vulkan;
|
||||||
|
class Device
|
||||||
|
{
|
||||||
|
CP_DELETE_COPY_AND_MOVE_CTOR(Device);
|
||||||
|
private:
|
||||||
|
Vulkan& vulkan;
|
||||||
|
|
||||||
|
VkPhysicalDevice physicalDevice;
|
||||||
|
VkDevice device;
|
||||||
|
VkCommandPool commandPool;
|
||||||
|
|
||||||
|
// TODO: Move to SwapChain?
|
||||||
|
uint32_t graphicsQueueIndex;
|
||||||
|
uint32_t presentQueueIndex;
|
||||||
|
VkQueue graphicsQueue;
|
||||||
|
VkQueue presentQueue;
|
||||||
|
// TODO end
|
||||||
|
|
||||||
|
public:
|
||||||
|
Device(Vulkan& vulkan);
|
||||||
|
~Device();
|
||||||
|
|
||||||
|
VkQueue GetGraphicsQueue() const;
|
||||||
|
VkQueue GetPresentQueue() const;
|
||||||
|
VkCommandPool GetCommandPool() const;
|
||||||
|
VkPhysicalDevice GetPhysicalDevice() const;
|
||||||
|
operator VkDevice() const;
|
||||||
|
uint32_t FindMemoryType(uint32_t typeFilter, VkMemoryPropertyFlags properties);
|
||||||
|
|
||||||
|
private:
|
||||||
|
void SelectPhysicalDevice();
|
||||||
|
void InitializeLogicalDevice();
|
||||||
|
void InitializeCommandPool();
|
||||||
|
bool IsPhysicalDeviceSuitable(VkPhysicalDevice device);
|
||||||
|
bool CheckDeviceExtensionSupport(VkPhysicalDevice device);
|
||||||
|
std::vector<const char*> GetRequiredDeviceExtensions();
|
||||||
|
};
|
||||||
|
}
|
||||||
@@ -1,6 +1,7 @@
|
|||||||
#include "Instance.h"
|
#include "Instance.h"
|
||||||
|
|
||||||
#include "copium/core/QueueFamilies.h"
|
#include "copium/core/QueueFamilies.h"
|
||||||
|
#include "copium/core/SwapChain.h"
|
||||||
#include "copium/util/Common.h"
|
#include "copium/util/Common.h"
|
||||||
|
|
||||||
namespace Copium
|
namespace Copium
|
||||||
@@ -8,126 +9,15 @@ namespace Copium
|
|||||||
Instance::Instance(const std::string& applicationName)
|
Instance::Instance(const std::string& applicationName)
|
||||||
{
|
{
|
||||||
timer.Start();
|
timer.Start();
|
||||||
InitializeWindow(applicationName);
|
|
||||||
InitializeInstance(applicationName);
|
InitializeInstance(applicationName);
|
||||||
InitializeDebugMessenger();
|
InitializeDebugMessenger();
|
||||||
InitializeSurface();
|
|
||||||
SelectPhysicalDevice();
|
|
||||||
InitializeLogicalDevice();
|
|
||||||
InitializeCommandPool();
|
|
||||||
InitializeSwapChain();
|
|
||||||
InitializeSyncObjects();
|
|
||||||
CP_INFO("Instance : Initialized Vulkan in %f seconds", timer.Elapsed());
|
CP_INFO("Instance : Initialized Vulkan in %f seconds", timer.Elapsed());
|
||||||
}
|
}
|
||||||
|
|
||||||
Instance::~Instance()
|
Instance::~Instance()
|
||||||
{
|
{
|
||||||
for (size_t i = 0; i < MAX_FRAMES_IN_FLIGHT; ++i)
|
|
||||||
{
|
|
||||||
vkDestroyFence(device, inFlightFences[i], nullptr);
|
|
||||||
vkDestroySemaphore(device, renderFinishedSemaphores[i], nullptr);
|
|
||||||
vkDestroySemaphore(device, imageAvailableSemaphores[i], nullptr);
|
|
||||||
}
|
|
||||||
vkDestroyCommandPool(device, commandPool, nullptr);
|
|
||||||
swapChain.reset();
|
|
||||||
vkDestroyDevice(device, nullptr);
|
|
||||||
vkDestroySurfaceKHR(instance, surface, nullptr);
|
|
||||||
debugMessenger.reset();
|
debugMessenger.reset();
|
||||||
vkDestroyInstance(instance, nullptr);
|
vkDestroyInstance(instance, nullptr);
|
||||||
glfwDestroyWindow(window);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool Instance::BeginPresent()
|
|
||||||
{
|
|
||||||
vkWaitForFences(device, 1, &inFlightFences[flightIndex], VK_TRUE, UINT64_MAX);
|
|
||||||
|
|
||||||
if (!swapChain->BeginPresent(imageAvailableSemaphores[flightIndex]))
|
|
||||||
return false;
|
|
||||||
|
|
||||||
vkResetFences(device, 1, &inFlightFences[flightIndex]);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool Instance::EndPresent()
|
|
||||||
{
|
|
||||||
swapChain->EndPresent(presentQueue, &renderFinishedSemaphores[flightIndex], framebufferResized);
|
|
||||||
|
|
||||||
framebufferResized = false;
|
|
||||||
flightIndex = (flightIndex + 1) % MAX_FRAMES_IN_FLIGHT;
|
|
||||||
return !glfwWindowShouldClose(window);
|
|
||||||
}
|
|
||||||
|
|
||||||
void Instance::SubmitGraphicsQueue(const std::vector<VkCommandBuffer>& commandBuffers)
|
|
||||||
{
|
|
||||||
VkPipelineStageFlags waitStages[] = {VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT};
|
|
||||||
VkSubmitInfo submitInfo{};
|
|
||||||
submitInfo.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
|
|
||||||
submitInfo.waitSemaphoreCount = 1;
|
|
||||||
submitInfo.pWaitSemaphores = &imageAvailableSemaphores[flightIndex];
|
|
||||||
submitInfo.pWaitDstStageMask = waitStages;
|
|
||||||
submitInfo.commandBufferCount = commandBuffers.size();
|
|
||||||
submitInfo.pCommandBuffers = commandBuffers.data();
|
|
||||||
submitInfo.signalSemaphoreCount = 1;
|
|
||||||
submitInfo.pSignalSemaphores = &renderFinishedSemaphores[flightIndex];
|
|
||||||
|
|
||||||
CP_VK_ASSERT(vkQueueSubmit(graphicsQueue, 1, &submitInfo, inFlightFences[flightIndex]), "SubmitGraphicsQueue : Failed to submit command buffer");
|
|
||||||
}
|
|
||||||
|
|
||||||
GLFWwindow* Instance::GetWindow() const
|
|
||||||
{
|
|
||||||
return window;
|
|
||||||
}
|
|
||||||
|
|
||||||
VkSurfaceKHR Instance::GetSurface() const
|
|
||||||
{
|
|
||||||
return surface;
|
|
||||||
}
|
|
||||||
|
|
||||||
VkPhysicalDevice Instance::GetPhysicalDevice() const
|
|
||||||
{
|
|
||||||
return physicalDevice;
|
|
||||||
}
|
|
||||||
|
|
||||||
VkDevice Instance::GetDevice() const
|
|
||||||
{
|
|
||||||
return device;
|
|
||||||
}
|
|
||||||
|
|
||||||
VkCommandPool Instance::GetCommandPool() const
|
|
||||||
{
|
|
||||||
return commandPool;
|
|
||||||
}
|
|
||||||
|
|
||||||
VkQueue Instance::GetGraphicsQueue() const
|
|
||||||
{
|
|
||||||
return graphicsQueue;
|
|
||||||
}
|
|
||||||
|
|
||||||
int Instance::GetFlightIndex() const
|
|
||||||
{
|
|
||||||
return flightIndex;
|
|
||||||
}
|
|
||||||
|
|
||||||
int Instance::GetMaxFramesInFlight() const
|
|
||||||
{
|
|
||||||
return MAX_FRAMES_IN_FLIGHT;
|
|
||||||
}
|
|
||||||
|
|
||||||
const SwapChain& Instance::GetSwapChain() const
|
|
||||||
{
|
|
||||||
return *swapChain;
|
|
||||||
}
|
|
||||||
|
|
||||||
uint32_t Instance::FindMemoryType(uint32_t typeFilter, VkMemoryPropertyFlags properties)
|
|
||||||
{
|
|
||||||
VkPhysicalDeviceMemoryProperties memoryProperties;
|
|
||||||
vkGetPhysicalDeviceMemoryProperties(physicalDevice, &memoryProperties);
|
|
||||||
for (uint32_t i = 0; i < memoryProperties.memoryTypeCount; ++i)
|
|
||||||
{
|
|
||||||
if ((typeFilter & (1 << i)) && (memoryProperties.memoryTypes[i].propertyFlags & properties) == properties)
|
|
||||||
return i;
|
|
||||||
}
|
|
||||||
CP_ABORT("FindMemoryType : Failed to find suitable memory type");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Instance::operator VkInstance() const
|
Instance::operator VkInstance() const
|
||||||
@@ -135,29 +25,6 @@ namespace Copium
|
|||||||
return instance;
|
return instance;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Instance::InitializeWindow(const std::string& applicationName)
|
|
||||||
{
|
|
||||||
glfwWindowHint(GLFW_CLIENT_API, GLFW_NO_API);
|
|
||||||
|
|
||||||
|
|
||||||
#if defined(FULLSCREEN)
|
|
||||||
GLFWmonitor* monitor = glfwGetPrimaryMonitor();
|
|
||||||
const GLFWvidmode* mode = glfwGetVideoMode(monitor);
|
|
||||||
window = glfwCreateWindow(mode->width, mode->height, applicationName.c_str(), glfwGetPrimaryMonitor(), nullptr);
|
|
||||||
#elif defined(BORDERLESS_WINDOWED)
|
|
||||||
GLFWmonitor* monitor = glfwGetPrimaryMonitor();
|
|
||||||
const GLFWvidmode* mode = glfwGetVideoMode(monitor);
|
|
||||||
window = glfwCreateWindow(mode->width, mode->height, applicationName.c_str(), nullptr, nullptr);
|
|
||||||
glfwSetWindowMonitor(window, monitor, 0, 0, mode->width, mode->height, mode->refreshRate);
|
|
||||||
#else
|
|
||||||
window = glfwCreateWindow(WINDOW_WIDTH, WINDOW_HEIGHT, applicationName.c_str(), nullptr, nullptr);
|
|
||||||
#endif
|
|
||||||
CP_ASSERT(window, "InitializeWindow : Failed to initialize glfw window");
|
|
||||||
|
|
||||||
glfwSetWindowUserPointer(window, this);
|
|
||||||
glfwSetFramebufferSizeCallback(window, FramebufferResizeCallback);
|
|
||||||
}
|
|
||||||
|
|
||||||
void Instance::InitializeInstance(const std::string& applicationName)
|
void Instance::InitializeInstance(const std::string& applicationName)
|
||||||
{
|
{
|
||||||
VkApplicationInfo appInfo{};
|
VkApplicationInfo appInfo{};
|
||||||
@@ -200,111 +67,6 @@ namespace Copium
|
|||||||
debugMessenger = std::make_unique<DebugMessenger>(*this);
|
debugMessenger = std::make_unique<DebugMessenger>(*this);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Instance::InitializeSurface()
|
|
||||||
{
|
|
||||||
CP_VK_ASSERT(glfwCreateWindowSurface(instance, window, nullptr, &surface), "InitializeSurface : Failed to create Vulkan surface");
|
|
||||||
}
|
|
||||||
|
|
||||||
void Instance::SelectPhysicalDevice()
|
|
||||||
{
|
|
||||||
uint32_t deviceCount;
|
|
||||||
vkEnumeratePhysicalDevices(instance, &deviceCount, nullptr);
|
|
||||||
CP_ASSERT(deviceCount != 0, "SelectPhysicaDevice : No available devices support Vulkan");
|
|
||||||
|
|
||||||
std::vector<VkPhysicalDevice> devices(deviceCount);
|
|
||||||
vkEnumeratePhysicalDevices(instance, &deviceCount, devices.data());
|
|
||||||
CP_INFO("SelectPhysicaDevice : Available devices:");
|
|
||||||
for (auto&& device : devices)
|
|
||||||
{
|
|
||||||
VkPhysicalDeviceProperties deviceProperties;
|
|
||||||
vkGetPhysicalDeviceProperties(device, &deviceProperties);
|
|
||||||
CP_INFO_CONT("\t%s", deviceProperties.deviceName);
|
|
||||||
}
|
|
||||||
for (auto&& device : devices)
|
|
||||||
{
|
|
||||||
if (IsPhysicalDeviceSuitable(device))
|
|
||||||
{
|
|
||||||
VkPhysicalDeviceProperties deviceProperties;
|
|
||||||
vkGetPhysicalDeviceProperties(device, &deviceProperties);
|
|
||||||
physicalDevice = device;
|
|
||||||
CP_INFO("SelectPhysicaDevice : Selecting device: %s", deviceProperties.deviceName);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
CP_ASSERT(physicalDevice != VK_NULL_HANDLE, "SelectPhysicaDevice : Failed to find suitable GPU");
|
|
||||||
}
|
|
||||||
|
|
||||||
void Instance::InitializeLogicalDevice()
|
|
||||||
{
|
|
||||||
QueueFamiliesQuery query{surface, physicalDevice};
|
|
||||||
|
|
||||||
float queuePriority = 1.0f;
|
|
||||||
|
|
||||||
std::vector<VkDeviceQueueCreateInfo> queueCreateInfos{};
|
|
||||||
std::set<uint32_t> uniqueQueueFamilies{query.graphicsFamily.value(), query.presentFamily.value()};
|
|
||||||
for (auto&& queueFamily : uniqueQueueFamilies)
|
|
||||||
{
|
|
||||||
VkDeviceQueueCreateInfo queueCreateInfo{};
|
|
||||||
queueCreateInfo.sType = VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO;
|
|
||||||
queueCreateInfo.queueFamilyIndex = queueFamily;
|
|
||||||
queueCreateInfo.queueCount = 1;
|
|
||||||
queueCreateInfo.pQueuePriorities = &queuePriority;
|
|
||||||
queueCreateInfos.emplace_back(queueCreateInfo);
|
|
||||||
}
|
|
||||||
std::vector<const char*> deviceExtensions = GetRequiredDeviceExtensions();
|
|
||||||
VkPhysicalDeviceFeatures deviceFeatures{};
|
|
||||||
deviceFeatures.fillModeNonSolid = VK_TRUE;
|
|
||||||
deviceFeatures.samplerAnisotropy = VK_TRUE;
|
|
||||||
VkDeviceCreateInfo createInfo{};
|
|
||||||
createInfo.sType = VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO;
|
|
||||||
createInfo.pQueueCreateInfos = queueCreateInfos.data();
|
|
||||||
createInfo.queueCreateInfoCount = queueCreateInfos.size();
|
|
||||||
createInfo.pEnabledFeatures = &deviceFeatures;
|
|
||||||
createInfo.ppEnabledExtensionNames = deviceExtensions.data();
|
|
||||||
createInfo.enabledExtensionCount = deviceExtensions.size();
|
|
||||||
|
|
||||||
CP_VK_ASSERT(vkCreateDevice(physicalDevice, &createInfo, nullptr, &device), "InitializeLogicalDevice : Failed to initialize logical device");
|
|
||||||
|
|
||||||
graphicsQueueIndex = query.graphicsFamily.value();
|
|
||||||
presentQueueIndex = query.presentFamily.value();
|
|
||||||
vkGetDeviceQueue(device, graphicsQueueIndex, 0, &graphicsQueue);
|
|
||||||
vkGetDeviceQueue(device, presentQueueIndex, 0, &presentQueue);
|
|
||||||
}
|
|
||||||
|
|
||||||
void Instance::InitializeSwapChain()
|
|
||||||
{
|
|
||||||
swapChain = std::make_unique<SwapChain>(*this);
|
|
||||||
}
|
|
||||||
|
|
||||||
void Instance::InitializeCommandPool()
|
|
||||||
{
|
|
||||||
VkCommandPoolCreateInfo createInfo{};
|
|
||||||
createInfo.sType = VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO;
|
|
||||||
createInfo.flags = VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT;
|
|
||||||
createInfo.queueFamilyIndex = graphicsQueueIndex;
|
|
||||||
CP_VK_ASSERT(vkCreateCommandPool(device, &createInfo, nullptr, &commandPool), "InitializeCommandPool : Failed to initialize command pool");
|
|
||||||
}
|
|
||||||
|
|
||||||
void Instance::InitializeSyncObjects()
|
|
||||||
{
|
|
||||||
imageAvailableSemaphores.resize(MAX_FRAMES_IN_FLIGHT);
|
|
||||||
renderFinishedSemaphores.resize(MAX_FRAMES_IN_FLIGHT);
|
|
||||||
inFlightFences.resize(MAX_FRAMES_IN_FLIGHT);
|
|
||||||
VkSemaphoreCreateInfo semaphoreCreateInfo{};
|
|
||||||
semaphoreCreateInfo.sType = VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO;
|
|
||||||
for (size_t i = 0; i < MAX_FRAMES_IN_FLIGHT; ++i)
|
|
||||||
{
|
|
||||||
CP_VK_ASSERT(vkCreateSemaphore(device, &semaphoreCreateInfo, nullptr, &imageAvailableSemaphores[i]), "InitializeSyncObjects : Failed to initialize available image semaphore");
|
|
||||||
CP_VK_ASSERT(vkCreateSemaphore(device, &semaphoreCreateInfo, nullptr, &renderFinishedSemaphores[i]), "InitializeSyncObjects : Failed to initialize render finished semaphore");
|
|
||||||
|
|
||||||
VkFenceCreateInfo fenceCreateInfo{};
|
|
||||||
fenceCreateInfo.sType = VK_STRUCTURE_TYPE_FENCE_CREATE_INFO;
|
|
||||||
fenceCreateInfo.flags = VK_FENCE_CREATE_SIGNALED_BIT;
|
|
||||||
|
|
||||||
CP_VK_ASSERT(vkCreateFence(device, &fenceCreateInfo, nullptr, &inFlightFences[i]), "InitializeSyncObjects : Failed to initialize in flight fence");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
std::vector<const char*> Instance::GetRequiredExtensions()
|
std::vector<const char*> Instance::GetRequiredExtensions()
|
||||||
{
|
{
|
||||||
uint32_t glfwExtensionCount;
|
uint32_t glfwExtensionCount;
|
||||||
@@ -349,63 +111,11 @@ namespace Copium
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Instance::IsPhysicalDeviceSuitable(VkPhysicalDevice device)
|
|
||||||
{
|
|
||||||
VkPhysicalDeviceProperties deviceProperties;
|
|
||||||
vkGetPhysicalDeviceProperties(device, &deviceProperties);
|
|
||||||
if (deviceProperties.deviceType != VK_PHYSICAL_DEVICE_TYPE_DISCRETE_GPU)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
VkPhysicalDeviceFeatures deviceFeatures;
|
|
||||||
vkGetPhysicalDeviceFeatures(device, &deviceFeatures);
|
|
||||||
if (!deviceFeatures.fillModeNonSolid || !deviceFeatures.samplerAnisotropy)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
QueueFamiliesQuery query{surface, device};
|
|
||||||
if (!query.AllRequiredFamiliesSupported())
|
|
||||||
return false;
|
|
||||||
|
|
||||||
if (!CheckDeviceExtensionSupport(device))
|
|
||||||
return false;
|
|
||||||
SwapChainSupportDetails details{surface, device};
|
|
||||||
if (!details.Valid())
|
|
||||||
return false;
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool Instance::CheckDeviceExtensionSupport(VkPhysicalDevice device)
|
|
||||||
{
|
|
||||||
uint32_t extensionCount;
|
|
||||||
vkEnumerateDeviceExtensionProperties(device, nullptr, &extensionCount, nullptr);
|
|
||||||
std::vector<VkExtensionProperties> extensions{extensionCount};
|
|
||||||
vkEnumerateDeviceExtensionProperties(device, nullptr, &extensionCount, extensions.data());
|
|
||||||
|
|
||||||
for (auto&& requiredExtension : GetRequiredDeviceExtensions())
|
|
||||||
{
|
|
||||||
bool found = false;
|
|
||||||
for (auto&& extension : extensions)
|
|
||||||
{
|
|
||||||
if (std::strcmp(requiredExtension, extension.extensionName) == 0)
|
|
||||||
{
|
|
||||||
found = true;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (!found)
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
std::vector<const char*> Instance::GetRequiredDeviceExtensions()
|
|
||||||
{
|
|
||||||
return {VK_KHR_SWAPCHAIN_EXTENSION_NAME};
|
|
||||||
}
|
|
||||||
|
|
||||||
void Instance::FramebufferResizeCallback(GLFWwindow* window, int width, int height)
|
void Instance::FramebufferResizeCallback(GLFWwindow* window, int width, int height)
|
||||||
{
|
{
|
||||||
Instance* instance = static_cast<Instance*>(glfwGetWindowUserPointer(window));
|
Instance* instance = static_cast<Instance*>(glfwGetWindowUserPointer(window));
|
||||||
instance->framebufferResized = true;
|
// TODO: Fix swap chain resizing again
|
||||||
|
// instance->swapChain->ResizeFramebuffer(); // TODO: Should maybe be handled by an event system?
|
||||||
|
CP_UNIMPLEMENTED("Framebuffer resizing currently not supported");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1,7 +1,6 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "copium/core/DebugMessenger.h"
|
#include "copium/core/DebugMessenger.h"
|
||||||
#include "copium/core/SwapChain.h"
|
|
||||||
#include "copium/util/Timer.h"
|
#include "copium/util/Timer.h"
|
||||||
|
|
||||||
#include <vulkan/vulkan.hpp>
|
#include <vulkan/vulkan.hpp>
|
||||||
@@ -14,67 +13,29 @@ namespace Copium
|
|||||||
{
|
{
|
||||||
CP_DELETE_COPY_AND_MOVE_CTOR(Instance);
|
CP_DELETE_COPY_AND_MOVE_CTOR(Instance);
|
||||||
private:
|
private:
|
||||||
static const int MAX_FRAMES_IN_FLIGHT = 2;
|
|
||||||
static const int WINDOW_WIDTH = 1920;
|
|
||||||
static const int WINDOW_HEIGHT = 1080;
|
|
||||||
|
|
||||||
VkInstance instance;
|
VkInstance instance;
|
||||||
GLFWwindow* window;
|
|
||||||
VkSurfaceKHR surface;
|
|
||||||
std::unique_ptr<DebugMessenger> debugMessenger;
|
std::unique_ptr<DebugMessenger> debugMessenger;
|
||||||
VkPhysicalDevice physicalDevice = VK_NULL_HANDLE;
|
|
||||||
VkDevice device;
|
// TODO: Move to SwapChain?
|
||||||
uint32_t graphicsQueueIndex;
|
uint32_t graphicsQueueIndex;
|
||||||
uint32_t presentQueueIndex;
|
uint32_t presentQueueIndex;
|
||||||
VkQueue graphicsQueue;
|
VkQueue graphicsQueue;
|
||||||
VkQueue presentQueue;
|
VkQueue presentQueue;
|
||||||
std::unique_ptr<SwapChain> swapChain;
|
// TODO end
|
||||||
int flightIndex;
|
|
||||||
std::vector<VkSemaphore> imageAvailableSemaphores;
|
|
||||||
std::vector<VkSemaphore> renderFinishedSemaphores;
|
|
||||||
std::vector<VkFence> inFlightFences;
|
|
||||||
VkCommandPool commandPool;
|
|
||||||
bool framebufferResized = false;
|
|
||||||
|
|
||||||
int frameCount = 0;
|
|
||||||
Timer timer;
|
Timer timer;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
Instance(const std::string& applicationName);
|
Instance(const std::string& applicationName);
|
||||||
~Instance();
|
~Instance();
|
||||||
bool BeginPresent();
|
|
||||||
bool EndPresent();
|
|
||||||
void SubmitGraphicsQueue(const std::vector<VkCommandBuffer>& commandBuffers);
|
|
||||||
GLFWwindow* GetWindow() const;
|
|
||||||
VkSurfaceKHR GetSurface() const;
|
|
||||||
VkPhysicalDevice GetPhysicalDevice() const;
|
|
||||||
VkDevice GetDevice() const;
|
|
||||||
VkCommandPool GetCommandPool() const;
|
|
||||||
VkQueue GetGraphicsQueue() const;
|
|
||||||
int GetFlightIndex() const;
|
|
||||||
int GetMaxFramesInFlight() const;
|
|
||||||
const SwapChain& GetSwapChain() const;
|
|
||||||
// TODO: Create Device class and move this there
|
|
||||||
uint32_t FindMemoryType(uint32_t typeFilter, VkMemoryPropertyFlags properties);
|
|
||||||
|
|
||||||
operator VkInstance() const;
|
operator VkInstance() const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void InitializeWindow(const std::string& applicationName);
|
|
||||||
void InitializeInstance(const std::string& applicationName);
|
void InitializeInstance(const std::string& applicationName);
|
||||||
void InitializeDebugMessenger();
|
void InitializeDebugMessenger();
|
||||||
void InitializeSurface();
|
|
||||||
void SelectPhysicalDevice();
|
|
||||||
void InitializeLogicalDevice();
|
|
||||||
void InitializeSwapChain();
|
|
||||||
void InitializeCommandPool();
|
|
||||||
void InitializeSyncObjects();
|
|
||||||
std::vector<const char*> GetRequiredExtensions();
|
std::vector<const char*> GetRequiredExtensions();
|
||||||
bool CheckLayerSupport(const std::vector<const char*>& layers);
|
bool CheckLayerSupport(const std::vector<const char*>& layers);
|
||||||
bool IsPhysicalDeviceSuitable(VkPhysicalDevice device);
|
|
||||||
bool CheckDeviceExtensionSupport(VkPhysicalDevice device);
|
|
||||||
std::vector<const char*> GetRequiredDeviceExtensions();
|
|
||||||
static void FramebufferResizeCallback(GLFWwindow* window, int width, int height);
|
static void FramebufferResizeCallback(GLFWwindow* window, int width, int height);
|
||||||
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,15 +1,11 @@
|
|||||||
#include "copium/core/SwapChain.h"
|
#include "copium/core/SwapChain.h"
|
||||||
|
|
||||||
#include "copium/buffer/CommandBuffer.h"
|
#include "copium/core/Device.h"
|
||||||
#include "copium/core/Instance.h"
|
#include "copium/core/Instance.h"
|
||||||
#include "copium/core/QueueFamilies.h"
|
#include "copium/core/QueueFamilies.h"
|
||||||
#include "copium/sampler/DepthAttachment.h"
|
#include "copium/core/Window.h"
|
||||||
#include "copium/sampler/Image.h"
|
#include "copium/sampler/Image.h"
|
||||||
|
|
||||||
#include <glfw/glfw3.h>
|
|
||||||
#include <vector>
|
|
||||||
#include <vulkan/vulkan.h>
|
|
||||||
|
|
||||||
namespace Copium
|
namespace Copium
|
||||||
{
|
{
|
||||||
SwapChainSupportDetails::SwapChainSupportDetails(VkSurfaceKHR surface, VkPhysicalDevice physicalDevice)
|
SwapChainSupportDetails::SwapChainSupportDetails(VkSurfaceKHR surface, VkPhysicalDevice physicalDevice)
|
||||||
@@ -38,20 +34,27 @@ namespace Copium
|
|||||||
return !formats.empty() && !presentModes.empty();
|
return !formats.empty() && !presentModes.empty();
|
||||||
}
|
}
|
||||||
|
|
||||||
SwapChain::SwapChain(Instance& instance)
|
SwapChain::SwapChain(Vulkan& vulkan)
|
||||||
: instance{instance}
|
: vulkan{vulkan}
|
||||||
{
|
{
|
||||||
Initialize();
|
Initialize();
|
||||||
InitializeImageViews();
|
InitializeImageViews();
|
||||||
InitializeDepthAttachment();
|
InitializeDepthAttachment();
|
||||||
InitializeRenderPass();
|
InitializeRenderPass();
|
||||||
InitializeFramebuffers();
|
InitializeFramebuffers();
|
||||||
|
InitializeSyncObjects();
|
||||||
}
|
}
|
||||||
|
|
||||||
SwapChain::~SwapChain()
|
SwapChain::~SwapChain()
|
||||||
{
|
{
|
||||||
|
for (size_t i = 0; i < MAX_FRAMES_IN_FLIGHT; ++i)
|
||||||
|
{
|
||||||
|
vkDestroyFence(vulkan.GetDevice(), inFlightFences[i], nullptr);
|
||||||
|
vkDestroySemaphore(vulkan.GetDevice(), renderFinishedSemaphores[i], nullptr);
|
||||||
|
vkDestroySemaphore(vulkan.GetDevice(), imageAvailableSemaphores[i], nullptr);
|
||||||
|
}
|
||||||
Destroy();
|
Destroy();
|
||||||
vkDestroyRenderPass(instance.GetDevice(), renderPass, nullptr);
|
vkDestroyRenderPass(vulkan.GetDevice(), renderPass, nullptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
void SwapChain::BeginFrameBuffer(const CommandBuffer& commandBuffer) const
|
void SwapChain::BeginFrameBuffer(const CommandBuffer& commandBuffer) const
|
||||||
@@ -109,47 +112,75 @@ namespace Copium
|
|||||||
return framebuffers[imageIndex];
|
return framebuffers[imageIndex];
|
||||||
}
|
}
|
||||||
|
|
||||||
bool SwapChain::BeginPresent(VkSemaphore signalSemaphore)
|
bool SwapChain::BeginPresent()
|
||||||
{
|
{
|
||||||
VkResult result = vkAcquireNextImageKHR(instance.GetDevice(), handle, UINT64_MAX, signalSemaphore, VK_NULL_HANDLE, &imageIndex);
|
vkWaitForFences(vulkan.GetDevice(), 1, &inFlightFences[flightIndex], VK_TRUE, UINT64_MAX);
|
||||||
|
|
||||||
|
VkResult result = vkAcquireNextImageKHR(vulkan.GetDevice(), handle, UINT64_MAX, imageAvailableSemaphores[flightIndex], VK_NULL_HANDLE, &imageIndex);
|
||||||
if (result == VK_ERROR_OUT_OF_DATE_KHR)
|
if (result == VK_ERROR_OUT_OF_DATE_KHR)
|
||||||
{
|
{
|
||||||
Recreate();
|
Recreate();
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
vkResetFences(vulkan.GetDevice(), 1, &inFlightFences[flightIndex]);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void SwapChain::EndPresent(VkQueue presentQueue, VkSemaphore* waitSemaphore, bool framebufferResized)
|
void SwapChain::SubmitToGraphicsQueue(const CommandBuffer& commandBuffer)
|
||||||
|
{
|
||||||
|
VkCommandBuffer cmd = commandBuffer;
|
||||||
|
VkPipelineStageFlags waitStages[] = {VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT};
|
||||||
|
VkSubmitInfo submitInfo{};
|
||||||
|
submitInfo.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
|
||||||
|
submitInfo.waitSemaphoreCount = 1;
|
||||||
|
submitInfo.pWaitSemaphores = &imageAvailableSemaphores[flightIndex];
|
||||||
|
submitInfo.pWaitDstStageMask = waitStages;
|
||||||
|
submitInfo.commandBufferCount = 1;
|
||||||
|
submitInfo.pCommandBuffers = &cmd;
|
||||||
|
submitInfo.signalSemaphoreCount = 1;
|
||||||
|
submitInfo.pSignalSemaphores = &renderFinishedSemaphores[flightIndex];
|
||||||
|
|
||||||
|
CP_VK_ASSERT(vkQueueSubmit(vulkan.GetDevice().GetGraphicsQueue(), 1, &submitInfo, inFlightFences[flightIndex]), "SubmitGraphicsQueue : Failed to submit command buffer");
|
||||||
|
}
|
||||||
|
|
||||||
|
void SwapChain::EndPresent()
|
||||||
{
|
{
|
||||||
VkPresentInfoKHR presentInfo{};
|
VkPresentInfoKHR presentInfo{};
|
||||||
presentInfo.sType = VK_STRUCTURE_TYPE_PRESENT_INFO_KHR;
|
presentInfo.sType = VK_STRUCTURE_TYPE_PRESENT_INFO_KHR;
|
||||||
presentInfo.waitSemaphoreCount = 1;
|
presentInfo.waitSemaphoreCount = 1;
|
||||||
presentInfo.pWaitSemaphores = waitSemaphore;
|
presentInfo.pWaitSemaphores = &renderFinishedSemaphores[flightIndex];
|
||||||
presentInfo.swapchainCount = 1;
|
presentInfo.swapchainCount = 1;
|
||||||
presentInfo.pSwapchains = &handle;
|
presentInfo.pSwapchains = &handle;
|
||||||
presentInfo.pImageIndices = &imageIndex;
|
presentInfo.pImageIndices = &imageIndex;
|
||||||
presentInfo.pResults = nullptr;
|
presentInfo.pResults = nullptr;
|
||||||
|
|
||||||
VkResult result = vkQueuePresentKHR(presentQueue, &presentInfo);
|
VkResult result = vkQueuePresentKHR(vulkan.GetDevice().GetPresentQueue(), &presentInfo);
|
||||||
if (result == VK_ERROR_OUT_OF_DATE_KHR || result == VK_SUBOPTIMAL_KHR || framebufferResized)
|
if (result == VK_ERROR_OUT_OF_DATE_KHR || result == VK_SUBOPTIMAL_KHR || resizeFramebuffer)
|
||||||
{
|
{
|
||||||
Recreate();
|
Recreate();
|
||||||
|
resizeFramebuffer = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
flightIndex = (flightIndex + 1) % MAX_FRAMES_IN_FLIGHT;
|
||||||
|
}
|
||||||
|
|
||||||
|
void SwapChain::ResizeFramebuffer()
|
||||||
|
{
|
||||||
|
resizeFramebuffer = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void SwapChain::Recreate()
|
void SwapChain::Recreate()
|
||||||
{
|
{
|
||||||
int width = 0;
|
int width = 0;
|
||||||
int height = 0;
|
int height = 0;
|
||||||
glfwGetFramebufferSize(instance.GetWindow(), &width, &height);
|
glfwGetFramebufferSize(vulkan.GetWindow().GetWindow(), &width, &height);
|
||||||
while (width == 0 || height == 0)
|
while (width == 0 || height == 0)
|
||||||
{
|
{
|
||||||
glfwGetFramebufferSize(instance.GetWindow(), &width, &height);
|
glfwGetFramebufferSize(vulkan.GetWindow().GetWindow(), &width, &height);
|
||||||
glfwWaitEvents();
|
glfwWaitEvents();
|
||||||
}
|
}
|
||||||
|
|
||||||
vkDeviceWaitIdle(instance.GetDevice());
|
vkDeviceWaitIdle(vulkan.GetDevice());
|
||||||
|
|
||||||
Destroy();
|
Destroy();
|
||||||
|
|
||||||
@@ -159,13 +190,18 @@ namespace Copium
|
|||||||
InitializeFramebuffers();
|
InitializeFramebuffers();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int SwapChain::GetFlightIndex() const
|
||||||
|
{
|
||||||
|
return flightIndex;
|
||||||
|
}
|
||||||
|
|
||||||
void SwapChain::Initialize()
|
void SwapChain::Initialize()
|
||||||
{
|
{
|
||||||
SwapChainSupportDetails swapChainSupport{instance.GetSurface(), instance.GetPhysicalDevice()};
|
SwapChainSupportDetails swapChainSupport{vulkan.GetWindow().GetSurface(), vulkan.GetDevice().GetPhysicalDevice()};
|
||||||
|
|
||||||
VkSurfaceFormatKHR format = SelectSwapSurfaceFormat(swapChainSupport.formats);
|
VkSurfaceFormatKHR format = SelectSwapSurfaceFormat(swapChainSupport.formats);
|
||||||
VkPresentModeKHR presentMode = SelectSwapPresentMode(swapChainSupport.presentModes);
|
VkPresentModeKHR presentMode = SelectSwapPresentMode(swapChainSupport.presentModes);
|
||||||
extent = SelectSwapExtent(instance.GetWindow(), swapChainSupport.capabilities);
|
extent = SelectSwapExtent(vulkan.GetWindow().GetWindow(), swapChainSupport.capabilities);
|
||||||
imageFormat = format.format;
|
imageFormat = format.format;
|
||||||
uint32_t imageCount = swapChainSupport.capabilities.minImageCount + 1;
|
uint32_t imageCount = swapChainSupport.capabilities.minImageCount + 1;
|
||||||
if (swapChainSupport.capabilities.maxImageCount != 0)
|
if (swapChainSupport.capabilities.maxImageCount != 0)
|
||||||
@@ -173,12 +209,12 @@ namespace Copium
|
|||||||
imageCount = std::min(imageCount, swapChainSupport.capabilities.maxImageCount);
|
imageCount = std::min(imageCount, swapChainSupport.capabilities.maxImageCount);
|
||||||
}
|
}
|
||||||
|
|
||||||
QueueFamiliesQuery queueFamilies{instance.GetSurface(), instance.GetPhysicalDevice()};
|
QueueFamiliesQuery queueFamilies{vulkan.GetWindow().GetSurface(), vulkan.GetDevice().GetPhysicalDevice()};
|
||||||
std::vector<uint32_t> queueFamilyIndices{queueFamilies.graphicsFamily.value(), queueFamilies.presentFamily.value()};
|
std::vector<uint32_t> queueFamilyIndices{queueFamilies.graphicsFamily.value(), queueFamilies.presentFamily.value()};
|
||||||
|
|
||||||
VkSwapchainCreateInfoKHR createInfo{};
|
VkSwapchainCreateInfoKHR createInfo{};
|
||||||
createInfo.sType = VK_STRUCTURE_TYPE_SWAPCHAIN_CREATE_INFO_KHR;
|
createInfo.sType = VK_STRUCTURE_TYPE_SWAPCHAIN_CREATE_INFO_KHR;
|
||||||
createInfo.surface = instance.GetSurface();
|
createInfo.surface = vulkan.GetWindow().GetSurface();
|
||||||
createInfo.minImageCount = imageCount;
|
createInfo.minImageCount = imageCount;
|
||||||
createInfo.imageFormat = format.format;
|
createInfo.imageFormat = format.format;
|
||||||
createInfo.imageColorSpace = format.colorSpace;
|
createInfo.imageColorSpace = format.colorSpace;
|
||||||
@@ -203,11 +239,11 @@ namespace Copium
|
|||||||
createInfo.pQueueFamilyIndices = nullptr;
|
createInfo.pQueueFamilyIndices = nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
CP_VK_ASSERT(vkCreateSwapchainKHR(instance.GetDevice(), &createInfo, nullptr, &handle), "Initialize : Failed to initialize the swapchain");
|
CP_VK_ASSERT(vkCreateSwapchainKHR(vulkan.GetDevice(), &createInfo, nullptr, &handle), "Initialize : Failed to initialize the swapchain");
|
||||||
|
|
||||||
vkGetSwapchainImagesKHR(instance.GetDevice(), handle, &imageCount, nullptr);
|
vkGetSwapchainImagesKHR(vulkan.GetDevice(), handle, &imageCount, nullptr);
|
||||||
images.resize(imageCount);
|
images.resize(imageCount);
|
||||||
vkGetSwapchainImagesKHR(instance.GetDevice(), handle, &imageCount, images.data());
|
vkGetSwapchainImagesKHR(vulkan.GetDevice(), handle, &imageCount, images.data());
|
||||||
}
|
}
|
||||||
|
|
||||||
void SwapChain::InitializeImageViews()
|
void SwapChain::InitializeImageViews()
|
||||||
@@ -215,13 +251,13 @@ namespace Copium
|
|||||||
imageViews.resize(images.size());
|
imageViews.resize(images.size());
|
||||||
for (size_t i = 0; i < images.size(); i++)
|
for (size_t i = 0; i < images.size(); i++)
|
||||||
{
|
{
|
||||||
imageViews[i] = Image::InitializeImageView(instance, images[i], imageFormat, VK_IMAGE_ASPECT_COLOR_BIT);
|
imageViews[i] = Image::InitializeImageView(vulkan, images[i], imageFormat, VK_IMAGE_ASPECT_COLOR_BIT);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void SwapChain::InitializeDepthAttachment()
|
void SwapChain::InitializeDepthAttachment()
|
||||||
{
|
{
|
||||||
depthAttachment = std::make_unique<DepthAttachment>(instance, extent.width, extent.height);
|
depthAttachment = std::make_unique<DepthAttachment>(vulkan, extent.width, extent.height);
|
||||||
}
|
}
|
||||||
|
|
||||||
void SwapChain::InitializeRenderPass()
|
void SwapChain::InitializeRenderPass()
|
||||||
@@ -237,7 +273,7 @@ namespace Copium
|
|||||||
colorAttachment.finalLayout = VK_IMAGE_LAYOUT_PRESENT_SRC_KHR;
|
colorAttachment.finalLayout = VK_IMAGE_LAYOUT_PRESENT_SRC_KHR;
|
||||||
|
|
||||||
VkAttachmentDescription depthAttachment{};
|
VkAttachmentDescription depthAttachment{};
|
||||||
depthAttachment.format = Image::SelectDepthFormat(instance);
|
depthAttachment.format = Image::SelectDepthFormat(vulkan);
|
||||||
depthAttachment.samples = VK_SAMPLE_COUNT_1_BIT;
|
depthAttachment.samples = VK_SAMPLE_COUNT_1_BIT;
|
||||||
depthAttachment.loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR;
|
depthAttachment.loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR;
|
||||||
depthAttachment.storeOp = VK_ATTACHMENT_STORE_OP_STORE;
|
depthAttachment.storeOp = VK_ATTACHMENT_STORE_OP_STORE;
|
||||||
@@ -278,7 +314,7 @@ namespace Copium
|
|||||||
renderPassCreateInfo.dependencyCount = 1;
|
renderPassCreateInfo.dependencyCount = 1;
|
||||||
renderPassCreateInfo.pDependencies = &dependency;
|
renderPassCreateInfo.pDependencies = &dependency;
|
||||||
|
|
||||||
CP_VK_ASSERT(vkCreateRenderPass(instance.GetDevice(), &renderPassCreateInfo, nullptr, &renderPass), "InitializeRenderPass : Failed to initialze render pass");
|
CP_VK_ASSERT(vkCreateRenderPass(vulkan.GetDevice(), &renderPassCreateInfo, nullptr, &renderPass), "InitializeRenderPass : Failed to initialze render pass");
|
||||||
}
|
}
|
||||||
|
|
||||||
void SwapChain::InitializeFramebuffers()
|
void SwapChain::InitializeFramebuffers()
|
||||||
@@ -298,7 +334,27 @@ namespace Copium
|
|||||||
createInfo.height = extent.height;
|
createInfo.height = extent.height;
|
||||||
createInfo.layers = 1;
|
createInfo.layers = 1;
|
||||||
|
|
||||||
CP_VK_ASSERT(vkCreateFramebuffer(instance.GetDevice(), &createInfo, nullptr, &framebuffers[i]), "InitializeFramebuffers : Failed to initialize swap chain framebuffer");
|
CP_VK_ASSERT(vkCreateFramebuffer(vulkan.GetDevice(), &createInfo, nullptr, &framebuffers[i]), "InitializeFramebuffers : Failed to initialize swap chain framebuffer");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void SwapChain::InitializeSyncObjects()
|
||||||
|
{
|
||||||
|
imageAvailableSemaphores.resize(MAX_FRAMES_IN_FLIGHT);
|
||||||
|
renderFinishedSemaphores.resize(MAX_FRAMES_IN_FLIGHT);
|
||||||
|
inFlightFences.resize(MAX_FRAMES_IN_FLIGHT);
|
||||||
|
VkSemaphoreCreateInfo semaphoreCreateInfo{};
|
||||||
|
semaphoreCreateInfo.sType = VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO;
|
||||||
|
for (size_t i = 0; i < MAX_FRAMES_IN_FLIGHT; ++i)
|
||||||
|
{
|
||||||
|
CP_VK_ASSERT(vkCreateSemaphore(vulkan.GetDevice(), &semaphoreCreateInfo, nullptr, &imageAvailableSemaphores[i]), "InitializeSyncObjects : Failed to initialize available image semaphore");
|
||||||
|
CP_VK_ASSERT(vkCreateSemaphore(vulkan.GetDevice(), &semaphoreCreateInfo, nullptr, &renderFinishedSemaphores[i]), "InitializeSyncObjects : Failed to initialize render finished semaphore");
|
||||||
|
|
||||||
|
VkFenceCreateInfo fenceCreateInfo{};
|
||||||
|
fenceCreateInfo.sType = VK_STRUCTURE_TYPE_FENCE_CREATE_INFO;
|
||||||
|
fenceCreateInfo.flags = VK_FENCE_CREATE_SIGNALED_BIT;
|
||||||
|
|
||||||
|
CP_VK_ASSERT(vkCreateFence(vulkan.GetDevice(), &fenceCreateInfo, nullptr, &inFlightFences[i]), "InitializeSyncObjects : Failed to initialize in flight fence");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -306,13 +362,13 @@ namespace Copium
|
|||||||
{
|
{
|
||||||
for (auto&& framebuffer : framebuffers)
|
for (auto&& framebuffer : framebuffers)
|
||||||
{
|
{
|
||||||
vkDestroyFramebuffer(instance.GetDevice(), framebuffer, nullptr);
|
vkDestroyFramebuffer(vulkan.GetDevice(), framebuffer, nullptr);
|
||||||
}
|
}
|
||||||
for (auto&& swapChainImageView : imageViews)
|
for (auto&& swapChainImageView : imageViews)
|
||||||
{
|
{
|
||||||
vkDestroyImageView(instance.GetDevice(), swapChainImageView, nullptr);
|
vkDestroyImageView(vulkan.GetDevice(), swapChainImageView, nullptr);
|
||||||
}
|
}
|
||||||
vkDestroySwapchainKHR(instance.GetDevice(), handle, nullptr);
|
vkDestroySwapchainKHR(vulkan.GetDevice(), handle, nullptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
VkSurfaceFormatKHR SwapChain::SelectSwapSurfaceFormat(const std::vector<VkSurfaceFormatKHR>& availableFormats)
|
VkSurfaceFormatKHR SwapChain::SelectSwapSurfaceFormat(const std::vector<VkSurfaceFormatKHR>& availableFormats)
|
||||||
|
|||||||
@@ -1,5 +1,8 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include "copium/buffer/CommandBuffer.h"
|
||||||
|
#include "copium/core/Vulkan.h"
|
||||||
|
#include "copium/sampler/DepthAttachment.h"
|
||||||
#include "copium/util/Common.h"
|
#include "copium/util/Common.h"
|
||||||
|
|
||||||
#include <GLFW/glfw3.h>
|
#include <GLFW/glfw3.h>
|
||||||
@@ -8,10 +11,6 @@
|
|||||||
|
|
||||||
namespace Copium
|
namespace Copium
|
||||||
{
|
{
|
||||||
class Instance;
|
|
||||||
class CommandBuffer;
|
|
||||||
class DepthAttachment;
|
|
||||||
|
|
||||||
struct SwapChainSupportDetails
|
struct SwapChainSupportDetails
|
||||||
{
|
{
|
||||||
VkSurfaceCapabilitiesKHR capabilities;
|
VkSurfaceCapabilitiesKHR capabilities;
|
||||||
@@ -25,8 +24,10 @@ namespace Copium
|
|||||||
class SwapChain final
|
class SwapChain final
|
||||||
{
|
{
|
||||||
CP_DELETE_COPY_AND_MOVE_CTOR(SwapChain);
|
CP_DELETE_COPY_AND_MOVE_CTOR(SwapChain);
|
||||||
|
public:
|
||||||
|
static const int MAX_FRAMES_IN_FLIGHT = 2;
|
||||||
private:
|
private:
|
||||||
Instance& instance;
|
Vulkan& vulkan;
|
||||||
|
|
||||||
VkSwapchainKHR handle;
|
VkSwapchainKHR handle;
|
||||||
VkRenderPass renderPass;
|
VkRenderPass renderPass;
|
||||||
@@ -37,9 +38,15 @@ namespace Copium
|
|||||||
std::vector<VkImage> images;
|
std::vector<VkImage> images;
|
||||||
std::vector<VkFramebuffer> framebuffers;
|
std::vector<VkFramebuffer> framebuffers;
|
||||||
uint32_t imageIndex;
|
uint32_t imageIndex;
|
||||||
|
bool resizeFramebuffer;
|
||||||
|
|
||||||
|
int flightIndex;
|
||||||
|
std::vector<VkSemaphore> imageAvailableSemaphores;
|
||||||
|
std::vector<VkSemaphore> renderFinishedSemaphores;
|
||||||
|
std::vector<VkFence> inFlightFences;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
SwapChain(Instance& instance);
|
SwapChain(Vulkan& vulkan);
|
||||||
~SwapChain();
|
~SwapChain();
|
||||||
|
|
||||||
void BeginFrameBuffer(const CommandBuffer& commandBuffer) const;
|
void BeginFrameBuffer(const CommandBuffer& commandBuffer) const;
|
||||||
@@ -48,10 +55,13 @@ namespace Copium
|
|||||||
VkRenderPass GetRenderPass() const;
|
VkRenderPass GetRenderPass() const;
|
||||||
VkExtent2D GetExtent() const;
|
VkExtent2D GetExtent() const;
|
||||||
VkFramebuffer GetFramebuffer() const;
|
VkFramebuffer GetFramebuffer() const;
|
||||||
bool BeginPresent(VkSemaphore signalSemaphore);
|
bool BeginPresent();
|
||||||
void EndPresent(VkQueue presentQueue, VkSemaphore* waitSemaphore, bool framebufferResized);
|
void SubmitToGraphicsQueue(const CommandBuffer& commandBuffer);
|
||||||
|
void EndPresent();
|
||||||
|
void ResizeFramebuffer();
|
||||||
void Recreate();
|
void Recreate();
|
||||||
|
|
||||||
|
int GetFlightIndex() const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void Initialize();
|
void Initialize();
|
||||||
@@ -59,6 +69,7 @@ namespace Copium
|
|||||||
void InitializeDepthAttachment();
|
void InitializeDepthAttachment();
|
||||||
void InitializeRenderPass();
|
void InitializeRenderPass();
|
||||||
void InitializeFramebuffers();
|
void InitializeFramebuffers();
|
||||||
|
void InitializeSyncObjects();
|
||||||
void Destroy();
|
void Destroy();
|
||||||
|
|
||||||
VkSurfaceFormatKHR SelectSwapSurfaceFormat(const std::vector<VkSurfaceFormatKHR>& availableFormats);
|
VkSurfaceFormatKHR SelectSwapSurfaceFormat(const std::vector<VkSurfaceFormatKHR>& availableFormats);
|
||||||
|
|||||||
@@ -0,0 +1,54 @@
|
|||||||
|
#include "copium/core/Vulkan.h"
|
||||||
|
|
||||||
|
#include "copium/core/Device.h"
|
||||||
|
#include "copium/core/Instance.h"
|
||||||
|
#include "copium/core/SwapChain.h"
|
||||||
|
#include "copium/core/Window.h"
|
||||||
|
|
||||||
|
namespace Copium
|
||||||
|
{
|
||||||
|
void Vulkan::SetInstance(std::unique_ptr<Instance>&& instance)
|
||||||
|
{
|
||||||
|
this->instance = std::move(instance);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Vulkan::SetWindow(std::unique_ptr<Window>&& window)
|
||||||
|
{
|
||||||
|
this->window = std::move(window);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Vulkan::SetDevice(std::unique_ptr<Device>&& device)
|
||||||
|
{
|
||||||
|
this->device = std::move(device);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Vulkan::SetSwapChain(std::unique_ptr<SwapChain>&& swapChain)
|
||||||
|
{
|
||||||
|
this->swapChain = std::move(swapChain);
|
||||||
|
}
|
||||||
|
|
||||||
|
Instance& Vulkan::GetInstance() const
|
||||||
|
{
|
||||||
|
return *instance;
|
||||||
|
}
|
||||||
|
|
||||||
|
Window& Vulkan::GetWindow() const
|
||||||
|
{
|
||||||
|
return *window;
|
||||||
|
}
|
||||||
|
|
||||||
|
Device& Vulkan::GetDevice() const
|
||||||
|
{
|
||||||
|
return *device;
|
||||||
|
}
|
||||||
|
|
||||||
|
SwapChain& Vulkan::GetSwapChain() const
|
||||||
|
{
|
||||||
|
return *swapChain;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Vulkan::Valid()
|
||||||
|
{
|
||||||
|
return instance && window && device && swapChain;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,31 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <memory>
|
||||||
|
|
||||||
|
namespace Copium
|
||||||
|
{
|
||||||
|
class Instance;
|
||||||
|
class Window;
|
||||||
|
class Device;
|
||||||
|
class SwapChain;
|
||||||
|
|
||||||
|
class Vulkan
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
std::unique_ptr<Instance> instance;
|
||||||
|
std::unique_ptr<Window> window;
|
||||||
|
std::unique_ptr<Device> device;
|
||||||
|
std::unique_ptr<SwapChain> swapChain;
|
||||||
|
public:
|
||||||
|
void SetInstance(std::unique_ptr<Instance>&& instance);
|
||||||
|
void SetWindow(std::unique_ptr<Window>&& window);
|
||||||
|
void SetDevice(std::unique_ptr<Device>&& device);
|
||||||
|
void SetSwapChain(std::unique_ptr<SwapChain>&& swapChain);
|
||||||
|
Instance& GetInstance() const;
|
||||||
|
Window& GetWindow() const;
|
||||||
|
Device& GetDevice() const;
|
||||||
|
SwapChain& GetSwapChain() const;
|
||||||
|
bool Valid();
|
||||||
|
|
||||||
|
};
|
||||||
|
}
|
||||||
@@ -0,0 +1,78 @@
|
|||||||
|
#include "copium/core/Window.h"
|
||||||
|
|
||||||
|
#include "copium/core/Instance.h"
|
||||||
|
#include "copium/core/SwapChain.h"
|
||||||
|
|
||||||
|
namespace Copium
|
||||||
|
{
|
||||||
|
Window::Window(Vulkan& vulkan, const std::string& windowName, int width, int height, Mode mode)
|
||||||
|
: vulkan{vulkan}
|
||||||
|
{
|
||||||
|
InitializeWindow(windowName, width, height, mode);
|
||||||
|
InitializeSurface();
|
||||||
|
}
|
||||||
|
|
||||||
|
Window::~Window()
|
||||||
|
{
|
||||||
|
vkDestroySurfaceKHR(vulkan.GetInstance(), surface, nullptr);
|
||||||
|
glfwDestroyWindow(window);
|
||||||
|
}
|
||||||
|
|
||||||
|
VkSurfaceKHR Window::GetSurface() const
|
||||||
|
{
|
||||||
|
return surface;
|
||||||
|
}
|
||||||
|
|
||||||
|
GLFWwindow* Window::GetWindow()
|
||||||
|
{
|
||||||
|
return window;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Window::InitializeWindow(const std::string& windowName, int width, int height, Mode mode)
|
||||||
|
{
|
||||||
|
glfwWindowHint(GLFW_CLIENT_API, GLFW_NO_API);
|
||||||
|
|
||||||
|
switch (mode)
|
||||||
|
{
|
||||||
|
case Mode::Fullscreen:
|
||||||
|
{
|
||||||
|
GLFWmonitor* monitor = glfwGetPrimaryMonitor();
|
||||||
|
const GLFWvidmode* mode = glfwGetVideoMode(monitor);
|
||||||
|
window = glfwCreateWindow(mode->width, mode->height, windowName.c_str(), glfwGetPrimaryMonitor(), nullptr);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case Mode::BorderlessWindowed:
|
||||||
|
{
|
||||||
|
GLFWmonitor* monitor = glfwGetPrimaryMonitor();
|
||||||
|
const GLFWvidmode* mode = glfwGetVideoMode(monitor);
|
||||||
|
window = glfwCreateWindow(mode->width, mode->height, windowName.c_str(), nullptr, nullptr);
|
||||||
|
glfwSetWindowMonitor(window, monitor, 0, 0, mode->width, mode->height, mode->refreshRate);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case Mode::Windowed:
|
||||||
|
{
|
||||||
|
window = glfwCreateWindow(width, height, windowName.c_str(), nullptr, nullptr);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
CP_ABORT("Window : Unreachable switch case");
|
||||||
|
}
|
||||||
|
|
||||||
|
CP_ASSERT(window, "InitializeWindow : Failed to initialize glfw window");
|
||||||
|
|
||||||
|
glfwSetWindowUserPointer(window, this);
|
||||||
|
glfwSetFramebufferSizeCallback(window, FramebufferResizeCallback);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Window::InitializeSurface()
|
||||||
|
{
|
||||||
|
CP_VK_ASSERT(glfwCreateWindowSurface(vulkan.GetInstance(), window, nullptr, &surface), "InitializeSurface : Failed to create Vulkan surface");
|
||||||
|
}
|
||||||
|
|
||||||
|
void Window::FramebufferResizeCallback(GLFWwindow* glfwWindow, int width, int height)
|
||||||
|
{
|
||||||
|
Window* window = static_cast<Window*>(glfwGetWindowUserPointer(glfwWindow));
|
||||||
|
window->vulkan.GetSwapChain().ResizeFramebuffer(); // TODO: Should maybe be handled by an event system?
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,37 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "copium/core/Vulkan.h"
|
||||||
|
#include "copium/util/Common.h"
|
||||||
|
|
||||||
|
#include <GLFW/glfw3.h>
|
||||||
|
|
||||||
|
namespace Copium
|
||||||
|
{
|
||||||
|
class Window final
|
||||||
|
{
|
||||||
|
CP_DELETE_COPY_AND_MOVE_CTOR(Window);
|
||||||
|
public:
|
||||||
|
enum class Mode
|
||||||
|
{
|
||||||
|
Fullscreen, BorderlessWindowed, Windowed
|
||||||
|
};
|
||||||
|
private:
|
||||||
|
Vulkan& vulkan;
|
||||||
|
|
||||||
|
GLFWwindow* window;
|
||||||
|
VkSurfaceKHR surface;
|
||||||
|
|
||||||
|
public:
|
||||||
|
Window(Vulkan& vulkan, const std::string& windowName, int width, int height, Mode mode);
|
||||||
|
~Window();
|
||||||
|
|
||||||
|
VkSurfaceKHR GetSurface() const;
|
||||||
|
GLFWwindow* GetWindow();
|
||||||
|
|
||||||
|
private:
|
||||||
|
void InitializeWindow(const std::string& windowName, int width, int height, Mode mode);
|
||||||
|
void InitializeSurface();
|
||||||
|
static void FramebufferResizeCallback(GLFWwindow* glfwWindow, int width, int height);
|
||||||
|
|
||||||
|
};
|
||||||
|
}
|
||||||
@@ -3,7 +3,7 @@
|
|||||||
#include "copium/buffer/IndexBuffer.h"
|
#include "copium/buffer/IndexBuffer.h"
|
||||||
#include "copium/buffer/VertexBuffer.h"
|
#include "copium/buffer/VertexBuffer.h"
|
||||||
#include "copium/buffer/CommandBuffer.h"
|
#include "copium/buffer/CommandBuffer.h"
|
||||||
#include "copium/core/Instance.h"
|
#include "copium/core/Vulkan.h"
|
||||||
#include "copium/util/Common.h"
|
#include "copium/util/Common.h"
|
||||||
|
|
||||||
#include <vector>
|
#include <vector>
|
||||||
@@ -19,18 +19,18 @@ namespace Copium
|
|||||||
std::unique_ptr<VertexBuffer> vertexBuffer;
|
std::unique_ptr<VertexBuffer> vertexBuffer;
|
||||||
public:
|
public:
|
||||||
template <typename T>
|
template <typename T>
|
||||||
Mesh(Instance& instance, const std::vector<T>& vertices, const std::vector<uint16_t>& indices);
|
Mesh(Vulkan& vulkan, const std::vector<T>& vertices, const std::vector<uint16_t>& indices);
|
||||||
|
|
||||||
void Bind(const CommandBuffer& commandBuffer);
|
void Bind(const CommandBuffer& commandBuffer);
|
||||||
void Render(const CommandBuffer& commandBuffer);
|
void Render(const CommandBuffer& commandBuffer);
|
||||||
};
|
};
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
Mesh::Mesh(Instance& instance, const std::vector<T>& vertices, const std::vector<uint16_t>& indices)
|
Mesh::Mesh(Vulkan& vulkan, const std::vector<T>& vertices, const std::vector<uint16_t>& indices)
|
||||||
{
|
{
|
||||||
indexBuffer = std::make_unique<IndexBuffer>(instance, indices.size());
|
indexBuffer = std::make_unique<IndexBuffer>(vulkan, indices.size());
|
||||||
indexBuffer->UpdateStaging((void*)indices.data());
|
indexBuffer->UpdateStaging((void*)indices.data());
|
||||||
vertexBuffer = std::make_unique<VertexBuffer>(instance, T::GetDescriptor(), vertices.size());
|
vertexBuffer = std::make_unique<VertexBuffer>(vulkan, T::GetDescriptor(), vertices.size());
|
||||||
vertexBuffer ->UpdateStaging(0, (void*)vertices.data());
|
vertexBuffer ->UpdateStaging(0, (void*)vertices.data());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,50 +1,52 @@
|
|||||||
#include "copium/pipeline/DescriptorPool.h"
|
#include "copium/pipeline/DescriptorPool.h"
|
||||||
|
|
||||||
|
#include "copium/core/Device.h"
|
||||||
|
#include "copium/core/SwapChain.h"
|
||||||
|
|
||||||
namespace Copium
|
namespace Copium
|
||||||
{
|
{
|
||||||
DescriptorPool::DescriptorPool(Instance& instance)
|
DescriptorPool::DescriptorPool(Vulkan& vulkan)
|
||||||
: instance{instance}
|
: vulkan{vulkan}
|
||||||
{
|
{
|
||||||
std::vector<VkDescriptorPoolSize> poolSizes{2};
|
std::vector<VkDescriptorPoolSize> poolSizes{2};
|
||||||
poolSizes[0].type = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
|
poolSizes[0].type = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER;
|
||||||
poolSizes[0].descriptorCount = DESCRIPTOR_SET_COUNT * instance.GetMaxFramesInFlight(); // TODO: how should this actually be determined?
|
poolSizes[0].descriptorCount = DESCRIPTOR_SET_COUNT * SwapChain::MAX_FRAMES_IN_FLIGHT; // TODO: how should this actually be determined?
|
||||||
|
|
||||||
poolSizes[1].type = VK_DESCRIPTOR_TYPE_SAMPLER;
|
poolSizes[1].type = VK_DESCRIPTOR_TYPE_SAMPLER;
|
||||||
poolSizes[1].descriptorCount = DESCRIPTOR_SET_COUNT * instance.GetMaxFramesInFlight(); // TODO: how should this actually be determined?
|
poolSizes[1].descriptorCount = DESCRIPTOR_SET_COUNT * SwapChain::MAX_FRAMES_IN_FLIGHT; // TODO: how should this actually be determined?
|
||||||
|
|
||||||
VkDescriptorPoolCreateInfo createInfo{};
|
VkDescriptorPoolCreateInfo createInfo{};
|
||||||
createInfo.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO;
|
createInfo.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO;
|
||||||
createInfo.poolSizeCount = poolSizes.size();
|
createInfo.poolSizeCount = poolSizes.size();
|
||||||
createInfo.pPoolSizes = poolSizes.data();
|
createInfo.pPoolSizes = poolSizes.data();
|
||||||
createInfo.maxSets = DESCRIPTOR_SET_COUNT * instance.GetMaxFramesInFlight();
|
createInfo.maxSets = DESCRIPTOR_SET_COUNT * SwapChain::MAX_FRAMES_IN_FLIGHT;
|
||||||
createInfo.flags = VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT;
|
createInfo.flags = VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT;
|
||||||
|
|
||||||
CP_VK_ASSERT(vkCreateDescriptorPool(instance.GetDevice(), &createInfo, nullptr, &descriptorPool), "DescriptorPool : Failed to initialize descriptor pool");
|
CP_VK_ASSERT(vkCreateDescriptorPool(vulkan.GetDevice(), &createInfo, nullptr, &descriptorPool), "DescriptorPool : Failed to initialize descriptor pool");
|
||||||
}
|
}
|
||||||
|
|
||||||
DescriptorPool::~DescriptorPool()
|
DescriptorPool::~DescriptorPool()
|
||||||
{
|
{
|
||||||
vkDestroyDescriptorPool(instance.GetDevice(), descriptorPool, nullptr);
|
vkDestroyDescriptorPool(vulkan.GetDevice(), descriptorPool, nullptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<VkDescriptorSet> DescriptorPool::AllocateDescriptorSets(VkDescriptorSetLayout descriptorSetLayout)
|
std::vector<VkDescriptorSet> DescriptorPool::AllocateDescriptorSets(VkDescriptorSetLayout descriptorSetLayout)
|
||||||
{
|
{
|
||||||
std::vector<VkDescriptorSet> descriptorSets;
|
std::vector<VkDescriptorSet> descriptorSets{SwapChain::MAX_FRAMES_IN_FLIGHT};
|
||||||
std::vector<VkDescriptorSetLayout> layouts{static_cast<size_t>(instance.GetMaxFramesInFlight()), descriptorSetLayout};
|
std::vector<VkDescriptorSetLayout> layouts{SwapChain::MAX_FRAMES_IN_FLIGHT, descriptorSetLayout};
|
||||||
VkDescriptorSetAllocateInfo allocateInfo{};
|
VkDescriptorSetAllocateInfo allocateInfo{};
|
||||||
allocateInfo.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO;
|
allocateInfo.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO;
|
||||||
allocateInfo.descriptorPool = descriptorPool;
|
allocateInfo.descriptorPool = descriptorPool;
|
||||||
allocateInfo.descriptorSetCount = instance.GetMaxFramesInFlight();
|
allocateInfo.descriptorSetCount = descriptorSets.size();
|
||||||
allocateInfo.pSetLayouts = layouts.data();
|
allocateInfo.pSetLayouts = layouts.data();
|
||||||
|
|
||||||
descriptorSets.resize(instance.GetMaxFramesInFlight());
|
CP_VK_ASSERT(vkAllocateDescriptorSets(vulkan.GetDevice(), &allocateInfo, descriptorSets.data()), "AllocateDescriptorSets : Failed to allocate descriptor sets");
|
||||||
CP_VK_ASSERT(vkAllocateDescriptorSets(instance.GetDevice(), &allocateInfo, descriptorSets.data()), "AllocateDescriptorSets : Failed to allocate descriptor sets");
|
|
||||||
|
|
||||||
return descriptorSets;
|
return descriptorSets;
|
||||||
}
|
}
|
||||||
|
|
||||||
void DescriptorPool::FreeDescriptorSets(const std::vector<VkDescriptorSet>& descriptorSets)
|
void DescriptorPool::FreeDescriptorSets(const std::vector<VkDescriptorSet>& descriptorSets)
|
||||||
{
|
{
|
||||||
vkFreeDescriptorSets(instance.GetDevice(), descriptorPool, descriptorSets.size(), descriptorSets.data());
|
vkFreeDescriptorSets(vulkan.GetDevice(), descriptorPool, descriptorSets.size(), descriptorSets.data());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1,7 +1,7 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "copium/util/Common.h"
|
#include "copium/util/Common.h"
|
||||||
#include "copium/core/Instance.h"
|
#include "copium/core/Vulkan.h"
|
||||||
|
|
||||||
#include <vulkan/vulkan.hpp>
|
#include <vulkan/vulkan.hpp>
|
||||||
|
|
||||||
@@ -11,12 +11,12 @@ namespace Copium
|
|||||||
{
|
{
|
||||||
CP_DELETE_COPY_AND_MOVE_CTOR(DescriptorPool);
|
CP_DELETE_COPY_AND_MOVE_CTOR(DescriptorPool);
|
||||||
private:
|
private:
|
||||||
Instance& instance;
|
Vulkan& vulkan;
|
||||||
|
|
||||||
VkDescriptorPool descriptorPool;
|
VkDescriptorPool descriptorPool;
|
||||||
static const int DESCRIPTOR_SET_COUNT = 100;
|
static const int DESCRIPTOR_SET_COUNT = 100;
|
||||||
public:
|
public:
|
||||||
DescriptorPool(Instance& instance);
|
DescriptorPool(Vulkan& vulkan);
|
||||||
~DescriptorPool();
|
~DescriptorPool();
|
||||||
|
|
||||||
std::vector<VkDescriptorSet> AllocateDescriptorSets(VkDescriptorSetLayout descriptorSetLayout);
|
std::vector<VkDescriptorSet> AllocateDescriptorSets(VkDescriptorSetLayout descriptorSetLayout);
|
||||||
|
|||||||
@@ -1,9 +1,12 @@
|
|||||||
#include "copium/pipeline/DescriptorSet.h"
|
#include "copium/pipeline/DescriptorSet.h"
|
||||||
|
|
||||||
|
#include "copium/core/Device.h"
|
||||||
|
#include "copium/core/SwapChain.h"
|
||||||
|
|
||||||
namespace Copium
|
namespace Copium
|
||||||
{
|
{
|
||||||
DescriptorSet::DescriptorSet(Instance& instance, DescriptorPool& descriptorPool, VkDescriptorSetLayout descriptorSetLayout)
|
DescriptorSet::DescriptorSet(Vulkan& vulkan, DescriptorPool& descriptorPool, VkDescriptorSetLayout descriptorSetLayout)
|
||||||
: instance{instance}, descriptorPool{descriptorPool}, descriptorSetLayout{descriptorSetLayout}
|
: vulkan{vulkan}, descriptorPool{descriptorPool}, descriptorSetLayout{descriptorSetLayout}
|
||||||
{
|
{
|
||||||
descriptorSets = descriptorPool.AllocateDescriptorSets(descriptorSetLayout);
|
descriptorSets = descriptorPool.AllocateDescriptorSets(descriptorSetLayout);
|
||||||
}
|
}
|
||||||
@@ -15,7 +18,7 @@ namespace Copium
|
|||||||
|
|
||||||
void DescriptorSet::AddUniform(const UniformBuffer& uniformBuffer, uint32_t binding)
|
void DescriptorSet::AddUniform(const UniformBuffer& uniformBuffer, uint32_t binding)
|
||||||
{
|
{
|
||||||
for (size_t i = 0; i < instance.GetMaxFramesInFlight(); ++i) {
|
for (size_t i = 0; i < descriptorSets.size(); ++i) {
|
||||||
VkDescriptorBufferInfo bufferInfo = uniformBuffer.GetDescriptorBufferInfo(i);
|
VkDescriptorBufferInfo bufferInfo = uniformBuffer.GetDescriptorBufferInfo(i);
|
||||||
|
|
||||||
VkWriteDescriptorSet descriptorWrite{};
|
VkWriteDescriptorSet descriptorWrite{};
|
||||||
@@ -28,13 +31,13 @@ namespace Copium
|
|||||||
descriptorWrite.pBufferInfo = &bufferInfo;
|
descriptorWrite.pBufferInfo = &bufferInfo;
|
||||||
descriptorWrite.pImageInfo = nullptr;
|
descriptorWrite.pImageInfo = nullptr;
|
||||||
descriptorWrite.pTexelBufferView = nullptr;
|
descriptorWrite.pTexelBufferView = nullptr;
|
||||||
vkUpdateDescriptorSets(instance.GetDevice(), 1, &descriptorWrite, 0, nullptr);
|
vkUpdateDescriptorSets(vulkan.GetDevice(), 1, &descriptorWrite, 0, nullptr);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void DescriptorSet::AddSampler(const Sampler& sampler, uint32_t binding)
|
void DescriptorSet::AddSampler(const Sampler& sampler, uint32_t binding)
|
||||||
{
|
{
|
||||||
for (size_t i = 0; i < instance.GetMaxFramesInFlight(); ++i) {
|
for (size_t i = 0; i < descriptorSets.size(); ++i) {
|
||||||
VkDescriptorImageInfo imageInfo = sampler.GetDescriptorImageInfo(i);
|
VkDescriptorImageInfo imageInfo = sampler.GetDescriptorImageInfo(i);
|
||||||
VkWriteDescriptorSet descriptorWrite{};
|
VkWriteDescriptorSet descriptorWrite{};
|
||||||
descriptorWrite.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
|
descriptorWrite.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
|
||||||
@@ -46,12 +49,12 @@ namespace Copium
|
|||||||
descriptorWrite.pBufferInfo = nullptr;
|
descriptorWrite.pBufferInfo = nullptr;
|
||||||
descriptorWrite.pImageInfo = &imageInfo;
|
descriptorWrite.pImageInfo = &imageInfo;
|
||||||
descriptorWrite.pTexelBufferView = nullptr;
|
descriptorWrite.pTexelBufferView = nullptr;
|
||||||
vkUpdateDescriptorSets(instance.GetDevice(), 1, &descriptorWrite, 0, nullptr);
|
vkUpdateDescriptorSets(vulkan.GetDevice(), 1, &descriptorWrite, 0, nullptr);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
DescriptorSet::operator VkDescriptorSet() const
|
DescriptorSet::operator VkDescriptorSet() const
|
||||||
{
|
{
|
||||||
return descriptorSets[instance.GetFlightIndex()];
|
return descriptorSets[vulkan.GetSwapChain().GetFlightIndex()];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -13,14 +13,14 @@ namespace Copium
|
|||||||
{
|
{
|
||||||
CP_DELETE_COPY_AND_MOVE_CTOR(DescriptorSet);
|
CP_DELETE_COPY_AND_MOVE_CTOR(DescriptorSet);
|
||||||
private:
|
private:
|
||||||
Instance& instance;
|
Vulkan& vulkan;
|
||||||
DescriptorPool& descriptorPool;
|
DescriptorPool& descriptorPool;
|
||||||
VkDescriptorSetLayout descriptorSetLayout;
|
VkDescriptorSetLayout descriptorSetLayout;
|
||||||
|
|
||||||
std::vector<VkDescriptorSet> descriptorSets;
|
std::vector<VkDescriptorSet> descriptorSets;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
DescriptorSet(Instance& instance, DescriptorPool& descriptorPool, VkDescriptorSetLayout descriptorSetLayout);
|
DescriptorSet(Vulkan& vulkan, DescriptorPool& descriptorPool, VkDescriptorSetLayout descriptorSetLayout);
|
||||||
~DescriptorSet();
|
~DescriptorSet();
|
||||||
|
|
||||||
void AddUniform(const UniformBuffer& uniformBuffer, uint32_t binding);
|
void AddUniform(const UniformBuffer& uniformBuffer, uint32_t binding);
|
||||||
|
|||||||
@@ -1,12 +1,13 @@
|
|||||||
#include "copium/pipeline/Pipeline.h"
|
#include "copium/pipeline/Pipeline.h"
|
||||||
|
|
||||||
|
#include "copium/core/Device.h"
|
||||||
#include "copium/pipeline/Shader.h"
|
#include "copium/pipeline/Shader.h"
|
||||||
#include "copium/util/FileSystem.h"
|
#include "copium/util/FileSystem.h"
|
||||||
|
|
||||||
namespace Copium
|
namespace Copium
|
||||||
{
|
{
|
||||||
Pipeline::Pipeline(Instance& instance, PipelineCreator creator)
|
Pipeline::Pipeline(Vulkan& vulkan, PipelineCreator creator)
|
||||||
: instance{instance}
|
: vulkan{vulkan}
|
||||||
{
|
{
|
||||||
InitializeDescriptorSetLayout(creator);
|
InitializeDescriptorSetLayout(creator);
|
||||||
InitializePipeline(creator);
|
InitializePipeline(creator);
|
||||||
@@ -14,11 +15,11 @@ namespace Copium
|
|||||||
|
|
||||||
Pipeline::~Pipeline()
|
Pipeline::~Pipeline()
|
||||||
{
|
{
|
||||||
vkDestroyPipeline(instance.GetDevice(), graphicsPipeline, nullptr);
|
vkDestroyPipeline(vulkan.GetDevice(), graphicsPipeline, nullptr);
|
||||||
vkDestroyPipelineLayout(instance.GetDevice(), pipelineLayout, nullptr);
|
vkDestroyPipelineLayout(vulkan.GetDevice(), pipelineLayout, nullptr);
|
||||||
for (auto&& descriptorSetLayout : descriptorSetLayouts)
|
for (auto&& descriptorSetLayout : descriptorSetLayouts)
|
||||||
{
|
{
|
||||||
vkDestroyDescriptorSetLayout(instance.GetDevice(), descriptorSetLayout, nullptr);
|
vkDestroyDescriptorSetLayout(vulkan.GetDevice(), descriptorSetLayout, nullptr);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -67,13 +68,13 @@ namespace Copium
|
|||||||
createInfo.bindingCount = layoutBindings.size();
|
createInfo.bindingCount = layoutBindings.size();
|
||||||
createInfo.pBindings = layoutBindings.data();
|
createInfo.pBindings = layoutBindings.data();
|
||||||
|
|
||||||
CP_VK_ASSERT(vkCreateDescriptorSetLayout(instance.GetDevice(), &createInfo, nullptr, &descriptorSetLayouts[i++]), "InitializeDescriptorSetLayout : Failed to initialize descriptor set layout");
|
CP_VK_ASSERT(vkCreateDescriptorSetLayout(vulkan.GetDevice(), &createInfo, nullptr, &descriptorSetLayouts[i++]), "InitializeDescriptorSetLayout : Failed to initialize descriptor set layout");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Pipeline::InitializePipeline(const PipelineCreator& creator)
|
void Pipeline::InitializePipeline(const PipelineCreator& creator)
|
||||||
{
|
{
|
||||||
Shader shader{instance, Shader::Type::GlslFile, creator.vertexShader, creator.fragmentShader};
|
Shader shader{vulkan, Shader::Type::GlslFile, creator.vertexShader, creator.fragmentShader};
|
||||||
|
|
||||||
VkPipelineVertexInputStateCreateInfo vertexInputCreateInfo{};
|
VkPipelineVertexInputStateCreateInfo vertexInputCreateInfo{};
|
||||||
vertexInputCreateInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO;
|
vertexInputCreateInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO;
|
||||||
@@ -183,7 +184,7 @@ namespace Copium
|
|||||||
pipelineLayoutCreateInfo.pushConstantRangeCount = 0;
|
pipelineLayoutCreateInfo.pushConstantRangeCount = 0;
|
||||||
pipelineLayoutCreateInfo.pPushConstantRanges = nullptr;
|
pipelineLayoutCreateInfo.pPushConstantRanges = nullptr;
|
||||||
|
|
||||||
CP_VK_ASSERT(vkCreatePipelineLayout(instance.GetDevice(), &pipelineLayoutCreateInfo, nullptr, &pipelineLayout), "InitializePipeline : Failed to initialize pipeline layout");
|
CP_VK_ASSERT(vkCreatePipelineLayout(vulkan.GetDevice(), &pipelineLayoutCreateInfo, nullptr, &pipelineLayout), "InitializePipeline : Failed to initialize pipeline layout");
|
||||||
|
|
||||||
const std::vector<VkPipelineShaderStageCreateInfo>& shaderStages = shader.GetShaderStages();
|
const std::vector<VkPipelineShaderStageCreateInfo>& shaderStages = shader.GetShaderStages();
|
||||||
VkGraphicsPipelineCreateInfo graphicsPipelineCreateInfo{};
|
VkGraphicsPipelineCreateInfo graphicsPipelineCreateInfo{};
|
||||||
@@ -204,6 +205,6 @@ namespace Copium
|
|||||||
graphicsPipelineCreateInfo.basePipelineHandle = VK_NULL_HANDLE;
|
graphicsPipelineCreateInfo.basePipelineHandle = VK_NULL_HANDLE;
|
||||||
graphicsPipelineCreateInfo.basePipelineIndex = -1;
|
graphicsPipelineCreateInfo.basePipelineIndex = -1;
|
||||||
|
|
||||||
CP_VK_ASSERT(vkCreateGraphicsPipelines(instance.GetDevice(), VK_NULL_HANDLE, 1, &graphicsPipelineCreateInfo, nullptr, &graphicsPipeline), "InitializePipeline : Failed to initialize graphics pipeline");
|
CP_VK_ASSERT(vkCreateGraphicsPipelines(vulkan.GetDevice(), VK_NULL_HANDLE, 1, &graphicsPipelineCreateInfo, nullptr, &graphicsPipeline), "InitializePipeline : Failed to initialize graphics pipeline");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1,7 +1,7 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "copium/buffer/CommandBuffer.h"
|
#include "copium/buffer/CommandBuffer.h"
|
||||||
#include "copium/core/Instance.h"
|
#include "copium/core/Vulkan.h"
|
||||||
#include "copium/pipeline/DescriptorSet.h"
|
#include "copium/pipeline/DescriptorSet.h"
|
||||||
#include "copium/pipeline/PipelineCreator.h"
|
#include "copium/pipeline/PipelineCreator.h"
|
||||||
#include "copium/util/Common.h"
|
#include "copium/util/Common.h"
|
||||||
@@ -15,7 +15,7 @@ namespace Copium
|
|||||||
{
|
{
|
||||||
CP_DELETE_COPY_AND_MOVE_CTOR(Pipeline);
|
CP_DELETE_COPY_AND_MOVE_CTOR(Pipeline);
|
||||||
private:
|
private:
|
||||||
Instance& instance;
|
Vulkan& vulkan;
|
||||||
|
|
||||||
std::vector<VkDescriptorSetLayout> descriptorSetLayouts{};
|
std::vector<VkDescriptorSetLayout> descriptorSetLayouts{};
|
||||||
std::vector<VkDescriptorSet> boundDescriptorSets;
|
std::vector<VkDescriptorSet> boundDescriptorSets;
|
||||||
@@ -23,7 +23,7 @@ namespace Copium
|
|||||||
VkPipeline graphicsPipeline;
|
VkPipeline graphicsPipeline;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
Pipeline(Instance& instance, PipelineCreator creator);
|
Pipeline(Vulkan& vulkan, PipelineCreator creator);
|
||||||
~Pipeline();
|
~Pipeline();
|
||||||
void Bind(const CommandBuffer& commandBuffer);
|
void Bind(const CommandBuffer& commandBuffer);
|
||||||
void SetDescriptorSet(uint32_t setIndex, const DescriptorSet& descriptorSet);
|
void SetDescriptorSet(uint32_t setIndex, const DescriptorSet& descriptorSet);
|
||||||
|
|||||||
@@ -1,11 +1,12 @@
|
|||||||
#include "Shader.h"
|
#include "Shader.h"
|
||||||
|
|
||||||
#include "copium/util/FileSystem.h"
|
#include "copium/util/FileSystem.h"
|
||||||
|
#include "copium/core/Device.h"
|
||||||
|
|
||||||
namespace Copium
|
namespace Copium
|
||||||
{
|
{
|
||||||
Shader::Shader(Instance& instance, Type type, const std::string& vertexInput, const std::string& fragmentInput)
|
Shader::Shader(Vulkan& vulkan, Type type, const std::string& vertexInput, const std::string& fragmentInput)
|
||||||
: instance{instance}
|
: vulkan{vulkan}
|
||||||
{
|
{
|
||||||
switch (type)
|
switch (type)
|
||||||
{
|
{
|
||||||
@@ -45,8 +46,8 @@ namespace Copium
|
|||||||
|
|
||||||
Shader::~Shader()
|
Shader::~Shader()
|
||||||
{
|
{
|
||||||
vkDestroyShaderModule(instance.GetDevice(), vertShaderModule, nullptr);
|
vkDestroyShaderModule(vulkan.GetDevice(), vertShaderModule, nullptr);
|
||||||
vkDestroyShaderModule(instance.GetDevice(), fragShaderModule, nullptr);
|
vkDestroyShaderModule(vulkan.GetDevice(), fragShaderModule, nullptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
const std::vector<VkPipelineShaderStageCreateInfo> Shader::GetShaderStages() const
|
const std::vector<VkPipelineShaderStageCreateInfo> Shader::GetShaderStages() const
|
||||||
@@ -126,7 +127,7 @@ namespace Copium
|
|||||||
createInfo.pCode = data;
|
createInfo.pCode = data;
|
||||||
|
|
||||||
VkShaderModule shaderModule;
|
VkShaderModule shaderModule;
|
||||||
CP_VK_ASSERT(vkCreateShaderModule(instance.GetDevice(), &createInfo, nullptr, &shaderModule), "InitializeShaderModule : Failed to initialize shader module");
|
CP_VK_ASSERT(vkCreateShaderModule(vulkan.GetDevice(), &createInfo, nullptr, &shaderModule), "InitializeShaderModule : Failed to initialize shader module");
|
||||||
|
|
||||||
return shaderModule;
|
return shaderModule;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,9 +1,10 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "copium/core/Instance.h"
|
#include "copium/core/Vulkan.h"
|
||||||
#include "copium/util/Common.h"
|
#include "copium/util/Common.h"
|
||||||
|
|
||||||
#include <shaderc/shaderc.hpp>
|
#include <shaderc/shaderc.hpp>
|
||||||
|
#include <vulkan/vulkan.hpp>
|
||||||
|
|
||||||
namespace Copium
|
namespace Copium
|
||||||
{
|
{
|
||||||
@@ -17,13 +18,13 @@ namespace Copium
|
|||||||
};
|
};
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Instance& instance;
|
Vulkan& vulkan;
|
||||||
|
|
||||||
VkShaderModule vertShaderModule;
|
VkShaderModule vertShaderModule;
|
||||||
VkShaderModule fragShaderModule;
|
VkShaderModule fragShaderModule;
|
||||||
std::vector<VkPipelineShaderStageCreateInfo> shaderStages;
|
std::vector<VkPipelineShaderStageCreateInfo> shaderStages;
|
||||||
public:
|
public:
|
||||||
Shader(Instance& instance, Type type, const std::string& vertexInput, const std::string& fragmentInput);
|
Shader(Vulkan& vulkan, Type type, const std::string& vertexInput, const std::string& fragmentInput);
|
||||||
~Shader();
|
~Shader();
|
||||||
|
|
||||||
const std::vector<VkPipelineShaderStageCreateInfo> GetShaderStages() const;
|
const std::vector<VkPipelineShaderStageCreateInfo> GetShaderStages() const;
|
||||||
|
|||||||
@@ -1,11 +1,13 @@
|
|||||||
#include "copium/sampler/ColorAttachment.h"
|
#include "copium/sampler/ColorAttachment.h"
|
||||||
|
|
||||||
|
#include "copium/core/Device.h"
|
||||||
|
#include "copium/core/SwapChain.h"
|
||||||
#include "copium/sampler/Image.h"
|
#include "copium/sampler/Image.h"
|
||||||
|
|
||||||
namespace Copium
|
namespace Copium
|
||||||
{
|
{
|
||||||
ColorAttachment::ColorAttachment(Instance& instance, int width, int height)
|
ColorAttachment::ColorAttachment(Vulkan& vulkan, int width, int height)
|
||||||
: Sampler{instance}
|
: Sampler{vulkan}
|
||||||
{
|
{
|
||||||
InitializeColorAttachment(width, height);
|
InitializeColorAttachment(width, height);
|
||||||
}
|
}
|
||||||
@@ -13,11 +15,11 @@ namespace Copium
|
|||||||
ColorAttachment::~ColorAttachment()
|
ColorAttachment::~ColorAttachment()
|
||||||
{
|
{
|
||||||
for (auto&& image : images)
|
for (auto&& image : images)
|
||||||
vkDestroyImage(instance.GetDevice(), image, nullptr);
|
vkDestroyImage(vulkan.GetDevice(), image, nullptr);
|
||||||
for (auto&& imageMemory : imageMemories)
|
for (auto&& imageMemory : imageMemories)
|
||||||
vkFreeMemory(instance.GetDevice(), imageMemory, nullptr);
|
vkFreeMemory(vulkan.GetDevice(), imageMemory, nullptr);
|
||||||
for (auto&& imageView : imageViews)
|
for (auto&& imageView : imageViews)
|
||||||
vkDestroyImageView(instance.GetDevice(), imageView, nullptr);
|
vkDestroyImageView(vulkan.GetDevice(), imageView, nullptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
VkDescriptorImageInfo ColorAttachment::GetDescriptorImageInfo(int index) const
|
VkDescriptorImageInfo ColorAttachment::GetDescriptorImageInfo(int index) const
|
||||||
@@ -40,13 +42,13 @@ namespace Copium
|
|||||||
|
|
||||||
void ColorAttachment::InitializeColorAttachment(int width, int height)
|
void ColorAttachment::InitializeColorAttachment(int width, int height)
|
||||||
{
|
{
|
||||||
images.resize(instance.GetMaxFramesInFlight());
|
images.resize(SwapChain::MAX_FRAMES_IN_FLIGHT);
|
||||||
imageMemories.resize(instance.GetMaxFramesInFlight());
|
imageViews.resize(SwapChain::MAX_FRAMES_IN_FLIGHT);
|
||||||
imageViews.resize(instance.GetMaxFramesInFlight());
|
imageMemories.resize(SwapChain::MAX_FRAMES_IN_FLIGHT);
|
||||||
for (size_t i = 0; i < images.size(); i++)
|
for (size_t i = 0; i < images.size(); i++)
|
||||||
{
|
{
|
||||||
Image::InitializeImage(instance, width, height, VK_FORMAT_R8G8B8A8_SRGB, VK_IMAGE_TILING_OPTIMAL, VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_SAMPLED_BIT, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT, &images[i], &imageMemories[i]);
|
Image::InitializeImage(vulkan, width, height, VK_FORMAT_R8G8B8A8_SRGB, VK_IMAGE_TILING_OPTIMAL, VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_SAMPLED_BIT, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT, &images[i], &imageMemories[i]);
|
||||||
imageViews[i] = Image::InitializeImageView(instance, images[i], VK_FORMAT_R8G8B8A8_SRGB, VK_IMAGE_ASPECT_COLOR_BIT);
|
imageViews[i] = Image::InitializeImageView(vulkan, images[i], VK_FORMAT_R8G8B8A8_SRGB, VK_IMAGE_ASPECT_COLOR_BIT);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "copium/core/Instance.h"
|
#include "copium/core/Vulkan.h"
|
||||||
#include "copium/sampler/Sampler.h"
|
#include "copium/sampler/Sampler.h"
|
||||||
#include "copium/util/Common.h"
|
#include "copium/util/Common.h"
|
||||||
|
|
||||||
@@ -16,7 +16,7 @@ namespace Copium
|
|||||||
std::vector<VkDeviceMemory> imageMemories;
|
std::vector<VkDeviceMemory> imageMemories;
|
||||||
std::vector<VkImageView> imageViews;
|
std::vector<VkImageView> imageViews;
|
||||||
public:
|
public:
|
||||||
ColorAttachment(Instance& instance, int width, int height);
|
ColorAttachment(Vulkan& vulkan, int width, int height);
|
||||||
~ColorAttachment() override;
|
~ColorAttachment() override;
|
||||||
|
|
||||||
VkDescriptorImageInfo GetDescriptorImageInfo(int index) const override;
|
VkDescriptorImageInfo GetDescriptorImageInfo(int index) const override;
|
||||||
|
|||||||
@@ -1,20 +1,21 @@
|
|||||||
#include "copium/sampler/DepthAttachment.h"
|
#include "copium/sampler/DepthAttachment.h"
|
||||||
|
|
||||||
|
#include "copium/core/Device.h"
|
||||||
#include "copium/sampler/Image.h"
|
#include "copium/sampler/Image.h"
|
||||||
|
|
||||||
namespace Copium
|
namespace Copium
|
||||||
{
|
{
|
||||||
DepthAttachment::DepthAttachment(Instance& instance, int width, int height)
|
DepthAttachment::DepthAttachment(Vulkan& vulkan, int width, int height)
|
||||||
: Sampler{instance}
|
: Sampler{vulkan}
|
||||||
{
|
{
|
||||||
InitializeDepthAttachment(width, height);
|
InitializeDepthAttachment(width, height);
|
||||||
}
|
}
|
||||||
|
|
||||||
DepthAttachment::~DepthAttachment()
|
DepthAttachment::~DepthAttachment()
|
||||||
{
|
{
|
||||||
vkDestroyImage(instance.GetDevice(), image, nullptr);
|
vkDestroyImage(vulkan.GetDevice(), image, nullptr);
|
||||||
vkFreeMemory(instance.GetDevice(), imageMemory, nullptr);
|
vkFreeMemory(vulkan.GetDevice(), imageMemory, nullptr);
|
||||||
vkDestroyImageView(instance.GetDevice(), imageView, nullptr);
|
vkDestroyImageView(vulkan.GetDevice(), imageView, nullptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
VkDescriptorImageInfo DepthAttachment::GetDescriptorImageInfo(int index) const
|
VkDescriptorImageInfo DepthAttachment::GetDescriptorImageInfo(int index) const
|
||||||
@@ -33,8 +34,8 @@ namespace Copium
|
|||||||
|
|
||||||
void DepthAttachment::InitializeDepthAttachment(int width, int height)
|
void DepthAttachment::InitializeDepthAttachment(int width, int height)
|
||||||
{
|
{
|
||||||
VkFormat depthFormat = Image::SelectDepthFormat(instance);
|
VkFormat depthFormat = Image::SelectDepthFormat(vulkan);
|
||||||
Image::InitializeImage(instance, width, height, depthFormat, VK_IMAGE_TILING_OPTIMAL, VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT | VK_IMAGE_USAGE_SAMPLED_BIT, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT, &image, &imageMemory);
|
Image::InitializeImage(vulkan, width, height, depthFormat, VK_IMAGE_TILING_OPTIMAL, VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT | VK_IMAGE_USAGE_SAMPLED_BIT, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT, &image, &imageMemory);
|
||||||
imageView = Image::InitializeImageView(instance, image, depthFormat, VK_IMAGE_ASPECT_DEPTH_BIT);
|
imageView = Image::InitializeImageView(vulkan, image, depthFormat, VK_IMAGE_ASPECT_DEPTH_BIT);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "copium/core/Instance.h"
|
#include "copium/core/Vulkan.h"
|
||||||
#include "copium/sampler/Sampler.h"
|
#include "copium/sampler/Sampler.h"
|
||||||
#include "copium/util/Common.h"
|
#include "copium/util/Common.h"
|
||||||
|
|
||||||
@@ -16,7 +16,7 @@ namespace Copium
|
|||||||
VkDeviceMemory imageMemory;
|
VkDeviceMemory imageMemory;
|
||||||
VkImageView imageView;
|
VkImageView imageView;
|
||||||
public:
|
public:
|
||||||
DepthAttachment(Instance& instance, int width, int height);
|
DepthAttachment(Vulkan& vulkan, int width, int height);
|
||||||
~DepthAttachment() override;
|
~DepthAttachment() override;
|
||||||
|
|
||||||
VkDescriptorImageInfo GetDescriptorImageInfo(int index) const override;
|
VkDescriptorImageInfo GetDescriptorImageInfo(int index) const override;
|
||||||
|
|||||||
@@ -1,10 +1,11 @@
|
|||||||
#include "copium/sampler/Image.h"
|
#include "copium/sampler/Image.h"
|
||||||
|
|
||||||
#include "copium/buffer/CommandBufferScoped.h"
|
#include "copium/buffer/CommandBufferScoped.h"
|
||||||
|
#include "copium/core/Device.h"
|
||||||
|
|
||||||
namespace Copium
|
namespace Copium
|
||||||
{
|
{
|
||||||
void Image::InitializeImage(Instance& instance, uint32_t width, uint32_t height, VkFormat format, VkImageTiling tiling, VkImageUsageFlags usage, VkMemoryPropertyFlags properties, VkImage* image, VkDeviceMemory* imageMemory)
|
void Image::InitializeImage(Vulkan& vulkan, uint32_t width, uint32_t height, VkFormat format, VkImageTiling tiling, VkImageUsageFlags usage, VkMemoryPropertyFlags properties, VkImage* image, VkDeviceMemory* imageMemory)
|
||||||
{
|
{
|
||||||
VkImageCreateInfo createInfo{};
|
VkImageCreateInfo createInfo{};
|
||||||
createInfo.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
|
createInfo.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
|
||||||
@@ -22,22 +23,22 @@ namespace Copium
|
|||||||
createInfo.samples = VK_SAMPLE_COUNT_1_BIT;
|
createInfo.samples = VK_SAMPLE_COUNT_1_BIT;
|
||||||
createInfo.flags = 0;
|
createInfo.flags = 0;
|
||||||
|
|
||||||
CP_VK_ASSERT(vkCreateImage(instance.GetDevice(), &createInfo, nullptr, image), "InitializeImage : Failed to initialize image");
|
CP_VK_ASSERT(vkCreateImage(vulkan.GetDevice(), &createInfo, nullptr, image), "InitializeImage : Failed to initialize image");
|
||||||
|
|
||||||
VkMemoryRequirements memoryRequirements;
|
VkMemoryRequirements memoryRequirements;
|
||||||
vkGetImageMemoryRequirements(instance.GetDevice(), *image, &memoryRequirements);
|
vkGetImageMemoryRequirements(vulkan.GetDevice(), *image, &memoryRequirements);
|
||||||
|
|
||||||
VkMemoryAllocateInfo allocateInfo{};
|
VkMemoryAllocateInfo allocateInfo{};
|
||||||
allocateInfo.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO;
|
allocateInfo.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO;
|
||||||
allocateInfo.allocationSize = memoryRequirements.size;
|
allocateInfo.allocationSize = memoryRequirements.size;
|
||||||
allocateInfo.memoryTypeIndex = instance.FindMemoryType(memoryRequirements.memoryTypeBits, properties);
|
allocateInfo.memoryTypeIndex = vulkan.GetDevice().FindMemoryType(memoryRequirements.memoryTypeBits, properties);
|
||||||
|
|
||||||
CP_VK_ASSERT(vkAllocateMemory(instance.GetDevice(), &allocateInfo, nullptr, imageMemory), "InitializeImage : Failed to initiallizse image memory");
|
CP_VK_ASSERT(vkAllocateMemory(vulkan.GetDevice(), &allocateInfo, nullptr, imageMemory), "InitializeImage : Failed to initiallizse image memory");
|
||||||
|
|
||||||
vkBindImageMemory(instance.GetDevice(), *image, *imageMemory, 0);
|
vkBindImageMemory(vulkan.GetDevice(), *image, *imageMemory, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
VkImageView Image::InitializeImageView(Instance& instance, VkImage image, VkFormat format, VkImageAspectFlags aspectFlags)
|
VkImageView Image::InitializeImageView(Vulkan& vulkan, VkImage image, VkFormat format, VkImageAspectFlags aspectFlags)
|
||||||
{
|
{
|
||||||
VkImageView imageView;
|
VkImageView imageView;
|
||||||
VkImageViewCreateInfo createInfo{};
|
VkImageViewCreateInfo createInfo{};
|
||||||
@@ -54,13 +55,13 @@ namespace Copium
|
|||||||
createInfo.subresourceRange.levelCount = 1;
|
createInfo.subresourceRange.levelCount = 1;
|
||||||
createInfo.subresourceRange.baseArrayLayer = 0;
|
createInfo.subresourceRange.baseArrayLayer = 0;
|
||||||
createInfo.subresourceRange.layerCount = 1;
|
createInfo.subresourceRange.layerCount = 1;
|
||||||
CP_VK_ASSERT(vkCreateImageView(instance.GetDevice(), &createInfo, nullptr, &imageView), "InitializeImageView : Failed to initialize image view");
|
CP_VK_ASSERT(vkCreateImageView(vulkan.GetDevice(), &createInfo, nullptr, &imageView), "InitializeImageView : Failed to initialize image view");
|
||||||
return imageView;
|
return imageView;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Image::TransitionImageLayout(Instance& instance, VkImage image, VkFormat format, VkImageLayout oldLayout, VkImageLayout newLayout)
|
void Image::TransitionImageLayout(Vulkan& vulkan, VkImage image, VkFormat format, VkImageLayout oldLayout, VkImageLayout newLayout)
|
||||||
{
|
{
|
||||||
CommandBufferScoped commandBuffer{instance};
|
CommandBufferScoped commandBuffer{vulkan};
|
||||||
|
|
||||||
VkImageMemoryBarrier barrier{};
|
VkImageMemoryBarrier barrier{};
|
||||||
barrier.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER;
|
barrier.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER;
|
||||||
@@ -126,9 +127,9 @@ namespace Copium
|
|||||||
vkCmdPipelineBarrier(commandBuffer, srcStage, dstStage, 0, 0, nullptr, 0, nullptr, 1, &barrier);
|
vkCmdPipelineBarrier(commandBuffer, srcStage, dstStage, 0, 0, nullptr, 0, nullptr, 1, &barrier);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Image::CopyBufferToImage(Instance& instance, const Buffer& buffer, VkImage image, uint32_t width, uint32_t height)
|
void Image::CopyBufferToImage(Vulkan& vulkan, const Buffer& buffer, VkImage image, uint32_t width, uint32_t height)
|
||||||
{
|
{
|
||||||
CommandBufferScoped commandBuffer{instance};
|
CommandBufferScoped commandBuffer{vulkan};
|
||||||
|
|
||||||
VkBufferImageCopy region{};
|
VkBufferImageCopy region{};
|
||||||
region.bufferOffset = 0;
|
region.bufferOffset = 0;
|
||||||
@@ -147,9 +148,9 @@ namespace Copium
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
VkFormat Image::SelectDepthFormat(Instance& instance)
|
VkFormat Image::SelectDepthFormat(Vulkan& vulkan)
|
||||||
{
|
{
|
||||||
return SelectSupportedFormat(instance, {VK_FORMAT_D32_SFLOAT, VK_FORMAT_D32_SFLOAT_S8_UINT, VK_FORMAT_D24_UNORM_S8_UINT}, VK_IMAGE_TILING_OPTIMAL, VK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT);
|
return SelectSupportedFormat(vulkan, {VK_FORMAT_D32_SFLOAT, VK_FORMAT_D32_SFLOAT_S8_UINT, VK_FORMAT_D24_UNORM_S8_UINT}, VK_IMAGE_TILING_OPTIMAL, VK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Image::HasStencilComponent(VkFormat format)
|
bool Image::HasStencilComponent(VkFormat format)
|
||||||
@@ -157,12 +158,12 @@ namespace Copium
|
|||||||
return format == VK_FORMAT_D32_SFLOAT_S8_UINT || format == VK_FORMAT_D24_UNORM_S8_UINT;
|
return format == VK_FORMAT_D32_SFLOAT_S8_UINT || format == VK_FORMAT_D24_UNORM_S8_UINT;
|
||||||
}
|
}
|
||||||
|
|
||||||
VkFormat Image::SelectSupportedFormat(Instance& instance, const std::vector<VkFormat>& candidates, VkImageTiling tiling, VkFormatFeatureFlags features)
|
VkFormat Image::SelectSupportedFormat(Vulkan& vulkan, const std::vector<VkFormat>& candidates, VkImageTiling tiling, VkFormatFeatureFlags features)
|
||||||
{
|
{
|
||||||
for (VkFormat format : candidates)
|
for (VkFormat format : candidates)
|
||||||
{
|
{
|
||||||
VkFormatProperties properties;
|
VkFormatProperties properties;
|
||||||
vkGetPhysicalDeviceFormatProperties(instance.GetPhysicalDevice(), format, &properties);
|
vkGetPhysicalDeviceFormatProperties(vulkan.GetDevice().GetPhysicalDevice(), format, &properties);
|
||||||
if (tiling == VK_IMAGE_TILING_LINEAR && (properties.linearTilingFeatures & features) == features)
|
if (tiling == VK_IMAGE_TILING_LINEAR && (properties.linearTilingFeatures & features) == features)
|
||||||
{
|
{
|
||||||
return format;
|
return format;
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "copium/buffer/Buffer.h"
|
#include "copium/buffer/Buffer.h"
|
||||||
#include "copium/core/Instance.h"
|
#include "copium/core/Vulkan.h"
|
||||||
#include "copium/util/Common.h"
|
#include "copium/util/Common.h"
|
||||||
|
|
||||||
#include <vulkan/vulkan.hpp>
|
#include <vulkan/vulkan.hpp>
|
||||||
@@ -12,14 +12,14 @@ namespace Copium
|
|||||||
{
|
{
|
||||||
CP_STATIC_CLASS(Image);
|
CP_STATIC_CLASS(Image);
|
||||||
public:
|
public:
|
||||||
static void InitializeImage(Instance& instance, uint32_t width, uint32_t height, VkFormat format, VkImageTiling tiling, VkImageUsageFlags usage, VkMemoryPropertyFlags properties, VkImage* image, VkDeviceMemory* imageMemory);
|
static void InitializeImage(Vulkan& vulkan, uint32_t width, uint32_t height, VkFormat format, VkImageTiling tiling, VkImageUsageFlags usage, VkMemoryPropertyFlags properties, VkImage* image, VkDeviceMemory* imageMemory);
|
||||||
static VkImageView InitializeImageView(Instance& instance, VkImage image, VkFormat format, VkImageAspectFlags aspectFlags);
|
static VkImageView InitializeImageView(Vulkan& vulkan, VkImage image, VkFormat format, VkImageAspectFlags aspectFlags);
|
||||||
static void TransitionImageLayout(Instance& instance, VkImage image, VkFormat format, VkImageLayout oldLayout, VkImageLayout newLayout);
|
static void TransitionImageLayout(Vulkan& vulkan, VkImage image, VkFormat format, VkImageLayout oldLayout, VkImageLayout newLayout);
|
||||||
static void CopyBufferToImage(Instance& instance, const Buffer& buffer, VkImage image, uint32_t width, uint32_t height);
|
static void CopyBufferToImage(Vulkan& vulkan, const Buffer& buffer, VkImage image, uint32_t width, uint32_t height);
|
||||||
static VkFormat SelectDepthFormat(Instance& instance);
|
static VkFormat SelectDepthFormat(Vulkan& vulkan);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
static bool HasStencilComponent(VkFormat format);
|
static bool HasStencilComponent(VkFormat format);
|
||||||
static VkFormat SelectSupportedFormat(Instance& instance, const std::vector<VkFormat>& candidates, VkImageTiling tiling, VkFormatFeatureFlags features);
|
static VkFormat SelectSupportedFormat(Vulkan& vulkan, const std::vector<VkFormat>& candidates, VkImageTiling tiling, VkFormatFeatureFlags features);
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
@@ -1,22 +1,24 @@
|
|||||||
#include "copium/sampler/Sampler.h"
|
#include "copium/sampler/Sampler.h"
|
||||||
|
|
||||||
|
#include "copium/core/Device.h"
|
||||||
|
|
||||||
namespace Copium
|
namespace Copium
|
||||||
{
|
{
|
||||||
Sampler::Sampler(Instance& instance)
|
Sampler::Sampler(Vulkan& vulkan)
|
||||||
: instance{instance}
|
: vulkan{vulkan}
|
||||||
{
|
{
|
||||||
InitializeSampler();
|
InitializeSampler();
|
||||||
}
|
}
|
||||||
|
|
||||||
Sampler::~Sampler()
|
Sampler::~Sampler()
|
||||||
{
|
{
|
||||||
vkDestroySampler(instance.GetDevice(), sampler, nullptr);
|
vkDestroySampler(vulkan.GetDevice(), sampler, nullptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Sampler::InitializeSampler()
|
void Sampler::InitializeSampler()
|
||||||
{
|
{
|
||||||
VkPhysicalDeviceProperties properties{};
|
VkPhysicalDeviceProperties properties{};
|
||||||
vkGetPhysicalDeviceProperties(instance.GetPhysicalDevice(), &properties);
|
vkGetPhysicalDeviceProperties(vulkan.GetDevice().GetPhysicalDevice(), &properties);
|
||||||
|
|
||||||
VkSamplerCreateInfo createInfo{};
|
VkSamplerCreateInfo createInfo{};
|
||||||
createInfo.sType = VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO;
|
createInfo.sType = VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO;
|
||||||
@@ -35,6 +37,6 @@ namespace Copium
|
|||||||
createInfo.minLod = 0.0f;
|
createInfo.minLod = 0.0f;
|
||||||
createInfo.maxLod = 0.0f;
|
createInfo.maxLod = 0.0f;
|
||||||
|
|
||||||
CP_VK_ASSERT(vkCreateSampler(instance.GetDevice(), &createInfo, nullptr, &sampler), "InitializeSampler : Failed to initialize texture sampler");
|
CP_VK_ASSERT(vkCreateSampler(vulkan.GetDevice(), &createInfo, nullptr, &sampler), "InitializeSampler : Failed to initialize texture sampler");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "copium/core/Instance.h"
|
#include "copium/core/Vulkan.h"
|
||||||
#include "copium/util/Common.h"
|
#include "copium/util/Common.h"
|
||||||
|
|
||||||
#include <vulkan/vulkan.hpp>
|
#include <vulkan/vulkan.hpp>
|
||||||
@@ -11,10 +11,10 @@ namespace Copium
|
|||||||
{
|
{
|
||||||
CP_DELETE_COPY_AND_MOVE_CTOR(Sampler);
|
CP_DELETE_COPY_AND_MOVE_CTOR(Sampler);
|
||||||
protected:
|
protected:
|
||||||
Instance& instance;
|
Vulkan& vulkan;
|
||||||
VkSampler sampler;
|
VkSampler sampler;
|
||||||
public:
|
public:
|
||||||
Sampler(Instance& instance);
|
Sampler(Vulkan& vulkan);
|
||||||
virtual ~Sampler();
|
virtual ~Sampler();
|
||||||
|
|
||||||
virtual VkDescriptorImageInfo GetDescriptorImageInfo(int index) const = 0;
|
virtual VkDescriptorImageInfo GetDescriptorImageInfo(int index) const = 0;
|
||||||
|
|||||||
@@ -1,21 +1,23 @@
|
|||||||
#include "copium/sampler/Texture2D.h"
|
#include "copium/sampler/Texture2D.h"
|
||||||
|
|
||||||
|
#include "copium/core/Device.h"
|
||||||
|
|
||||||
#define STB_IMAGE_IMPLEMENTATION
|
#define STB_IMAGE_IMPLEMENTATION
|
||||||
#include <stb/stb_image.h>
|
#include <stb/stb_image.h>
|
||||||
|
|
||||||
namespace Copium
|
namespace Copium
|
||||||
{
|
{
|
||||||
Texture2D::Texture2D(Instance& instance, const std::string& filename)
|
Texture2D::Texture2D(Vulkan& vulkan, const std::string& filename)
|
||||||
: Sampler{instance}
|
: Sampler{vulkan}
|
||||||
{
|
{
|
||||||
InitializeTextureImage(filename);
|
InitializeTextureImage(filename);
|
||||||
}
|
}
|
||||||
|
|
||||||
Texture2D::~Texture2D()
|
Texture2D::~Texture2D()
|
||||||
{
|
{
|
||||||
vkDestroyImage(instance.GetDevice(), image, nullptr);
|
vkDestroyImage(vulkan.GetDevice(), image, nullptr);
|
||||||
vkFreeMemory(instance.GetDevice(), imageMemory, nullptr);
|
vkFreeMemory(vulkan.GetDevice(), imageMemory, nullptr);
|
||||||
vkDestroyImageView(instance.GetDevice(), imageView, nullptr);
|
vkDestroyImageView(vulkan.GetDevice(), imageView, nullptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
VkDescriptorImageInfo Texture2D::GetDescriptorImageInfo(int index) const
|
VkDescriptorImageInfo Texture2D::GetDescriptorImageInfo(int index) const
|
||||||
@@ -38,16 +40,16 @@ namespace Copium
|
|||||||
CP_ASSERT(pixels, "InitializeTextureImage : Failed to load texture image");
|
CP_ASSERT(pixels, "InitializeTextureImage : Failed to load texture image");
|
||||||
|
|
||||||
VkDeviceSize bufferSize = texWidth * texHeight * 4;
|
VkDeviceSize bufferSize = texWidth * texHeight * 4;
|
||||||
Buffer stagingBuffer{instance, VK_BUFFER_USAGE_TRANSFER_SRC_BIT, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT, bufferSize, 1};
|
Buffer stagingBuffer{vulkan, VK_BUFFER_USAGE_TRANSFER_SRC_BIT, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT, bufferSize, 1};
|
||||||
void* data = stagingBuffer.Map();
|
void* data = stagingBuffer.Map();
|
||||||
memcpy(data, pixels, bufferSize);
|
memcpy(data, pixels, bufferSize);
|
||||||
stagingBuffer.Unmap();
|
stagingBuffer.Unmap();
|
||||||
stbi_image_free(pixels);
|
stbi_image_free(pixels);
|
||||||
|
|
||||||
Image::InitializeImage(instance, texWidth, texHeight, VK_FORMAT_R8G8B8A8_SRGB, VK_IMAGE_TILING_OPTIMAL, VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_SAMPLED_BIT, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT, &image, &imageMemory);
|
Image::InitializeImage(vulkan, texWidth, texHeight, VK_FORMAT_R8G8B8A8_SRGB, VK_IMAGE_TILING_OPTIMAL, VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_SAMPLED_BIT, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT, &image, &imageMemory);
|
||||||
Image::TransitionImageLayout(instance, image, VK_FORMAT_R8G8B8A8_SRGB, VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL);
|
Image::TransitionImageLayout(vulkan, image, VK_FORMAT_R8G8B8A8_SRGB, VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL);
|
||||||
Image::CopyBufferToImage(instance, stagingBuffer, image, texWidth, texHeight);
|
Image::CopyBufferToImage(vulkan, stagingBuffer, image, texWidth, texHeight);
|
||||||
Image::TransitionImageLayout(instance, image, VK_FORMAT_R8G8B8A8_SRGB, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL);
|
Image::TransitionImageLayout(vulkan, image, VK_FORMAT_R8G8B8A8_SRGB, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL);
|
||||||
imageView = Image::InitializeImageView(instance, image, VK_FORMAT_R8G8B8A8_SRGB, VK_IMAGE_ASPECT_COLOR_BIT);
|
imageView = Image::InitializeImageView(vulkan, image, VK_FORMAT_R8G8B8A8_SRGB, VK_IMAGE_ASPECT_COLOR_BIT);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "copium/buffer/CommandBufferScoped.h"
|
#include "copium/buffer/CommandBufferScoped.h"
|
||||||
#include "copium/core/Instance.h"
|
#include "copium/core/Vulkan.h"
|
||||||
#include "copium/sampler/Image.h"
|
#include "copium/sampler/Image.h"
|
||||||
#include "copium/sampler/Sampler.h"
|
#include "copium/sampler/Sampler.h"
|
||||||
#include "copium/util/Common.h"
|
#include "copium/util/Common.h"
|
||||||
@@ -18,7 +18,7 @@ namespace Copium
|
|||||||
VkDeviceMemory imageMemory;
|
VkDeviceMemory imageMemory;
|
||||||
VkImageView imageView;
|
VkImageView imageView;
|
||||||
public:
|
public:
|
||||||
Texture2D(Instance& instance, const std::string& filename);
|
Texture2D(Vulkan& vulkan, const std::string& filename);
|
||||||
~Texture2D() override;
|
~Texture2D() override;
|
||||||
|
|
||||||
VkDescriptorImageInfo GetDescriptorImageInfo(int index) const override;
|
VkDescriptorImageInfo GetDescriptorImageInfo(int index) const override;
|
||||||
|
|||||||
Reference in New Issue
Block a user