Formatted EVERYTHING

This commit is contained in:
Dynamitos
2024-06-09 12:20:53 +02:00
parent f18bf8acbe
commit d95dab850c
265 changed files with 8002 additions and 12310 deletions
+21 -19
View File
@@ -6,7 +6,8 @@
// using namespace Seele::Vulkan;
// SubAllocation::SubAllocation(PAllocation owner, VkDeviceSize requestedSize, VkDeviceSize allocatedOffset, VkDeviceSize allocatedSize, VkDeviceSize alignedOffset)
// SubAllocation::SubAllocation(PAllocation owner, VkDeviceSize requestedSize, VkDeviceSize allocatedOffset, VkDeviceSize allocatedSize,
// VkDeviceSize alignedOffset)
// : owner(owner)
// , requestedSize(requestedSize)
// , allocatedOffset(allocatedOffset)
@@ -112,10 +113,9 @@
// void Allocation::markFree(PSubAllocation allocation)
// {
// //std::cout << "Freeing " << allocation->allocatedOffset << "-" << allocation->allocatedOffset + allocation->allocatedSize << std::endl;
// assert(activeAllocations.find(allocation) != activeAllocations.end());
// VkDeviceSize lowerBound = allocation->allocatedOffset;
// VkDeviceSize upperBound = allocation->allocatedOffset + allocation->allocatedSize;
// //std::cout << "Freeing " << allocation->allocatedOffset << "-" << allocation->allocatedOffset + allocation->allocatedSize <<
// std::endl; assert(activeAllocations.find(allocation) != activeAllocations.end()); VkDeviceSize lowerBound =
// allocation->allocatedOffset; VkDeviceSize upperBound = allocation->allocatedOffset + allocation->allocatedSize;
// freeRanges[lowerBound] = allocation->allocatedSize;
// for (const auto& [lower, size] : freeRanges)
// {
@@ -171,7 +171,7 @@
// for (size_t i = 0; i < memProperties.memoryHeapCount; ++i)
// {
// VkMemoryHeap memoryHeap = memProperties.memoryHeaps[i];
// HeapInfo heapInfo;
// HeapInfo heapInfo;
// heapInfo.maxSize = memoryHeap.size;
// //std::cout << "Creating heap " << i << " with properties " << memoryHeap.flags << " size " << memoryHeap.size << std::endl;
// heaps.add(std::move(heapInfo));
@@ -182,7 +182,8 @@
// {
// }
// OSubAllocation Allocator::allocate(const VkMemoryRequirements2 &memRequirements2, VkMemoryPropertyFlags properties, VkMemoryDedicatedAllocateInfo *dedicatedInfo)
// OSubAllocation Allocator::allocate(const VkMemoryRequirements2 &memRequirements2, VkMemoryPropertyFlags properties,
// VkMemoryDedicatedAllocateInfo *dedicatedInfo)
// {
// const VkMemoryRequirements &requirements = memRequirements2.memoryRequirements;
// uint32 memoryTypeIndex = findMemoryType(requirements.memoryTypeBits, properties);
@@ -195,10 +196,10 @@
// {
// OAllocation newAllocation = new Allocation(graphics, this, requirements.size, memoryTypeIndex, properties, dedicatedInfo);
// heaps[heapIndex].inUse += newAllocation->bytesAllocated;
// std::cout << "Heap " << heapIndex << ": " << (float)heaps[heapIndex].inUse / heaps[heapIndex].maxSize * 100 << "%" << std::endl;
// heaps[heapIndex].allocations.add(std::move(newAllocation));
// return heaps[heapIndex].allocations.back()->getSuballocation(requirements.size, requirements.alignment);
// }
// std::cout << "Heap " << heapIndex << ": " << (float)heaps[heapIndex].inUse / heaps[heapIndex].maxSize * 100 << "%" <<
// std::endl; heaps[heapIndex].allocations.add(std::move(newAllocation)); return
// heaps[heapIndex].allocations.back()->getSuballocation(requirements.size, requirements.alignment);
// }
// }
// for (auto& alloc : heaps[heapIndex].allocations)
// {
@@ -213,9 +214,9 @@
// }
// // no suitable allocations found, allocate new block
// OAllocation newAllocation = new Allocation(graphics, this, (requirements.size > DEFAULT_ALLOCATION) ? requirements.size : DEFAULT_ALLOCATION, memoryTypeIndex, properties, nullptr);
// heaps[heapIndex].inUse += newAllocation->bytesAllocated;
// std::cout << "Heap " << heapIndex << ": " << (float)heaps[heapIndex].inUse / heaps[heapIndex].maxSize * 100 << "%" << std::endl;
// OAllocation newAllocation = new Allocation(graphics, this, (requirements.size > DEFAULT_ALLOCATION) ? requirements.size :
// DEFAULT_ALLOCATION, memoryTypeIndex, properties, nullptr); heaps[heapIndex].inUse += newAllocation->bytesAllocated; std::cout <<
// "Heap " << heapIndex << ": " << (float)heaps[heapIndex].inUse / heaps[heapIndex].maxSize * 100 << "%" << std::endl;
// heaps[heapIndex].allocations.add(std::move(newAllocation));
// return heaps[heapIndex].allocations.back()->getSuballocation(requirements.size, requirements.alignment);
// }
@@ -241,16 +242,17 @@
// std::cout << "Heap " << heapIndex << std::endl;
// for (uint32 alloc = 0; alloc < heaps[heapIndex].allocations.size(); ++alloc)
// {
// std::cout << "[" << alloc << "]: " << (float)heaps[heapIndex].allocations[alloc]->bytesUsed / heaps[heapIndex].allocations[alloc]->bytesAllocated << std::endl;
// std::cout << "[" << alloc << "]: " << (float)heaps[heapIndex].allocations[alloc]->bytesUsed /
// heaps[heapIndex].allocations[alloc]->bytesAllocated << std::endl;
// }
// }
// }
// uint32 Allocator::findMemoryType(uint32 typeFilter, VkMemoryPropertyFlags properties)
// {
// for (uint32 i = 0; i < memProperties.memoryTypeCount; i++)
// for (uint32 i = 0; i < memProperties.memoryTypeCount; i++)
// {
// if ((typeFilter & (1 << i)) && (memProperties.memoryTypes[i].propertyFlags & properties) == properties)
// if ((typeFilter & (1 << i)) && (memProperties.memoryTypes[i].propertyFlags & properties) == properties)
// {
// return i;
// }
@@ -334,7 +336,7 @@
// .queueFamilyIndexCount = 1,
// .pQueueFamilyIndices = &queueIndex,
// };
// VkBuffer buffer;
// VK_CHECK(vkCreateBuffer(graphics->getDevice(), &stagingBufferCreateInfo, nullptr, &buffer));
@@ -361,7 +363,7 @@
// owner
// );
// vkBindBufferMemory(graphics->getDevice(), buffer, stagingBuffer->getMemory(), stagingBuffer->getOffset());
// return stagingBuffer;
// }
+2 -3
View File
@@ -16,9 +16,8 @@
// class SubAllocation
// {
// public:
// SubAllocation(PAllocation owner, VkDeviceSize requestedSize, VkDeviceSize allocatedOffset, VkDeviceSize allocatedSize, VkDeviceSize alignedOffset);
// ~SubAllocation();
// VkDeviceMemory getHandle() const;
// SubAllocation(PAllocation owner, VkDeviceSize requestedSize, VkDeviceSize allocatedOffset, VkDeviceSize allocatedSize, VkDeviceSize
// alignedOffset); ~SubAllocation(); VkDeviceMemory getHandle() const;
// constexpr VkDeviceSize getSize() const
// {
+385 -492
View File
@@ -6,579 +6,472 @@
using namespace Seele;
using namespace Seele::Vulkan;
BufferAllocation::BufferAllocation(PGraphics graphics)
: CommandBoundResource(graphics) {}
BufferAllocation::BufferAllocation(PGraphics graphics) : CommandBoundResource(graphics) {}
BufferAllocation::~BufferAllocation() {
if (buffer != VK_NULL_HANDLE) {
vmaDestroyBuffer(graphics->getAllocator(), buffer, allocation);
}
if (buffer != VK_NULL_HANDLE) {
vmaDestroyBuffer(graphics->getAllocator(), buffer, allocation);
}
}
struct PendingBuffer {
OBufferAllocation allocation;
uint64 offset;
Gfx::QueueType prevQueue;
bool writeOnly;
OBufferAllocation allocation;
uint64 offset;
Gfx::QueueType prevQueue;
bool writeOnly;
};
static Map<Vulkan::Buffer *, PendingBuffer> pendingBuffers;
static Map<Vulkan::Buffer*, PendingBuffer> pendingBuffers;
Buffer::Buffer(PGraphics graphics, uint64 size, VkBufferUsageFlags usage,
Gfx::QueueType &queueType, bool dynamic, std::string name)
Buffer::Buffer(PGraphics graphics, uint64 size, VkBufferUsageFlags usage, Gfx::QueueType& queueType, bool dynamic, std::string name)
: graphics(graphics), currentBuffer(0), owner(queueType),
usage(usage | VK_BUFFER_USAGE_TRANSFER_DST_BIT |
VK_BUFFER_USAGE_TRANSFER_SRC_BIT),
dynamic(dynamic), name(name) {
createBuffer(size);
usage(usage | VK_BUFFER_USAGE_TRANSFER_DST_BIT | VK_BUFFER_USAGE_TRANSFER_SRC_BIT), dynamic(dynamic), name(name) {
createBuffer(size);
}
Buffer::~Buffer() {
for (uint32 i = 0; i < buffers.size(); ++i) {
graphics->getDestructionManager()->queueResourceForDestruction(
std::move(buffers[i]));
}
for (uint32 i = 0; i < buffers.size(); ++i) {
graphics->getDestructionManager()->queueResourceForDestruction(std::move(buffers[i]));
}
}
void Buffer::executeOwnershipBarrier(Gfx::QueueType newOwner) {
if (getSize() == 0)
return;
Gfx::QueueFamilyMapping mapping = graphics->getFamilyMapping();
VkBufferMemoryBarrier barrier = {
.sType = VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER,
.pNext = nullptr,
.srcQueueFamilyIndex = mapping.getQueueTypeFamilyIndex(owner),
.dstQueueFamilyIndex = mapping.getQueueTypeFamilyIndex(newOwner),
.buffer = getHandle(),
.offset = 0,
.size = getSize(),
};
PCommandPool sourcePool = graphics->getQueueCommands(owner);
PCommandPool dstPool = nullptr;
VkPipelineStageFlags srcStage = VK_PIPELINE_STAGE_ALL_COMMANDS_BIT;
VkPipelineStageFlags dstStage = VK_PIPELINE_STAGE_ALL_COMMANDS_BIT;
assert(barrier.srcQueueFamilyIndex != barrier.dstQueueFamilyIndex);
if (owner == Gfx::QueueType::TRANSFER) {
barrier.srcAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT;
srcStage = VK_PIPELINE_STAGE_TRANSFER_BIT;
} else if (owner == Gfx::QueueType::COMPUTE) {
barrier.srcAccessMask = VK_ACCESS_SHADER_WRITE_BIT;
srcStage = VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT;
} else if (owner == Gfx::QueueType::GRAPHICS) {
barrier.srcAccessMask = getSourceAccessMask();
srcStage = VK_PIPELINE_STAGE_ALL_GRAPHICS_BIT;
}
if (newOwner == Gfx::QueueType::TRANSFER) {
barrier.dstAccessMask = VK_ACCESS_TRANSFER_READ_BIT;
dstStage = VK_PIPELINE_STAGE_TRANSFER_BIT;
dstPool = graphics->getTransferCommands();
} else if (newOwner == Gfx::QueueType::COMPUTE) {
barrier.dstAccessMask = VK_ACCESS_SHADER_READ_BIT;
dstStage = VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT;
dstPool = graphics->getComputeCommands();
} else if (newOwner == Gfx::QueueType::GRAPHICS) {
barrier.dstAccessMask = getDestAccessMask();
dstStage = VK_PIPELINE_STAGE_ALL_GRAPHICS_BIT;
dstPool = graphics->getGraphicsCommands();
}
VkCommandBuffer srcCommand = sourcePool->getCommands()->getHandle();
VkCommandBuffer dstCommand = dstPool->getCommands()->getHandle();
vkCmdPipelineBarrier(srcCommand, srcStage, srcStage, 0, 0, nullptr, 1,
&barrier, 0, nullptr);
vkCmdPipelineBarrier(dstCommand, dstStage, dstStage, 0, 0, nullptr, 1,
&barrier, 0, nullptr);
sourcePool->submitCommands();
}
void Buffer::executePipelineBarrier(VkAccessFlags srcAccess,
VkPipelineStageFlags srcStage,
VkAccessFlags dstAccess,
VkPipelineStageFlags dstStage) {
if (getSize() == 0)
return;
PCommand commandBuffer = graphics->getQueueCommands(owner)->getCommands();
VkBufferMemoryBarrier barrier = {
.sType = VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER,
.pNext = nullptr,
.srcAccessMask = srcAccess,
.dstAccessMask = dstAccess,
.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED,
.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED,
.buffer = getHandle(),
.offset = 0,
.size = getSize(),
};
vkCmdPipelineBarrier(commandBuffer->getHandle(), srcStage, dstStage, 0, 0,
nullptr, 1, &barrier, 0, nullptr);
}
void *Buffer::map(bool writeOnly) { return mapRegion(0, getSize(), writeOnly); }
void *Buffer::mapRegion(uint64 regionOffset, uint64 regionSize,
bool writeOnly) {
if (regionSize == 0)
return nullptr;
void *data = nullptr;
PendingBuffer pending;
pending.allocation = new BufferAllocation(graphics);
pending.allocation->size = regionSize;
pending.writeOnly = writeOnly;
pending.prevQueue = owner;
pending.offset = regionOffset;
if (writeOnly) {
if (buffers[currentBuffer]->properties &
VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT) {
VK_CHECK(vmaMapMemory(graphics->getAllocator(),
buffers[currentBuffer]->allocation, &data));
} else {
VkBufferCreateInfo stagingInfo = {
.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,
.pNext = nullptr,
.flags = 0,
.size = regionSize,
.usage = VK_BUFFER_USAGE_TRANSFER_SRC_BIT,
.sharingMode = VK_SHARING_MODE_EXCLUSIVE,
};
VmaAllocationCreateInfo allocInfo = {
.flags = VMA_ALLOCATION_CREATE_HOST_ACCESS_RANDOM_BIT |
VMA_ALLOCATION_CREATE_MAPPED_BIT,
.usage = VMA_MEMORY_USAGE_AUTO,
.requiredFlags = VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT,
};
VK_CHECK(vmaCreateBuffer(graphics->getAllocator(), &stagingInfo,
&allocInfo, &pending.allocation->buffer,
&pending.allocation->allocation, nullptr));
vmaMapMemory(graphics->getAllocator(), pending.allocation->allocation,
&data);
vmaSetAllocationName(graphics->getAllocator(),
pending.allocation->allocation, "MappingStaging");
if (getSize() == 0)
return;
Gfx::QueueFamilyMapping mapping = graphics->getFamilyMapping();
VkBufferMemoryBarrier barrier = {
.sType = VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER,
.pNext = nullptr,
.srcQueueFamilyIndex = mapping.getQueueTypeFamilyIndex(owner),
.dstQueueFamilyIndex = mapping.getQueueTypeFamilyIndex(newOwner),
.buffer = getHandle(),
.offset = 0,
.size = getSize(),
};
PCommandPool sourcePool = graphics->getQueueCommands(owner);
PCommandPool dstPool = nullptr;
VkPipelineStageFlags srcStage = VK_PIPELINE_STAGE_ALL_COMMANDS_BIT;
VkPipelineStageFlags dstStage = VK_PIPELINE_STAGE_ALL_COMMANDS_BIT;
assert(barrier.srcQueueFamilyIndex != barrier.dstQueueFamilyIndex);
if (owner == Gfx::QueueType::TRANSFER) {
barrier.srcAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT;
srcStage = VK_PIPELINE_STAGE_TRANSFER_BIT;
} else if (owner == Gfx::QueueType::COMPUTE) {
barrier.srcAccessMask = VK_ACCESS_SHADER_WRITE_BIT;
srcStage = VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT;
} else if (owner == Gfx::QueueType::GRAPHICS) {
barrier.srcAccessMask = getSourceAccessMask();
srcStage = VK_PIPELINE_STAGE_ALL_GRAPHICS_BIT;
}
} else {
assert(false);
}
pendingBuffers[this] = std::move(pending);
if (newOwner == Gfx::QueueType::TRANSFER) {
barrier.dstAccessMask = VK_ACCESS_TRANSFER_READ_BIT;
dstStage = VK_PIPELINE_STAGE_TRANSFER_BIT;
dstPool = graphics->getTransferCommands();
} else if (newOwner == Gfx::QueueType::COMPUTE) {
barrier.dstAccessMask = VK_ACCESS_SHADER_READ_BIT;
dstStage = VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT;
dstPool = graphics->getComputeCommands();
} else if (newOwner == Gfx::QueueType::GRAPHICS) {
barrier.dstAccessMask = getDestAccessMask();
dstStage = VK_PIPELINE_STAGE_ALL_GRAPHICS_BIT;
dstPool = graphics->getGraphicsCommands();
}
VkCommandBuffer srcCommand = sourcePool->getCommands()->getHandle();
VkCommandBuffer dstCommand = dstPool->getCommands()->getHandle();
vkCmdPipelineBarrier(srcCommand, srcStage, srcStage, 0, 0, nullptr, 1, &barrier, 0, nullptr);
vkCmdPipelineBarrier(dstCommand, dstStage, dstStage, 0, 0, nullptr, 1, &barrier, 0, nullptr);
sourcePool->submitCommands();
}
assert(data);
return data;
void Buffer::executePipelineBarrier(VkAccessFlags srcAccess, VkPipelineStageFlags srcStage, VkAccessFlags dstAccess,
VkPipelineStageFlags dstStage) {
if (getSize() == 0)
return;
PCommand commandBuffer = graphics->getQueueCommands(owner)->getCommands();
VkBufferMemoryBarrier barrier = {
.sType = VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER,
.pNext = nullptr,
.srcAccessMask = srcAccess,
.dstAccessMask = dstAccess,
.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED,
.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED,
.buffer = getHandle(),
.offset = 0,
.size = getSize(),
};
vkCmdPipelineBarrier(commandBuffer->getHandle(), srcStage, dstStage, 0, 0, nullptr, 1, &barrier, 0, nullptr);
}
void* Buffer::map(bool writeOnly) { return mapRegion(0, getSize(), writeOnly); }
void* Buffer::mapRegion(uint64 regionOffset, uint64 regionSize, bool writeOnly) {
if (regionSize == 0)
return nullptr;
void* data = nullptr;
PendingBuffer pending;
pending.allocation = new BufferAllocation(graphics);
pending.allocation->size = regionSize;
pending.writeOnly = writeOnly;
pending.prevQueue = owner;
pending.offset = regionOffset;
if (writeOnly) {
if (buffers[currentBuffer]->properties & VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT) {
VK_CHECK(vmaMapMemory(graphics->getAllocator(), buffers[currentBuffer]->allocation, &data));
} else {
VkBufferCreateInfo stagingInfo = {
.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,
.pNext = nullptr,
.flags = 0,
.size = regionSize,
.usage = VK_BUFFER_USAGE_TRANSFER_SRC_BIT,
.sharingMode = VK_SHARING_MODE_EXCLUSIVE,
};
VmaAllocationCreateInfo allocInfo = {
.flags = VMA_ALLOCATION_CREATE_HOST_ACCESS_RANDOM_BIT | VMA_ALLOCATION_CREATE_MAPPED_BIT,
.usage = VMA_MEMORY_USAGE_AUTO,
.requiredFlags = VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT,
};
VK_CHECK(vmaCreateBuffer(graphics->getAllocator(), &stagingInfo, &allocInfo, &pending.allocation->buffer,
&pending.allocation->allocation, nullptr));
vmaMapMemory(graphics->getAllocator(), pending.allocation->allocation, &data);
vmaSetAllocationName(graphics->getAllocator(), pending.allocation->allocation, "MappingStaging");
}
} else {
assert(false);
}
pendingBuffers[this] = std::move(pending);
assert(data);
return data;
}
void Buffer::unmap() {
auto found = pendingBuffers.find(this);
if (found != pendingBuffers.end()) {
PendingBuffer &pending = found->value;
if (pending.writeOnly) {
if (buffers[currentBuffer]->properties &
VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT) {
vmaUnmapMemory(graphics->getAllocator(),
buffers[currentBuffer]->allocation);
} else {
vmaFlushAllocation(graphics->getAllocator(),
pending.allocation->allocation, 0, VK_WHOLE_SIZE);
vmaUnmapMemory(graphics->getAllocator(),
pending.allocation->allocation);
PCommand command = graphics->getQueueCommands(owner)->getCommands();
command->bindResource(PBufferAllocation(pending.allocation));
VkCommandBuffer cmdHandle = command->getHandle();
auto found = pendingBuffers.find(this);
if (found != pendingBuffers.end()) {
PendingBuffer& pending = found->value;
if (pending.writeOnly) {
if (buffers[currentBuffer]->properties & VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT) {
vmaUnmapMemory(graphics->getAllocator(), buffers[currentBuffer]->allocation);
} else {
vmaFlushAllocation(graphics->getAllocator(), pending.allocation->allocation, 0, VK_WHOLE_SIZE);
vmaUnmapMemory(graphics->getAllocator(), pending.allocation->allocation);
PCommand command = graphics->getQueueCommands(owner)->getCommands();
command->bindResource(PBufferAllocation(pending.allocation));
VkCommandBuffer cmdHandle = command->getHandle();
VkBufferCopy region = {
.srcOffset = 0,
.dstOffset = pending.offset,
.size = pending.allocation->size,
};
VkBufferMemoryBarrier barrier = {
.sType = VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER,
.pNext = nullptr,
.srcAccessMask = VK_ACCESS_MEMORY_READ_BIT,
.dstAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT,
.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED,
.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED,
.buffer = buffers[currentBuffer]->buffer,
.offset = 0,
.size = buffers[currentBuffer]->size,
};
vkCmdPipelineBarrier(cmdHandle, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT,
VK_PIPELINE_STAGE_TRANSFER_BIT, 0, 0, nullptr, 1,
&barrier, 0, nullptr);
vkCmdCopyBuffer(cmdHandle, pending.allocation->buffer,
buffers[currentBuffer]->buffer, 1, &region);
barrier = {
.sType = VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER,
.pNext = nullptr,
.srcAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT,
.dstAccessMask = VK_ACCESS_MEMORY_READ_BIT,
.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED,
.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED,
.buffer = buffers[currentBuffer]->buffer,
.offset = 0,
.size = buffers[currentBuffer]->size,
};
vkCmdPipelineBarrier(cmdHandle, VK_PIPELINE_STAGE_TRANSFER_BIT,
VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, 0, 0, nullptr,
1, &barrier, 0, nullptr);
graphics->getDestructionManager()->queueResourceForDestruction(
std::move(pending.allocation));
}
VkBufferCopy region = {
.srcOffset = 0,
.dstOffset = pending.offset,
.size = pending.allocation->size,
};
VkBufferMemoryBarrier barrier = {
.sType = VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER,
.pNext = nullptr,
.srcAccessMask = VK_ACCESS_MEMORY_READ_BIT,
.dstAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT,
.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED,
.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED,
.buffer = buffers[currentBuffer]->buffer,
.offset = 0,
.size = buffers[currentBuffer]->size,
};
vkCmdPipelineBarrier(cmdHandle, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, 0, 0, nullptr, 1,
&barrier, 0, nullptr);
vkCmdCopyBuffer(cmdHandle, pending.allocation->buffer, buffers[currentBuffer]->buffer, 1, &region);
barrier = {
.sType = VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER,
.pNext = nullptr,
.srcAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT,
.dstAccessMask = VK_ACCESS_MEMORY_READ_BIT,
.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED,
.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED,
.buffer = buffers[currentBuffer]->buffer,
.offset = 0,
.size = buffers[currentBuffer]->size,
};
vkCmdPipelineBarrier(cmdHandle, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, 0, 0, nullptr, 1,
&barrier, 0, nullptr);
graphics->getDestructionManager()->queueResourceForDestruction(std::move(pending.allocation));
}
}
pendingBuffers.erase(this);
}
pendingBuffers.erase(this);
}
}
void Buffer::rotateBuffer(uint64 size, bool preserveContents) {
assert(dynamic);
size = std::max(getSize(), size);
for (size_t i = 0; i < buffers.size(); ++i) {
if (buffers[i]->isCurrentlyBound()) {
continue;
}
if (buffers[i]->size < size) {
vmaDestroyBuffer(graphics->getAllocator(), buffers[i]->buffer,
buffers[i]->allocation);
VkBufferCreateInfo info = {
.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,
.pNext = nullptr,
.size = size,
.usage = usage,
.sharingMode = VK_SHARING_MODE_EXCLUSIVE,
};
VmaAllocationCreateInfo allocInfo = {
.flags =
VMA_ALLOCATION_CREATE_HOST_ACCESS_ALLOW_TRANSFER_INSTEAD_BIT |
VMA_ALLOCATION_CREATE_HOST_ACCESS_SEQUENTIAL_WRITE_BIT,
.usage = VMA_MEMORY_USAGE_AUTO,
};
VK_CHECK(vmaCreateBuffer(graphics->getAllocator(), &info, &allocInfo,
&buffers[i]->buffer, &buffers[i]->allocation,
&buffers[i]->info));
vmaGetAllocationMemoryProperties(graphics->getAllocator(),
buffers[i]->allocation,
&buffers[i]->properties);
if (!name.empty()) {
VkDebugUtilsObjectNameInfoEXT nameInfo = {
.sType = VK_STRUCTURE_TYPE_DEBUG_UTILS_OBJECT_NAME_INFO_EXT,
.pNext = nullptr,
.objectType = VK_OBJECT_TYPE_BUFFER,
.objectHandle = (uint64)buffers[i]->buffer,
.pObjectName = this->name.c_str()};
graphics->vkSetDebugUtilsObjectNameEXT(&nameInfo);
}
buffers[i]->size = size;
assert(dynamic);
size = std::max(getSize(), size);
for (size_t i = 0; i < buffers.size(); ++i) {
if (buffers[i]->isCurrentlyBound()) {
continue;
}
if (buffers[i]->size < size) {
vmaDestroyBuffer(graphics->getAllocator(), buffers[i]->buffer, buffers[i]->allocation);
VkBufferCreateInfo info = {
.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,
.pNext = nullptr,
.size = size,
.usage = usage,
.sharingMode = VK_SHARING_MODE_EXCLUSIVE,
};
VmaAllocationCreateInfo allocInfo = {
.flags =
VMA_ALLOCATION_CREATE_HOST_ACCESS_ALLOW_TRANSFER_INSTEAD_BIT | VMA_ALLOCATION_CREATE_HOST_ACCESS_SEQUENTIAL_WRITE_BIT,
.usage = VMA_MEMORY_USAGE_AUTO,
};
VK_CHECK(vmaCreateBuffer(graphics->getAllocator(), &info, &allocInfo, &buffers[i]->buffer, &buffers[i]->allocation,
&buffers[i]->info));
vmaGetAllocationMemoryProperties(graphics->getAllocator(), buffers[i]->allocation, &buffers[i]->properties);
if (!name.empty()) {
VkDebugUtilsObjectNameInfoEXT nameInfo = {.sType = VK_STRUCTURE_TYPE_DEBUG_UTILS_OBJECT_NAME_INFO_EXT,
.pNext = nullptr,
.objectType = VK_OBJECT_TYPE_BUFFER,
.objectHandle = (uint64)buffers[i]->buffer,
.pObjectName = this->name.c_str()};
graphics->vkSetDebugUtilsObjectNameEXT(&nameInfo);
}
buffers[i]->size = size;
}
if (preserveContents) {
copyBuffer(currentBuffer, i);
}
currentBuffer = i;
return;
}
createBuffer(size);
if (preserveContents) {
copyBuffer(currentBuffer, i);
copyBuffer(currentBuffer, buffers.size() - 1);
}
currentBuffer = i;
return;
}
createBuffer(size);
if (preserveContents) {
copyBuffer(currentBuffer, buffers.size() - 1);
}
currentBuffer = buffers.size() - 1;
currentBuffer = buffers.size() - 1;
}
void Buffer::createBuffer(uint64 size) {
VkBufferCreateInfo info = {
.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,
.pNext = nullptr,
.size = size,
.usage = usage,
.sharingMode = VK_SHARING_MODE_EXCLUSIVE,
};
VmaAllocationCreateInfo allocInfo = {
.flags = VMA_ALLOCATION_CREATE_HOST_ACCESS_ALLOW_TRANSFER_INSTEAD_BIT |
VMA_ALLOCATION_CREATE_HOST_ACCESS_SEQUENTIAL_WRITE_BIT,
.usage = VMA_MEMORY_USAGE_AUTO,
};
buffers.add(new BufferAllocation(graphics));
if (size > 0) {
VK_CHECK(vmaCreateBuffer(
graphics->getAllocator(), &info, &allocInfo, &buffers.back()->buffer,
&buffers.back()->allocation, &buffers.back()->info));
buffers.back()->size = size;
vmaGetAllocationMemoryProperties(graphics->getAllocator(),
buffers.back()->allocation,
&buffers.back()->properties);
VkBufferDeviceAddressInfo addrInfo = {
.sType = VK_STRUCTURE_TYPE_BUFFER_DEVICE_ADDRESS_INFO_KHR,
VkBufferCreateInfo info = {
.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,
.pNext = nullptr,
.buffer = buffers.back()->buffer,
.size = size,
.usage = usage,
.sharingMode = VK_SHARING_MODE_EXCLUSIVE,
};
buffers.back()->deviceAddress =
vkGetBufferDeviceAddress(graphics->getDevice(), &addrInfo);
if (!name.empty()) {
VkDebugUtilsObjectNameInfoEXT nameInfo = {
.sType = VK_STRUCTURE_TYPE_DEBUG_UTILS_OBJECT_NAME_INFO_EXT,
.pNext = nullptr,
.objectType = VK_OBJECT_TYPE_BUFFER,
.objectHandle = (uint64)buffers.back()->buffer,
.pObjectName = this->name.c_str()};
graphics->vkSetDebugUtilsObjectNameEXT(&nameInfo);
VmaAllocationCreateInfo allocInfo = {
.flags = VMA_ALLOCATION_CREATE_HOST_ACCESS_ALLOW_TRANSFER_INSTEAD_BIT | VMA_ALLOCATION_CREATE_HOST_ACCESS_SEQUENTIAL_WRITE_BIT,
.usage = VMA_MEMORY_USAGE_AUTO,
};
buffers.add(new BufferAllocation(graphics));
if (size > 0) {
VK_CHECK(vmaCreateBuffer(graphics->getAllocator(), &info, &allocInfo, &buffers.back()->buffer, &buffers.back()->allocation,
&buffers.back()->info));
buffers.back()->size = size;
vmaGetAllocationMemoryProperties(graphics->getAllocator(), buffers.back()->allocation, &buffers.back()->properties);
VkBufferDeviceAddressInfo addrInfo = {
.sType = VK_STRUCTURE_TYPE_BUFFER_DEVICE_ADDRESS_INFO_KHR,
.pNext = nullptr,
.buffer = buffers.back()->buffer,
};
buffers.back()->deviceAddress = vkGetBufferDeviceAddress(graphics->getDevice(), &addrInfo);
if (!name.empty()) {
VkDebugUtilsObjectNameInfoEXT nameInfo = {.sType = VK_STRUCTURE_TYPE_DEBUG_UTILS_OBJECT_NAME_INFO_EXT,
.pNext = nullptr,
.objectType = VK_OBJECT_TYPE_BUFFER,
.objectHandle = (uint64)buffers.back()->buffer,
.pObjectName = this->name.c_str()};
graphics->vkSetDebugUtilsObjectNameEXT(&nameInfo);
}
}
}
}
void Buffer::copyBuffer(uint64 src, uint64 dst) {
if (src == dst) {
return;
}
PCommand command = graphics->getQueueCommands(owner)->getCommands();
VkBufferMemoryBarrier srcBarrier = {
.sType = VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER,
.pNext = nullptr,
.srcAccessMask = VK_ACCESS_MEMORY_WRITE_BIT,
.dstAccessMask = VK_ACCESS_TRANSFER_READ_BIT,
.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED,
.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED,
.buffer = buffers[src]->buffer,
.offset = 0,
.size = buffers[src]->size,
};
vkCmdPipelineBarrier(command->getHandle(),
VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT,
VK_PIPELINE_STAGE_TRANSFER_BIT, 0, 0, nullptr, 1,
&srcBarrier, 0, nullptr);
VkBufferCopy region = {
.srcOffset = 0, .dstOffset = 0, .size = buffers[src]->size};
vkCmdCopyBuffer(command->getHandle(), buffers[src]->buffer,
buffers[dst]->buffer, 1, &region);
VkBufferMemoryBarrier dstBarrier = {
.sType = VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER,
.pNext = nullptr,
.srcAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT,
.dstAccessMask = VK_ACCESS_MEMORY_READ_BIT,
.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED,
.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED,
.buffer = buffers[dst]->buffer,
.offset = 0,
.size = buffers[dst]->size,
};
vkCmdPipelineBarrier(command->getHandle(), VK_PIPELINE_STAGE_TRANSFER_BIT,
VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, 0, 0, nullptr, 1,
&dstBarrier, 0, nullptr);
if (src == dst) {
return;
}
PCommand command = graphics->getQueueCommands(owner)->getCommands();
VkBufferMemoryBarrier srcBarrier = {
.sType = VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER,
.pNext = nullptr,
.srcAccessMask = VK_ACCESS_MEMORY_WRITE_BIT,
.dstAccessMask = VK_ACCESS_TRANSFER_READ_BIT,
.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED,
.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED,
.buffer = buffers[src]->buffer,
.offset = 0,
.size = buffers[src]->size,
};
vkCmdPipelineBarrier(command->getHandle(), VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, 0, 0, nullptr, 1,
&srcBarrier, 0, nullptr);
VkBufferCopy region = {.srcOffset = 0, .dstOffset = 0, .size = buffers[src]->size};
vkCmdCopyBuffer(command->getHandle(), buffers[src]->buffer, buffers[dst]->buffer, 1, &region);
VkBufferMemoryBarrier dstBarrier = {
.sType = VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER,
.pNext = nullptr,
.srcAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT,
.dstAccessMask = VK_ACCESS_MEMORY_READ_BIT,
.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED,
.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED,
.buffer = buffers[dst]->buffer,
.offset = 0,
.size = buffers[dst]->size,
};
vkCmdPipelineBarrier(command->getHandle(), VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, 0, 0, nullptr, 1,
&dstBarrier, 0, nullptr);
}
UniformBuffer::UniformBuffer(PGraphics graphics,
const UniformBufferCreateInfo &createInfo)
UniformBuffer::UniformBuffer(PGraphics graphics, const UniformBufferCreateInfo& createInfo)
: Gfx::UniformBuffer(graphics->getFamilyMapping(), createInfo.sourceData),
Vulkan::Buffer(graphics, createInfo.sourceData.size,
VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT, currentOwner,
createInfo.dynamic, createInfo.name) {
if (getSize() > 0 && createInfo.sourceData.data != nullptr) {
void *data = map();
std::memcpy(data, createInfo.sourceData.data, createInfo.sourceData.size);
unmap();
}
Vulkan::Buffer(graphics, createInfo.sourceData.size, VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT, currentOwner, createInfo.dynamic,
createInfo.name) {
if (getSize() > 0 && createInfo.sourceData.data != nullptr) {
void* data = map();
std::memcpy(data, createInfo.sourceData.data, createInfo.sourceData.size);
unmap();
}
}
UniformBuffer::~UniformBuffer() {}
void UniformBuffer::updateContents(const DataSource &sourceData) {
void *data = map();
std::memcpy(data, sourceData.data, sourceData.size);
unmap();
}
void UniformBuffer::rotateBuffer(uint64 size) {
Vulkan::Buffer::rotateBuffer(size);
}
void UniformBuffer::requestOwnershipTransfer(Gfx::QueueType newOwner) {
Gfx::QueueOwnedResource::transferOwnership(newOwner);
}
void UniformBuffer::executeOwnershipBarrier(Gfx::QueueType newOwner) {
Vulkan::Buffer::executeOwnershipBarrier(newOwner);
}
void UniformBuffer::executePipelineBarrier(VkAccessFlags srcAccess,
VkPipelineStageFlags srcStage,
VkAccessFlags dstAccess,
VkPipelineStageFlags dstStage) {
Vulkan::Buffer::executePipelineBarrier(srcAccess, srcStage, dstAccess,
dstStage);
}
VkAccessFlags UniformBuffer::getSourceAccessMask() {
return VK_ACCESS_MEMORY_WRITE_BIT;
}
VkAccessFlags UniformBuffer::getDestAccessMask() {
return VK_ACCESS_UNIFORM_READ_BIT;
}
ShaderBuffer::ShaderBuffer(PGraphics graphics,
const ShaderBufferCreateInfo &sourceData)
: Gfx::ShaderBuffer(graphics->getFamilyMapping(), sourceData.numElements,
sourceData.sourceData),
Vulkan::Buffer(
graphics, sourceData.sourceData.size,
VK_BUFFER_USAGE_STORAGE_BUFFER_BIT |
(sourceData.vertexBuffer
? VK_BUFFER_USAGE_ACCELERATION_STRUCTURE_BUILD_INPUT_READ_ONLY_BIT_KHR |
VK_BUFFER_USAGE_SHADER_DEVICE_ADDRESS_BIT
: 0),
currentOwner, sourceData.dynamic, sourceData.name) {
if (getSize() > 0 && sourceData.sourceData.data != nullptr) {
void *data = map();
std::memcpy(data, sourceData.sourceData.data, sourceData.sourceData.size);
void UniformBuffer::updateContents(const DataSource& sourceData) {
void* data = map();
std::memcpy(data, sourceData.data, sourceData.size);
unmap();
}
}
void UniformBuffer::rotateBuffer(uint64 size) { Vulkan::Buffer::rotateBuffer(size); }
void UniformBuffer::requestOwnershipTransfer(Gfx::QueueType newOwner) { Gfx::QueueOwnedResource::transferOwnership(newOwner); }
void UniformBuffer::executeOwnershipBarrier(Gfx::QueueType newOwner) { Vulkan::Buffer::executeOwnershipBarrier(newOwner); }
void UniformBuffer::executePipelineBarrier(VkAccessFlags srcAccess, VkPipelineStageFlags srcStage, VkAccessFlags dstAccess,
VkPipelineStageFlags dstStage) {
Vulkan::Buffer::executePipelineBarrier(srcAccess, srcStage, dstAccess, dstStage);
}
VkAccessFlags UniformBuffer::getSourceAccessMask() { return VK_ACCESS_MEMORY_WRITE_BIT; }
VkAccessFlags UniformBuffer::getDestAccessMask() { return VK_ACCESS_UNIFORM_READ_BIT; }
ShaderBuffer::ShaderBuffer(PGraphics graphics, const ShaderBufferCreateInfo& sourceData)
: Gfx::ShaderBuffer(graphics->getFamilyMapping(), sourceData.numElements, sourceData.sourceData),
Vulkan::Buffer(graphics, sourceData.sourceData.size,
VK_BUFFER_USAGE_STORAGE_BUFFER_BIT |
(sourceData.vertexBuffer ? VK_BUFFER_USAGE_ACCELERATION_STRUCTURE_BUILD_INPUT_READ_ONLY_BIT_KHR |
VK_BUFFER_USAGE_SHADER_DEVICE_ADDRESS_BIT
: 0),
currentOwner, sourceData.dynamic, sourceData.name) {
if (getSize() > 0 && sourceData.sourceData.data != nullptr) {
void* data = map();
std::memcpy(data, sourceData.sourceData.data, sourceData.sourceData.size);
unmap();
}
}
ShaderBuffer::~ShaderBuffer() {}
void ShaderBuffer::updateContents(const ShaderBufferCreateInfo &createInfo) {
if (createInfo.sourceData.data == nullptr) {
return;
}
// We always want to update, as the contents could be different on the GPU
void *data = map();
std::memcpy((char *)data + createInfo.sourceData.offset,
createInfo.sourceData.data, createInfo.sourceData.size);
unmap();
void ShaderBuffer::updateContents(const ShaderBufferCreateInfo& createInfo) {
if (createInfo.sourceData.data == nullptr) {
return;
}
// We always want to update, as the contents could be different on the GPU
void* data = map();
std::memcpy((char*)data + createInfo.sourceData.offset, createInfo.sourceData.data, createInfo.sourceData.size);
unmap();
}
void Seele::Vulkan::ShaderBuffer::rotateBuffer(uint64 size,
bool preserveContents) {
assert(dynamic);
Vulkan::Buffer::rotateBuffer(size, preserveContents);
void Seele::Vulkan::ShaderBuffer::rotateBuffer(uint64 size, bool preserveContents) {
assert(dynamic);
Vulkan::Buffer::rotateBuffer(size, preserveContents);
}
void *ShaderBuffer::mapRegion(uint64 offset, uint64 size, bool writeOnly) {
return Vulkan::Buffer::mapRegion(offset, size, writeOnly);
}
void* ShaderBuffer::mapRegion(uint64 offset, uint64 size, bool writeOnly) { return Vulkan::Buffer::mapRegion(offset, size, writeOnly); }
void ShaderBuffer::unmap() { Vulkan::Buffer::unmap(); }
void ShaderBuffer::clear() {
vkCmdFillBuffer(graphics->getQueueCommands(owner)->getCommands()->getHandle(),
Vulkan::Buffer::getHandle(), 0, VK_WHOLE_SIZE, 0);
vkCmdFillBuffer(graphics->getQueueCommands(owner)->getCommands()->getHandle(), Vulkan::Buffer::getHandle(), 0, VK_WHOLE_SIZE, 0);
}
void ShaderBuffer::requestOwnershipTransfer(Gfx::QueueType newOwner) {
Gfx::QueueOwnedResource::transferOwnership(newOwner);
}
void ShaderBuffer::requestOwnershipTransfer(Gfx::QueueType newOwner) { Gfx::QueueOwnedResource::transferOwnership(newOwner); }
void ShaderBuffer::executeOwnershipBarrier(Gfx::QueueType newOwner) {
Vulkan::Buffer::executeOwnershipBarrier(newOwner);
}
void ShaderBuffer::executeOwnershipBarrier(Gfx::QueueType newOwner) { Vulkan::Buffer::executeOwnershipBarrier(newOwner); }
void ShaderBuffer::executePipelineBarrier(VkAccessFlags srcAccess,
VkPipelineStageFlags srcStage,
VkAccessFlags dstAccess,
void ShaderBuffer::executePipelineBarrier(VkAccessFlags srcAccess, VkPipelineStageFlags srcStage, VkAccessFlags dstAccess,
VkPipelineStageFlags dstStage) {
Vulkan::Buffer::executePipelineBarrier(srcAccess, srcStage, dstAccess,
dstStage);
Vulkan::Buffer::executePipelineBarrier(srcAccess, srcStage, dstAccess, dstStage);
}
VkAccessFlags ShaderBuffer::getSourceAccessMask() {
return VK_ACCESS_MEMORY_WRITE_BIT;
}
VkAccessFlags ShaderBuffer::getSourceAccessMask() { return VK_ACCESS_MEMORY_WRITE_BIT; }
VkAccessFlags ShaderBuffer::getDestAccessMask() {
return VK_ACCESS_MEMORY_READ_BIT;
}
VkAccessFlags ShaderBuffer::getDestAccessMask() { return VK_ACCESS_MEMORY_READ_BIT; }
VertexBuffer::VertexBuffer(PGraphics graphics,
const VertexBufferCreateInfo &sourceData)
: Gfx::VertexBuffer(graphics->getFamilyMapping(), sourceData.numVertices,
sourceData.vertexSize, sourceData.sourceData.owner),
Vulkan::Buffer(graphics, sourceData.sourceData.size,
VK_BUFFER_USAGE_VERTEX_BUFFER_BIT, currentOwner, false,
sourceData.name) {
if (sourceData.sourceData.data != nullptr) {
void *data = map();
std::memcpy(data, sourceData.sourceData.data, sourceData.sourceData.size);
unmap();
}
VertexBuffer::VertexBuffer(PGraphics graphics, const VertexBufferCreateInfo& sourceData)
: Gfx::VertexBuffer(graphics->getFamilyMapping(), sourceData.numVertices, sourceData.vertexSize, sourceData.sourceData.owner),
Vulkan::Buffer(graphics, sourceData.sourceData.size, VK_BUFFER_USAGE_VERTEX_BUFFER_BIT, currentOwner, false, sourceData.name) {
if (sourceData.sourceData.data != nullptr) {
void* data = map();
std::memcpy(data, sourceData.sourceData.data, sourceData.sourceData.size);
unmap();
}
}
VertexBuffer::~VertexBuffer() {}
void VertexBuffer::updateRegion(DataSource update) {
void *data = mapRegion(update.offset, update.size);
std::memcpy(data, update.data, update.size);
unmap();
}
void VertexBuffer::download(Array<uint8> &buffer) {
void *data = map(false);
buffer.resize(getSize());
std::memcpy(buffer.data(), data, getSize());
unmap();
}
void VertexBuffer::requestOwnershipTransfer(Gfx::QueueType newOwner) {
Gfx::QueueOwnedResource::transferOwnership(newOwner);
}
void VertexBuffer::executeOwnershipBarrier(Gfx::QueueType newOwner) {
Vulkan::Buffer::executeOwnershipBarrier(newOwner);
}
void VertexBuffer::executePipelineBarrier(VkAccessFlags srcAccess,
VkPipelineStageFlags srcStage,
VkAccessFlags dstAccess,
VkPipelineStageFlags dstStage) {
Vulkan::Buffer::executePipelineBarrier(srcAccess, srcStage, dstAccess,
dstStage);
}
VkAccessFlags VertexBuffer::getSourceAccessMask() {
return VK_ACCESS_MEMORY_WRITE_BIT;
}
VkAccessFlags VertexBuffer::getDestAccessMask() {
return VK_ACCESS_VERTEX_ATTRIBUTE_READ_BIT;
}
IndexBuffer::IndexBuffer(PGraphics graphics,
const IndexBufferCreateInfo &sourceData)
: Gfx::IndexBuffer(graphics->getFamilyMapping(), sourceData.sourceData.size,
sourceData.indexType, sourceData.sourceData.owner),
Vulkan::Buffer(
graphics, sourceData.sourceData.size,
VK_BUFFER_USAGE_INDEX_BUFFER_BIT |
VK_BUFFER_USAGE_ACCELERATION_STRUCTURE_BUILD_INPUT_READ_ONLY_BIT_KHR |
VK_BUFFER_USAGE_SHADER_DEVICE_ADDRESS_BIT,
currentOwner, false, sourceData.name) {
if (sourceData.sourceData.data != nullptr) {
void *data = map();
std::memcpy(data, sourceData.sourceData.data, sourceData.sourceData.size);
void* data = mapRegion(update.offset, update.size);
std::memcpy(data, update.data, update.size);
unmap();
}
}
void VertexBuffer::download(Array<uint8>& buffer) {
void* data = map(false);
buffer.resize(getSize());
std::memcpy(buffer.data(), data, getSize());
unmap();
}
void VertexBuffer::requestOwnershipTransfer(Gfx::QueueType newOwner) { Gfx::QueueOwnedResource::transferOwnership(newOwner); }
void VertexBuffer::executeOwnershipBarrier(Gfx::QueueType newOwner) { Vulkan::Buffer::executeOwnershipBarrier(newOwner); }
void VertexBuffer::executePipelineBarrier(VkAccessFlags srcAccess, VkPipelineStageFlags srcStage, VkAccessFlags dstAccess,
VkPipelineStageFlags dstStage) {
Vulkan::Buffer::executePipelineBarrier(srcAccess, srcStage, dstAccess, dstStage);
}
VkAccessFlags VertexBuffer::getSourceAccessMask() { return VK_ACCESS_MEMORY_WRITE_BIT; }
VkAccessFlags VertexBuffer::getDestAccessMask() { return VK_ACCESS_VERTEX_ATTRIBUTE_READ_BIT; }
IndexBuffer::IndexBuffer(PGraphics graphics, const IndexBufferCreateInfo& sourceData)
: Gfx::IndexBuffer(graphics->getFamilyMapping(), sourceData.sourceData.size, sourceData.indexType, sourceData.sourceData.owner),
Vulkan::Buffer(graphics, sourceData.sourceData.size,
VK_BUFFER_USAGE_INDEX_BUFFER_BIT | VK_BUFFER_USAGE_ACCELERATION_STRUCTURE_BUILD_INPUT_READ_ONLY_BIT_KHR |
VK_BUFFER_USAGE_SHADER_DEVICE_ADDRESS_BIT,
currentOwner, false, sourceData.name) {
if (sourceData.sourceData.data != nullptr) {
void* data = map();
std::memcpy(data, sourceData.sourceData.data, sourceData.sourceData.size);
unmap();
}
}
IndexBuffer::~IndexBuffer() {}
void IndexBuffer::download(Array<uint8> &buffer) {
void *data = map(false);
buffer.resize(getSize());
std::memcpy(buffer.data(), data, getSize());
unmap();
void IndexBuffer::download(Array<uint8>& buffer) {
void* data = map(false);
buffer.resize(getSize());
std::memcpy(buffer.data(), data, getSize());
unmap();
}
void IndexBuffer::requestOwnershipTransfer(Gfx::QueueType newOwner) {
Gfx::QueueOwnedResource::transferOwnership(newOwner);
}
void IndexBuffer::requestOwnershipTransfer(Gfx::QueueType newOwner) { Gfx::QueueOwnedResource::transferOwnership(newOwner); }
void IndexBuffer::executeOwnershipBarrier(Gfx::QueueType newOwner) {
Vulkan::Buffer::executeOwnershipBarrier(newOwner);
}
void IndexBuffer::executeOwnershipBarrier(Gfx::QueueType newOwner) { Vulkan::Buffer::executeOwnershipBarrier(newOwner); }
void IndexBuffer::executePipelineBarrier(VkAccessFlags srcAccess,
VkPipelineStageFlags srcStage,
VkAccessFlags dstAccess,
void IndexBuffer::executePipelineBarrier(VkAccessFlags srcAccess, VkPipelineStageFlags srcStage, VkAccessFlags dstAccess,
VkPipelineStageFlags dstStage) {
Vulkan::Buffer::executePipelineBarrier(srcAccess, srcStage, dstAccess,
dstStage);
Vulkan::Buffer::executePipelineBarrier(srcAccess, srcStage, dstAccess, dstStage);
}
VkAccessFlags IndexBuffer::getSourceAccessMask() {
return VK_ACCESS_MEMORY_WRITE_BIT;
}
VkAccessFlags IndexBuffer::getSourceAccessMask() { return VK_ACCESS_MEMORY_WRITE_BIT; }
VkAccessFlags IndexBuffer::getDestAccessMask() {
return VK_ACCESS_INDEX_READ_BIT;
}
VkAccessFlags IndexBuffer::getDestAccessMask() { return VK_ACCESS_INDEX_READ_BIT; }
+96 -116
View File
@@ -8,153 +8,133 @@ namespace Vulkan {
DECLARE_REF(Command)
DECLARE_REF(Fence)
class BufferAllocation : public CommandBoundResource {
public:
BufferAllocation(PGraphics graphics);
virtual ~BufferAllocation();
VkBuffer buffer = VK_NULL_HANDLE;
VmaAllocation allocation = VmaAllocation();
VmaAllocationInfo info = VmaAllocationInfo();
VkMemoryPropertyFlags properties = 0;
uint64 size = 0;
VkDeviceAddress deviceAddress;
public:
BufferAllocation(PGraphics graphics);
virtual ~BufferAllocation();
VkBuffer buffer = VK_NULL_HANDLE;
VmaAllocation allocation = VmaAllocation();
VmaAllocationInfo info = VmaAllocationInfo();
VkMemoryPropertyFlags properties = 0;
uint64 size = 0;
VkDeviceAddress deviceAddress;
};
DEFINE_REF(BufferAllocation);
class Buffer {
public:
Buffer(PGraphics graphics, uint64 size, VkBufferUsageFlags usage,
Gfx::QueueType &queueType, bool dynamic, std::string name);
virtual ~Buffer();
VkBuffer getHandle() const { return buffers[currentBuffer]->buffer; }
VkDeviceAddress getDeviceAddress() const {
return buffers[currentBuffer]->deviceAddress;
}
PBufferAllocation getAlloc() const { return buffers[currentBuffer]; }
uint64 getSize() const { return buffers[currentBuffer]->size; }
void *map(bool writeOnly = true);
void *mapRegion(uint64 regionOffset, uint64 regionSize,
bool writeOnly = true);
void unmap();
public:
Buffer(PGraphics graphics, uint64 size, VkBufferUsageFlags usage, Gfx::QueueType& queueType, bool dynamic, std::string name);
virtual ~Buffer();
VkBuffer getHandle() const { return buffers[currentBuffer]->buffer; }
VkDeviceAddress getDeviceAddress() const { return buffers[currentBuffer]->deviceAddress; }
PBufferAllocation getAlloc() const { return buffers[currentBuffer]; }
uint64 getSize() const { return buffers[currentBuffer]->size; }
void* map(bool writeOnly = true);
void* mapRegion(uint64 regionOffset, uint64 regionSize, bool writeOnly = true);
void unmap();
protected:
PGraphics graphics;
uint32 currentBuffer;
Gfx::QueueType &owner;
Array<OBufferAllocation> buffers;
VkBufferUsageFlags usage;
bool dynamic;
std::string name;
void rotateBuffer(uint64 size, bool preserveContents = false);
void createBuffer(uint64 size);
void copyBuffer(uint64 src, uint64 dest);
protected:
PGraphics graphics;
uint32 currentBuffer;
Gfx::QueueType& owner;
Array<OBufferAllocation> buffers;
VkBufferUsageFlags usage;
bool dynamic;
std::string name;
void rotateBuffer(uint64 size, bool preserveContents = false);
void createBuffer(uint64 size);
void copyBuffer(uint64 src, uint64 dest);
void executeOwnershipBarrier(Gfx::QueueType newOwner);
void executePipelineBarrier(VkAccessFlags srcAccess,
VkPipelineStageFlags srcStage,
VkAccessFlags dstAccess,
VkPipelineStageFlags dstStage);
void executeOwnershipBarrier(Gfx::QueueType newOwner);
void executePipelineBarrier(VkAccessFlags srcAccess, VkPipelineStageFlags srcStage, VkAccessFlags dstAccess,
VkPipelineStageFlags dstStage);
virtual void requestOwnershipTransfer(Gfx::QueueType newOwner) = 0;
virtual void requestOwnershipTransfer(Gfx::QueueType newOwner) = 0;
virtual VkAccessFlags getSourceAccessMask() = 0;
virtual VkAccessFlags getDestAccessMask() = 0;
virtual VkAccessFlags getSourceAccessMask() = 0;
virtual VkAccessFlags getDestAccessMask() = 0;
};
DEFINE_REF(Buffer)
class VertexBuffer : public Gfx::VertexBuffer, public Buffer {
public:
VertexBuffer(PGraphics graphics, const VertexBufferCreateInfo &sourceData);
virtual ~VertexBuffer();
public:
VertexBuffer(PGraphics graphics, const VertexBufferCreateInfo& sourceData);
virtual ~VertexBuffer();
virtual void updateRegion(DataSource update) override;
virtual void download(Array<uint8> &buffer) override;
virtual void updateRegion(DataSource update) override;
virtual void download(Array<uint8>& buffer) override;
protected:
// Inherited via Vulkan::Buffer
virtual VkAccessFlags getSourceAccessMask() override;
virtual VkAccessFlags getDestAccessMask() override;
virtual void requestOwnershipTransfer(Gfx::QueueType newOwner) override;
// Inherited via QueueOwnedResource
virtual void executeOwnershipBarrier(Gfx::QueueType newOwner) override;
virtual void
executePipelineBarrier(Gfx::SeAccessFlags srcAccess,
Gfx::SePipelineStageFlags srcStage,
Gfx::SeAccessFlags dstAccess,
Gfx::SePipelineStageFlags dstStage) override;
protected:
// Inherited via Vulkan::Buffer
virtual VkAccessFlags getSourceAccessMask() override;
virtual VkAccessFlags getDestAccessMask() override;
virtual void requestOwnershipTransfer(Gfx::QueueType newOwner) override;
// Inherited via QueueOwnedResource
virtual void executeOwnershipBarrier(Gfx::QueueType newOwner) override;
virtual void executePipelineBarrier(Gfx::SeAccessFlags srcAccess, Gfx::SePipelineStageFlags srcStage, Gfx::SeAccessFlags dstAccess,
Gfx::SePipelineStageFlags dstStage) override;
};
DEFINE_REF(VertexBuffer)
class IndexBuffer : public Gfx::IndexBuffer, public Buffer {
public:
IndexBuffer(PGraphics graphics, const IndexBufferCreateInfo &sourceData);
virtual ~IndexBuffer();
public:
IndexBuffer(PGraphics graphics, const IndexBufferCreateInfo& sourceData);
virtual ~IndexBuffer();
virtual void download(Array<uint8> &buffer) override;
virtual void download(Array<uint8>& buffer) override;
protected:
// Inherited via Vulkan::Buffer
virtual VkAccessFlags getSourceAccessMask() override;
virtual VkAccessFlags getDestAccessMask() override;
virtual void requestOwnershipTransfer(Gfx::QueueType newOwner) override;
// Inherited via QueueOwnedResource
virtual void executeOwnershipBarrier(Gfx::QueueType newOwner) override;
virtual void
executePipelineBarrier(Gfx::SeAccessFlags srcAccess,
Gfx::SePipelineStageFlags srcStage,
Gfx::SeAccessFlags dstAccess,
Gfx::SePipelineStageFlags dstStage) override;
protected:
// Inherited via Vulkan::Buffer
virtual VkAccessFlags getSourceAccessMask() override;
virtual VkAccessFlags getDestAccessMask() override;
virtual void requestOwnershipTransfer(Gfx::QueueType newOwner) override;
// Inherited via QueueOwnedResource
virtual void executeOwnershipBarrier(Gfx::QueueType newOwner) override;
virtual void executePipelineBarrier(Gfx::SeAccessFlags srcAccess, Gfx::SePipelineStageFlags srcStage, Gfx::SeAccessFlags dstAccess,
Gfx::SePipelineStageFlags dstStage) override;
};
DEFINE_REF(IndexBuffer)
class UniformBuffer : public Gfx::UniformBuffer, public Buffer {
public:
UniformBuffer(PGraphics graphics, const UniformBufferCreateInfo &sourceData);
virtual ~UniformBuffer();
virtual void updateContents(const DataSource &sourceData) override;
virtual void rotateBuffer(uint64 size) override;
public:
UniformBuffer(PGraphics graphics, const UniformBufferCreateInfo& sourceData);
virtual ~UniformBuffer();
virtual void updateContents(const DataSource& sourceData) override;
virtual void rotateBuffer(uint64 size) override;
protected:
// Inherited via Vulkan::Buffer
virtual VkAccessFlags getSourceAccessMask() override;
virtual VkAccessFlags getDestAccessMask() override;
virtual void requestOwnershipTransfer(Gfx::QueueType newOwner) override;
// Inherited via QueueOwnedResource
virtual void executeOwnershipBarrier(Gfx::QueueType newOwner) override;
virtual void
executePipelineBarrier(Gfx::SeAccessFlags srcAccess,
Gfx::SePipelineStageFlags srcStage,
Gfx::SeAccessFlags dstAccess,
Gfx::SePipelineStageFlags dstStage) override;
protected:
// Inherited via Vulkan::Buffer
virtual VkAccessFlags getSourceAccessMask() override;
virtual VkAccessFlags getDestAccessMask() override;
virtual void requestOwnershipTransfer(Gfx::QueueType newOwner) override;
// Inherited via QueueOwnedResource
virtual void executeOwnershipBarrier(Gfx::QueueType newOwner) override;
virtual void executePipelineBarrier(Gfx::SeAccessFlags srcAccess, Gfx::SePipelineStageFlags srcStage, Gfx::SeAccessFlags dstAccess,
Gfx::SePipelineStageFlags dstStage) override;
private:
private:
};
DEFINE_REF(UniformBuffer)
class ShaderBuffer : public Gfx::ShaderBuffer, public Buffer {
public:
ShaderBuffer(PGraphics graphics, const ShaderBufferCreateInfo &sourceData);
virtual ~ShaderBuffer();
virtual void
updateContents(const ShaderBufferCreateInfo &createInfo) override;
virtual void rotateBuffer(uint64 size,
bool preserveContents = false) override;
virtual void *mapRegion(uint64 offset, uint64 size, bool writeOnly) override;
virtual void unmap() override;
public:
ShaderBuffer(PGraphics graphics, const ShaderBufferCreateInfo& sourceData);
virtual ~ShaderBuffer();
virtual void updateContents(const ShaderBufferCreateInfo& createInfo) override;
virtual void rotateBuffer(uint64 size, bool preserveContents = false) override;
virtual void* mapRegion(uint64 offset, uint64 size, bool writeOnly) override;
virtual void unmap() override;
virtual void clear() override;
virtual void clear() override;
protected:
// Inherited via Vulkan::Buffer
virtual VkAccessFlags getSourceAccessMask() override;
virtual VkAccessFlags getDestAccessMask() override;
virtual void requestOwnershipTransfer(Gfx::QueueType newOwner) override;
// Inherited via QueueOwnedResource
virtual void executeOwnershipBarrier(Gfx::QueueType newOwner) override;
virtual void
executePipelineBarrier(Gfx::SeAccessFlags srcAccess,
Gfx::SePipelineStageFlags srcStage,
Gfx::SeAccessFlags dstAccess,
Gfx::SePipelineStageFlags dstStage) override;
protected:
// Inherited via Vulkan::Buffer
virtual VkAccessFlags getSourceAccessMask() override;
virtual VkAccessFlags getDestAccessMask() override;
virtual void requestOwnershipTransfer(Gfx::QueueType newOwner) override;
// Inherited via QueueOwnedResource
virtual void executeOwnershipBarrier(Gfx::QueueType newOwner) override;
virtual void executePipelineBarrier(Gfx::SeAccessFlags srcAccess, Gfx::SePipelineStageFlags srcStage, Gfx::SeAccessFlags dstAccess,
Gfx::SePipelineStageFlags dstStage) override;
private:
private:
};
DEFINE_REF(ShaderBuffer)
+119 -218
View File
@@ -1,21 +1,17 @@
#include "Command.h"
#include "Graphics.h"
#include "Pipeline.h"
#include "Descriptor.h"
#include "Enums.h"
#include "Framebuffer.h"
#include "RenderPass.h"
#include "Graphics.h"
#include "Pipeline.h"
#include "Descriptor.h"
#include "RenderPass.h"
#include "Window.h"
using namespace Seele;
using namespace Seele::Vulkan;
Command::Command(PGraphics graphics, PCommandPool pool)
: graphics(graphics)
, pool(pool)
{
Command::Command(PGraphics graphics, PCommandPool pool) : graphics(graphics), pool(pool) {
VkCommandBufferAllocateInfo allocInfo = {
.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO,
.pNext = nullptr,
@@ -28,17 +24,15 @@ Command::Command(PGraphics graphics, PCommandPool pool)
fence = new Fence(graphics);
signalSemaphore = new Semaphore(graphics);
state = State::Init;
//std::cout << "Cmd " << handle << " semaphore " << signalSemaphore->getHandle() << std::endl;
// std::cout << "Cmd " << handle << " semaphore " << signalSemaphore->getHandle() << std::endl;
}
Command::~Command()
{
Command::~Command() {
vkFreeCommandBuffers(graphics->getDevice(), pool->getHandle(), 1, &handle);
waitSemaphores.clear();
}
void Command::begin()
{
void Command::begin() {
VkCommandBufferBeginInfo beginInfo = {
.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO,
.pNext = nullptr,
@@ -49,14 +43,12 @@ void Command::begin()
state = State::Begin;
}
void Command::end()
{
void Command::end() {
VK_CHECK(vkEndCommandBuffer(handle));
state = State::End;
}
void Command::beginRenderPass(PRenderPass renderPass, PFramebuffer framebuffer)
{
void Command::beginRenderPass(PRenderPass renderPass, PFramebuffer framebuffer) {
assert(state == State::Begin);
boundRenderPass = renderPass;
boundFramebuffer = framebuffer;
@@ -73,8 +65,7 @@ void Command::beginRenderPass(PRenderPass renderPass, PFramebuffer framebuffer)
state = State::RenderPass;
}
void Command::endRenderPass()
{
void Command::endRenderPass() {
boundRenderPass->endRenderPass();
boundRenderPass = nullptr;
boundFramebuffer = nullptr;
@@ -82,23 +73,19 @@ void Command::endRenderPass()
state = State::Begin;
}
void Command::executeCommands(Array<Gfx::ORenderCommand> commands)
{
void Command::executeCommands(Array<Gfx::ORenderCommand> commands) {
assert(state == State::RenderPass);
if(commands.size() == 0)
{
//std::cout << "No commands provided" << std::endl;
if (commands.size() == 0) {
// std::cout << "No commands provided" << std::endl;
return;
}
Array<VkCommandBuffer> cmdBuffers(commands.size());
for (uint32 i = 0; i < commands.size(); ++i)
{
for (uint32 i = 0; i < commands.size(); ++i) {
auto command = Gfx::PRenderCommand(commands[i]).cast<RenderCommand>();
command->end();
for(auto& descriptor : command->boundResources)
{
for (auto& descriptor : command->boundResources) {
boundResources.add(descriptor);
//std::cout << "Cmd " << handle << " bound descriptor " << descriptor->getHandle() << std::endl;
// std::cout << "Cmd " << handle << " bound descriptor " << descriptor->getHandle() << std::endl;
}
cmdBuffers[i] = command->getHandle();
executingRenders.add(std::move(commands[i]));
@@ -106,21 +93,17 @@ void Command::executeCommands(Array<Gfx::ORenderCommand> commands)
vkCmdExecuteCommands(handle, (uint32)cmdBuffers.size(), cmdBuffers.data());
}
void Command::executeCommands(Array<Gfx::OComputeCommand> commands)
{
if(commands.size() == 0)
{
void Command::executeCommands(Array<Gfx::OComputeCommand> commands) {
if (commands.size() == 0) {
return;
}
Array<VkCommandBuffer> cmdBuffers(commands.size());
for (uint32 i = 0; i < commands.size(); ++i)
{
for (uint32 i = 0; i < commands.size(); ++i) {
auto command = Gfx::PComputeCommand(commands[i]).cast<ComputeCommand>();
command->end();
for(auto& descriptor : command->boundResources)
{
for (auto& descriptor : command->boundResources) {
boundResources.add(descriptor);
//std::cout << "Cmd " << handle << " bound descriptor " << descriptor->getHandle() << std::endl;
// std::cout << "Cmd " << handle << " bound descriptor " << descriptor->getHandle() << std::endl;
}
cmdBuffers[i] = command->getHandle();
executingComputes.add(std::move(commands[i]));
@@ -128,35 +111,29 @@ void Command::executeCommands(Array<Gfx::OComputeCommand> commands)
vkCmdExecuteCommands(handle, (uint32)cmdBuffers.size(), cmdBuffers.data());
}
void Command::waitForSemaphore(VkPipelineStageFlags flags, PSemaphore semaphore)
{
void Command::waitForSemaphore(VkPipelineStageFlags flags, PSemaphore semaphore) {
waitSemaphores.add(semaphore);
waitFlags.add(flags);
//std::cout << "Cmd " << handle << " wait for " << semaphore->getHandle() << std::endl;
// std::cout << "Cmd " << handle << " wait for " << semaphore->getHandle() << std::endl;
}
void Command::checkFence()
{
void Command::checkFence() {
assert(state == State::Submit || !fence->isSignaled());
if (fence->isSignaled())
{
//std::cout << "Cmd " << handle << " was signaled" << std::endl;
if (fence->isSignaled()) {
// std::cout << "Cmd " << handle << " was signaled" << std::endl;
vkResetCommandBuffer(handle, VK_COMMAND_BUFFER_RESET_RELEASE_RESOURCES_BIT);
fence->reset();
for(auto& command : executingComputes)
{
for (auto& command : executingComputes) {
command->reset();
}
pool->cacheCommands(std::move(executingComputes));
for(auto& command : executingRenders)
{
for (auto& command : executingRenders) {
command->reset();
}
pool->cacheCommands(std::move(executingRenders));
for(auto& descriptor : boundResources)
{
for (auto& descriptor : boundResources) {
descriptor->unbind();
//std::cout << "Cmd " << handle << " unbind " << descriptor->getHandle() << std::endl;
// std::cout << "Cmd " << handle << " unbind " << descriptor->getHandle() << std::endl;
}
boundResources.clear();
graphics->getDestructionManager()->notifyCommandComplete();
@@ -164,11 +141,9 @@ void Command::checkFence()
}
}
void Command::waitForCommand(uint32 timeout)
{
void Command::waitForCommand(uint32 timeout) {
pool->submitCommands();
if (state == State::Begin)
{
if (state == State::Begin) {
// is already done
return;
}
@@ -176,26 +151,16 @@ void Command::waitForCommand(uint32 timeout)
checkFence();
}
void Command::bindResource(PCommandBoundResource resource)
{
void Command::bindResource(PCommandBoundResource resource) {
resource->bind();
boundResources.add(resource);
}
PFence Command::getFence()
{
return fence;
}
PFence Command::getFence() { return fence; }
PCommandPool Command::getPool()
{
return pool;
}
PCommandPool Command::getPool() { return pool; }
RenderCommand::RenderCommand(PGraphics graphics, VkCommandPool cmdPool)
: graphics(graphics)
, owner(cmdPool)
{
RenderCommand::RenderCommand(PGraphics graphics, VkCommandPool cmdPool) : graphics(graphics), owner(cmdPool) {
VkCommandBufferAllocateInfo allocInfo = {
.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO,
.pNext = nullptr,
@@ -206,14 +171,9 @@ RenderCommand::RenderCommand(PGraphics graphics, VkCommandPool cmdPool)
VK_CHECK(vkAllocateCommandBuffers(graphics->getDevice(), &allocInfo, &handle));
}
RenderCommand::~RenderCommand() { vkFreeCommandBuffers(graphics->getDevice(), owner, 1, &handle); }
RenderCommand::~RenderCommand()
{
vkFreeCommandBuffers(graphics->getDevice(), owner, 1, &handle);
}
void RenderCommand::begin(PRenderPass renderPass, PFramebuffer framebuffer)
{
void RenderCommand::begin(PRenderPass renderPass, PFramebuffer framebuffer) {
threadId = std::this_thread::get_id();
ready = false;
VkCommandBufferInheritanceInfo inheritanceInfo = {
@@ -234,93 +194,81 @@ void RenderCommand::begin(PRenderPass renderPass, PFramebuffer framebuffer)
VK_CHECK(vkBeginCommandBuffer(handle, &beginInfo));
}
void RenderCommand::end()
{
VK_CHECK(vkEndCommandBuffer(handle));
}
void RenderCommand::end() { VK_CHECK(vkEndCommandBuffer(handle)); }
void RenderCommand::reset()
{
void RenderCommand::reset() {
vkResetCommandBuffer(handle, VK_COMMAND_BUFFER_RESET_RELEASE_RESOURCES_BIT);
boundResources.clear();
ready = true;
}
bool RenderCommand::isReady()
{
return ready;
}
bool RenderCommand::isReady() { return ready; }
void RenderCommand::setViewport(Gfx::PViewport viewport)
{
void RenderCommand::setViewport(Gfx::PViewport viewport) {
assert(threadId == std::this_thread::get_id());
VkViewport vp = viewport.cast<Viewport>()->getHandle();
VkRect2D scissors = {
.offset = {
.x = (int32)viewport->getOffsetX(),
.y = (int32)viewport->getOffsetY(),
},
.extent = {
.width = viewport->getWidth(),
.height = viewport->getHeight(),
},
.offset =
{
.x = (int32)viewport->getOffsetX(),
.y = (int32)viewport->getOffsetY(),
},
.extent =
{
.width = viewport->getWidth(),
.height = viewport->getHeight(),
},
};
vkCmdSetViewport(handle, 0, 1, &vp);
vkCmdSetScissor(handle, 0, 1, &scissors);
}
void RenderCommand::bindPipeline(Gfx::PGraphicsPipeline gfxPipeline)
{
void RenderCommand::bindPipeline(Gfx::PGraphicsPipeline gfxPipeline) {
assert(threadId == std::this_thread::get_id());
pipeline = gfxPipeline.cast<GraphicsPipeline>();
pipeline->bind(handle);
}
void RenderCommand::bindDescriptor(Gfx::PDescriptorSet descriptorSet, Array<uint32> dynamicOffsets)
{
void RenderCommand::bindDescriptor(Gfx::PDescriptorSet descriptorSet, Array<uint32> dynamicOffsets) {
assert(threadId == std::this_thread::get_id());
auto descriptor = descriptorSet.cast<DescriptorSet>();
assert(descriptor->writeDescriptors.size() == 0);
descriptor->bind();
boundResources.add(descriptor.getHandle());
for (auto binding : descriptor->boundResources)
{
for (auto binding : descriptor->boundResources) {
binding->bind();
boundResources.add(binding);
}
VkDescriptorSet setHandle = descriptor->getHandle();
vkCmdBindDescriptorSets(handle, VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline->getLayout(), pipeline->getPipelineLayout()->findParameter(descriptorSet->getName()), 1, &setHandle, dynamicOffsets.size(), dynamicOffsets.data());
vkCmdBindDescriptorSets(handle, VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline->getLayout(),
pipeline->getPipelineLayout()->findParameter(descriptorSet->getName()), 1, &setHandle, dynamicOffsets.size(),
dynamicOffsets.data());
}
void RenderCommand::bindDescriptor(const Array<Gfx::PDescriptorSet>& descriptorSets, Array<uint32> dynamicOffsets)
{
void RenderCommand::bindDescriptor(const Array<Gfx::PDescriptorSet>& descriptorSets, Array<uint32> dynamicOffsets) {
assert(threadId == std::this_thread::get_id());
VkDescriptorSet* sets = new VkDescriptorSet[descriptorSets.size()];
for(uint32 i = 0; i < descriptorSets.size(); ++i)
{
for (uint32 i = 0; i < descriptorSets.size(); ++i) {
auto descriptorSet = descriptorSets[i].cast<DescriptorSet>();
assert(descriptorSet->writeDescriptors.size() == 0);
descriptorSet->bind();
boundResources.add(descriptorSet.getHandle());
for (auto binding : descriptorSet->boundResources)
{
for (auto binding : descriptorSet->boundResources) {
binding->bind();
boundResources.add(binding);
}
sets[pipeline->getPipelineLayout()->findParameter(descriptorSet->getName())] = descriptorSet->getHandle();
}
vkCmdBindDescriptorSets(handle, VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline->getLayout(), 0, (uint32)descriptorSets.size(), sets, dynamicOffsets.size(), dynamicOffsets.data());
vkCmdBindDescriptorSets(handle, VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline->getLayout(), 0, (uint32)descriptorSets.size(), sets,
dynamicOffsets.size(), dynamicOffsets.data());
delete[] sets;
}
void RenderCommand::bindVertexBuffer(const Array<Gfx::PVertexBuffer>& streams)
{
void RenderCommand::bindVertexBuffer(const Array<Gfx::PVertexBuffer>& streams) {
assert(threadId == std::this_thread::get_id());
Array<VkBuffer> buffers(streams.size());
Array<VkDeviceSize> offsets(streams.size());
for(uint32 i = 0; i < streams.size(); ++i)
{
for (uint32 i = 0; i < streams.size(); ++i) {
PVertexBuffer buf = streams[i].cast<VertexBuffer>();
buffers[i] = buf->getHandle();
offsets[i] = 0;
@@ -329,8 +277,7 @@ void RenderCommand::bindVertexBuffer(const Array<Gfx::PVertexBuffer>& streams)
};
vkCmdBindVertexBuffers(handle, 0, (uint32)streams.size(), buffers.data(), offsets.data());
}
void RenderCommand::bindIndexBuffer(Gfx::PIndexBuffer indexBuffer)
{
void RenderCommand::bindIndexBuffer(Gfx::PIndexBuffer indexBuffer) {
assert(threadId == std::this_thread::get_id());
PIndexBuffer buf = indexBuffer.cast<IndexBuffer>();
buf->getAlloc()->bind();
@@ -338,39 +285,31 @@ void RenderCommand::bindIndexBuffer(Gfx::PIndexBuffer indexBuffer)
vkCmdBindIndexBuffer(handle, buf->getHandle(), 0, cast(buf->getIndexType()));
}
void RenderCommand::pushConstants(Gfx::SeShaderStageFlags stage, uint32 offset, uint32 size, const void* data)
{
void RenderCommand::pushConstants(Gfx::SeShaderStageFlags stage, uint32 offset, uint32 size, const void* data) {
assert(threadId == std::this_thread::get_id());
vkCmdPushConstants(handle, pipeline->getLayout(), stage, offset, size, data);
}
void RenderCommand::draw(uint32 vertexCount, uint32 instanceCount, int32 firstVertex, uint32 firstInstance)
{
void RenderCommand::draw(uint32 vertexCount, uint32 instanceCount, int32 firstVertex, uint32 firstInstance) {
assert(threadId == std::this_thread::get_id());
vkCmdDraw(handle, vertexCount, instanceCount, firstVertex, firstInstance);
}
void RenderCommand::drawIndexed(uint32 indexCount, uint32 instanceCount, int32 firstIndex, uint32 vertexOffset, uint32 firstInstance)
{
void RenderCommand::drawIndexed(uint32 indexCount, uint32 instanceCount, int32 firstIndex, uint32 vertexOffset, uint32 firstInstance) {
assert(threadId == std::this_thread::get_id());
vkCmdDrawIndexed(handle, indexCount, instanceCount, firstIndex, vertexOffset, firstInstance);
}
void RenderCommand::drawMesh(uint32 groupX, uint32 groupY, uint32 groupZ)
{
void RenderCommand::drawMesh(uint32 groupX, uint32 groupY, uint32 groupZ) {
assert(threadId == std::this_thread::get_id());
graphics->vkCmdDrawMeshTasksEXT(handle, groupX, groupY, groupZ);
}
void RenderCommand::drawMeshIndirect(Gfx::PShaderBuffer buffer, uint64 offset, uint32 drawCount, uint32 stride)
{
void RenderCommand::drawMeshIndirect(Gfx::PShaderBuffer buffer, uint64 offset, uint32 drawCount, uint32 stride) {
assert(threadId == std::this_thread::get_id());
graphics->vkCmdDrawMeshTasksIndirectEXT(handle, buffer.cast<ShaderBuffer>()->getHandle(), offset, drawCount, stride);
}
ComputeCommand::ComputeCommand(PGraphics graphics, VkCommandPool cmdPool)
: graphics(graphics)
, owner(cmdPool)
{
ComputeCommand::ComputeCommand(PGraphics graphics, VkCommandPool cmdPool) : graphics(graphics), owner(cmdPool) {
VkCommandBufferAllocateInfo allocInfo = {
.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO,
.pNext = nullptr,
@@ -381,14 +320,9 @@ ComputeCommand::ComputeCommand(PGraphics graphics, VkCommandPool cmdPool)
VK_CHECK(vkAllocateCommandBuffers(graphics->getDevice(), &allocInfo, &handle));
}
ComputeCommand::~ComputeCommand() { vkFreeCommandBuffers(graphics->getDevice(), owner, 1, &handle); }
ComputeCommand::~ComputeCommand()
{
vkFreeCommandBuffers(graphics->getDevice(), owner, 1, &handle);
}
void ComputeCommand::begin()
{
void ComputeCommand::begin() {
threadId = std::this_thread::get_id();
ready = false;
VkCommandBufferInheritanceInfo inheritanceInfo = {
@@ -409,86 +343,74 @@ void ComputeCommand::begin()
VK_CHECK(vkBeginCommandBuffer(handle, &beginInfo));
}
void ComputeCommand::end()
{
void ComputeCommand::end() {
assert(threadId == std::this_thread::get_id());
VK_CHECK(vkEndCommandBuffer(handle));
}
void ComputeCommand::reset()
{
void ComputeCommand::reset() {
assert(threadId == std::this_thread::get_id());
vkResetCommandBuffer(handle, VK_COMMAND_BUFFER_RESET_RELEASE_RESOURCES_BIT);
boundResources.clear();
ready = true;
}
bool ComputeCommand::isReady()
{
return ready;
}
bool ComputeCommand::isReady() { return ready; }
void ComputeCommand::bindPipeline(Gfx::PComputePipeline computePipeline)
{
void ComputeCommand::bindPipeline(Gfx::PComputePipeline computePipeline) {
assert(threadId == std::this_thread::get_id());
pipeline = computePipeline.cast<ComputePipeline>();
pipeline->bind(handle);
}
void ComputeCommand::bindDescriptor(Gfx::PDescriptorSet descriptorSet, Array<uint32> dynamicOffsets)
{
void ComputeCommand::bindDescriptor(Gfx::PDescriptorSet descriptorSet, Array<uint32> dynamicOffsets) {
assert(threadId == std::this_thread::get_id());
auto descriptor = descriptorSet.cast<DescriptorSet>();
assert(descriptor->writeDescriptors.size() == 0);
boundResources.add(descriptor.getHandle());
for (auto binding : descriptor->boundResources)
{
for (auto binding : descriptor->boundResources) {
binding->bind();
boundResources.add(binding);
}
VkDescriptorSet setHandle = descriptor->getHandle();
vkCmdBindDescriptorSets(handle, VK_PIPELINE_BIND_POINT_COMPUTE, pipeline->getLayout(), pipeline->getPipelineLayout()->findParameter(descriptorSet->getName()), 1, &setHandle, dynamicOffsets.size(), dynamicOffsets.data());
vkCmdBindDescriptorSets(handle, VK_PIPELINE_BIND_POINT_COMPUTE, pipeline->getLayout(),
pipeline->getPipelineLayout()->findParameter(descriptorSet->getName()), 1, &setHandle, dynamicOffsets.size(),
dynamicOffsets.data());
}
void ComputeCommand::bindDescriptor(const Array<Gfx::PDescriptorSet>& descriptorSets, Array<uint32> dynamicOffsets)
{
void ComputeCommand::bindDescriptor(const Array<Gfx::PDescriptorSet>& descriptorSets, Array<uint32> dynamicOffsets) {
assert(threadId == std::this_thread::get_id());
VkDescriptorSet* sets = new VkDescriptorSet[descriptorSets.size()];
for(uint32 i = 0; i < descriptorSets.size(); ++i)
{
for (uint32 i = 0; i < descriptorSets.size(); ++i) {
auto descriptorSet = descriptorSets[i].cast<DescriptorSet>();
assert(descriptorSet->writeDescriptors.size() == 0);
descriptorSet->bind();
boundResources.add(descriptorSet.getHandle());
//std::cout << "Binding descriptor " << descriptorSet->getHandle() << " to cmd " << handle << std::endl;
for (auto binding : descriptorSet->boundResources)
{
// std::cout << "Binding descriptor " << descriptorSet->getHandle() << " to cmd " << handle << std::endl;
for (auto binding : descriptorSet->boundResources) {
binding->bind();
boundResources.add(binding);
}
sets[pipeline->getPipelineLayout()->findParameter(descriptorSet->getName())] = descriptorSet->getHandle();
}
vkCmdBindDescriptorSets(handle, VK_PIPELINE_BIND_POINT_COMPUTE, pipeline->getLayout(), 0, (uint32)descriptorSets.size(), sets, dynamicOffsets.size(), dynamicOffsets.data());
vkCmdBindDescriptorSets(handle, VK_PIPELINE_BIND_POINT_COMPUTE, pipeline->getLayout(), 0, (uint32)descriptorSets.size(), sets,
dynamicOffsets.size(), dynamicOffsets.data());
delete[] sets;
}
void ComputeCommand::pushConstants(Gfx::SeShaderStageFlags stage, uint32 offset, uint32 size, const void* data)
{
void ComputeCommand::pushConstants(Gfx::SeShaderStageFlags stage, uint32 offset, uint32 size, const void* data) {
assert(threadId == std::this_thread::get_id());
vkCmdPushConstants(handle, pipeline->getLayout(), stage, offset, size, data);
}
void ComputeCommand::dispatch(uint32 threadX, uint32 threadY, uint32 threadZ)
{
void ComputeCommand::dispatch(uint32 threadX, uint32 threadY, uint32 threadZ) {
assert(threadId == std::this_thread::get_id());
vkCmdDispatch(handle, threadX, threadY, threadZ);
}
CommandPool::CommandPool(PGraphics graphics, PQueue queue)
: graphics(graphics), queue(queue), queueFamilyIndex(queue->getFamilyIndex())
{
CommandPool::CommandPool(PGraphics graphics, PQueue queue) : graphics(graphics), queue(queue), queueFamilyIndex(queue->getFamilyIndex()) {
VkCommandPoolCreateInfo info = {
.sType = VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO,
.pNext = nullptr,
@@ -498,16 +420,14 @@ CommandPool::CommandPool(PGraphics graphics, PQueue queue)
VK_CHECK(vkCreateCommandPool(graphics->getDevice(), &info, nullptr, &commandPool));
// TODO: dont reset individual commands, reset pool instead
allocatedBuffers.add(new Command(graphics, this));
command = allocatedBuffers.back();
command->begin();
}
CommandPool::~CommandPool()
{
CommandPool::~CommandPool() {
vkDeviceWaitIdle(graphics->getDevice());
for (auto& cmd : allocatedBuffers)
{
for (auto& cmd : allocatedBuffers) {
cmd->checkFence();
}
allocatedRenderCommands.clear();
@@ -518,32 +438,22 @@ CommandPool::~CommandPool()
queue = nullptr;
}
PCommand CommandPool::getCommands()
{
return command;
}
void CommandPool::cacheCommands(Array<ORenderCommand> commands)
{
for(auto&& cmd : commands)
{
allocatedRenderCommands.add(std::move(cmd));
}
PCommand CommandPool::getCommands() { return command; }
void CommandPool::cacheCommands(Array<ORenderCommand> commands) {
for (auto&& cmd : commands) {
allocatedRenderCommands.add(std::move(cmd));
}
}
void CommandPool::cacheCommands(Array<OComputeCommand> commands)
{
for(auto&& cmd : commands)
{
allocatedComputeCommands.add(std::move(cmd));
}
void CommandPool::cacheCommands(Array<OComputeCommand> commands) {
for (auto&& cmd : commands) {
allocatedComputeCommands.add(std::move(cmd));
}
}
ORenderCommand CommandPool::createRenderCommand(const std::string& name)
{
for (uint32 i = 0; i < allocatedRenderCommands.size(); ++i)
{
if (allocatedRenderCommands[i]->isReady())
{
ORenderCommand CommandPool::createRenderCommand(const std::string& name) {
for (uint32 i = 0; i < allocatedRenderCommands.size(); ++i) {
if (allocatedRenderCommands[i]->isReady()) {
ORenderCommand cmdBuffer = std::move(allocatedRenderCommands[i]);
allocatedRenderCommands.removeAt(i, false);
cmdBuffer->name = name;
@@ -557,12 +467,9 @@ ORenderCommand CommandPool::createRenderCommand(const std::string& name)
return result;
}
OComputeCommand CommandPool::createComputeCommand(const std::string& name)
{
for (uint32 i = 0; i < allocatedComputeCommands.size(); ++i)
{
if (allocatedComputeCommands[i]->isReady())
{
OComputeCommand CommandPool::createComputeCommand(const std::string& name) {
for (uint32 i = 0; i < allocatedComputeCommands.size(); ++i) {
if (allocatedComputeCommands[i]->isReady()) {
OComputeCommand cmdBuffer = std::move(allocatedComputeCommands[i]);
allocatedComputeCommands.removeAt(i, false);
cmdBuffer->name = name;
@@ -576,32 +483,26 @@ OComputeCommand CommandPool::createComputeCommand(const std::string& name)
return result;
}
void CommandPool::submitCommands(PSemaphore signalSemaphore)
{
void CommandPool::submitCommands(PSemaphore signalSemaphore) {
assert(command->state == Command::State::Begin); // Not in a renderpass
command->end();
Array<VkSemaphore> semaphores = { command->signalSemaphore->getHandle() };
if (signalSemaphore != nullptr)
{
Array<VkSemaphore> semaphores = {command->signalSemaphore->getHandle()};
if (signalSemaphore != nullptr) {
semaphores.add(signalSemaphore->getHandle());
}
queue->submitCommandBuffer(command, semaphores);
//std::cout << "Cmd " << command->getHandle() << " signalling " << command->signalSemaphore->getHandle() << std::endl;
// std::cout << "Cmd " << command->getHandle() << " signalling " << command->signalSemaphore->getHandle() << std::endl;
PSemaphore waitSemaphore = command->signalSemaphore;
for (uint32 i = 0; i < allocatedBuffers.size(); ++i)
{
for (uint32 i = 0; i < allocatedBuffers.size(); ++i) {
PCommand cmdBuffer = allocatedBuffers[i];
cmdBuffer->checkFence();
if (cmdBuffer->state == Command::State::Init)
{
if (cmdBuffer->state == Command::State::Init) {
command = cmdBuffer;
command->begin();
command->waitForSemaphore(VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, waitSemaphore);
return;
}
else
{
} else {
assert(cmdBuffer->state == Command::State::Submit);
}
}
+117 -120
View File
@@ -14,143 +14,140 @@ DECLARE_REF(ComputeCommand)
DECLARE_REF(DescriptorSet)
DECLARE_REF(CommandPool)
class Command {
public:
Command(PGraphics graphics, PCommandPool pool);
~Command();
constexpr VkCommandBuffer getHandle() { return handle; }
void reset();
void begin();
void end();
void beginRenderPass(PRenderPass renderPass, PFramebuffer framebuffer);
void endRenderPass();
void executeCommands(Array<Gfx::ORenderCommand> secondaryCommands);
void executeCommands(Array<Gfx::OComputeCommand> secondaryCommands);
void waitForSemaphore(VkPipelineStageFlags stages, PSemaphore waitSemaphore);
void bindResource(PCommandBoundResource resource);
void checkFence();
void waitForCommand(uint32 timeToWait = 1000000u);
PFence getFence();
PCommandPool getPool();
enum State {
Init,
Begin,
RenderPass,
End,
Submit,
};
public:
Command(PGraphics graphics, PCommandPool pool);
~Command();
constexpr VkCommandBuffer getHandle() { return handle; }
void reset();
void begin();
void end();
void beginRenderPass(PRenderPass renderPass, PFramebuffer framebuffer);
void endRenderPass();
void executeCommands(Array<Gfx::ORenderCommand> secondaryCommands);
void executeCommands(Array<Gfx::OComputeCommand> secondaryCommands);
void waitForSemaphore(VkPipelineStageFlags stages, PSemaphore waitSemaphore);
void bindResource(PCommandBoundResource resource);
void checkFence();
void waitForCommand(uint32 timeToWait = 1000000u);
PFence getFence();
PCommandPool getPool();
enum State {
Init,
Begin,
RenderPass,
End,
Submit,
};
private:
PGraphics graphics;
PCommandPool pool;
OFence fence;
OSemaphore signalSemaphore;
State state;
VkViewport currentViewport;
VkRect2D currentScissor;
VkCommandBuffer handle;
PRenderPass boundRenderPass;
PFramebuffer boundFramebuffer;
Array<PSemaphore> waitSemaphores;
Array<VkPipelineStageFlags> waitFlags;
Array<ORenderCommand> executingRenders;
Array<OComputeCommand> executingComputes;
Array<PDescriptorSet> boundResources;
friend class RenderCommand;
friend class CommandPool;
friend class Queue;
private:
PGraphics graphics;
PCommandPool pool;
OFence fence;
OSemaphore signalSemaphore;
State state;
VkViewport currentViewport;
VkRect2D currentScissor;
VkCommandBuffer handle;
PRenderPass boundRenderPass;
PFramebuffer boundFramebuffer;
Array<PSemaphore> waitSemaphores;
Array<VkPipelineStageFlags> waitFlags;
Array<ORenderCommand> executingRenders;
Array<OComputeCommand> executingComputes;
Array<PDescriptorSet> boundResources;
friend class RenderCommand;
friend class CommandPool;
friend class Queue;
};
DEFINE_REF(Command)
DECLARE_REF(GraphicsPipeline)
DECLARE_REF(ComputePipeline)
class RenderCommand : public Gfx::RenderCommand {
public:
RenderCommand(PGraphics graphics, VkCommandPool cmdPool);
virtual ~RenderCommand();
constexpr VkCommandBuffer getHandle() { return handle; }
void begin(PRenderPass renderPass, PFramebuffer framebuffer);
void end();
void reset();
bool isReady();
virtual void setViewport(Gfx::PViewport viewport) override;
virtual void bindPipeline(Gfx::PGraphicsPipeline pipeline) override;
virtual void bindDescriptor(Gfx::PDescriptorSet descriptorSet, Array<uint32> dynamicOffsets) override;
virtual void bindDescriptor(const Array<Gfx::PDescriptorSet>& descriptorSets, Array<uint32> dynamicOffsets) override;
virtual void bindVertexBuffer(const Array<Gfx::PVertexBuffer>& buffers) override;
virtual void bindIndexBuffer(Gfx::PIndexBuffer indexBuffer) override;
virtual void pushConstants(Gfx::SeShaderStageFlags stage, uint32 offset, uint32 size,
const void* data) override;
virtual void draw(uint32 vertexCount, uint32 instanceCount, int32 firstVertex, uint32 firstInstance) override;
virtual void drawIndexed(uint32 indexCount, uint32 instanceCount, int32 firstIndex, uint32 vertexOffset,
uint32 firstInstance) override;
virtual void drawMesh(uint32 groupX, uint32 groupY, uint32 groupZ) override;
virtual void drawMeshIndirect(Gfx::PShaderBuffer buffer, uint64 offset, uint32 drawCount, uint32 stride) override;
public:
RenderCommand(PGraphics graphics, VkCommandPool cmdPool);
virtual ~RenderCommand();
constexpr VkCommandBuffer getHandle() { return handle; }
void begin(PRenderPass renderPass, PFramebuffer framebuffer);
void end();
void reset();
bool isReady();
virtual void setViewport(Gfx::PViewport viewport) override;
virtual void bindPipeline(Gfx::PGraphicsPipeline pipeline) override;
virtual void bindDescriptor(Gfx::PDescriptorSet descriptorSet, Array<uint32> dynamicOffsets) override;
virtual void bindDescriptor(const Array<Gfx::PDescriptorSet>& descriptorSets, Array<uint32> dynamicOffsets) override;
virtual void bindVertexBuffer(const Array<Gfx::PVertexBuffer>& buffers) override;
virtual void bindIndexBuffer(Gfx::PIndexBuffer indexBuffer) override;
virtual void pushConstants(Gfx::SeShaderStageFlags stage, uint32 offset, uint32 size, const void* data) override;
virtual void draw(uint32 vertexCount, uint32 instanceCount, int32 firstVertex, uint32 firstInstance) override;
virtual void drawIndexed(uint32 indexCount, uint32 instanceCount, int32 firstIndex, uint32 vertexOffset, uint32 firstInstance) override;
virtual void drawMesh(uint32 groupX, uint32 groupY, uint32 groupZ) override;
virtual void drawMeshIndirect(Gfx::PShaderBuffer buffer, uint64 offset, uint32 drawCount, uint32 stride) override;
private:
PGraphicsPipeline pipeline;
bool ready;
Array<PCommandBoundResource> boundResources;
VkViewport currentViewport;
VkRect2D currentScissor;
PGraphics graphics;
std::thread::id threadId;
VkCommandBuffer handle;
VkCommandPool owner;
friend class Command;
private:
PGraphicsPipeline pipeline;
bool ready;
Array<PCommandBoundResource> boundResources;
VkViewport currentViewport;
VkRect2D currentScissor;
PGraphics graphics;
std::thread::id threadId;
VkCommandBuffer handle;
VkCommandPool owner;
friend class Command;
};
DEFINE_REF(RenderCommand)
class ComputeCommand : public Gfx::ComputeCommand {
public:
ComputeCommand(PGraphics graphics, VkCommandPool cmdPool);
virtual ~ComputeCommand();
inline VkCommandBuffer getHandle() { return handle; }
void begin();
void end();
void reset();
bool isReady();
virtual void bindPipeline(Gfx::PComputePipeline pipeline) override;
virtual void bindDescriptor(Gfx::PDescriptorSet set, Array<uint32> dynamicOffsets) override;
virtual void bindDescriptor(const Array<Gfx::PDescriptorSet>& sets, Array<uint32> dynamicOffsets) override;
virtual void pushConstants(Gfx::SeShaderStageFlags stage, uint32 offset, uint32 size,
const void* data) override;
virtual void dispatch(uint32 threadX, uint32 threadY, uint32 threadZ) override;
public:
ComputeCommand(PGraphics graphics, VkCommandPool cmdPool);
virtual ~ComputeCommand();
inline VkCommandBuffer getHandle() { return handle; }
void begin();
void end();
void reset();
bool isReady();
virtual void bindPipeline(Gfx::PComputePipeline pipeline) override;
virtual void bindDescriptor(Gfx::PDescriptorSet set, Array<uint32> dynamicOffsets) override;
virtual void bindDescriptor(const Array<Gfx::PDescriptorSet>& sets, Array<uint32> dynamicOffsets) override;
virtual void pushConstants(Gfx::SeShaderStageFlags stage, uint32 offset, uint32 size, const void* data) override;
virtual void dispatch(uint32 threadX, uint32 threadY, uint32 threadZ) override;
private:
PComputePipeline pipeline;
bool ready;
Array<PCommandBoundResource> boundResources;
VkViewport currentViewport;
VkRect2D currentScissor;
PGraphics graphics;
std::thread::id threadId;
VkCommandBuffer handle;
VkCommandPool owner;
friend class Command;
private:
PComputePipeline pipeline;
bool ready;
Array<PCommandBoundResource> boundResources;
VkViewport currentViewport;
VkRect2D currentScissor;
PGraphics graphics;
std::thread::id threadId;
VkCommandBuffer handle;
VkCommandPool owner;
friend class Command;
};
DEFINE_REF(ComputeCommand)
class CommandPool {
public:
CommandPool(PGraphics graphics, PQueue queue);
virtual ~CommandPool();
constexpr PQueue getQueue() const { return queue; }
PCommand getCommands();
void cacheCommands(Array<ORenderCommand> commands);
void cacheCommands(Array<OComputeCommand> commands);
ORenderCommand createRenderCommand(const std::string& name);
OComputeCommand createComputeCommand(const std::string& name);
constexpr VkCommandPool getHandle() const { return commandPool; }
void submitCommands(PSemaphore signalSemaphore = nullptr);
public:
CommandPool(PGraphics graphics, PQueue queue);
virtual ~CommandPool();
constexpr PQueue getQueue() const { return queue; }
PCommand getCommands();
void cacheCommands(Array<ORenderCommand> commands);
void cacheCommands(Array<OComputeCommand> commands);
ORenderCommand createRenderCommand(const std::string& name);
OComputeCommand createComputeCommand(const std::string& name);
constexpr VkCommandPool getHandle() const { return commandPool; }
void submitCommands(PSemaphore signalSemaphore = nullptr);
private:
PGraphics graphics;
VkCommandPool commandPool;
PQueue queue;
uint32 queueFamilyIndex;
PCommand command;
Array<OCommand> allocatedBuffers;
Array<ORenderCommand> allocatedRenderCommands;
Array<OComputeCommand> allocatedComputeCommands;
private:
PGraphics graphics;
VkCommandPool commandPool;
PQueue queue;
uint32 queueFamilyIndex;
PCommand command;
Array<OCommand> allocatedBuffers;
Array<ORenderCommand> allocatedRenderCommands;
Array<OComputeCommand> allocatedComputeCommands;
};
DEFINE_REF(CommandPool)
} // namespace Vulkan
+18 -26
View File
@@ -3,34 +3,26 @@
using namespace Seele::Vulkan;
VkBool32 Seele::Vulkan::debugCallback(
VkDebugUtilsMessageSeverityFlagBitsEXT messageSeverity,
VkDebugUtilsMessageTypeFlagsEXT messageTypes,
const VkDebugUtilsMessengerCallbackDataEXT* pCallbackData,
void* pUserData)
{
std::cerr << pCallbackData->pMessage << std::endl;
return VK_FALSE;
VkBool32 Seele::Vulkan::debugCallback(VkDebugUtilsMessageSeverityFlagBitsEXT messageSeverity, VkDebugUtilsMessageTypeFlagsEXT messageTypes,
const VkDebugUtilsMessengerCallbackDataEXT* pCallbackData, void* pUserData) {
std::cerr << pCallbackData->pMessage << std::endl;
return VK_FALSE;
}
VkResult Seele::Vulkan::CreateDebugUtilsMessengerEXT(VkInstance instance, const VkDebugUtilsMessengerCreateInfoEXT *pCreateInfo, const VkAllocationCallbacks *pAllocator, VkDebugUtilsMessengerEXT *pCallback)
{
auto func = (PFN_vkCreateDebugUtilsMessengerEXT)vkGetInstanceProcAddr(instance, "vkCreateDebugUtilsMessengerEXT");
if (func != nullptr)
{
return func(instance, pCreateInfo, pAllocator, pCallback);
}
else
{
return VK_ERROR_EXTENSION_NOT_PRESENT;
}
VkResult Seele::Vulkan::CreateDebugUtilsMessengerEXT(VkInstance instance, const VkDebugUtilsMessengerCreateInfoEXT* pCreateInfo,
const VkAllocationCallbacks* pAllocator, VkDebugUtilsMessengerEXT* pCallback) {
auto func = (PFN_vkCreateDebugUtilsMessengerEXT)vkGetInstanceProcAddr(instance, "vkCreateDebugUtilsMessengerEXT");
if (func != nullptr) {
return func(instance, pCreateInfo, pAllocator, pCallback);
} else {
return VK_ERROR_EXTENSION_NOT_PRESENT;
}
}
void Seele::Vulkan::DestroyDebugUtilsMessengerEXT(VkInstance instance, const VkAllocationCallbacks *pAllocator, VkDebugUtilsMessengerEXT pCallback)
{
auto func = (PFN_vkDestroyDebugUtilsMessengerEXT)vkGetInstanceProcAddr(instance, "vkDestroyDebugUtilsMessengerEXT");
if (func != nullptr)
{
func(instance, pCallback, pAllocator);
}
void Seele::Vulkan::DestroyDebugUtilsMessengerEXT(VkInstance instance, const VkAllocationCallbacks* pAllocator,
VkDebugUtilsMessengerEXT pCallback) {
auto func = (PFN_vkDestroyDebugUtilsMessengerEXT)vkGetInstanceProcAddr(instance, "vkDestroyDebugUtilsMessengerEXT");
if (func != nullptr) {
func(instance, pCallback, pAllocator);
}
}
+7 -11
View File
@@ -2,17 +2,13 @@
#include "Containers/Array.h"
#include <vulkan/vulkan.h>
namespace Seele
{
namespace Vulkan
{
VkBool32 debugCallback(
VkDebugUtilsMessageSeverityFlagBitsEXT messageSeverity,
VkDebugUtilsMessageTypeFlagsEXT messageTypes,
const VkDebugUtilsMessengerCallbackDataEXT* pCallbackData,
void* pUserData);
namespace Seele {
namespace Vulkan {
VkBool32 debugCallback(VkDebugUtilsMessageSeverityFlagBitsEXT messageSeverity, VkDebugUtilsMessageTypeFlagsEXT messageTypes,
const VkDebugUtilsMessengerCallbackDataEXT* pCallbackData, void* pUserData);
VkResult CreateDebugUtilsMessengerEXT(VkInstance instance, const VkDebugUtilsMessengerCreateInfoEXT *pCreateInfo, const VkAllocationCallbacks *pAllocator, VkDebugUtilsMessengerEXT *pCallback);
void DestroyDebugUtilsMessengerEXT(VkInstance instance, const VkAllocationCallbacks *pAllocator, VkDebugUtilsMessengerEXT pCallback);
VkResult CreateDebugUtilsMessengerEXT(VkInstance instance, const VkDebugUtilsMessengerCreateInfoEXT* pCreateInfo,
const VkAllocationCallbacks* pAllocator, VkDebugUtilsMessengerEXT* pCallback);
void DestroyDebugUtilsMessengerEXT(VkInstance instance, const VkAllocationCallbacks* pAllocator, VkDebugUtilsMessengerEXT pCallback);
} // namespace Vulkan
} // namespace Seele
+32 -52
View File
@@ -1,9 +1,10 @@
#include "Descriptor.h"
#include "Buffer.h"
#include "CRC.h"
#include "Command.h"
#include "Graphics.h"
#include "Texture.h"
#include "CRC.h"
using namespace Seele;
using namespace Seele::Vulkan;
@@ -56,9 +57,7 @@ void DescriptorLayout::create() {
}
DescriptorPool::DescriptorPool(PGraphics graphics, PDescriptorLayout layout)
: CommandBoundResource(graphics)
, graphics(graphics)
, layout(layout) {
: CommandBoundResource(graphics), graphics(graphics), layout(layout) {
for (uint32 i = 0; i < cachedHandles.size(); ++i) {
cachedHandles[i] = nullptr;
}
@@ -91,10 +90,8 @@ DescriptorPool::DescriptorPool(PGraphics graphics, PDescriptorLayout layout)
}
DescriptorPool::~DescriptorPool() {
for (size_t i = 0; i < maxSets; ++i)
{
if (cachedHandles[i] != nullptr)
{
for (size_t i = 0; i < maxSets; ++i) {
if (cachedHandles[i] != nullptr) {
cachedHandles[i] = nullptr;
}
}
@@ -168,26 +165,16 @@ void DescriptorPool::reset() {
}
DescriptorSet::DescriptorSet(PGraphics graphics, PDescriptorPool owner)
: Gfx::DescriptorSet(owner->getLayout())
, CommandBoundResource(graphics)
, setHandle(VK_NULL_HANDLE)
, graphics(graphics)
, owner(owner)
, bindCount(0)
, currentlyInUse(false)
{
: Gfx::DescriptorSet(owner->getLayout()), CommandBoundResource(graphics), setHandle(VK_NULL_HANDLE), graphics(graphics), owner(owner),
bindCount(0), currentlyInUse(false) {
boundResources.resize(owner->getLayout()->getBindings().size());
}
DescriptorSet::~DescriptorSet()
{
vkFreeDescriptorSets(graphics->getDevice(), owner->getHandle(), 1, &setHandle);
}
DescriptorSet::~DescriptorSet() { vkFreeDescriptorSets(graphics->getDevice(), owner->getHandle(), 1, &setHandle); }
void DescriptorSet::updateBuffer(uint32_t binding, Gfx::PUniformBuffer uniformBuffer) {
PUniformBuffer vulkanBuffer = uniformBuffer.cast<UniformBuffer>();
if (boundResources[binding] == vulkanBuffer->getAlloc())
{
if (boundResources[binding] == vulkanBuffer->getAlloc()) {
return;
}
@@ -195,7 +182,7 @@ void DescriptorSet::updateBuffer(uint32_t binding, Gfx::PUniformBuffer uniformBu
.buffer = vulkanBuffer->getHandle(),
.offset = 0,
.range = vulkanBuffer->getSize(),
});
});
writeDescriptors.add(VkWriteDescriptorSet{
.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET,
@@ -206,15 +193,14 @@ void DescriptorSet::updateBuffer(uint32_t binding, Gfx::PUniformBuffer uniformBu
.descriptorCount = 1,
.descriptorType = cast(layout->getBindings()[binding].descriptorType),
.pBufferInfo = &bufferInfos.back(),
});
});
boundResources[binding] = vulkanBuffer->getAlloc();
}
void DescriptorSet::updateBuffer(uint32_t binding, Gfx::PShaderBuffer shaderBuffer) {
PShaderBuffer vulkanBuffer = shaderBuffer.cast<ShaderBuffer>();
if (boundResources[binding] == vulkanBuffer->getAlloc())
{
if (boundResources[binding] == vulkanBuffer->getAlloc()) {
return;
}
@@ -222,7 +208,7 @@ void DescriptorSet::updateBuffer(uint32_t binding, Gfx::PShaderBuffer shaderBuff
.buffer = vulkanBuffer->getHandle(),
.offset = 0,
.range = vulkanBuffer->getSize(),
});
});
writeDescriptors.add(VkWriteDescriptorSet{
.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET,
.pNext = nullptr,
@@ -232,15 +218,14 @@ void DescriptorSet::updateBuffer(uint32_t binding, Gfx::PShaderBuffer shaderBuff
.descriptorCount = 1,
.descriptorType = cast(layout->getBindings()[binding].descriptorType),
.pBufferInfo = &bufferInfos.back(),
});
});
boundResources[binding] = vulkanBuffer->getAlloc();
}
void DescriptorSet::updateBuffer(uint32_t binding, uint32 index, Gfx::PShaderBuffer shaderBuffer) {
PShaderBuffer vulkanBuffer = shaderBuffer.cast<ShaderBuffer>();
if (boundResources[binding] == vulkanBuffer->getAlloc())
{
if (boundResources[binding] == vulkanBuffer->getAlloc()) {
return;
}
@@ -248,7 +233,7 @@ void DescriptorSet::updateBuffer(uint32_t binding, uint32 index, Gfx::PShaderBuf
.buffer = vulkanBuffer->getHandle(),
.offset = 0,
.range = vulkanBuffer->getSize(),
});
});
writeDescriptors.add(VkWriteDescriptorSet{
.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET,
@@ -259,15 +244,14 @@ void DescriptorSet::updateBuffer(uint32_t binding, uint32 index, Gfx::PShaderBuf
.descriptorCount = 1,
.descriptorType = cast(layout->getBindings()[binding].descriptorType),
.pBufferInfo = &bufferInfos.back(),
});
});
boundResources[binding] = vulkanBuffer->getAlloc();
}
void DescriptorSet::updateSampler(uint32_t binding, Gfx::PSampler samplerState) {
PSampler vulkanSampler = samplerState.cast<Sampler>();
if (boundResources[binding] == vulkanSampler->getHandle())
{
if (boundResources[binding] == vulkanSampler->getHandle()) {
return;
}
@@ -275,7 +259,7 @@ void DescriptorSet::updateSampler(uint32_t binding, Gfx::PSampler samplerState)
.sampler = vulkanSampler->getSampler(),
.imageView = VK_NULL_HANDLE,
.imageLayout = VK_IMAGE_LAYOUT_UNDEFINED,
});
});
writeDescriptors.add(VkWriteDescriptorSet{
.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET,
@@ -286,15 +270,14 @@ void DescriptorSet::updateSampler(uint32_t binding, Gfx::PSampler samplerState)
.descriptorCount = 1,
.descriptorType = VK_DESCRIPTOR_TYPE_SAMPLER,
.pImageInfo = &imageInfos.back(),
});
});
boundResources[binding] = vulkanSampler->getHandle();
}
void DescriptorSet::updateTexture(uint32_t binding, Gfx::PTexture texture, Gfx::PSampler samplerState) {
TextureBase* vulkanTexture = texture.cast<TextureBase>().getHandle();
if (boundResources[binding] == vulkanTexture->getHandle())
{
if (boundResources[binding] == vulkanTexture->getHandle()) {
return;
}
@@ -303,12 +286,11 @@ void DescriptorSet::updateTexture(uint32_t binding, Gfx::PTexture texture, Gfx::
.sampler = samplerState != nullptr ? samplerState.cast<Sampler>()->getSampler() : VK_NULL_HANDLE,
.imageView = vulkanTexture->getView(),
.imageLayout = cast(vulkanTexture->getLayout()),
});
});
VkDescriptorType descriptorType = VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE;
if (samplerState != nullptr) {
descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER;
}
else if (vulkanTexture->getUsage() & VK_IMAGE_USAGE_STORAGE_BIT) {
} else if (vulkanTexture->getUsage() & VK_IMAGE_USAGE_STORAGE_BIT) {
descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_IMAGE;
}
writeDescriptors.add(VkWriteDescriptorSet{
@@ -320,7 +302,7 @@ void DescriptorSet::updateTexture(uint32_t binding, Gfx::PTexture texture, Gfx::
.descriptorCount = 1,
.descriptorType = descriptorType,
.pImageInfo = &imageInfos.back(),
});
});
boundResources[binding] = vulkanTexture->getHandle();
}
@@ -330,15 +312,14 @@ void DescriptorSet::updateTextureArray(uint32_t binding, Array<Gfx::PTexture> te
boundResources.resize(binding + textures.size());
for (auto& gfxTexture : textures) {
TextureBase* vulkanTexture = gfxTexture.cast<TextureBase>().getHandle();
if (boundResources[binding + arrayElement] == vulkanTexture->getHandle())
{
if (boundResources[binding + arrayElement] == vulkanTexture->getHandle()) {
continue;
}
imageInfos.add(VkDescriptorImageInfo{
.sampler = VK_NULL_HANDLE,
.imageView = vulkanTexture->getView(),
.imageLayout = cast(vulkanTexture->getLayout()),
});
});
VkDescriptorType descriptorType = VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE;
if (vulkanTexture->getUsage() & VK_IMAGE_USAGE_STORAGE_BIT) {
@@ -354,7 +335,7 @@ void DescriptorSet::updateTextureArray(uint32_t binding, Array<Gfx::PTexture> te
.descriptorCount = 1,
.descriptorType = descriptorType,
.pImageInfo = &imageInfos.back(),
});
});
vulkanTexture->getHandle()->bind();
}
}
@@ -385,8 +366,7 @@ void PipelineLayout::create() {
PDescriptorLayout layout = desc.cast<DescriptorLayout>();
layout->create();
uint32 parameterIndex = parameterMapping[layout->getName()];
if (parameterIndex >= vulkanDescriptorLayouts.size())
{
if (parameterIndex >= vulkanDescriptorLayouts.size()) {
vulkanDescriptorLayouts.resize(parameterIndex + 1);
}
vulkanDescriptorLayouts[parameterIndex] = layout->getHandle();
@@ -409,10 +389,10 @@ void PipelineLayout::create() {
.pPushConstantRanges = vkPushConstants.data(),
};
layoutHash = CRC::Calculate(createInfo.pPushConstantRanges,
sizeof(VkPushConstantRange) * createInfo.pushConstantRangeCount, CRC::CRC_32());
layoutHash = CRC::Calculate(createInfo.pSetLayouts, sizeof(VkDescriptorSetLayout) * createInfo.setLayoutCount,
CRC::CRC_32(), layoutHash);
layoutHash =
CRC::Calculate(createInfo.pPushConstantRanges, sizeof(VkPushConstantRange) * createInfo.pushConstantRangeCount, CRC::CRC_32());
layoutHash =
CRC::Calculate(createInfo.pSetLayouts, sizeof(VkDescriptorSetLayout) * createInfo.setLayoutCount, CRC::CRC_32(), layoutHash);
std::unique_lock l(layoutLock);
if (cachedLayouts.contains(layoutHash)) {
+65 -65
View File
@@ -8,90 +8,90 @@ namespace Seele {
namespace Vulkan {
DECLARE_REF(Graphics)
class DescriptorLayout : public Gfx::DescriptorLayout {
public:
DescriptorLayout(PGraphics graphics, const std::string& name);
virtual ~DescriptorLayout();
virtual void create() override;
constexpr VkDescriptorSetLayout getHandle() const { return layoutHandle; }
public:
DescriptorLayout(PGraphics graphics, const std::string& name);
virtual ~DescriptorLayout();
virtual void create() override;
constexpr VkDescriptorSetLayout getHandle() const { return layoutHandle; }
private:
PGraphics graphics;
Array<VkDescriptorSetLayoutBinding> bindings;
VkDescriptorSetLayout layoutHandle;
friend class DescriptorPool;
private:
PGraphics graphics;
Array<VkDescriptorSetLayoutBinding> bindings;
VkDescriptorSetLayout layoutHandle;
friend class DescriptorPool;
};
DEFINE_REF(DescriptorLayout)
DECLARE_REF(DescriptorSet)
class DescriptorPool : public Gfx::DescriptorPool, public CommandBoundResource {
public:
DescriptorPool(PGraphics graphics, PDescriptorLayout layout);
virtual ~DescriptorPool();
virtual Gfx::PDescriptorSet allocateDescriptorSet() override;
virtual void reset() override;
public:
DescriptorPool(PGraphics graphics, PDescriptorLayout layout);
virtual ~DescriptorPool();
virtual Gfx::PDescriptorSet allocateDescriptorSet() override;
virtual void reset() override;
constexpr VkDescriptorPool getHandle() const { return poolHandle; }
constexpr PDescriptorLayout getLayout() const { return layout; }
constexpr VkDescriptorPool getHandle() const { return poolHandle; }
constexpr PDescriptorLayout getLayout() const { return layout; }
private:
PGraphics graphics;
PDescriptorLayout layout;
const static int maxSets = 64;
StaticArray<ODescriptorSet, maxSets> cachedHandles;
VkDescriptorPool poolHandle;
DescriptorPool* nextAlloc = nullptr;
private:
PGraphics graphics;
PDescriptorLayout layout;
const static int maxSets = 64;
StaticArray<ODescriptorSet, maxSets> cachedHandles;
VkDescriptorPool poolHandle;
DescriptorPool* nextAlloc = nullptr;
};
DEFINE_REF(DescriptorPool)
class DescriptorSet : public Gfx::DescriptorSet, public CommandBoundResource {
public:
DescriptorSet(PGraphics graphics, PDescriptorPool owner);
virtual ~DescriptorSet();
virtual void writeChanges() override;
virtual void updateBuffer(uint32_t binding, Gfx::PUniformBuffer uniformBuffer) override;
virtual void updateBuffer(uint32_t binding, Gfx::PShaderBuffer uniformBuffer) override;
virtual void updateBuffer(uint32_t binding, uint32 index, Gfx::PShaderBuffer uniformBuffer) override;
virtual void updateSampler(uint32_t binding, Gfx::PSampler samplerState) override;
virtual void updateTexture(uint32_t binding, Gfx::PTexture texture, Gfx::PSampler sampler = nullptr) override;
virtual void updateTextureArray(uint32_t binding, Array<Gfx::PTexture> texture) override;
public:
DescriptorSet(PGraphics graphics, PDescriptorPool owner);
virtual ~DescriptorSet();
virtual void writeChanges() override;
virtual void updateBuffer(uint32_t binding, Gfx::PUniformBuffer uniformBuffer) override;
virtual void updateBuffer(uint32_t binding, Gfx::PShaderBuffer uniformBuffer) override;
virtual void updateBuffer(uint32_t binding, uint32 index, Gfx::PShaderBuffer uniformBuffer) override;
virtual void updateSampler(uint32_t binding, Gfx::PSampler samplerState) override;
virtual void updateTexture(uint32_t binding, Gfx::PTexture texture, Gfx::PSampler sampler = nullptr) override;
virtual void updateTextureArray(uint32_t binding, Array<Gfx::PTexture> texture) override;
constexpr bool isCurrentlyInUse() const { return currentlyInUse; }
constexpr void allocate() { currentlyInUse = true; }
constexpr void free() { currentlyInUse = false; }
constexpr VkDescriptorSet getHandle() const { return setHandle; }
constexpr bool isCurrentlyInUse() const { return currentlyInUse; }
constexpr void allocate() { currentlyInUse = true; }
constexpr void free() { currentlyInUse = false; }
constexpr VkDescriptorSet getHandle() const { return setHandle; }
private:
List<VkDescriptorImageInfo> imageInfos;
List<VkDescriptorBufferInfo> bufferInfos;
Array<VkWriteDescriptorSet> writeDescriptors;
// contains the previously bound resources at every binding
// since the layout is fixed, trying to bind a texture to a buffer
// would not work anyways, so casts should be safe
//Array<void*> cachedData;
Array<PCommandBoundResource> boundResources;
VkDescriptorSet setHandle;
PGraphics graphics;
PDescriptorPool owner;
uint32 bindCount;
bool currentlyInUse;
friend class DescriptorPool;
friend class Command;
friend class RenderCommand;
friend class ComputeCommand;
private:
List<VkDescriptorImageInfo> imageInfos;
List<VkDescriptorBufferInfo> bufferInfos;
Array<VkWriteDescriptorSet> writeDescriptors;
// contains the previously bound resources at every binding
// since the layout is fixed, trying to bind a texture to a buffer
// would not work anyways, so casts should be safe
// Array<void*> cachedData;
Array<PCommandBoundResource> boundResources;
VkDescriptorSet setHandle;
PGraphics graphics;
PDescriptorPool owner;
uint32 bindCount;
bool currentlyInUse;
friend class DescriptorPool;
friend class Command;
friend class RenderCommand;
friend class ComputeCommand;
};
DEFINE_REF(DescriptorSet)
class PipelineLayout : public Gfx::PipelineLayout {
public:
PipelineLayout(PGraphics graphics, const std::string& name, Gfx::PPipelineLayout baseLayout);
virtual ~PipelineLayout();
virtual void create();
constexpr VkPipelineLayout getHandle() const { return layoutHandle; }
public:
PipelineLayout(PGraphics graphics, const std::string& name, Gfx::PPipelineLayout baseLayout);
virtual ~PipelineLayout();
virtual void create();
constexpr VkPipelineLayout getHandle() const { return layoutHandle; }
private:
Array<VkDescriptorSetLayout> vulkanDescriptorLayouts;
PGraphics graphics;
VkPipelineLayout layoutHandle;
private:
Array<VkDescriptorSetLayout> vulkanDescriptorLayouts;
PGraphics graphics;
VkPipelineLayout layoutHandle;
};
DEFINE_REF(PipelineLayout)
+145 -218
View File
@@ -5,10 +5,8 @@ using namespace Seele;
using namespace Seele::Vulkan;
using namespace Seele::Gfx;
VkDescriptorType Seele::Vulkan::cast(const Seele::Gfx::SeDescriptorType &descriptorType)
{
switch (descriptorType)
{
VkDescriptorType Seele::Vulkan::cast(const Seele::Gfx::SeDescriptorType& descriptorType) {
switch (descriptorType) {
case SE_DESCRIPTOR_TYPE_SAMPLER:
return VK_DESCRIPTOR_TYPE_SAMPLER;
case SE_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER:
@@ -43,10 +41,8 @@ VkDescriptorType Seele::Vulkan::cast(const Seele::Gfx::SeDescriptorType &descrip
return VK_DESCRIPTOR_TYPE_MAX_ENUM;
}
Seele::Gfx::SeDescriptorType Seele::Vulkan::cast(const VkDescriptorType &descriptorType)
{
switch (descriptorType)
{
Seele::Gfx::SeDescriptorType Seele::Vulkan::cast(const VkDescriptorType& descriptorType) {
switch (descriptorType) {
case VK_DESCRIPTOR_TYPE_SAMPLER:
return SE_DESCRIPTOR_TYPE_SAMPLER;
@@ -77,14 +73,12 @@ Seele::Gfx::SeDescriptorType Seele::Vulkan::cast(const VkDescriptorType &descrip
return SE_DESCRIPTOR_TYPE_ACCELERATION_STRUCTURE_NV;
#endif
default:
throw std::logic_error("Not implemented");
throw std::logic_error("Not implemented");
}
}
VkShaderStageFlagBits Seele::Vulkan::cast(const Seele::Gfx::SeShaderStageFlagBits &stage)
{
switch (stage)
{
VkShaderStageFlagBits Seele::Vulkan::cast(const Seele::Gfx::SeShaderStageFlagBits& stage) {
switch (stage) {
case SE_SHADER_STAGE_VERTEX_BIT:
return VK_SHADER_STAGE_VERTEX_BIT;
@@ -102,15 +96,13 @@ VkShaderStageFlagBits Seele::Vulkan::cast(const Seele::Gfx::SeShaderStageFlagBit
return VK_SHADER_STAGE_ALL_GRAPHICS;
case SE_SHADER_STAGE_ALL:
return VK_SHADER_STAGE_ALL;
default: throw std::logic_error("Not implemented");
default:
throw std::logic_error("Not implemented");
}
}
Seele::Gfx::SeShaderStageFlagBits Seele::Vulkan::cast(const VkShaderStageFlagBits &stage)
{
switch (stage)
{
Seele::Gfx::SeShaderStageFlagBits Seele::Vulkan::cast(const VkShaderStageFlagBits& stage) {
switch (stage) {
case VK_SHADER_STAGE_VERTEX_BIT:
return SE_SHADER_STAGE_VERTEX_BIT;
case VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT:
@@ -127,16 +119,13 @@ Seele::Gfx::SeShaderStageFlagBits Seele::Vulkan::cast(const VkShaderStageFlagBit
return SE_SHADER_STAGE_ALL_GRAPHICS;
case VK_SHADER_STAGE_ALL:
return SE_SHADER_STAGE_ALL;
default: throw std::logic_error("Not implemented");
default:
throw std::logic_error("Not implemented");
}
}
VkFormat Seele::Vulkan::cast(const Seele::Gfx::SeFormat &format)
{
switch (format)
{
VkFormat Seele::Vulkan::cast(const Seele::Gfx::SeFormat& format) {
switch (format) {
case SE_FORMAT_UNDEFINED:
return VK_FORMAT_UNDEFINED;
case SE_FORMAT_R4G4_UNORM_PACK8:
@@ -595,10 +584,8 @@ VkFormat Seele::Vulkan::cast(const Seele::Gfx::SeFormat &format)
return VK_FORMAT_MAX_ENUM;
}
}
Seele::Gfx::SeFormat Seele::Vulkan::cast(const VkFormat &format)
{
switch (format)
{
Seele::Gfx::SeFormat Seele::Vulkan::cast(const VkFormat& format) {
switch (format) {
case VK_FORMAT_UNDEFINED:
return SE_FORMAT_UNDEFINED;
case VK_FORMAT_R4G4_UNORM_PACK8:
@@ -1053,15 +1040,13 @@ Seele::Gfx::SeFormat Seele::Vulkan::cast(const VkFormat &format)
return SE_FORMAT_PVRTC2_2BPP_SRGB_BLOCK_IMG;
case VK_FORMAT_PVRTC2_4BPP_SRGB_BLOCK_IMG:
return SE_FORMAT_PVRTC2_4BPP_SRGB_BLOCK_IMG;
default: throw std::logic_error("Not implemented");
default:
throw std::logic_error("Not implemented");
}
}
VkImageLayout Seele::Vulkan::cast(const Gfx::SeImageLayout &imageLayout)
{
switch (imageLayout)
{
VkImageLayout Seele::Vulkan::cast(const Gfx::SeImageLayout& imageLayout) {
switch (imageLayout) {
case SE_IMAGE_LAYOUT_UNDEFINED:
return VK_IMAGE_LAYOUT_UNDEFINED;
case SE_IMAGE_LAYOUT_GENERAL:
@@ -1092,14 +1077,12 @@ VkImageLayout Seele::Vulkan::cast(const Gfx::SeImageLayout &imageLayout)
return VK_IMAGE_LAYOUT_SHADING_RATE_OPTIMAL_NV;
case SE_IMAGE_LAYOUT_FRAGMENT_DENSITY_MAP_OPTIMAL_EXT:
return VK_IMAGE_LAYOUT_FRAGMENT_DENSITY_MAP_OPTIMAL_EXT;
default: throw std::logic_error("Not implemented");
default:
throw std::logic_error("Not implemented");
}
}
Gfx::SeImageLayout Seele::Vulkan::cast(const VkImageLayout &imageLayout)
{
switch (imageLayout)
{
Gfx::SeImageLayout Seele::Vulkan::cast(const VkImageLayout& imageLayout) {
switch (imageLayout) {
case VK_IMAGE_LAYOUT_UNDEFINED:
return SE_IMAGE_LAYOUT_UNDEFINED;
case VK_IMAGE_LAYOUT_GENERAL:
@@ -1130,67 +1113,57 @@ Gfx::SeImageLayout Seele::Vulkan::cast(const VkImageLayout &imageLayout)
return SE_IMAGE_LAYOUT_SHADING_RATE_OPTIMAL_NV;
case VK_IMAGE_LAYOUT_FRAGMENT_DENSITY_MAP_OPTIMAL_EXT:
return SE_IMAGE_LAYOUT_FRAGMENT_DENSITY_MAP_OPTIMAL_EXT;
default: throw std::logic_error("Not implemented");
default:
throw std::logic_error("Not implemented");
}
}
VkAttachmentStoreOp Seele::Vulkan::cast(const Gfx::SeAttachmentStoreOp &storeOp)
{
switch (storeOp)
{
VkAttachmentStoreOp Seele::Vulkan::cast(const Gfx::SeAttachmentStoreOp& storeOp) {
switch (storeOp) {
case SE_ATTACHMENT_STORE_OP_STORE:
return VK_ATTACHMENT_STORE_OP_STORE;
case SE_ATTACHMENT_STORE_OP_DONT_CARE:
return VK_ATTACHMENT_STORE_OP_DONT_CARE;
default: throw std::logic_error("Not implemented");
default:
throw std::logic_error("Not implemented");
}
}
Gfx::SeAttachmentStoreOp Seele::Vulkan::cast(const VkAttachmentStoreOp &storeOp)
{
switch (storeOp)
{
Gfx::SeAttachmentStoreOp Seele::Vulkan::cast(const VkAttachmentStoreOp& storeOp) {
switch (storeOp) {
case VK_ATTACHMENT_STORE_OP_STORE:
return SE_ATTACHMENT_STORE_OP_STORE;
case VK_ATTACHMENT_STORE_OP_DONT_CARE:
return SE_ATTACHMENT_STORE_OP_DONT_CARE;
default: throw std::logic_error("Not implemented");
default:
throw std::logic_error("Not implemented");
}
}
VkAttachmentLoadOp Seele::Vulkan::cast(const Gfx::SeAttachmentLoadOp &loadOp)
{
switch (loadOp)
{
VkAttachmentLoadOp Seele::Vulkan::cast(const Gfx::SeAttachmentLoadOp& loadOp) {
switch (loadOp) {
case SE_ATTACHMENT_LOAD_OP_LOAD:
return VK_ATTACHMENT_LOAD_OP_LOAD;
case SE_ATTACHMENT_LOAD_OP_CLEAR:
return VK_ATTACHMENT_LOAD_OP_CLEAR;
case SE_ATTACHMENT_LOAD_OP_DONT_CARE:
return VK_ATTACHMENT_LOAD_OP_DONT_CARE;
default: throw std::logic_error("Not implemented");
default:
throw std::logic_error("Not implemented");
}
}
Gfx::SeAttachmentLoadOp Seele::Vulkan::cast(const VkAttachmentLoadOp &loadOp)
{
switch (loadOp)
{
Gfx::SeAttachmentLoadOp Seele::Vulkan::cast(const VkAttachmentLoadOp& loadOp) {
switch (loadOp) {
case VK_ATTACHMENT_LOAD_OP_LOAD:
return SE_ATTACHMENT_LOAD_OP_LOAD;
case VK_ATTACHMENT_LOAD_OP_CLEAR:
return SE_ATTACHMENT_LOAD_OP_CLEAR;
case VK_ATTACHMENT_LOAD_OP_DONT_CARE:
return SE_ATTACHMENT_LOAD_OP_DONT_CARE;
default: throw std::logic_error("Not implemented");
default:
throw std::logic_error("Not implemented");
}
}
VkIndexType Seele::Vulkan::cast(const Gfx::SeIndexType &indexType)
{
switch (indexType)
{
VkIndexType Seele::Vulkan::cast(const Gfx::SeIndexType& indexType) {
switch (indexType) {
case Gfx::SE_INDEX_TYPE_UINT16:
return VK_INDEX_TYPE_UINT16;
case Gfx::SE_INDEX_TYPE_UINT32:
@@ -1199,23 +1172,19 @@ VkIndexType Seele::Vulkan::cast(const Gfx::SeIndexType &indexType)
return VK_INDEX_TYPE_MAX_ENUM;
}
}
Gfx::SeIndexType Seele::Vulkan::cast(const VkIndexType &indexType)
{
switch (indexType)
{
Gfx::SeIndexType Seele::Vulkan::cast(const VkIndexType& indexType) {
switch (indexType) {
case VK_INDEX_TYPE_UINT16:
return Gfx::SE_INDEX_TYPE_UINT16;
case VK_INDEX_TYPE_UINT32:
return Gfx::SE_INDEX_TYPE_UINT32;
default: throw std::logic_error("Not implemented");
default:
throw std::logic_error("Not implemented");
}
}
VkPrimitiveTopology Seele::Vulkan::cast(const Gfx::SePrimitiveTopology &topology)
{
switch (topology)
{
VkPrimitiveTopology Seele::Vulkan::cast(const Gfx::SePrimitiveTopology& topology) {
switch (topology) {
case SE_PRIMITIVE_TOPOLOGY_POINT_LIST:
return VK_PRIMITIVE_TOPOLOGY_POINT_LIST;
case SE_PRIMITIVE_TOPOLOGY_LINE_LIST:
@@ -1242,10 +1211,8 @@ VkPrimitiveTopology Seele::Vulkan::cast(const Gfx::SePrimitiveTopology &topology
return VK_PRIMITIVE_TOPOLOGY_MAX_ENUM;
}
}
Gfx::SePrimitiveTopology Seele::Vulkan::cast(const VkPrimitiveTopology &topology)
{
switch (topology)
{
Gfx::SePrimitiveTopology Seele::Vulkan::cast(const VkPrimitiveTopology& topology) {
switch (topology) {
case VK_PRIMITIVE_TOPOLOGY_POINT_LIST:
return SE_PRIMITIVE_TOPOLOGY_POINT_LIST;
case VK_PRIMITIVE_TOPOLOGY_LINE_LIST:
@@ -1268,15 +1235,13 @@ Gfx::SePrimitiveTopology Seele::Vulkan::cast(const VkPrimitiveTopology &topology
return SE_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP_WITH_ADJACENCY;
case VK_PRIMITIVE_TOPOLOGY_PATCH_LIST:
return SE_PRIMITIVE_TOPOLOGY_PATCH_LIST;
default: throw std::logic_error("Not implemented");
default:
throw std::logic_error("Not implemented");
}
}
VkPolygonMode Seele::Vulkan::cast(const Gfx::SePolygonMode &mode)
{
switch (mode)
{
VkPolygonMode Seele::Vulkan::cast(const Gfx::SePolygonMode& mode) {
switch (mode) {
case SE_POLYGON_MODE_FILL:
return VK_POLYGON_MODE_FILL;
case SE_POLYGON_MODE_LINE:
@@ -1287,24 +1252,20 @@ VkPolygonMode Seele::Vulkan::cast(const Gfx::SePolygonMode &mode)
return VK_POLYGON_MODE_MAX_ENUM;
}
}
Gfx::SePolygonMode Seele::Vulkan::cast(const VkPolygonMode &mode)
{
switch (mode)
{
Gfx::SePolygonMode Seele::Vulkan::cast(const VkPolygonMode& mode) {
switch (mode) {
case VK_POLYGON_MODE_FILL:
return SE_POLYGON_MODE_FILL;
case VK_POLYGON_MODE_LINE:
return SE_POLYGON_MODE_LINE;
case VK_POLYGON_MODE_POINT:
return SE_POLYGON_MODE_POINT;
default: throw std::logic_error("Not implemented");
default:
throw std::logic_error("Not implemented");
}
}
VkCompareOp Seele::Vulkan::cast(const Gfx::SeCompareOp &op)
{
switch (op)
{
VkCompareOp Seele::Vulkan::cast(const Gfx::SeCompareOp& op) {
switch (op) {
case SE_COMPARE_OP_NEVER:
return VK_COMPARE_OP_NEVER;
case SE_COMPARE_OP_LESS:
@@ -1321,14 +1282,12 @@ VkCompareOp Seele::Vulkan::cast(const Gfx::SeCompareOp &op)
return VK_COMPARE_OP_GREATER_OR_EQUAL;
case SE_COMPARE_OP_ALWAYS:
return VK_COMPARE_OP_ALWAYS;
default: throw std::logic_error("Not implemented");
default:
throw std::logic_error("Not implemented");
}
}
Gfx::SeCompareOp Seele::Vulkan::cast(const VkCompareOp &op)
{
switch (op)
{
Gfx::SeCompareOp Seele::Vulkan::cast(const VkCompareOp& op) {
switch (op) {
case VK_COMPARE_OP_NEVER:
return SE_COMPARE_OP_NEVER;
case VK_COMPARE_OP_LESS:
@@ -1345,181 +1304,155 @@ Gfx::SeCompareOp Seele::Vulkan::cast(const VkCompareOp &op)
return SE_COMPARE_OP_GREATER_OR_EQUAL;
case VK_COMPARE_OP_ALWAYS:
return SE_COMPARE_OP_ALWAYS;
default: throw std::logic_error("Not implemented");
default:
throw std::logic_error("Not implemented");
}
}
VkClearValue Seele::Vulkan::cast(const Gfx::SeClearValue& clear)
{
VkClearValue Seele::Vulkan::cast(const Gfx::SeClearValue& clear) {
VkClearValue result;
if constexpr (sizeof(clear) == sizeof(Gfx::SeClearColorValue))
{
if constexpr (sizeof(clear) == sizeof(Gfx::SeClearColorValue)) {
result.color.float32[0] = clear.color.float32[0];
result.color.float32[1] = clear.color.float32[1];
result.color.float32[2] = clear.color.float32[2];
result.color.float32[3] = clear.color.float32[3];
}
else
{
} else {
result.depthStencil.depth = clear.depthStencil.depth;
result.depthStencil.stencil = clear.depthStencil.stencil;
}
return result;
}
Gfx::SeClearValue Seele::Vulkan::cast(const VkClearValue& clear)
{
Gfx::SeClearValue Seele::Vulkan::cast(const VkClearValue& clear) {
Gfx::SeClearValue result;
if constexpr (sizeof(clear) == sizeof(VkClearColorValue))
{
if constexpr (sizeof(clear) == sizeof(VkClearColorValue)) {
result.color.float32[0] = clear.color.float32[0];
result.color.float32[1] = clear.color.float32[1];
result.color.float32[2] = clear.color.float32[2];
result.color.float32[3] = clear.color.float32[3];
}
else
{
} else {
result.depthStencil.depth = clear.depthStencil.depth;
result.depthStencil.stencil = clear.depthStencil.stencil;
}
return result;
}
VkSamplerAddressMode Seele::Vulkan::cast(const Gfx::SeSamplerAddressMode &mode)
{
switch(mode)
{
case SE_SAMPLER_ADDRESS_MODE_REPEAT:
VkSamplerAddressMode Seele::Vulkan::cast(const Gfx::SeSamplerAddressMode& mode) {
switch (mode) {
case SE_SAMPLER_ADDRESS_MODE_REPEAT:
return VK_SAMPLER_ADDRESS_MODE_REPEAT;
case SE_SAMPLER_ADDRESS_MODE_MIRRORED_REPEAT:
case SE_SAMPLER_ADDRESS_MODE_MIRRORED_REPEAT:
return VK_SAMPLER_ADDRESS_MODE_MIRRORED_REPEAT;
case SE_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE:
case SE_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE:
return VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE;
case SE_SAMPLER_ADDRESS_MODE_CLAMP_TO_BORDER:
case SE_SAMPLER_ADDRESS_MODE_CLAMP_TO_BORDER:
return VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_BORDER;
case SE_SAMPLER_ADDRESS_MODE_MIRROR_CLAMP_TO_EDGE:
case SE_SAMPLER_ADDRESS_MODE_MIRROR_CLAMP_TO_EDGE:
return VK_SAMPLER_ADDRESS_MODE_MIRROR_CLAMP_TO_EDGE;
default:
return VK_SAMPLER_ADDRESS_MODE_MAX_ENUM;
}
}
Gfx::SeSamplerAddressMode Seele::Vulkan::cast(const VkSamplerAddressMode &mode)
{
switch(mode)
{
case VK_SAMPLER_ADDRESS_MODE_REPEAT:
Gfx::SeSamplerAddressMode Seele::Vulkan::cast(const VkSamplerAddressMode& mode) {
switch (mode) {
case VK_SAMPLER_ADDRESS_MODE_REPEAT:
return SE_SAMPLER_ADDRESS_MODE_REPEAT;
case VK_SAMPLER_ADDRESS_MODE_MIRRORED_REPEAT:
case VK_SAMPLER_ADDRESS_MODE_MIRRORED_REPEAT:
return SE_SAMPLER_ADDRESS_MODE_MIRRORED_REPEAT;
case VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE:
case VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE:
return SE_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE;
case VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_BORDER:
case VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_BORDER:
return SE_SAMPLER_ADDRESS_MODE_CLAMP_TO_BORDER;
case VK_SAMPLER_ADDRESS_MODE_MIRROR_CLAMP_TO_EDGE:
case VK_SAMPLER_ADDRESS_MODE_MIRROR_CLAMP_TO_EDGE:
return SE_SAMPLER_ADDRESS_MODE_MIRROR_CLAMP_TO_EDGE;
default: throw std::logic_error("Not implemented");
default:
throw std::logic_error("Not implemented");
}
}
VkBorderColor Seele::Vulkan::cast(const Gfx::SeBorderColor &color)
{
switch(color)
{
case SE_BORDER_COLOR_FLOAT_TRANSPARENT_BLACK:
VkBorderColor Seele::Vulkan::cast(const Gfx::SeBorderColor& color) {
switch (color) {
case SE_BORDER_COLOR_FLOAT_TRANSPARENT_BLACK:
return VK_BORDER_COLOR_FLOAT_TRANSPARENT_BLACK;
case SE_BORDER_COLOR_INT_TRANSPARENT_BLACK:
case SE_BORDER_COLOR_INT_TRANSPARENT_BLACK:
return VK_BORDER_COLOR_INT_TRANSPARENT_BLACK;
case SE_BORDER_COLOR_FLOAT_OPAQUE_BLACK:
case SE_BORDER_COLOR_FLOAT_OPAQUE_BLACK:
return VK_BORDER_COLOR_FLOAT_OPAQUE_BLACK;
case SE_BORDER_COLOR_INT_OPAQUE_BLACK:
case SE_BORDER_COLOR_INT_OPAQUE_BLACK:
return VK_BORDER_COLOR_INT_OPAQUE_BLACK;
case SE_BORDER_COLOR_FLOAT_OPAQUE_WHITE:
case SE_BORDER_COLOR_FLOAT_OPAQUE_WHITE:
return VK_BORDER_COLOR_FLOAT_OPAQUE_WHITE;
case SE_BORDER_COLOR_INT_OPAQUE_WHITE:
case SE_BORDER_COLOR_INT_OPAQUE_WHITE:
return VK_BORDER_COLOR_INT_OPAQUE_WHITE;
default:
return VK_BORDER_COLOR_MAX_ENUM;
}
}
Gfx::SeBorderColor Seele::Vulkan::cast(const VkBorderColor &color)
{
switch(color)
{
case VK_BORDER_COLOR_FLOAT_TRANSPARENT_BLACK:
return SE_BORDER_COLOR_FLOAT_TRANSPARENT_BLACK;
case VK_BORDER_COLOR_INT_TRANSPARENT_BLACK:
return SE_BORDER_COLOR_INT_TRANSPARENT_BLACK;
case VK_BORDER_COLOR_FLOAT_OPAQUE_BLACK:
return SE_BORDER_COLOR_FLOAT_OPAQUE_BLACK;
case VK_BORDER_COLOR_INT_OPAQUE_BLACK:
return SE_BORDER_COLOR_INT_OPAQUE_BLACK;
case VK_BORDER_COLOR_FLOAT_OPAQUE_WHITE:
return SE_BORDER_COLOR_FLOAT_OPAQUE_WHITE;
case VK_BORDER_COLOR_INT_OPAQUE_WHITE:
return SE_BORDER_COLOR_INT_OPAQUE_WHITE;
default: throw std::logic_error("Not implemented");
Gfx::SeBorderColor Seele::Vulkan::cast(const VkBorderColor& color) {
switch (color) {
case VK_BORDER_COLOR_FLOAT_TRANSPARENT_BLACK:
return SE_BORDER_COLOR_FLOAT_TRANSPARENT_BLACK;
case VK_BORDER_COLOR_INT_TRANSPARENT_BLACK:
return SE_BORDER_COLOR_INT_TRANSPARENT_BLACK;
case VK_BORDER_COLOR_FLOAT_OPAQUE_BLACK:
return SE_BORDER_COLOR_FLOAT_OPAQUE_BLACK;
case VK_BORDER_COLOR_INT_OPAQUE_BLACK:
return SE_BORDER_COLOR_INT_OPAQUE_BLACK;
case VK_BORDER_COLOR_FLOAT_OPAQUE_WHITE:
return SE_BORDER_COLOR_FLOAT_OPAQUE_WHITE;
case VK_BORDER_COLOR_INT_OPAQUE_WHITE:
return SE_BORDER_COLOR_INT_OPAQUE_WHITE;
default:
throw std::logic_error("Not implemented");
}
}
VkFilter Seele::Vulkan::cast(const Gfx::SeFilter &filter)
{
switch(filter)
{
case SE_FILTER_NEAREST:
VkFilter Seele::Vulkan::cast(const Gfx::SeFilter& filter) {
switch (filter) {
case SE_FILTER_NEAREST:
return VK_FILTER_NEAREST;
case SE_FILTER_LINEAR:
case SE_FILTER_LINEAR:
return VK_FILTER_LINEAR;
case SE_FILTER_CUBIC_IMG:
case SE_FILTER_CUBIC_IMG:
return VK_FILTER_CUBIC_IMG;
default: throw std::logic_error("Not implemented");
default:
throw std::logic_error("Not implemented");
}
}
Gfx::SeFilter Seele::Vulkan::cast(const VkFilter &filter)
{
switch(filter)
{
case VK_FILTER_NEAREST:
Gfx::SeFilter Seele::Vulkan::cast(const VkFilter& filter) {
switch (filter) {
case VK_FILTER_NEAREST:
return SE_FILTER_NEAREST;
case VK_FILTER_LINEAR:
case VK_FILTER_LINEAR:
return SE_FILTER_LINEAR;
case VK_FILTER_CUBIC_IMG:
case VK_FILTER_CUBIC_IMG:
return SE_FILTER_CUBIC_IMG;
default: throw std::logic_error("Not implemented");
default:
throw std::logic_error("Not implemented");
}
}
VkSamplerMipmapMode Seele::Vulkan::cast(const Gfx::SeSamplerMipmapMode &filter)
{
switch(filter)
{
VkSamplerMipmapMode Seele::Vulkan::cast(const Gfx::SeSamplerMipmapMode& filter) {
switch (filter) {
case SE_SAMPLER_MIPMAP_MODE_NEAREST:
return VK_SAMPLER_MIPMAP_MODE_NEAREST;
case SE_SAMPLER_MIPMAP_MODE_LINEAR:
return VK_SAMPLER_MIPMAP_MODE_LINEAR;
default: throw std::logic_error("Not implemented");
default:
throw std::logic_error("Not implemented");
}
}
Gfx::SeSamplerMipmapMode Seele::Vulkan::cast(const VkSamplerMipmapMode &filter)
{
switch(filter)
{
Gfx::SeSamplerMipmapMode Seele::Vulkan::cast(const VkSamplerMipmapMode& filter) {
switch (filter) {
case VK_SAMPLER_MIPMAP_MODE_NEAREST:
return SE_SAMPLER_MIPMAP_MODE_NEAREST;
case VK_SAMPLER_MIPMAP_MODE_LINEAR:
return SE_SAMPLER_MIPMAP_MODE_LINEAR;
default: throw std::logic_error("Not implemented");
default:
throw std::logic_error("Not implemented");
}
}
VkAccessFlagBits Seele::Vulkan::cast(const Gfx::SeAccessFlagBits &flags)
{
switch(flags)
{
VkAccessFlagBits Seele::Vulkan::cast(const Gfx::SeAccessFlagBits& flags) {
switch (flags) {
case SE_ACCESS_INDIRECT_COMMAND_READ_BIT:
return VK_ACCESS_INDIRECT_COMMAND_READ_BIT;
case SE_ACCESS_INDEX_READ_BIT:
@@ -1575,10 +1508,8 @@ VkAccessFlagBits Seele::Vulkan::cast(const Gfx::SeAccessFlagBits &flags)
}
}
Gfx::SeAccessFlagBits Seele::Vulkan::cast(const VkAccessFlagBits &flags)
{
switch(flags)
{
Gfx::SeAccessFlagBits Seele::Vulkan::cast(const VkAccessFlagBits& flags) {
switch (flags) {
case VK_ACCESS_INDIRECT_COMMAND_READ_BIT:
return SE_ACCESS_INDIRECT_COMMAND_READ_BIT;
case VK_ACCESS_INDEX_READ_BIT:
@@ -1633,10 +1564,8 @@ Gfx::SeAccessFlagBits Seele::Vulkan::cast(const VkAccessFlagBits &flags)
return SE_ACCESS_FLAG_BITS_MAX_ENUM;
}
}
VkPipelineStageFlagBits Seele::Vulkan::cast(const Gfx::SePipelineStageFlagBits &flags)
{
switch(flags)
{
VkPipelineStageFlagBits Seele::Vulkan::cast(const Gfx::SePipelineStageFlagBits& flags) {
switch (flags) {
case SE_PIPELINE_STAGE_TOP_OF_PIPE_BIT:
return VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT;
case SE_PIPELINE_STAGE_DRAW_INDIRECT_BIT:
@@ -1695,10 +1624,8 @@ VkPipelineStageFlagBits Seele::Vulkan::cast(const Gfx::SePipelineStageFlagBits &
return VK_PIPELINE_STAGE_FLAG_BITS_MAX_ENUM;
}
}
Gfx::SePipelineStageFlagBits Seele::Vulkan::cast(const VkPipelineStageFlagBits &flags)
{
switch(flags)
{
Gfx::SePipelineStageFlagBits Seele::Vulkan::cast(const VkPipelineStageFlagBits& flags) {
switch (flags) {
case VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT:
return SE_PIPELINE_STAGE_TOP_OF_PIPE_BIT;
case VK_PIPELINE_STAGE_DRAW_INDIRECT_BIT:
+49 -52
View File
@@ -1,60 +1,57 @@
#pragma once
#include "Graphics/Enums.h"
#include <vulkan/vulkan.h>
#include <iostream>
#include <thread>
#include <vulkan/vulkan.h>
#define VK_CHECK(f) \
{ \
VkResult res = (f); \
if (res != VK_SUCCESS) \
{ \
if(res == VK_ERROR_DEVICE_LOST) \
{ \
std::this_thread::sleep_for(std::chrono::seconds(3)); \
} \
std::cout << "Fatal : VkResult is " << res << " in " << __FILE__ << " at line " << __LINE__ << std::endl; \
abort(); \
} \
}
namespace Seele
{
namespace Vulkan
{
VkDescriptorType cast(const Gfx::SeDescriptorType &descriptorType);
Gfx::SeDescriptorType cast(const VkDescriptorType &descriptorType);
VkShaderStageFlagBits cast(const Gfx::SeShaderStageFlagBits &stage);
Gfx::SeShaderStageFlagBits cast(const VkShaderStageFlagBits &stage);
VkFormat cast(const Gfx::SeFormat &format);
Gfx::SeFormat cast(const VkFormat &format);
VkImageLayout cast(const Gfx::SeImageLayout &imageLayout);
Gfx::SeImageLayout cast(const VkImageLayout &imageLayout);
VkAttachmentStoreOp cast(const Gfx::SeAttachmentStoreOp &storeOp);
Gfx::SeAttachmentStoreOp cast(const VkAttachmentStoreOp &storeOp);
VkAttachmentLoadOp cast(const Gfx::SeAttachmentLoadOp &loadOp);
Gfx::SeAttachmentLoadOp cast(const VkAttachmentLoadOp &loadOp);
VkIndexType cast(const Gfx::SeIndexType &indexType);
Gfx::SeIndexType cast(const VkIndexType &indexType);
VkPrimitiveTopology cast(const Gfx::SePrimitiveTopology &topology);
Gfx::SePrimitiveTopology cast(const VkPrimitiveTopology &topology);
VkPolygonMode cast(const Gfx::SePolygonMode &mode);
Gfx::SePolygonMode cast(const VkPolygonMode &mode);
VkCompareOp cast(const Gfx::SeCompareOp &op);
Gfx::SeCompareOp cast(const VkCompareOp &op);
VkClearValue cast(const Gfx::SeClearValue &clear);
Gfx::SeClearValue cast(const VkClearValue &clear);
VkSamplerAddressMode cast(const Gfx::SeSamplerAddressMode &mode);
Gfx::SeSamplerAddressMode cast(const VkSamplerAddressMode &mode);
VkBorderColor cast(const Gfx::SeBorderColor &color);
Gfx::SeBorderColor cast(const VkBorderColor &color);
VkFilter cast(const Gfx::SeFilter &filter);
Gfx::SeFilter cast(const VkFilter &filter);
VkSamplerMipmapMode cast(const Gfx::SeSamplerMipmapMode &filter);
Gfx::SeSamplerMipmapMode cast(const VkSamplerMipmapMode &filter);
VkAccessFlagBits cast(const Gfx::SeAccessFlagBits &flags);
Gfx::SeAccessFlagBits cast(const VkAccessFlagBits &flags);
VkPipelineStageFlagBits cast(const Gfx::SePipelineStageFlagBits &flags);
Gfx::SePipelineStageFlagBits cast(const VkPipelineStageFlagBits &flags);
#define VK_CHECK(f) \
{ \
VkResult res = (f); \
if (res != VK_SUCCESS) { \
if (res == VK_ERROR_DEVICE_LOST) { \
std::this_thread::sleep_for(std::chrono::seconds(3)); \
} \
std::cout << "Fatal : VkResult is " << res << " in " << __FILE__ << " at line " << __LINE__ << std::endl; \
abort(); \
} \
}
namespace Seele {
namespace Vulkan {
VkDescriptorType cast(const Gfx::SeDescriptorType& descriptorType);
Gfx::SeDescriptorType cast(const VkDescriptorType& descriptorType);
VkShaderStageFlagBits cast(const Gfx::SeShaderStageFlagBits& stage);
Gfx::SeShaderStageFlagBits cast(const VkShaderStageFlagBits& stage);
VkFormat cast(const Gfx::SeFormat& format);
Gfx::SeFormat cast(const VkFormat& format);
VkImageLayout cast(const Gfx::SeImageLayout& imageLayout);
Gfx::SeImageLayout cast(const VkImageLayout& imageLayout);
VkAttachmentStoreOp cast(const Gfx::SeAttachmentStoreOp& storeOp);
Gfx::SeAttachmentStoreOp cast(const VkAttachmentStoreOp& storeOp);
VkAttachmentLoadOp cast(const Gfx::SeAttachmentLoadOp& loadOp);
Gfx::SeAttachmentLoadOp cast(const VkAttachmentLoadOp& loadOp);
VkIndexType cast(const Gfx::SeIndexType& indexType);
Gfx::SeIndexType cast(const VkIndexType& indexType);
VkPrimitiveTopology cast(const Gfx::SePrimitiveTopology& topology);
Gfx::SePrimitiveTopology cast(const VkPrimitiveTopology& topology);
VkPolygonMode cast(const Gfx::SePolygonMode& mode);
Gfx::SePolygonMode cast(const VkPolygonMode& mode);
VkCompareOp cast(const Gfx::SeCompareOp& op);
Gfx::SeCompareOp cast(const VkCompareOp& op);
VkClearValue cast(const Gfx::SeClearValue& clear);
Gfx::SeClearValue cast(const VkClearValue& clear);
VkSamplerAddressMode cast(const Gfx::SeSamplerAddressMode& mode);
Gfx::SeSamplerAddressMode cast(const VkSamplerAddressMode& mode);
VkBorderColor cast(const Gfx::SeBorderColor& color);
Gfx::SeBorderColor cast(const VkBorderColor& color);
VkFilter cast(const Gfx::SeFilter& filter);
Gfx::SeFilter cast(const VkFilter& filter);
VkSamplerMipmapMode cast(const Gfx::SeSamplerMipmapMode& filter);
Gfx::SeSamplerMipmapMode cast(const VkSamplerMipmapMode& filter);
VkAccessFlagBits cast(const Gfx::SeAccessFlagBits& flags);
Gfx::SeAccessFlagBits cast(const VkAccessFlagBits& flags);
VkPipelineStageFlagBits cast(const Gfx::SePipelineStageFlagBits& flags);
Gfx::SePipelineStageFlagBits cast(const VkPipelineStageFlagBits& flags);
} // namespace Vulkan
} // namespace Seele
+12 -20
View File
@@ -1,57 +1,50 @@
#include "Framebuffer.h"
#include "Enums.h"
#include "RenderPass.h"
#include "Graphics.h"
#include "Texture.h"
#include "CRC.h"
#include "Enums.h"
#include "Graphics.h"
#include "RenderPass.h"
#include "Texture.h"
using namespace Seele;
using namespace Seele::Vulkan;
Framebuffer::Framebuffer(PGraphics graphics, PRenderPass renderPass, Gfx::RenderTargetLayout renderTargetLayout)
: graphics(graphics)
, layout(renderTargetLayout)
, renderPass(renderPass)
{
: graphics(graphics), layout(renderTargetLayout), renderPass(renderPass) {
FramebufferDescription description;
std::memset(&description, 0, sizeof(FramebufferDescription));
Array<VkImageView> attachments;
uint32 width = 0;
uint32 height = 0;
for (auto inputAttachment : layout.inputAttachments)
{
for (auto inputAttachment : layout.inputAttachments) {
PTexture2D vkInputAttachment = inputAttachment.getTexture().cast<Texture2D>();
attachments.add(vkInputAttachment->getView());
description.inputAttachments[description.numInputAttachments++] = vkInputAttachment->getView();
width = std::max(width, vkInputAttachment->getWidth());
height = std::max(height, vkInputAttachment->getHeight());
}
for (auto colorAttachment : layout.colorAttachments)
{
for (auto colorAttachment : layout.colorAttachments) {
PTexture2D vkColorAttachment = colorAttachment.getTexture().cast<Texture2D>();
attachments.add(vkColorAttachment->getView());
description.colorAttachments[description.numColorAttachments++] = vkColorAttachment->getView();
width = std::max(width, vkColorAttachment->getWidth());
height = std::max(height, vkColorAttachment->getHeight());
}
for (auto resolveAttachment : layout.resolveAttachments)
{
for (auto resolveAttachment : layout.resolveAttachments) {
PTexture2D vkResolveAttachment = resolveAttachment.getTexture().cast<Texture2D>();
attachments.add(vkResolveAttachment->getView());
description.resolveAttachments[description.numResolveAttachments++] = vkResolveAttachment->getView();
width = std::max(width, vkResolveAttachment->getWidth());
height = std::max(height, vkResolveAttachment->getHeight());
}
if (layout.depthAttachment.getTexture() != nullptr)
{
if (layout.depthAttachment.getTexture() != nullptr) {
PTexture2D vkDepthAttachment = layout.depthAttachment.getTexture().cast<Texture2D>();
attachments.add(vkDepthAttachment->getView());
description.depthAttachment = vkDepthAttachment->getView();
width = std::max(width, vkDepthAttachment->getWidth());
height = std::max(height, vkDepthAttachment->getHeight());
}
if (layout.depthResolveAttachment.getTexture() != nullptr)
{
if (layout.depthResolveAttachment.getTexture() != nullptr) {
PTexture2D vkDepthAttachment = layout.depthResolveAttachment.getTexture().cast<Texture2D>();
attachments.add(vkDepthAttachment->getView());
description.depthResolveAttachment = vkDepthAttachment->getView();
@@ -74,8 +67,7 @@ Framebuffer::Framebuffer(PGraphics graphics, PRenderPass renderPass, Gfx::Render
hash = CRC::Calculate(&description, sizeof(FramebufferDescription), CRC::CRC_32());
}
Framebuffer::~Framebuffer()
{
Framebuffer::~Framebuffer() {
vkDestroyFramebuffer(graphics->getDevice(), handle, nullptr);
graphics = nullptr;
}
+8 -18
View File
@@ -3,13 +3,10 @@
#include "Graphics.h"
#include "Graphics/RenderTarget.h"
namespace Seele
{
namespace Vulkan
{
namespace Seele {
namespace Vulkan {
DECLARE_REF(RenderPass)
struct FramebufferDescription
{
struct FramebufferDescription {
StaticArray<VkImageView, 16> inputAttachments;
StaticArray<VkImageView, 16> colorAttachments;
StaticArray<VkImageView, 16> resolveAttachments;
@@ -19,21 +16,14 @@ struct FramebufferDescription
uint32 numColorAttachments;
uint32 numResolveAttachments;
};
class Framebuffer
{
public:
class Framebuffer {
public:
Framebuffer(PGraphics graphics, PRenderPass renderpass, Gfx::RenderTargetLayout renderTargetLayout);
virtual ~Framebuffer();
constexpr VkFramebuffer getHandle() const
{
return handle;
}
constexpr uint32 getHash() const
{
return hash;
}
constexpr VkFramebuffer getHandle() const { return handle; }
constexpr uint32 getHash() const { return hash; }
private:
private:
uint32 hash;
PGraphics graphics;
VkFramebuffer handle;
+138 -253
View File
@@ -1,21 +1,22 @@
#include "Graphics.h"
#include "Debug.h"
#include "Allocator.h"
#include "Buffer.h"
#include "Command.h"
#include "Debug.h"
#include "Descriptor.h"
#include "Framebuffer.h"
#include "Graphics/Enums.h"
#include "Graphics/Graphics.h"
#include "Graphics/Initializer.h"
#include "PipelineCache.h"
#include "Command.h"
#include "Descriptor.h"
#include "Window.h"
#include "RenderPass.h"
#include "Framebuffer.h"
#include "Shader.h"
#include "RayTracing.h"
#include "RenderPass.h"
#include "Shader.h"
#include "Window.h"
#include <GLFW/glfw3.h>
#include <cstring>
#include <vulkan/vulkan_core.h>
#define VMA_IMPLEMENTATION
#include "vk_mem_alloc.h"
@@ -26,16 +27,9 @@ thread_local PCommandPool Seele::Vulkan::Graphics::graphicsCommands = nullptr;
thread_local PCommandPool Seele::Vulkan::Graphics::computeCommands = nullptr;
thread_local PCommandPool Seele::Vulkan::Graphics::transferCommands = nullptr;
Graphics::Graphics()
: instance(VK_NULL_HANDLE)
, handle(VK_NULL_HANDLE)
, physicalDevice(VK_NULL_HANDLE)
, callback(VK_NULL_HANDLE)
{
}
Graphics::Graphics() : instance(VK_NULL_HANDLE), handle(VK_NULL_HANDLE), physicalDevice(VK_NULL_HANDLE), callback(VK_NULL_HANDLE) {}
Graphics::~Graphics()
{
Graphics::~Graphics() {
vkDeviceWaitIdle(handle);
pipelineCache = nullptr;
allocatedFramebuffers.clear();
@@ -49,8 +43,7 @@ Graphics::~Graphics()
vkDestroyInstance(instance, nullptr);
}
void Graphics::init(GraphicsInitializer initInfo)
{
void Graphics::init(GraphicsInitializer initInfo) {
initInstance(initInfo);
#if ENABLE_VALIDATION
setupDebugCallback();
@@ -74,152 +67,102 @@ void Graphics::init(GraphicsInitializer initInfo)
destructionManager = new DestructionManager(this);
}
Gfx::OWindow Graphics::createWindow(const WindowCreateInfo &createInfo)
{
return new Window(this, createInfo);
}
Gfx::OWindow Graphics::createWindow(const WindowCreateInfo& createInfo) { return new Window(this, createInfo); }
Gfx::OViewport Graphics::createViewport(Gfx::PWindow owner, const ViewportCreateInfo &viewportInfo)
{
Gfx::OViewport Graphics::createViewport(Gfx::PWindow owner, const ViewportCreateInfo& viewportInfo) {
return new Viewport(owner, viewportInfo);
}
Gfx::ORenderPass Graphics::createRenderPass(Gfx::RenderTargetLayout layout, Array<Gfx::SubPassDependency> dependencies, Gfx::PViewport renderArea)
{
Gfx::ORenderPass Graphics::createRenderPass(Gfx::RenderTargetLayout layout, Array<Gfx::SubPassDependency> dependencies,
Gfx::PViewport renderArea) {
return new RenderPass(this, std::move(layout), std::move(dependencies), renderArea);
}
void Graphics::beginRenderPass(Gfx::PRenderPass renderPass)
{
void Graphics::beginRenderPass(Gfx::PRenderPass renderPass) {
PRenderPass rp = renderPass.cast<RenderPass>();
uint32 framebufferHash = rp->getFramebufferHash();
PFramebuffer framebuffer;
{
auto found = allocatedFramebuffers.find(framebufferHash);
if (found == allocatedFramebuffers.end())
{
if (found == allocatedFramebuffers.end()) {
allocatedFramebuffers[framebufferHash] = new Framebuffer(this, rp, rp->getLayout());
framebuffer = allocatedFramebuffers[framebufferHash];
}
else
{
} else {
framebuffer = std::move(found->value);
}
}
getGraphicsCommands()->getCommands()->beginRenderPass(rp, framebuffer);
}
void Graphics::endRenderPass()
{
void Graphics::endRenderPass() {
getGraphicsCommands()->getCommands()->endRenderPass();
getGraphicsCommands()->submitCommands();
}
void Graphics::waitDeviceIdle()
{
vkDeviceWaitIdle(handle);
}
void Graphics::waitDeviceIdle() { vkDeviceWaitIdle(handle); }
void Graphics::executeCommands(Array<Gfx::ORenderCommand> commands)
{
void Graphics::executeCommands(Array<Gfx::ORenderCommand> commands) {
getGraphicsCommands()->getCommands()->executeCommands(std::move(commands));
}
void Graphics::executeCommands(Array<Gfx::OComputeCommand> commands)
{
void Graphics::executeCommands(Array<Gfx::OComputeCommand> commands) {
getComputeCommands()->getCommands()->executeCommands(std::move(commands));
}
Gfx::OTexture2D Graphics::createTexture2D(const TextureCreateInfo &createInfo)
{
return new Texture2D(this, createInfo);
}
Gfx::OTexture2D Graphics::createTexture2D(const TextureCreateInfo& createInfo) { return new Texture2D(this, createInfo); }
Gfx::OTexture3D Graphics::createTexture3D(const TextureCreateInfo &createInfo)
{
return new Texture3D(this, createInfo);
}
Gfx::OTexture3D Graphics::createTexture3D(const TextureCreateInfo& createInfo) { return new Texture3D(this, createInfo); }
Gfx::OTextureCube Graphics::createTextureCube(const TextureCreateInfo &createInfo)
{
return new TextureCube(this, createInfo);
}
Gfx::OTextureCube Graphics::createTextureCube(const TextureCreateInfo& createInfo) { return new TextureCube(this, createInfo); }
Gfx::OUniformBuffer Graphics::createUniformBuffer(const UniformBufferCreateInfo &bulkData)
{
return new UniformBuffer(this, bulkData);
}
Gfx::OUniformBuffer Graphics::createUniformBuffer(const UniformBufferCreateInfo& bulkData) { return new UniformBuffer(this, bulkData); }
Gfx::OShaderBuffer Graphics::createShaderBuffer(const ShaderBufferCreateInfo &bulkData)
{
return new ShaderBuffer(this, bulkData);
}
Gfx::OVertexBuffer Graphics::createVertexBuffer(const VertexBufferCreateInfo &bulkData)
{
return new VertexBuffer(this, bulkData);
}
Gfx::OShaderBuffer Graphics::createShaderBuffer(const ShaderBufferCreateInfo& bulkData) { return new ShaderBuffer(this, bulkData); }
Gfx::OVertexBuffer Graphics::createVertexBuffer(const VertexBufferCreateInfo& bulkData) { return new VertexBuffer(this, bulkData); }
Gfx::OIndexBuffer Graphics::createIndexBuffer(const IndexBufferCreateInfo &bulkData)
{
return new IndexBuffer(this, bulkData);
}
Gfx::ORenderCommand Graphics::createRenderCommand(const std::string& name)
{
return getGraphicsCommands()->createRenderCommand(name);
}
Gfx::OIndexBuffer Graphics::createIndexBuffer(const IndexBufferCreateInfo& bulkData) { return new IndexBuffer(this, bulkData); }
Gfx::ORenderCommand Graphics::createRenderCommand(const std::string& name) { return getGraphicsCommands()->createRenderCommand(name); }
Gfx::OComputeCommand Graphics::createComputeCommand(const std::string& name)
{
return getComputeCommands()->createComputeCommand(name);
}
Gfx::OComputeCommand Graphics::createComputeCommand(const std::string& name) { return getComputeCommands()->createComputeCommand(name); }
Gfx::OVertexShader Graphics::createVertexShader(const ShaderCreateInfo& createInfo)
{
Gfx::OVertexShader Graphics::createVertexShader(const ShaderCreateInfo& createInfo) {
OVertexShader shader = new VertexShader(this);
shader->create(createInfo);
return shader;
}
Gfx::OFragmentShader Graphics::createFragmentShader(const ShaderCreateInfo& createInfo)
{
Gfx::OFragmentShader Graphics::createFragmentShader(const ShaderCreateInfo& createInfo) {
OFragmentShader shader = new FragmentShader(this);
shader->create(createInfo);
return shader;
}
Gfx::OComputeShader Graphics::createComputeShader(const ShaderCreateInfo& createInfo)
{
Gfx::OComputeShader Graphics::createComputeShader(const ShaderCreateInfo& createInfo) {
OComputeShader shader = new ComputeShader(this);
shader->create(createInfo);
return shader;
}
Gfx::OTaskShader Graphics::createTaskShader(const ShaderCreateInfo& createInfo)
{
Gfx::OTaskShader Graphics::createTaskShader(const ShaderCreateInfo& createInfo) {
OTaskShader shader = new TaskShader(this);
shader->create(createInfo);
return shader;
}
Gfx::OMeshShader Graphics::createMeshShader(const ShaderCreateInfo& createInfo)
{
Gfx::OMeshShader Graphics::createMeshShader(const ShaderCreateInfo& createInfo) {
OMeshShader shader = new MeshShader(this);
shader->create(createInfo);
return shader;
}
Gfx::PGraphicsPipeline Graphics::createGraphicsPipeline(Gfx::LegacyPipelineCreateInfo createInfo)
{
Gfx::PGraphicsPipeline Graphics::createGraphicsPipeline(Gfx::LegacyPipelineCreateInfo createInfo) {
return pipelineCache->createPipeline(std::move(createInfo));
}
Gfx::PGraphicsPipeline Graphics::createGraphicsPipeline(Gfx::MeshPipelineCreateInfo createInfo)
{
Gfx::PGraphicsPipeline Graphics::createGraphicsPipeline(Gfx::MeshPipelineCreateInfo createInfo) {
return pipelineCache->createPipeline(std::move(createInfo));
}
Gfx::PComputePipeline Graphics::createComputePipeline(Gfx::ComputePipelineCreateInfo createInfo)
{
Gfx::PComputePipeline Graphics::createComputePipeline(Gfx::ComputePipelineCreateInfo createInfo) {
return pipelineCache->createPipeline(std::move(createInfo));
}
Gfx::OSampler Graphics::createSampler(const SamplerCreateInfo& createInfo)
{
Gfx::OSampler Graphics::createSampler(const SamplerCreateInfo& createInfo) {
VkSamplerCreateInfo vkInfo = {
.sType = VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO,
.pNext = nullptr,
@@ -243,87 +186,75 @@ Gfx::OSampler Graphics::createSampler(const SamplerCreateInfo& createInfo)
return new Sampler(this, vkInfo);
}
Gfx::ODescriptorLayout Graphics::createDescriptorLayout(const std::string& name)
{
return new DescriptorLayout(this, name);
}
Gfx::ODescriptorLayout Graphics::createDescriptorLayout(const std::string& name) { return new DescriptorLayout(this, name); }
Gfx::OPipelineLayout Graphics::createPipelineLayout(const std::string& name, Gfx::PPipelineLayout baseLayout)
{
Gfx::OPipelineLayout Graphics::createPipelineLayout(const std::string& name, Gfx::PPipelineLayout baseLayout) {
return new PipelineLayout(this, name, baseLayout);
}
Gfx::OVertexInput Graphics::createVertexInput(VertexInputStateCreateInfo createInfo)
{
return new VertexInput(createInfo);
}
Gfx::OVertexInput Graphics::createVertexInput(VertexInputStateCreateInfo createInfo) { return new VertexInput(createInfo); }
void Graphics::resolveTexture(Gfx::PTexture source, Gfx::PTexture destination)
{
void Graphics::resolveTexture(Gfx::PTexture source, Gfx::PTexture destination) {
PTextureBase sourceTex = source.cast<TextureBase>();
PTextureBase destinationTex = destination.cast<TextureBase>();
VkImageResolve resolve = {
.srcSubresource = VkImageSubresourceLayers {
.aspectMask = sourceTex->getAspect(),
.mipLevel = 0,
.baseArrayLayer = 0,
.layerCount = 1,
},
.srcOffset = VkOffset3D {
.x = 0,
.y = 0,
.z = 0,
},
.dstSubresource = VkImageSubresourceLayers {
.aspectMask = sourceTex->getAspect(),
.mipLevel = 0,
.baseArrayLayer = 0,
.layerCount = 1,
},
.dstOffset = VkOffset3D {
.x = 0,
.y = 0,
.z = 0,
},
.extent = VkExtent3D {
.width = sourceTex->getWidth(),
.height = sourceTex->getHeight(),
.depth = sourceTex->getDepth(),
},
.srcSubresource =
VkImageSubresourceLayers{
.aspectMask = sourceTex->getAspect(),
.mipLevel = 0,
.baseArrayLayer = 0,
.layerCount = 1,
},
.srcOffset =
VkOffset3D{
.x = 0,
.y = 0,
.z = 0,
},
.dstSubresource =
VkImageSubresourceLayers{
.aspectMask = sourceTex->getAspect(),
.mipLevel = 0,
.baseArrayLayer = 0,
.layerCount = 1,
},
.dstOffset =
VkOffset3D{
.x = 0,
.y = 0,
.z = 0,
},
.extent =
VkExtent3D{
.width = sourceTex->getWidth(),
.height = sourceTex->getHeight(),
.depth = sourceTex->getDepth(),
},
};
vkCmdResolveImage(getGraphicsCommands()->getCommands()->getHandle(), sourceTex->getImage(), cast(sourceTex->getLayout()), destinationTex->getImage(), cast(destinationTex->getLayout()), 1, &resolve);
vkCmdResolveImage(getGraphicsCommands()->getCommands()->getHandle(), sourceTex->getImage(), cast(sourceTex->getLayout()),
destinationTex->getImage(), cast(destinationTex->getLayout()), 1, &resolve);
}
Gfx::OBottomLevelAS Graphics::createBottomLevelAccelerationStructure(const Gfx::BottomLevelASCreateInfo& createInfo)
{
Gfx::OBottomLevelAS Graphics::createBottomLevelAccelerationStructure(const Gfx::BottomLevelASCreateInfo& createInfo) {
return new BottomLevelAS(this, createInfo);
}
Gfx::OTopLevelAS Graphics::createTopLevelAccelerationStructure(const Gfx::TopLevelASCreateInfo& createInfo)
{
Gfx::OTopLevelAS Graphics::createTopLevelAccelerationStructure(const Gfx::TopLevelASCreateInfo& createInfo) {
return new TopLevelAS(this, createInfo);
}
void Graphics::vkCmdDrawMeshTasksEXT(VkCommandBuffer cmd, uint32 groupX, uint32 groupY, uint32 groupZ)
{
void Graphics::vkCmdDrawMeshTasksEXT(VkCommandBuffer cmd, uint32 groupX, uint32 groupY, uint32 groupZ) {
cmdDrawMeshTasks(cmd, groupX, groupY, groupZ);
}
void Graphics::vkCmdDrawMeshTasksIndirectEXT(VkCommandBuffer cmd, VkBuffer buffer, uint64 offset, uint32 drawCount, uint32 stride)
{
void Graphics::vkCmdDrawMeshTasksIndirectEXT(VkCommandBuffer cmd, VkBuffer buffer, uint64 offset, uint32 drawCount, uint32 stride) {
cmdDrawMeshTasksIndirect(cmd, buffer, offset, drawCount, stride);
}
void Graphics::vkSetDebugUtilsObjectNameEXT(VkDebugUtilsObjectNameInfoEXT* info)
{
VK_CHECK(setDebugUtilsObjectName(handle, info));
}
void Graphics::vkSetDebugUtilsObjectNameEXT(VkDebugUtilsObjectNameInfoEXT* info) { VK_CHECK(setDebugUtilsObjectName(handle, info)); }
PCommandPool Graphics::getQueueCommands(Gfx::QueueType queueType)
{
switch (queueType)
{
PCommandPool Graphics::getQueueCommands(Gfx::QueueType queueType) {
switch (queueType) {
case Gfx::QueueType::GRAPHICS:
return getGraphicsCommands();
case Gfx::QueueType::COMPUTE:
@@ -334,41 +265,29 @@ PCommandPool Graphics::getQueueCommands(Gfx::QueueType queueType)
throw new std::logic_error("invalid queue type");
}
}
PCommandPool Graphics::getGraphicsCommands()
{
if(graphicsCommands == nullptr)
{
PCommandPool Graphics::getGraphicsCommands() {
if (graphicsCommands == nullptr) {
std::unique_lock l(poolLock);
graphicsCommands = pools.add(new CommandPool(this, queues[graphicsQueue]));
}
return graphicsCommands;
}
PCommandPool Graphics::getComputeCommands()
{
if(computeCommands == nullptr)
{
if(graphicsQueue == computeQueue)
{
PCommandPool Graphics::getComputeCommands() {
if (computeCommands == nullptr) {
if (graphicsQueue == computeQueue) {
computeCommands = getGraphicsCommands();
}
else
{
} else {
std::unique_lock l(poolLock);
computeCommands = pools.add(new CommandPool(this, queues[computeQueue]));
}
}
return computeCommands;
}
PCommandPool Graphics::getTransferCommands()
{
if(transferCommands == nullptr)
{
if(graphicsQueue == transferQueue)
{
PCommandPool Graphics::getTransferCommands() {
if (transferCommands == nullptr) {
if (graphicsQueue == transferQueue) {
transferCommands = getGraphicsCommands();
}
else
{
} else {
std::unique_lock l(poolLock);
transferCommands = pools.add(new CommandPool(this, queues[transferQueue]));
}
@@ -376,25 +295,17 @@ PCommandPool Graphics::getTransferCommands()
return transferCommands;
}
VmaAllocator Graphics::getAllocator()
{
return allocator;
}
VmaAllocator Graphics::getAllocator() { return allocator; }
PDestructionManager Graphics::getDestructionManager()
{
return destructionManager;
}
PDestructionManager Graphics::getDestructionManager() { return destructionManager; }
Array<const char *> Graphics::getRequiredExtensions()
{
Array<const char *> extensions;
Array<const char*> Graphics::getRequiredExtensions() {
Array<const char*> extensions;
unsigned int glfwExtensionCount = 0;
const char **glfwExtensions = glfwGetRequiredInstanceExtensions(&glfwExtensionCount);
const char** glfwExtensions = glfwGetRequiredInstanceExtensions(&glfwExtensionCount);
for (unsigned int i = 0; i < glfwExtensionCount; i++)
{
for (unsigned int i = 0; i < glfwExtensionCount; i++) {
extensions.add(glfwExtensions[i]);
}
#if ENABLE_VALIDATION
@@ -402,8 +313,7 @@ Array<const char *> Graphics::getRequiredExtensions()
#endif // ENABLE_VALIDATION
return extensions;
}
void Graphics::initInstance(GraphicsInitializer initInfo)
{
void Graphics::initInstance(GraphicsInitializer initInfo) {
glfwInit();
assert(glfwVulkanSupported());
VkApplicationInfo appInfo = {
@@ -415,10 +325,9 @@ void Graphics::initInstance(GraphicsInitializer initInfo)
.engineVersion = VK_MAKE_VERSION(0, 0, 1),
.apiVersion = VK_API_VERSION_1_3,
};
Array<const char*> extensions = getRequiredExtensions();
for (uint32 i = 0; i < initInfo.instanceExtensions.size(); ++i)
{
for (uint32 i = 0; i < initInfo.instanceExtensions.size(); ++i) {
extensions.add(initInfo.instanceExtensions[i]);
}
#ifdef __APPLE__
@@ -441,22 +350,21 @@ void Graphics::initInstance(GraphicsInitializer initInfo)
};
VK_CHECK(vkCreateInstance(&info, nullptr, &instance));
}
void Graphics::setupDebugCallback()
{
void Graphics::setupDebugCallback() {
VkDebugUtilsMessengerCreateInfoEXT createInfo = {
.sType = VK_STRUCTURE_TYPE_DEBUG_UTILS_MESSENGER_CREATE_INFO_EXT,
.pNext = nullptr,
.flags = 0,
.messageSeverity = VK_DEBUG_UTILS_MESSAGE_SEVERITY_ERROR_BIT_EXT| VK_DEBUG_UTILS_MESSAGE_SEVERITY_WARNING_BIT_EXT,
.messageType = VK_DEBUG_UTILS_MESSAGE_TYPE_GENERAL_BIT_EXT | VK_DEBUG_UTILS_MESSAGE_TYPE_VALIDATION_BIT_EXT | VK_DEBUG_UTILS_MESSAGE_TYPE_PERFORMANCE_BIT_EXT,
.messageSeverity = VK_DEBUG_UTILS_MESSAGE_SEVERITY_ERROR_BIT_EXT | VK_DEBUG_UTILS_MESSAGE_SEVERITY_WARNING_BIT_EXT,
.messageType = VK_DEBUG_UTILS_MESSAGE_TYPE_GENERAL_BIT_EXT | VK_DEBUG_UTILS_MESSAGE_TYPE_VALIDATION_BIT_EXT |
VK_DEBUG_UTILS_MESSAGE_TYPE_PERFORMANCE_BIT_EXT,
.pfnUserCallback = &debugCallback,
.pUserData = nullptr,
};
VK_CHECK(CreateDebugUtilsMessengerEXT(instance, &createInfo, nullptr, &callback));
}
void Graphics::pickPhysicalDevice()
{
void Graphics::pickPhysicalDevice() {
uint32 physicalDeviceCount;
vkEnumeratePhysicalDevices(instance, &physicalDeviceCount, nullptr);
Array<VkPhysicalDevice> physicalDevices(physicalDeviceCount);
@@ -474,26 +382,21 @@ void Graphics::pickPhysicalDevice()
features12.pNext = &features13;
features13.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_3_FEATURES;
features13.pNext = nullptr;
for (auto dev : physicalDevices)
{
for (auto dev : physicalDevices) {
uint32 currentRating = 0;
vkGetPhysicalDeviceProperties(dev, &props);
vkGetPhysicalDeviceFeatures2(dev, &features);
if (props.deviceType == VK_PHYSICAL_DEVICE_TYPE_DISCRETE_GPU)
{
if (props.deviceType == VK_PHYSICAL_DEVICE_TYPE_DISCRETE_GPU) {
std::cout << "found dedicated gpu " << props.deviceName << std::endl;
currentRating += 100;
}
else if (props.deviceType == VK_PHYSICAL_DEVICE_TYPE_INTEGRATED_GPU)
{
} else if (props.deviceType == VK_PHYSICAL_DEVICE_TYPE_INTEGRATED_GPU) {
std::cout << "found integrated gpu " << props.deviceName << std::endl;
currentRating += 10;
}
if (currentRating > deviceRating)
{
if (currentRating > deviceRating) {
deviceRating = currentRating;
bestDevice = dev;
std::cout << "bestDevice: " << props.deviceName << std::endl;
std::cout << "bestDevice: " << props.deviceName << std::endl;
}
}
physicalDevice = bestDevice;
@@ -501,16 +404,13 @@ void Graphics::pickPhysicalDevice()
vkGetPhysicalDeviceProperties(physicalDevice, &props);
vkGetPhysicalDeviceFeatures2(physicalDevice, &features);
features.features.robustBufferAccess = 0;
if (Gfx::useMeshShading)
{
if (Gfx::useMeshShading) {
uint32 count = 0;
vkEnumerateDeviceExtensionProperties(physicalDevice, NULL, &count, nullptr);
Array<VkExtensionProperties> extensionProps(count);
vkEnumerateDeviceExtensionProperties(physicalDevice, NULL, &count, extensionProps.data());
for (size_t i = 0; i < count; ++i)
{
if (std::strcmp(VK_EXT_MESH_SHADER_EXTENSION_NAME, extensionProps[i].extensionName) == 0)
{
for (size_t i = 0; i < count; ++i) {
if (std::strcmp(VK_EXT_MESH_SHADER_EXTENSION_NAME, extensionProps[i].extensionName) == 0) {
meshShadingEnabled = true;
break;
}
@@ -518,16 +418,14 @@ void Graphics::pickPhysicalDevice()
}
}
void Graphics::createDevice(GraphicsInitializer initializer)
{
void Graphics::createDevice(GraphicsInitializer initializer) {
uint32_t numQueueFamilies = 0;
vkGetPhysicalDeviceQueueFamilyProperties(physicalDevice, &numQueueFamilies, nullptr);
Array<VkQueueFamilyProperties> queueProperties(numQueueFamilies);
vkGetPhysicalDeviceQueueFamilyProperties(physicalDevice, &numQueueFamilies, queueProperties.data());
Array<VkDeviceQueueCreateInfo> queueInfos;
struct QueueCreateInfo
{
struct QueueCreateInfo {
int32 familyIndex = -1;
int32 queueIndex = -1;
};
@@ -535,42 +433,35 @@ void Graphics::createDevice(GraphicsInitializer initializer)
QueueCreateInfo transferQueueInfo;
QueueCreateInfo computeQueueInfo;
uint32 numPriorities = 0;
auto checkFamilyProperty = [](VkQueueFamilyProperties currProps, uint32 checkBit){
auto checkFamilyProperty = [](VkQueueFamilyProperties currProps, uint32 checkBit) {
return (currProps.queueFlags & checkBit) == checkBit;
};
auto updateQueueInfo = [&queueProperties](uint32 familyIndex, QueueCreateInfo& info, uint32& numQueues) {
if(info.familyIndex == -1) {
if(queueProperties[familyIndex].queueCount == numQueues)
{
if (info.familyIndex == -1) {
if (queueProperties[familyIndex].queueCount == numQueues) {
return;
}
info.familyIndex = familyIndex;
info.queueIndex = numQueues++;
}
};
for (uint32 familyIndex = 0; familyIndex < queueProperties.size(); ++familyIndex)
{
for (uint32 familyIndex = 0; familyIndex < queueProperties.size(); ++familyIndex) {
uint32 numQueuesForFamily = 0;
VkQueueFamilyProperties currProps = queueProperties[familyIndex];
if (checkFamilyProperty(currProps, VK_QUEUE_GRAPHICS_BIT))
{
if (checkFamilyProperty(currProps, VK_QUEUE_GRAPHICS_BIT)) {
updateQueueInfo(familyIndex, graphicsQueueInfo, numQueuesForFamily);
}
if(Gfx::useAsyncCompute)
{
if(checkFamilyProperty(currProps, VK_QUEUE_COMPUTE_BIT))
{
if (Gfx::useAsyncCompute) {
if (checkFamilyProperty(currProps, VK_QUEUE_COMPUTE_BIT)) {
updateQueueInfo(familyIndex, computeQueueInfo, numQueuesForFamily);
}
}
if ((currProps.queueFlags ^ VK_QUEUE_TRANSFER_BIT) == 0)
{
if ((currProps.queueFlags ^ VK_QUEUE_TRANSFER_BIT) == 0) {
updateQueueInfo(familyIndex, transferQueueInfo, numQueuesForFamily);
}
if (numQueuesForFamily > 0)
{
if (numQueuesForFamily > 0) {
VkDeviceQueueCreateInfo info = {
.sType = VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO,
.pNext = nullptr,
@@ -585,14 +476,12 @@ void Graphics::createDevice(GraphicsInitializer initializer)
}
Array<float> queuePriorities;
queuePriorities.resize(numPriorities);
float *currentPriority = queuePriorities.data();
for (uint32 index = 0; index < queueInfos.size(); ++index)
{
VkDeviceQueueCreateInfo &currQueue = queueInfos[index];
float* currentPriority = queuePriorities.data();
for (uint32 index = 0; index < queueInfos.size(); ++index) {
VkDeviceQueueCreateInfo& currQueue = queueInfos[index];
currQueue.pQueuePriorities = currentPriority;
for (int32_t queueIndex = 0; queueIndex < (int32_t)currQueue.queueCount; ++queueIndex)
{
for (int32_t queueIndex = 0; queueIndex < (int32_t)currQueue.queueCount; ++queueIndex) {
*currentPriority++ = 1.0f;
}
}
@@ -602,8 +491,7 @@ void Graphics::createDevice(GraphicsInitializer initializer)
.taskShader = VK_TRUE,
.meshShader = VK_TRUE,
};
if (supportMeshShading())
{
if (supportMeshShading()) {
features12.pNext = &enabledMeshShaderFeatures;
initializer.deviceExtensions.add(VK_EXT_MESH_SHADER_EXTENSION_NAME);
}
@@ -621,7 +509,7 @@ void Graphics::createDevice(GraphicsInitializer initializer)
};
VK_CHECK(vkCreateDevice(physicalDevice, &deviceInfo, nullptr, &handle));
//std::cout << "Vulkan handle: " << handle << std::endl;
// std::cout << "Vulkan handle: " << handle << std::endl;
cmdDrawMeshTasks = (PFN_vkCmdDrawMeshTasksEXT)vkGetDeviceProcAddr(handle, "vkCmdDrawMeshTasksEXT");
@@ -629,20 +517,17 @@ void Graphics::createDevice(GraphicsInitializer initializer)
computeQueue = 0;
transferQueue = 0;
queues.add(new Queue(this, graphicsQueueInfo.familyIndex, graphicsQueueInfo.queueIndex));
if(computeQueueInfo.familyIndex != -1)
{
if (computeQueueInfo.familyIndex != -1) {
computeQueue = queues.size();
queues.add(new Queue(this, computeQueueInfo.familyIndex, computeQueueInfo.queueIndex));
}
if(transferQueueInfo.familyIndex != -1)
{
if (transferQueueInfo.familyIndex != -1) {
transferQueue = queues.size();
queues.add(new Queue(this, transferQueueInfo.familyIndex, transferQueueInfo.queueIndex));
}
queueMapping.graphicsFamily = queues[graphicsQueue]->getFamilyIndex();
queueMapping.computeFamily = queues[computeQueue]->getFamilyIndex();
queueMapping.transferFamily = queues[transferQueue]->getFamilyIndex();
setDebugUtilsObjectName = (PFN_vkSetDebugUtilsObjectNameEXT)vkGetInstanceProcAddr(instance, "vkSetDebugUtilsObjectNameEXT");
}
+19 -21
View File
@@ -2,18 +2,15 @@
#include "Graphics/Graphics.h"
#include <vk_mem_alloc.h>
namespace Seele
{
namespace Vulkan
{
namespace Seele {
namespace Vulkan {
DECLARE_REF(DestructionManager)
DECLARE_REF(CommandPool)
DECLARE_REF(Queue)
DECLARE_REF(PipelineCache)
DECLARE_REF(Framebuffer)
class Graphics : public Gfx::Graphics
{
public:
class Graphics : public Gfx::Graphics {
public:
Graphics();
virtual ~Graphics();
constexpr VkInstance getInstance() const { return instance; };
@@ -30,10 +27,11 @@ public:
// Inherited via Graphics
virtual void init(GraphicsInitializer initializer) override;
virtual Gfx::OWindow createWindow(const WindowCreateInfo &createInfo) override;
virtual Gfx::OViewport createViewport(Gfx::PWindow owner, const ViewportCreateInfo &createInfo) override;
virtual Gfx::OWindow createWindow(const WindowCreateInfo& createInfo) override;
virtual Gfx::OViewport createViewport(Gfx::PWindow owner, const ViewportCreateInfo& createInfo) override;
virtual Gfx::ORenderPass createRenderPass(Gfx::RenderTargetLayout layout, Array<Gfx::SubPassDependency> dependencies, Gfx::PViewport renderArea) override;
virtual Gfx::ORenderPass createRenderPass(Gfx::RenderTargetLayout layout, Array<Gfx::SubPassDependency> dependencies,
Gfx::PViewport renderArea) override;
virtual void beginRenderPass(Gfx::PRenderPass renderPass) override;
virtual void endRenderPass() override;
virtual void waitDeviceIdle() override;
@@ -41,17 +39,17 @@ public:
virtual void executeCommands(Array<Gfx::ORenderCommand> commands) override;
virtual void executeCommands(Array<Gfx::OComputeCommand> commands) override;
virtual Gfx::OTexture2D createTexture2D(const TextureCreateInfo &createInfo) override;
virtual Gfx::OTexture3D createTexture3D(const TextureCreateInfo &createInfo) override;
virtual Gfx::OTextureCube createTextureCube(const TextureCreateInfo &createInfo) override;
virtual Gfx::OUniformBuffer createUniformBuffer(const UniformBufferCreateInfo &bulkData) override;
virtual Gfx::OShaderBuffer createShaderBuffer(const ShaderBufferCreateInfo &bulkData) override;
virtual Gfx::OVertexBuffer createVertexBuffer(const VertexBufferCreateInfo &bulkData) override;
virtual Gfx::OIndexBuffer createIndexBuffer(const IndexBufferCreateInfo &bulkData) override;
virtual Gfx::OTexture2D createTexture2D(const TextureCreateInfo& createInfo) override;
virtual Gfx::OTexture3D createTexture3D(const TextureCreateInfo& createInfo) override;
virtual Gfx::OTextureCube createTextureCube(const TextureCreateInfo& createInfo) override;
virtual Gfx::OUniformBuffer createUniformBuffer(const UniformBufferCreateInfo& bulkData) override;
virtual Gfx::OShaderBuffer createShaderBuffer(const ShaderBufferCreateInfo& bulkData) override;
virtual Gfx::OVertexBuffer createVertexBuffer(const VertexBufferCreateInfo& bulkData) override;
virtual Gfx::OIndexBuffer createIndexBuffer(const IndexBufferCreateInfo& bulkData) override;
virtual Gfx::ORenderCommand createRenderCommand(const std::string& name) override;
virtual Gfx::OComputeCommand createComputeCommand(const std::string& name) override;
virtual Gfx::OVertexShader createVertexShader(const ShaderCreateInfo& createInfo) override;
virtual Gfx::OFragmentShader createFragmentShader(const ShaderCreateInfo& createInfo) override;
virtual Gfx::OComputeShader createComputeShader(const ShaderCreateInfo& createInfo) override;
@@ -77,11 +75,11 @@ public:
void vkCmdDrawMeshTasksIndirectEXT(VkCommandBuffer handle, VkBuffer buffer, uint64 offset, uint32 drawCount, uint32 stride);
void vkSetDebugUtilsObjectNameEXT(VkDebugUtilsObjectNameInfoEXT* info);
protected:
protected:
PFN_vkCmdDrawMeshTasksEXT cmdDrawMeshTasks;
PFN_vkCmdDrawMeshTasksIndirectEXT cmdDrawMeshTasksIndirect;
PFN_vkSetDebugUtilsObjectNameEXT setDebugUtilsObjectName;
Array<const char *> getRequiredExtensions();
Array<const char*> getRequiredExtensions();
void initInstance(GraphicsInitializer initInfo);
void setupDebugCallback();
void pickPhysicalDevice();
+11 -41
View File
@@ -5,54 +5,24 @@
using namespace Seele;
using namespace Seele::Vulkan;
VertexInput::VertexInput(VertexInputStateCreateInfo createInfo)
: Gfx::VertexInput(createInfo)
{
}
VertexInput::VertexInput(VertexInputStateCreateInfo createInfo) : Gfx::VertexInput(createInfo) {}
VertexInput::~VertexInput()
{
}
VertexInput::~VertexInput() {}
GraphicsPipeline::GraphicsPipeline(PGraphics graphics, VkPipeline handle, Gfx::PPipelineLayout pipelineLayout)
: Gfx::GraphicsPipeline(std::move(pipelineLayout))
, graphics(graphics)
, pipeline(handle)
{
}
: Gfx::GraphicsPipeline(std::move(pipelineLayout)), graphics(graphics), pipeline(handle) {}
GraphicsPipeline::~GraphicsPipeline()
{
}
GraphicsPipeline::~GraphicsPipeline() {}
void GraphicsPipeline::bind(VkCommandBuffer handle)
{
vkCmdBindPipeline(handle, VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline);
}
void GraphicsPipeline::bind(VkCommandBuffer handle) { vkCmdBindPipeline(handle, VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline); }
VkPipelineLayout GraphicsPipeline::getLayout() const
{
return Gfx::PPipelineLayout(layout).cast<PipelineLayout>()->getHandle();
}
VkPipelineLayout GraphicsPipeline::getLayout() const { return Gfx::PPipelineLayout(layout).cast<PipelineLayout>()->getHandle(); }
ComputePipeline::ComputePipeline(PGraphics graphics, VkPipeline handle, Gfx::PPipelineLayout pipelineLayout)
: Gfx::ComputePipeline(std::move(pipelineLayout))
, graphics(graphics)
, pipeline(handle)
{
}
ComputePipeline::ComputePipeline(PGraphics graphics, VkPipeline handle, Gfx::PPipelineLayout pipelineLayout)
: Gfx::ComputePipeline(std::move(pipelineLayout)), graphics(graphics), pipeline(handle) {}
ComputePipeline::~ComputePipeline()
{
}
ComputePipeline::~ComputePipeline() {}
void ComputePipeline::bind(VkCommandBuffer handle)
{
vkCmdBindPipeline(handle, VK_PIPELINE_BIND_POINT_COMPUTE, pipeline);
}
void ComputePipeline::bind(VkCommandBuffer handle) { vkCmdBindPipeline(handle, VK_PIPELINE_BIND_POINT_COMPUTE, pipeline); }
VkPipelineLayout ComputePipeline::getLayout() const
{
return Gfx::PPipelineLayout(layout).cast<PipelineLayout>()->getHandle();
}
VkPipelineLayout ComputePipeline::getLayout() const { return Gfx::PPipelineLayout(layout).cast<PipelineLayout>()->getHandle(); }
+14 -16
View File
@@ -2,39 +2,37 @@
#include "Enums.h"
#include "Graphics/Pipeline.h"
namespace Seele
{
namespace Vulkan
{
class VertexInput : public Gfx::VertexInput
{
public:
namespace Seele {
namespace Vulkan {
class VertexInput : public Gfx::VertexInput {
public:
VertexInput(VertexInputStateCreateInfo createInfo);
virtual ~VertexInput();
private:
private:
};
DECLARE_REF(PipelineLayout)
DECLARE_REF(Graphics)
class GraphicsPipeline : public Gfx::GraphicsPipeline
{
public:
class GraphicsPipeline : public Gfx::GraphicsPipeline {
public:
GraphicsPipeline(PGraphics graphics, VkPipeline handle, Gfx::PPipelineLayout pipelineLayout);
virtual ~GraphicsPipeline();
void bind(VkCommandBuffer handle);
VkPipelineLayout getLayout() const;
private:
private:
PGraphics graphics;
VkPipeline pipeline;
};
DEFINE_REF(GraphicsPipeline)
class ComputePipeline : public Gfx::ComputePipeline
{
public:
class ComputePipeline : public Gfx::ComputePipeline {
public:
ComputePipeline(PGraphics graphics, VkPipeline handle, Gfx::PPipelineLayout pipelineLayout);
virtual ~ComputePipeline();
void bind(VkCommandBuffer handle);
VkPipelineLayout getLayout() const;
private:
private:
PGraphics graphics;
VkPipeline pipeline;
};
+60 -76
View File
@@ -1,18 +1,16 @@
#include "PipelineCache.h"
#include "Graphics.h"
#include "Enums.h"
#include "RenderPass.h"
#include "Descriptor.h"
#include "Enums.h"
#include "Graphics.h"
#include "RenderPass.h"
#include "Shader.h"
#include <fstream>
using namespace Seele;
using namespace Seele::Vulkan;
PipelineCache::PipelineCache(PGraphics graphics, const std::string& cacheFilePath)
: graphics(graphics)
, cacheFile(cacheFilePath)
{
PipelineCache::PipelineCache(PGraphics graphics, const std::string& cacheFilePath) : graphics(graphics), cacheFile(cacheFilePath) {
std::ifstream stream(cacheFilePath, std::ios::binary | std::ios::ate);
VkPipelineCacheCreateInfo cacheCreateInfo = {
.sType = VK_STRUCTURE_TYPE_PIPELINE_CACHE_CREATE_INFO,
@@ -20,8 +18,7 @@ PipelineCache::PipelineCache(PGraphics graphics, const std::string& cacheFilePat
.flags = 0,
.initialDataSize = 0,
};
if(stream.good())
{
if (stream.good()) {
Array<uint8> cacheData;
uint32 fileSize = static_cast<uint32>(stream.tellg());
cacheData.resize(fileSize);
@@ -34,8 +31,7 @@ PipelineCache::PipelineCache(PGraphics graphics, const std::string& cacheFilePat
VK_CHECK(vkCreatePipelineCache(graphics->getDevice(), &cacheCreateInfo, nullptr, &cache));
}
PipelineCache::~PipelineCache()
{
PipelineCache::~PipelineCache() {
size_t cacheSize;
VK_CHECK(vkGetPipelineCacheData(graphics->getDevice(), cache, &cacheSize, nullptr));
Array<uint8> cacheData(cacheSize);
@@ -48,29 +44,24 @@ PipelineCache::~PipelineCache()
std::cout << "Written " << cacheSize << " bytes to cache" << std::endl;
}
PGraphicsPipeline PipelineCache::createPipeline(Gfx::LegacyPipelineCreateInfo gfxInfo)
{
PGraphicsPipeline PipelineCache::createPipeline(Gfx::LegacyPipelineCreateInfo gfxInfo) {
uint32 hash = CRC::Calculate(&gfxInfo, sizeof(Gfx::LegacyPipelineCreateInfo), CRC::CRC_32());
if (graphicsPipelines.contains(hash))
{
if (graphicsPipelines.contains(hash)) {
return graphicsPipelines[hash];
}
PPipelineLayout layout = Gfx::PPipelineLayout(gfxInfo.pipelineLayout).cast<PipelineLayout>();
Array<VkVertexInputBindingDescription> bindings;
Array<VkVertexInputAttributeDescription> attributes;
if (gfxInfo.vertexInput != nullptr)
{
if (gfxInfo.vertexInput != nullptr) {
const VertexInputStateCreateInfo& vertexInputDesc = gfxInfo.vertexInput->getInfo();
for (const auto& b : vertexInputDesc.bindings)
{
for (const auto& b : vertexInputDesc.bindings) {
bindings.add() = {
.binding = b.binding,
.stride = b.stride,
.inputRate = VkVertexInputRate(b.inputRate),
};
}
for (const auto& a : vertexInputDesc.attributes)
{
for (const auto& a : vertexInputDesc.attributes) {
attributes.add() = {
.location = a.location,
.binding = a.binding,
@@ -104,8 +95,7 @@ PGraphicsPipeline PipelineCache::createPipeline(Gfx::LegacyPipelineCreateInfo gf
.pSpecializationInfo = nullptr,
};
if (gfxInfo.fragmentShader != nullptr)
{
if (gfxInfo.fragmentShader != nullptr) {
PFragmentShader fragment = gfxInfo.fragmentShader.cast<FragmentShader>();
stageInfos[stageCount++] = {
@@ -173,8 +163,7 @@ PGraphicsPipeline PipelineCache::createPipeline(Gfx::LegacyPipelineCreateInfo gf
.maxDepthBounds = gfxInfo.depthStencilState.maxDepthBounds,
};
Array<VkPipelineColorBlendAttachmentState> blendAttachments;
for(uint32 i = 0; i < gfxInfo.colorBlend.attachmentCount; ++i)
{
for (uint32 i = 0; i < gfxInfo.colorBlend.attachmentCount; ++i) {
const Gfx::ColorBlendState::BlendAttachment& attachment = gfxInfo.colorBlend.blendAttachments[i];
blendAttachments.add() = {
.blendEnable = attachment.blendEnable,
@@ -235,31 +224,26 @@ PGraphicsPipeline PipelineCache::createPipeline(Gfx::LegacyPipelineCreateInfo gf
auto endTime = std::chrono::high_resolution_clock::now();
int64 delta = std::chrono::duration_cast<std::chrono::microseconds>(endTime - beginTime).count();
std::cout << "Gfx creation time: " << delta << std::endl;
OGraphicsPipeline pipeline = new GraphicsPipeline(graphics, pipelineHandle, gfxInfo.pipelineLayout);
PGraphicsPipeline result = pipeline;
graphicsPipelines[hash] = std::move(pipeline);
return result;
}
PGraphicsPipeline PipelineCache::createPipeline(Gfx::MeshPipelineCreateInfo gfxInfo)
{
PGraphicsPipeline PipelineCache::createPipeline(Gfx::MeshPipelineCreateInfo gfxInfo) {
uint32 hash = CRC::Calculate(&gfxInfo, sizeof(Gfx::MeshPipelineCreateInfo), CRC::CRC_32());
if (graphicsPipelines.contains(hash))
{
if (graphicsPipelines.contains(hash)) {
return graphicsPipelines[hash];
}
PPipelineLayout layout = Gfx::PPipelineLayout(gfxInfo.pipelineLayout).cast<PipelineLayout>();
//uint32 hash = layout->getHash();
// uint32 hash = layout->getHash();
uint32 stageCount = 0;
VkPipelineShaderStageCreateInfo stageInfos[3];
std::memset(stageInfos, 0, sizeof(stageInfos));
if (gfxInfo.taskShader != nullptr)
{
if (gfxInfo.taskShader != nullptr) {
PTaskShader taskShader = gfxInfo.taskShader.cast<TaskShader>();
stageInfos[stageCount++] = {
.sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,
@@ -283,8 +267,7 @@ PGraphicsPipeline PipelineCache::createPipeline(Gfx::MeshPipelineCreateInfo gfxI
.pSpecializationInfo = nullptr,
};
if (gfxInfo.fragmentShader != nullptr)
{
if (gfxInfo.fragmentShader != nullptr) {
PFragmentShader fragment = gfxInfo.fragmentShader.cast<FragmentShader>();
stageInfos[stageCount++] = {
@@ -297,7 +280,7 @@ PGraphicsPipeline PipelineCache::createPipeline(Gfx::MeshPipelineCreateInfo gfxI
.pSpecializationInfo = nullptr,
};
}
//hash = CRC::Calculate(stageInfos, sizeof(stageInfos), CRC::CRC_32(), hash);
// hash = CRC::Calculate(stageInfos, sizeof(stageInfos), CRC::CRC_32(), hash);
VkPipelineViewportStateCreateInfo viewportInfo = {
.sType = VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO,
@@ -308,7 +291,7 @@ PGraphicsPipeline PipelineCache::createPipeline(Gfx::MeshPipelineCreateInfo gfxI
.scissorCount = 1,
.pScissors = nullptr,
};
//hash = CRC::Calculate(&viewportInfo, sizeof(VkPipelineViewportStateCreateInfo), CRC::CRC_32(), hash);
// hash = CRC::Calculate(&viewportInfo, sizeof(VkPipelineViewportStateCreateInfo), CRC::CRC_32(), hash);
VkPipelineRasterizationStateCreateInfo rasterizationState = {
.sType = VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO,
.pNext = nullptr,
@@ -324,7 +307,7 @@ PGraphicsPipeline PipelineCache::createPipeline(Gfx::MeshPipelineCreateInfo gfxI
.depthBiasSlopeFactor = gfxInfo.rasterizationState.depthBiasSlopeFactor,
.lineWidth = 0,
};
//hash = CRC::Calculate(&rasterizationState, sizeof(VkPipelineRasterizationStateCreateInfo), CRC::CRC_32(), hash);
// hash = CRC::Calculate(&rasterizationState, sizeof(VkPipelineRasterizationStateCreateInfo), CRC::CRC_32(), hash);
VkPipelineMultisampleStateCreateInfo multisampleState = {
.sType = VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO,
@@ -337,7 +320,7 @@ PGraphicsPipeline PipelineCache::createPipeline(Gfx::MeshPipelineCreateInfo gfxI
.alphaToCoverageEnable = gfxInfo.multisampleState.alphaCoverageEnable,
.alphaToOneEnable = gfxInfo.multisampleState.alphaToOneEnable,
};
//hash = CRC::Calculate(&multisampleState, sizeof(VkPipelineMultisampleStateCreateInfo), CRC::CRC_32(), hash);
// hash = CRC::Calculate(&multisampleState, sizeof(VkPipelineMultisampleStateCreateInfo), CRC::CRC_32(), hash);
VkPipelineDepthStencilStateCreateInfo depthStencilState = {
.sType = VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO,
@@ -348,32 +331,33 @@ PGraphicsPipeline PipelineCache::createPipeline(Gfx::MeshPipelineCreateInfo gfxI
.depthCompareOp = cast(gfxInfo.depthStencilState.depthCompareOp),
.depthBoundsTestEnable = gfxInfo.depthStencilState.depthBoundsTestEnable,
.stencilTestEnable = gfxInfo.depthStencilState.stencilTestEnable,
.front = VkStencilOpState{
.failOp = VK_STENCIL_OP_ZERO,
.passOp = (VkStencilOp)gfxInfo.depthStencilState.front,
.depthFailOp = VK_STENCIL_OP_ZERO,
.compareOp = VK_COMPARE_OP_ALWAYS,
.compareMask = 0,
.writeMask = 0,
.reference = 0,
},
.back = VkStencilOpState{
.failOp = VK_STENCIL_OP_ZERO,
.passOp = (VkStencilOp)gfxInfo.depthStencilState.back,
.depthFailOp = VK_STENCIL_OP_ZERO,
.compareOp = VK_COMPARE_OP_ALWAYS,
.compareMask = 0,
.writeMask = 0,
.reference = 0,
},
.front =
VkStencilOpState{
.failOp = VK_STENCIL_OP_ZERO,
.passOp = (VkStencilOp)gfxInfo.depthStencilState.front,
.depthFailOp = VK_STENCIL_OP_ZERO,
.compareOp = VK_COMPARE_OP_ALWAYS,
.compareMask = 0,
.writeMask = 0,
.reference = 0,
},
.back =
VkStencilOpState{
.failOp = VK_STENCIL_OP_ZERO,
.passOp = (VkStencilOp)gfxInfo.depthStencilState.back,
.depthFailOp = VK_STENCIL_OP_ZERO,
.compareOp = VK_COMPARE_OP_ALWAYS,
.compareMask = 0,
.writeMask = 0,
.reference = 0,
},
.minDepthBounds = gfxInfo.depthStencilState.minDepthBounds,
.maxDepthBounds = gfxInfo.depthStencilState.maxDepthBounds,
};
//hash = CRC::Calculate(&depthStencilState, sizeof(VkPipelineDepthStencilStateCreateInfo), CRC::CRC_32(), hash);
// hash = CRC::Calculate(&depthStencilState, sizeof(VkPipelineDepthStencilStateCreateInfo), CRC::CRC_32(), hash);
Array<VkPipelineColorBlendAttachmentState> blendAttachments;
for (uint32 i = 0; i < gfxInfo.colorBlend.attachmentCount; ++i)
{
for (uint32 i = 0; i < gfxInfo.colorBlend.attachmentCount; ++i) {
const Gfx::ColorBlendState::BlendAttachment& attachment = gfxInfo.colorBlend.blendAttachments[i];
blendAttachments.add() = {
.blendEnable = attachment.blendEnable,
@@ -386,7 +370,8 @@ PGraphicsPipeline PipelineCache::createPipeline(Gfx::MeshPipelineCreateInfo gfxI
.colorWriteMask = attachment.colorWriteMask,
};
}
//hash = CRC::Calculate(blendAttachments.data(), blendAttachments.size() * sizeof(VkPipelineColorBlendAttachmentState), CRC::CRC_32(), hash);
// hash = CRC::Calculate(blendAttachments.data(), blendAttachments.size() * sizeof(VkPipelineColorBlendAttachmentState), CRC::CRC_32(),
// hash);
VkPipelineColorBlendStateCreateInfo blendState = {
.sType = VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO,
@@ -403,7 +388,7 @@ PGraphicsPipeline PipelineCache::createPipeline(Gfx::MeshPipelineCreateInfo gfxI
StaticArray<VkDynamicState, 2> dynamicEnabled;
dynamicEnabled[numDynamicEnabled++] = VK_DYNAMIC_STATE_VIEWPORT;
dynamicEnabled[numDynamicEnabled++] = VK_DYNAMIC_STATE_SCISSOR;
//hash = CRC::Calculate(dynamicEnabled.data(), sizeof(dynamicEnabled), CRC::CRC_32(), hash);
// hash = CRC::Calculate(dynamicEnabled.data(), sizeof(dynamicEnabled), CRC::CRC_32(), hash);
VkPipelineDynamicStateCreateInfo dynamicState = {
.sType = VK_STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO,
@@ -443,9 +428,7 @@ PGraphicsPipeline PipelineCache::createPipeline(Gfx::MeshPipelineCreateInfo gfxI
return result;
}
PComputePipeline PipelineCache::createPipeline(Gfx::ComputePipelineCreateInfo computeInfo)
{
PComputePipeline PipelineCache::createPipeline(Gfx::ComputePipelineCreateInfo computeInfo) {
PPipelineLayout layout = Gfx::PPipelineLayout(computeInfo.pipelineLayout).cast<PipelineLayout>();
auto computeStage = computeInfo.computeShader.cast<ComputeShader>();
@@ -455,20 +438,21 @@ PComputePipeline PipelineCache::createPipeline(Gfx::ComputePipelineCreateInfo co
.sType = VK_STRUCTURE_TYPE_COMPUTE_PIPELINE_CREATE_INFO,
.pNext = 0,
.flags = 0,
.stage = {
.sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,
.pNext = nullptr,
.flags = 0,
.stage = VK_SHADER_STAGE_COMPUTE_BIT,
.module = computeStage->getModuleHandle(),
.pName = computeStage->getEntryPointName(),
},
.stage =
{
.sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,
.pNext = nullptr,
.flags = 0,
.stage = VK_SHADER_STAGE_COMPUTE_BIT,
.module = computeStage->getModuleHandle(),
.pName = computeStage->getEntryPointName(),
},
.layout = layout->getHandle(),
.basePipelineHandle = VK_NULL_HANDLE,
.basePipelineIndex = 0,
};
hash = CRC::Calculate(&createInfo, sizeof(createInfo), CRC::CRC_32(), hash);
VkPipeline pipelineHandle;
auto beginTime = std::chrono::high_resolution_clock::now();
VK_CHECK(vkCreateComputePipelines(graphics->getDevice(), cache, 1, &createInfo, nullptr, &pipelineHandle));
+6 -8
View File
@@ -1,19 +1,17 @@
#pragma once
#include "Pipeline.h"
namespace Seele
{
namespace Vulkan
{
class PipelineCache
{
public:
namespace Seele {
namespace Vulkan {
class PipelineCache {
public:
PipelineCache(PGraphics graphics, const std::string& cacheFilePath);
~PipelineCache();
PGraphicsPipeline createPipeline(Gfx::LegacyPipelineCreateInfo createInfo);
PGraphicsPipeline createPipeline(Gfx::MeshPipelineCreateInfo createInfo);
PComputePipeline createPipeline(Gfx::ComputePipelineCreateInfo createInfo);
private:
private:
Map<uint32, OGraphicsPipeline> graphicsPipelines;
Map<uint32, OComputePipeline> computePipelines;
std::mutex cacheLock;
+9 -16
View File
@@ -1,27 +1,22 @@
#include "Queue.h"
#include "Graphics.h"
#include "Allocator.h"
#include "Command.h"
#include "Enums.h"
#include "Graphics.h"
using namespace Seele;
using namespace Seele::Vulkan;
static constexpr bool waitIdleOnSubmit = false;
Queue::Queue(PGraphics graphics, uint32 familyIndex, uint32 queueIndex)
: graphics(graphics)
, familyIndex(familyIndex)
{
Queue::Queue(PGraphics graphics, uint32 familyIndex, uint32 queueIndex) : graphics(graphics), familyIndex(familyIndex) {
vkGetDeviceQueue(graphics->getDevice(), familyIndex, queueIndex, &queue);
}
Queue::~Queue()
{
}
Queue::~Queue() {}
void Queue::submitCommandBuffer(PCommand command, const Array<VkSemaphore>& signalSemaphores)
{
void Queue::submitCommandBuffer(PCommand command, const Array<VkSemaphore>& signalSemaphores) {
std::unique_lock lock(queueLock);
assert(command->state == Command::State::End);
@@ -30,11 +25,10 @@ void Queue::submitCommandBuffer(PCommand command, const Array<VkSemaphore>& sign
VkCommandBuffer cmdHandle = command->handle;
Array<VkSemaphore> waitSemaphores;
for (PSemaphore semaphore : command->waitSemaphores)
{
for (PSemaphore semaphore : command->waitSemaphores) {
waitSemaphores.add(semaphore->getHandle());
}
VkSubmitInfo submitInfo = {
.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO,
.pNext = nullptr,
@@ -46,15 +40,14 @@ void Queue::submitCommandBuffer(PCommand command, const Array<VkSemaphore>& sign
.signalSemaphoreCount = static_cast<uint32>(signalSemaphores.size()),
.pSignalSemaphores = signalSemaphores.data(),
};
VK_CHECK(vkQueueSubmit(queue, 1, &submitInfo, command->fence->getHandle()));
command->fence->submit();
command->state = Command::State::Submit;
command->waitFlags.clear();
command->waitSemaphores.clear();
if (waitIdleOnSubmit)
{
if (waitIdleOnSubmit) {
command->fence->wait(1000 * 1000ull);
}
+7 -16
View File
@@ -1,28 +1,19 @@
#pragma once
#include "Resources.h"
namespace Seele
{
namespace Vulkan
{
namespace Seele {
namespace Vulkan {
DECLARE_REF(Command)
DECLARE_REF(Graphics)
class Queue
{
public:
class Queue {
public:
Queue(PGraphics graphics, uint32 familyIndex, uint32 queueIndex);
virtual ~Queue();
void submitCommandBuffer(PCommand command, const Array<VkSemaphore>& signalSemaphore);
constexpr uint32 getFamilyIndex() const
{
return familyIndex;
}
constexpr VkQueue getHandle() const
{
return queue;
}
constexpr uint32 getFamilyIndex() const { return familyIndex; }
constexpr VkQueue getHandle() const { return queue; }
private:
private:
std::mutex queueLock;
PGraphics graphics;
VkQueue queue;
+28 -33
View File
@@ -1,41 +1,45 @@
#include "RayTracing.h"
#include "Buffer.h"
#include "Graphics/Buffer.h"
#include "Graphics/Initializer.h"
#include "Graphics/Mesh.h"
#include "Graphics/VertexData.h"
#include <vulkan/vulkan_core.h>
using namespace Seele::Vulkan;
BottomLevelAS::BottomLevelAS(PGraphics graphics, const Gfx::BottomLevelASCreateInfo& createInfo)
{
BottomLevelAS::BottomLevelAS(PGraphics graphics, const Gfx::BottomLevelASCreateInfo& createInfo) : graphics(graphics) {
VertexData* vertexData = createInfo.mesh->vertexData;
Gfx::PShaderBuffer positionBuffer = vertexData->getPositionBuffer();
Gfx::PIndexBuffer indexBuffer = vertexData->getIndexBuffer();
VkDeviceOrHostAddressConstKHR vertexDataDeviceAddress = {
.deviceAddress = createInfo.positionBuffer.cast<Buffer>()->getDeviceAddress() + createInfo.verticesOffset,
.deviceAddress = positionBuffer.cast<Buffer>()->getDeviceAddress(),
};
VkDeviceOrHostAddressConstKHR indexDataDeviceAddress = {
.deviceAddress = createInfo.indexBuffer.cast<Buffer>()->getDeviceAddress() + createInfo.indicesOffset,
.deviceAddress = indexBuffer.cast<Buffer>()->getDeviceAddress(),
};
VkAccelerationStructureGeometryKHR accelerationStructureGeometry = {
.sType = VK_STRUCTURE_TYPE_ACCELERATION_STRUCTURE_GEOMETRY_KHR,
.pNext = nullptr,
.geometryType = VK_GEOMETRY_TYPE_TRIANGLES_KHR,
.geometry = {.triangles = {
.sType = VK_STRUCTURE_TYPE_ACCELERATION_STRUCTURE_GEOMETRY_TRIANGLES_DATA_KHR,
.pNext = nullptr,
.vertexFormat = VK_FORMAT_R32G32B32_SFLOAT,
.vertexData = vertexDataDeviceAddress,
.vertexStride = sizeof(Vector),
.maxVertex = createInfo.positionBuffer->getNumElements(),
.indexType = VK_INDEX_TYPE_UINT32,
.indexData = indexDataDeviceAddress,
}},
.geometry = {.triangles =
{
.sType = VK_STRUCTURE_TYPE_ACCELERATION_STRUCTURE_GEOMETRY_TRIANGLES_DATA_KHR,
.pNext = nullptr,
.vertexFormat = VK_FORMAT_R32G32B32_SFLOAT,
.vertexData = vertexDataDeviceAddress,
.vertexStride = sizeof(Vector),
.maxVertex = static_cast<uint32_t>(createInfo.mesh->vertexCount),
.indexType = VK_INDEX_TYPE_UINT32,
.indexData = indexDataDeviceAddress,
}},
.flags = VK_GEOMETRY_OPAQUE_BIT_KHR,
};
VkAccelerationStructureBuildRangeInfoKHR buildRangeInfo = {
.primitiveCount = createInfo.meshData.numIndices / 3,
.primitiveOffset = 0,
.firstVertex = 0,
.transformOffset = 0
};
VkAccelerationStructureBuildRangeInfoKHR buildRangeInfo = {.primitiveCount = static_cast<uint32_t>(createInfo.mesh->indices.size()),
.primitiveOffset = 0,
.firstVertex = 0,
.transformOffset = 0};
VkAccelerationStructureBuildGeometryInfoKHR buildGeometry = {
.sType = VK_STRUCTURE_TYPE_ACCELERATION_STRUCTURE_BUILD_GEOMETRY_INFO_KHR,
@@ -51,17 +55,8 @@ BottomLevelAS::BottomLevelAS(PGraphics graphics, const Gfx::BottomLevelASCreateI
};
}
BottomLevelAS::~BottomLevelAS()
{
BottomLevelAS::~BottomLevelAS() {}
}
TopLevelAS::TopLevelAS(PGraphics graphics, const Gfx::TopLevelASCreateInfo& createInfo) {}
TopLevelAS::TopLevelAS(PGraphics graphics, const Gfx::TopLevelASCreateInfo& createInfo)
{
}
TopLevelAS::~TopLevelAS()
{
}
TopLevelAS::~TopLevelAS() {}
+14 -15
View File
@@ -1,32 +1,31 @@
#pragma once
#include "Graphics/Initializer.h"
#include "Graphics.h"
#include "Graphics/Initializer.h"
#include "Graphics/RayTracing.h"
#include <vulkan/vulkan_core.h>
namespace Seele
{
namespace Vulkan
{
class BottomLevelAS : public Gfx::BottomLevelAS
{
public:
namespace Seele {
namespace Vulkan {
class BottomLevelAS : public Gfx::BottomLevelAS {
public:
BottomLevelAS(PGraphics graphics, const Gfx::BottomLevelASCreateInfo& createInfo);
~BottomLevelAS();
private:
private:
PGraphics graphics;
VkAccelerationStructureKHR handle;
};
DEFINE_REF(BottomLevelAS)
class TopLevelAS : public Gfx::TopLevelAS
{
public:
class TopLevelAS : public Gfx::TopLevelAS {
public:
TopLevelAS(PGraphics graphics, const Gfx::TopLevelASCreateInfo& createInfo);
~TopLevelAS();
private:
private:
PGraphics graphics;
VkAccelerationStructureKHR handle;
};
DEFINE_REF(TopLevelAS)
}
}
} // namespace Vulkan
} // namespace Seele
+31 -48
View File
@@ -1,18 +1,18 @@
#include "RenderPass.h"
#include "Graphics.h"
#include "Framebuffer.h"
#include "Texture.h"
#include "Resources.h"
#include "Command.h"
#include "CRC.h"
#include "Command.h"
#include "Framebuffer.h"
#include "Graphics.h"
#include "Resources.h"
#include "Texture.h"
using namespace Seele;
using namespace Seele::Vulkan;
RenderPass::RenderPass(PGraphics graphics, Gfx::RenderTargetLayout _layout, Array<Gfx::SubPassDependency> _dependencies, Gfx::PViewport viewport)
: Gfx::RenderPass(std::move(_layout), std::move(_dependencies))
, graphics(graphics)
{
RenderPass::RenderPass(PGraphics graphics, Gfx::RenderTargetLayout _layout, Array<Gfx::SubPassDependency> _dependencies,
Gfx::PViewport viewport)
: Gfx::RenderPass(std::move(_layout), std::move(_dependencies)), graphics(graphics) {
renderArea.extent.width = viewport->getWidth();
renderArea.extent.height = viewport->getHeight();
renderArea.offset.x = viewport->getOffsetX();
@@ -26,8 +26,7 @@ RenderPass::RenderPass(PGraphics graphics, Gfx::RenderTargetLayout _layout, Arra
VkAttachmentReference2 depthResolveRef;
uint32 attachmentCounter = 0;
for (auto& inputAttachment : layout.inputAttachments)
{
for (auto& inputAttachment : layout.inputAttachments) {
PTexture2D image = inputAttachment.getTexture().cast<Texture2D>();
VkAttachmentDescription2& desc = attachments.add() = {
.sType = VK_STRUCTURE_TYPE_ATTACHMENT_DESCRIPTION_2,
@@ -41,14 +40,13 @@ RenderPass::RenderPass(PGraphics graphics, Gfx::RenderTargetLayout _layout, Arra
.initialLayout = cast(inputAttachment.getInitialLayout()),
.finalLayout = cast(inputAttachment.getFinalLayout()),
};
inputRefs.add() = {
.attachment = attachmentCounter++,
.layout = desc.initialLayout,
};
}
for (auto& colorAttachment : layout.colorAttachments)
{
for (auto& colorAttachment : layout.colorAttachments) {
attachments.add() = {
.sType = VK_STRUCTURE_TYPE_ATTACHMENT_DESCRIPTION_2,
.pNext = nullptr,
@@ -62,10 +60,9 @@ RenderPass::RenderPass(PGraphics graphics, Gfx::RenderTargetLayout _layout, Arra
.initialLayout = cast(colorAttachment.getInitialLayout()),
.finalLayout = cast(colorAttachment.getFinalLayout()),
};
VkClearValue& clearValue = clearValues.add();
if(attachments.back().loadOp == VK_ATTACHMENT_LOAD_OP_CLEAR)
{
if (attachments.back().loadOp == VK_ATTACHMENT_LOAD_OP_CLEAR) {
clearValue = cast(colorAttachment.clear);
}
@@ -76,8 +73,7 @@ RenderPass::RenderPass(PGraphics graphics, Gfx::RenderTargetLayout _layout, Arra
.layout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
};
}
for (auto& resolveAttachment : layout.resolveAttachments)
{
for (auto& resolveAttachment : layout.resolveAttachments) {
attachments.add() = {
.sType = VK_STRUCTURE_TYPE_ATTACHMENT_DESCRIPTION_2,
.pNext = nullptr,
@@ -93,8 +89,7 @@ RenderPass::RenderPass(PGraphics graphics, Gfx::RenderTargetLayout _layout, Arra
};
VkClearValue& clearValue = clearValues.add();
if (attachments.back().loadOp == VK_ATTACHMENT_LOAD_OP_CLEAR)
{
if (attachments.back().loadOp == VK_ATTACHMENT_LOAD_OP_CLEAR) {
clearValue = cast(resolveAttachment.clear);
}
@@ -105,8 +100,7 @@ RenderPass::RenderPass(PGraphics graphics, Gfx::RenderTargetLayout _layout, Arra
.layout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
};
}
if (layout.depthAttachment.getTexture() != nullptr)
{
if (layout.depthAttachment.getTexture() != nullptr) {
PTexture2D image = layout.depthAttachment.getTexture().cast<Texture2D>();
attachments.add() = {
.sType = VK_STRUCTURE_TYPE_ATTACHMENT_DESCRIPTION_2,
@@ -123,8 +117,7 @@ RenderPass::RenderPass(PGraphics graphics, Gfx::RenderTargetLayout _layout, Arra
};
VkClearValue& clearValue = clearValues.add();
if (attachments.back().loadOp == VK_ATTACHMENT_LOAD_OP_CLEAR)
{
if (attachments.back().loadOp == VK_ATTACHMENT_LOAD_OP_CLEAR) {
clearValue = cast(layout.depthAttachment.clear);
}
@@ -135,8 +128,7 @@ RenderPass::RenderPass(PGraphics graphics, Gfx::RenderTargetLayout _layout, Arra
.layout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL,
};
}
if (layout.depthResolveAttachment.getTexture() != nullptr)
{
if (layout.depthResolveAttachment.getTexture() != nullptr) {
PTexture2D image = layout.depthResolveAttachment.getTexture().cast<Texture2D>();
attachments.add() = {
.sType = VK_STRUCTURE_TYPE_ATTACHMENT_DESCRIPTION_2,
@@ -158,7 +150,7 @@ RenderPass::RenderPass(PGraphics graphics, Gfx::RenderTargetLayout _layout, Arra
.layout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL,
};
}
VkSubpassDescriptionDepthStencilResolve depthResolve = {
.sType = VK_STRUCTURE_TYPE_SUBPASS_DESCRIPTION_DEPTH_STENCIL_RESOLVE,
.pNext = nullptr,
@@ -179,7 +171,7 @@ RenderPass::RenderPass(PGraphics graphics, Gfx::RenderTargetLayout _layout, Arra
.pDepthStencilAttachment = &depthRef,
};
Array<VkSubpassDependency2> dep;
for(const auto& d : dependencies) {
for (const auto& d : dependencies) {
dep.add() = {
.sType = VK_STRUCTURE_TYPE_SUBPASS_DEPENDENCY_2,
.pNext = nullptr,
@@ -206,48 +198,39 @@ RenderPass::RenderPass(PGraphics graphics, Gfx::RenderTargetLayout _layout, Arra
VK_CHECK(vkCreateRenderPass2(graphics->getDevice(), &info, nullptr, &renderPass));
}
RenderPass::~RenderPass()
{
RenderPass::~RenderPass() {
vkDestroyRenderPass(graphics->getDevice(), renderPass, nullptr);
//graphics->getDestructionManager()->queueRenderPass(graphics->getGraphicsCommands()->getCommands(), renderPass);
// graphics->getDestructionManager()->queueRenderPass(graphics->getGraphicsCommands()->getCommands(), renderPass);
}
uint32 RenderPass::getFramebufferHash()
{
uint32 RenderPass::getFramebufferHash() {
FramebufferDescription description;
std::memset(&description, 0, sizeof(FramebufferDescription));
for (auto& inputAttachment : layout.inputAttachments)
{
for (auto& inputAttachment : layout.inputAttachments) {
PTexture2D tex = inputAttachment.getTexture().cast<Texture2D>();
description.inputAttachments[description.numInputAttachments++] = tex->getView();
}
for (auto& colorAttachment : layout.colorAttachments)
{
for (auto& colorAttachment : layout.colorAttachments) {
PTexture2D tex = colorAttachment.getTexture().cast<Texture2D>();
description.colorAttachments[description.numColorAttachments++] = tex->getView();
}
if (layout.depthAttachment.getTexture() != nullptr)
{
if (layout.depthAttachment.getTexture() != nullptr) {
PTexture2D tex = layout.depthAttachment.getTexture().cast<Texture2D>();
description.depthAttachment = tex->getView();
}
return CRC::Calculate(&description, sizeof(FramebufferDescription), CRC::CRC_32());
}
void Vulkan::RenderPass::endRenderPass()
{
for (auto& inputAttachment : layout.inputAttachments)
{
void Vulkan::RenderPass::endRenderPass() {
for (auto& inputAttachment : layout.inputAttachments) {
PTexture2D tex = inputAttachment.getTexture().cast<Texture2D>();
tex->setLayout(inputAttachment.getFinalLayout());
}
for (auto& colorAttachment : layout.colorAttachments)
{
for (auto& colorAttachment : layout.colorAttachments) {
PTexture2D tex = colorAttachment.getTexture().cast<Texture2D>();
tex->setLayout(colorAttachment.getFinalLayout());
}
if (layout.depthAttachment.getTexture() != nullptr)
{
if (layout.depthAttachment.getTexture() != nullptr) {
PTexture2D tex = layout.depthAttachment.getTexture().cast<Texture2D>();
tex->setLayout(layout.depthAttachment.getFinalLayout());
}
+13 -29
View File
@@ -1,39 +1,23 @@
#pragma once
#include "Graphics/RenderTarget.h"
#include "Graphics.h"
#include "Graphics/RenderTarget.h"
namespace Seele
{
namespace Vulkan
{
class RenderPass : public Gfx::RenderPass
{
public:
namespace Seele {
namespace Vulkan {
class RenderPass : public Gfx::RenderPass {
public:
RenderPass(PGraphics graphics, Gfx::RenderTargetLayout layout, Array<Gfx::SubPassDependency> dependencies, Gfx::PViewport viewport);
virtual ~RenderPass();
uint32 getFramebufferHash();
void endRenderPass();
constexpr VkRenderPass getHandle() const
{
return renderPass;
}
constexpr size_t getClearValueCount() const
{
return clearValues.size();
}
constexpr VkClearValue *getClearValues() const
{
return clearValues.data();
}
constexpr VkRect2D getRenderArea() const
{
return renderArea;
}
constexpr VkSubpassContents getSubpassContents() const
{
return subpassContents;
}
private:
constexpr VkRenderPass getHandle() const { return renderPass; }
constexpr size_t getClearValueCount() const { return clearValues.size(); }
constexpr VkClearValue* getClearValues() const { return clearValues.data(); }
constexpr VkRect2D getRenderArea() const { return renderArea; }
constexpr VkSubpassContents getSubpassContents() const { return subpassContents; }
private:
PGraphics graphics;
VkRenderPass renderPass;
Array<VkClearValue> clearValues;
+30 -77
View File
@@ -1,15 +1,14 @@
#include "Resources.h"
#include "Command.h"
#include "Enums.h"
#include "Graphics.h"
#include "Command.h"
#include "Window.h"
using namespace Seele;
using namespace Seele::Vulkan;
Semaphore::Semaphore(PGraphics graphics)
: graphics(graphics)
{
Semaphore::Semaphore(PGraphics graphics) : graphics(graphics) {
VkSemaphoreCreateInfo info = {
.sType = VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO,
.pNext = nullptr,
@@ -18,129 +17,83 @@ Semaphore::Semaphore(PGraphics graphics)
VK_CHECK(vkCreateSemaphore(graphics->getDevice(), &info, nullptr, &handle));
}
Semaphore::~Semaphore()
{
Semaphore::~Semaphore() {
// graphics->getDestructionManager()->queueSemaphore(graphics->getGraphicsCommands()->getCommands(), handle);
}
Fence::Fence(PGraphics graphics)
: graphics(graphics), status(Status::Ready)
{
VkFenceCreateInfo info = {
.sType = VK_STRUCTURE_TYPE_FENCE_CREATE_INFO,
.pNext = nullptr,
.flags = 0};
Fence::Fence(PGraphics graphics) : graphics(graphics), status(Status::Ready) {
VkFenceCreateInfo info = {.sType = VK_STRUCTURE_TYPE_FENCE_CREATE_INFO, .pNext = nullptr, .flags = 0};
VK_CHECK(vkCreateFence(graphics->getDevice(), &info, nullptr, &fence));
}
Fence::~Fence()
{
Fence::~Fence() {
vkWaitForFences(graphics->getDevice(), 1, &fence, true, 10000000);
vkDestroyFence(graphics->getDevice(), fence, nullptr);
}
void Fence::submit()
{
status = Status::InUse;
}
void Fence::submit() { status = Status::InUse; }
bool Fence::isSignaled()
{
if (status == Status::Signalled)
{
bool Fence::isSignaled() {
if (status == Status::Signalled) {
return true;
}
VkResult r = vkGetFenceStatus(graphics->getDevice(), fence);
if (r == VK_SUCCESS)
{
if (r == VK_SUCCESS) {
status = Status::Signalled;
return true;
}
if (r == VK_NOT_READY)
{
if (r == VK_NOT_READY) {
return false;
}
else
{
} else {
VK_CHECK(r);
return false;
}
}
void Fence::reset()
{
while (status == Status::InUse)
{
void Fence::reset() {
while (status == Status::InUse) {
wait(1000000);
}
if (status == Status::Signalled)
{
if (status == Status::Signalled) {
VK_CHECK(vkResetFences(graphics->getDevice(), 1, &fence));
status = Status::Ready;
}
}
void Fence::wait(uint64 timeout)
{
void Fence::wait(uint64 timeout) {
VkFence fences[] = {fence};
VkResult r = vkWaitForFences(graphics->getDevice(), 1, fences, true, timeout);
if (r == VK_SUCCESS)
{
if (r == VK_SUCCESS) {
status = Status::Signalled;
}
else if (r == VK_TIMEOUT)
{
} else if (r == VK_TIMEOUT) {
return;
}
else if (r != VK_NOT_READY)
{
} else if (r != VK_NOT_READY) {
VK_CHECK(r);
}
}
DestructionManager::DestructionManager(PGraphics graphics)
: graphics(graphics)
{
}
DestructionManager::DestructionManager(PGraphics graphics) : graphics(graphics) {}
DestructionManager::~DestructionManager()
{
}
DestructionManager::~DestructionManager() {}
void DestructionManager::queueResourceForDestruction(OCommandBoundResource resource)
{
resources.add(std::move(resource));
}
void DestructionManager::queueResourceForDestruction(OCommandBoundResource resource) { resources.add(std::move(resource)); }
void DestructionManager::notifyCommandComplete()
{
for (size_t i = 0; i < resources.size(); ++i)
{
if (!resources[i]->isCurrentlyBound())
{
void DestructionManager::notifyCommandComplete() {
for (size_t i = 0; i < resources.size(); ++i) {
if (!resources[i]->isCurrentlyBound()) {
resources.removeAt(i, false);
i--;
}
}
}
SamplerHandle::SamplerHandle(PGraphics graphics, VkSamplerCreateInfo createInfo)
: CommandBoundResource(graphics)
{
SamplerHandle::SamplerHandle(PGraphics graphics, VkSamplerCreateInfo createInfo) : CommandBoundResource(graphics) {
vkCreateSampler(graphics->getDevice(), &createInfo, nullptr, &sampler);
}
SamplerHandle::~SamplerHandle()
{
vkDestroySampler(graphics->getDevice(), sampler, nullptr);
}
SamplerHandle::~SamplerHandle() { vkDestroySampler(graphics->getDevice(), sampler, nullptr); }
Sampler::Sampler(PGraphics graphics, VkSamplerCreateInfo createInfo)
: graphics(graphics), handle(new SamplerHandle(graphics, createInfo))
{
}
: graphics(graphics), handle(new SamplerHandle(graphics, createInfo)) {}
Sampler::~Sampler()
{
graphics->getDestructionManager()->queueResourceForDestruction(std::move(handle));
}
Sampler::~Sampler() { graphics->getDestructionManager()->queueResourceForDestruction(std::move(handle)); }
+35 -52
View File
@@ -1,114 +1,97 @@
#pragma once
#include <vulkan/vulkan.h>
#include <vk_mem_alloc.h>
#include "Containers/List.h"
#include "Graphics/Resources.h"
#include <vk_mem_alloc.h>
#include <vulkan/vulkan.h>
namespace Seele
{
namespace Vulkan
{
namespace Seele {
namespace Vulkan {
DECLARE_REF(DescriptorPool)
DECLARE_REF(CommandPool)
DECLARE_REF(Command)
DECLARE_REF(Graphics)
class Semaphore
{
public:
class Semaphore {
public:
Semaphore(PGraphics graphics);
virtual ~Semaphore();
constexpr VkSemaphore getHandle() const
{
return handle;
}
private:
constexpr VkSemaphore getHandle() const { return handle; }
private:
VkSemaphore handle;
PGraphics graphics;
};
DEFINE_REF(Semaphore)
class Fence
{
public:
class Fence {
public:
Fence(PGraphics graphics);
~Fence();
void submit();
bool isSignaled();
void reset();
constexpr VkFence getHandle() const
{
return fence;
}
constexpr VkFence getHandle() const { return fence; }
void wait(uint64 timeout);
bool operator<(const Fence &other) const
{
return fence < other.fence;
}
bool operator<(const Fence& other) const { return fence < other.fence; }
private:
private:
PGraphics graphics;
enum class Status
{
Ready,
InUse,
Signalled,
enum class Status {
Ready,
InUse,
Signalled,
};
Status status;
VkFence fence;
};
DEFINE_REF(Fence)
DECLARE_REF(CommandBoundResource)
class DestructionManager
{
public:
class DestructionManager {
public:
DestructionManager(PGraphics graphics);
~DestructionManager();
void queueResourceForDestruction(OCommandBoundResource resource);
void notifyCommandComplete();
private:
private:
PGraphics graphics;
Array<OCommandBoundResource> resources;
};
DEFINE_REF(DestructionManager)
class CommandBoundResource
{
public:
CommandBoundResource(PGraphics graphics)
: graphics(graphics)
{
}
virtual ~CommandBoundResource()
{
class CommandBoundResource {
public:
CommandBoundResource(PGraphics graphics) : graphics(graphics) {}
virtual ~CommandBoundResource() {
if (isCurrentlyBound())
abort();
}
constexpr bool isCurrentlyBound() const { return bindCount > 0; }
constexpr void bind() { bindCount++; }
constexpr void unbind() { bindCount--; }
protected:
protected:
PGraphics graphics;
uint64 bindCount = 0;
};
DEFINE_REF(CommandBoundResource)
class SamplerHandle : public CommandBoundResource
{
public:
class SamplerHandle : public CommandBoundResource {
public:
SamplerHandle(PGraphics graphics, VkSamplerCreateInfo createInfo);
virtual ~SamplerHandle();
VkSampler sampler;
};
DEFINE_REF(SamplerHandle)
class Sampler : public Gfx::Sampler
{
public:
class Sampler : public Gfx::Sampler {
public:
Sampler(PGraphics graphics, VkSamplerCreateInfo createInfo);
virtual ~Sampler();
PSamplerHandle getHandle() const { return handle; }
VkSampler getSampler() const { return handle->sampler; }
private:
private:
PGraphics graphics;
OSamplerHandle handle;
};
+8 -18
View File
@@ -1,40 +1,30 @@
#include "Shader.h"
#include "Graphics.h"
#include "Graphics/slang-compile.h"
#include "slang.h"
#include "slang-com-ptr.h"
#include "slang.h"
#include "stdlib.h"
#include <fmt/core.h>
using namespace Seele;
using namespace Seele::Vulkan;
Shader::Shader(PGraphics graphics, VkShaderStageFlags stage)
: graphics(graphics)
, stage(stage)
{
}
Shader::Shader(PGraphics graphics, VkShaderStageFlags stage) : graphics(graphics), stage(stage) {}
Shader::~Shader()
{
if (module != VK_NULL_HANDLE)
{
Shader::~Shader() {
if (module != VK_NULL_HANDLE) {
vkDestroyShaderModule(graphics->getDevice(), module, nullptr);
}
}
uint32 Seele::Vulkan::Shader::getShaderHash() const
{
return hash;
}
uint32 Seele::Vulkan::Shader::getShaderHash() const { return hash; }
void Shader::create(ShaderCreateInfo createInfo)
{
void Shader::create(ShaderCreateInfo createInfo) {
Map<std::string, uint32> paramMapping;
Slang::ComPtr<slang::IBlob> kernelBlob = generateShader(createInfo, SLANG_SPIRV, paramMapping);
createInfo.rootSignature->addMapping(paramMapping);
VkShaderModuleCreateInfo moduleInfo =
{
VkShaderModuleCreateInfo moduleInfo = {
.sType = VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO,
.pNext = nullptr,
.flags = 0,
+18 -33
View File
@@ -1,37 +1,29 @@
#pragma once
#include "Resources.h"
#include "Enums.h"
#include "Graphics/Shader.h"
#include "Resources.h"
namespace Seele
{
namespace Vulkan
{
namespace Seele {
namespace Vulkan {
DECLARE_REF(Graphics)
DECLARE_REF(DescriptorLayout)
class Shader
{
public:
class Shader {
public:
Shader(PGraphics graphics, VkShaderStageFlags stage);
virtual ~Shader();
void create(ShaderCreateInfo createInfo);
constexpr VkShaderModule getModuleHandle() const
{
return module;
}
constexpr const char* getEntryPointName() const
{
//SLang renames all entry points to main, so we dont need that
return "main";//entryPointName.c_str();
}
constexpr VkShaderStageFlags getStage() const
{
return stage;
constexpr VkShaderModule getModuleHandle() const { return module; }
constexpr const char* getEntryPointName() const {
// SLang renames all entry points to main, so we dont need that
return "main"; // entryPointName.c_str();
}
constexpr VkShaderStageFlags getStage() const { return stage; }
uint32 getShaderHash() const;
private:
private:
PGraphics graphics;
VkShaderModule module;
VkShaderStageFlags stage;
@@ -39,17 +31,10 @@ private:
};
DEFINE_REF(Shader)
template <typename Base, VkShaderStageFlags stageFlags>
class ShaderBase : public Base, public Shader
{
public:
ShaderBase(PGraphics graphics)
: Shader(graphics, stageFlags)
{
}
virtual ~ShaderBase()
{
}
template <typename Base, VkShaderStageFlags stageFlags> class ShaderBase : public Base, public Shader {
public:
ShaderBase(PGraphics graphics) : Shader(graphics, stageFlags) {}
virtual ~ShaderBase() {}
};
using VertexShader = ShaderBase<Gfx::VertexShader, VK_SHADER_STAGE_VERTEX_BIT>;
using FragmentShader = ShaderBase<Gfx::FragmentShader, VK_SHADER_STAGE_FRAGMENT_BIT>;
@@ -63,4 +48,4 @@ DEFINE_REF(ComputeShader)
DEFINE_REF(TaskShader)
DEFINE_REF(MeshShader)
} // namespace Vulkan
}
} // namespace Seele
+150 -248
View File
@@ -6,10 +6,8 @@
using namespace Seele;
using namespace Seele::Vulkan;
VkImageAspectFlags getAspectFromFormat(Gfx::SeFormat format)
{
switch (format)
{
VkImageAspectFlags getAspectFromFormat(Gfx::SeFormat format) {
switch (format) {
case Gfx::SE_FORMAT_D16_UNORM:
return VK_IMAGE_ASPECT_DEPTH_BIT;
case Gfx::SE_FORMAT_D32_SFLOAT:
@@ -26,47 +24,28 @@ VkImageAspectFlags getAspectFromFormat(Gfx::SeFormat format)
}
}
TextureHandle::TextureHandle(PGraphics graphics) : CommandBoundResource(graphics) {}
TextureHandle::TextureHandle(PGraphics graphics)
: CommandBoundResource(graphics)
{
}
TextureHandle::~TextureHandle()
{
TextureHandle::~TextureHandle() {
vkDestroyImageView(graphics->getDevice(), imageView, nullptr);
if (ownsImage)
{
if (ownsImage) {
vmaDestroyImage(graphics->getAllocator(), image, allocation);
}
}
TextureBase::TextureBase(PGraphics graphics, VkImageViewType viewType,
const TextureCreateInfo& createInfo, Gfx::QueueType& owner, VkImage existingImage)
: currentOwner(owner)
, graphics(graphics)
, width(createInfo.width)
, height(createInfo.height)
, depth(createInfo.depth)
, arrayCount(createInfo.elements)
, layerCount(createInfo.layers)
, mipLevels(createInfo.mipLevels)
, samples(createInfo.samples)
, format(createInfo.format)
, usage(createInfo.usage)
, handle(new TextureHandle(graphics))
, aspect(getAspectFromFormat(createInfo.format))
, layout(Gfx::SE_IMAGE_LAYOUT_UNDEFINED)
{
TextureBase::TextureBase(PGraphics graphics, VkImageViewType viewType, const TextureCreateInfo& createInfo, Gfx::QueueType& owner,
VkImage existingImage)
: currentOwner(owner), graphics(graphics), width(createInfo.width), height(createInfo.height), depth(createInfo.depth),
arrayCount(createInfo.elements), layerCount(createInfo.layers), mipLevels(createInfo.mipLevels), samples(createInfo.samples),
format(createInfo.format), usage(createInfo.usage), handle(new TextureHandle(graphics)),
aspect(getAspectFromFormat(createInfo.format)), layout(Gfx::SE_IMAGE_LAYOUT_UNDEFINED) {
handle->image = existingImage;
handle->ownsImage = false;
if (existingImage == VK_NULL_HANDLE)
{
if (existingImage == VK_NULL_HANDLE) {
handle->ownsImage = true;
VkImageType type = VK_IMAGE_TYPE_MAX_ENUM;
VkImageCreateFlags flags = 0;
switch (viewType)
{
switch (viewType) {
case VK_IMAGE_VIEW_TYPE_1D:
case VK_IMAGE_VIEW_TYPE_1D_ARRAY:
type = VK_IMAGE_TYPE_1D;
@@ -87,12 +66,8 @@ TextureBase::TextureBase(PGraphics graphics, VkImageViewType viewType,
default:
break;
}
if ((usage & VK_IMAGE_USAGE_TRANSIENT_ATTACHMENT_BIT) == 0)
{
usage = usage
| VK_IMAGE_USAGE_TRANSFER_DST_BIT
| VK_IMAGE_USAGE_TRANSFER_SRC_BIT
| VK_IMAGE_USAGE_SAMPLED_BIT;
if ((usage & VK_IMAGE_USAGE_TRANSIENT_ATTACHMENT_BIT) == 0) {
usage = usage | VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_SAMPLED_BIT;
}
VkImageCreateInfo info = {
.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,
@@ -100,11 +75,12 @@ TextureBase::TextureBase(PGraphics graphics, VkImageViewType viewType,
.flags = flags,
.imageType = type,
.format = cast(format),
.extent = {
.width = width,
.height = height,
.depth = depth,
},
.extent =
{
.width = width,
.height = height,
.depth = depth,
},
.mipLevels = mipLevels,
.arrayLayers = arrayCount * layerCount,
.samples = (VkSampleCountFlagBits)samples,
@@ -120,11 +96,9 @@ TextureBase::TextureBase(PGraphics graphics, VkImageViewType viewType,
}
const DataSource& sourceData = createInfo.sourceData;
if (sourceData.size > 0)
{
changeLayout(Gfx::SE_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
VK_ACCESS_NONE, VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT,
VK_ACCESS_MEMORY_WRITE_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT);
if (sourceData.size > 0) {
changeLayout(Gfx::SE_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, VK_ACCESS_NONE, VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT,
VK_ACCESS_MEMORY_WRITE_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT);
void* data;
OBufferAllocation stagingAlloc = new BufferAllocation(graphics);
VkBufferCreateInfo stagingInfo = {
@@ -139,7 +113,8 @@ TextureBase::TextureBase(PGraphics graphics, VkImageViewType viewType,
.flags = VMA_ALLOCATION_CREATE_HOST_ACCESS_SEQUENTIAL_WRITE_BIT | VMA_ALLOCATION_CREATE_MAPPED_BIT,
.usage = VMA_MEMORY_USAGE_AUTO,
};
VK_CHECK(vmaCreateBuffer(graphics->getAllocator(), &stagingInfo, &alloc, &stagingAlloc->buffer, &stagingAlloc->allocation, nullptr));
VK_CHECK(
vmaCreateBuffer(graphics->getAllocator(), &stagingInfo, &alloc, &stagingAlloc->buffer, &stagingAlloc->allocation, nullptr));
vmaMapMemory(graphics->getAllocator(), stagingAlloc->allocation, &data);
vmaSetAllocationName(graphics->getAllocator(), stagingAlloc->allocation, "TextureStaging");
@@ -151,53 +126,40 @@ TextureBase::TextureBase(PGraphics graphics, VkImageViewType viewType,
.bufferOffset = 0,
.bufferRowLength = 0,
.bufferImageHeight = 0,
.imageSubresource = {
.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT,
.mipLevel = 0,
.baseArrayLayer = 0,
.layerCount = arrayCount * layerCount,
},
.imageOffset = {
.x = 0,
.y = 0,
.z = 0,
},
.imageExtent = {
.width = width,
.height = height,
.depth = depth
},
.imageSubresource =
{
.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT,
.mipLevel = 0,
.baseArrayLayer = 0,
.layerCount = arrayCount * layerCount,
},
.imageOffset =
{
.x = 0,
.y = 0,
.z = 0,
},
.imageExtent = {.width = width, .height = height, .depth = depth},
};
vkCmdCopyBufferToImage(commandPool->getCommands()->getHandle(),
stagingAlloc->buffer, handle->image, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1, &region);
vkCmdCopyBufferToImage(commandPool->getCommands()->getHandle(), stagingAlloc->buffer, handle->image,
VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1, &region);
commandPool->getCommands()->bindResource(PBufferAllocation(stagingAlloc));
// When loading a texture from a file, we will almost always use it as a texture map for fragment shaders
changeLayout(Gfx::SE_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL,
VK_ACCESS_TRANSFER_WRITE_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT,
VK_ACCESS_SHADER_READ_BIT, VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT);
changeLayout(Gfx::SE_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, VK_ACCESS_TRANSFER_WRITE_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT,
VK_ACCESS_SHADER_READ_BIT, VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT);
graphics->getDestructionManager()->queueResourceForDestruction(std::move(stagingAlloc));
}
else
{
if (usage & VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT)
{
changeLayout(Gfx::SE_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL,
VK_ACCESS_NONE, VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT,
VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT, VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT);
}
else if (usage & VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT)
{
changeLayout(Gfx::SE_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
VK_ACCESS_NONE, VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT,
VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT);
}
else
{
changeLayout(Gfx::SE_IMAGE_LAYOUT_GENERAL,
VK_ACCESS_NONE, VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT,
VK_ACCESS_MEMORY_WRITE_BIT, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT);
} else {
if (usage & VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT) {
changeLayout(Gfx::SE_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL, VK_ACCESS_NONE, VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT,
VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT, VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT);
} else if (usage & VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT) {
changeLayout(Gfx::SE_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, VK_ACCESS_NONE, VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT,
VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT);
} else {
changeLayout(Gfx::SE_IMAGE_LAYOUT_GENERAL, VK_ACCESS_NONE, VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT, VK_ACCESS_MEMORY_WRITE_BIT,
VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT);
}
}
VkImageViewCreateInfo viewInfo = {
@@ -207,35 +169,25 @@ TextureBase::TextureBase(PGraphics graphics, VkImageViewType viewType,
.image = handle->image,
.viewType = viewType,
.format = cast(format),
.subresourceRange = {
.aspectMask = aspect,
.levelCount = mipLevels,
.layerCount = layerCount,
},
.subresourceRange =
{
.aspectMask = aspect,
.levelCount = mipLevels,
.layerCount = layerCount,
},
};
VK_CHECK(vkCreateImageView(graphics->getDevice(), &viewInfo, nullptr, &handle->imageView));
}
TextureBase::~TextureBase()
{
graphics->getDestructionManager()->queueResourceForDestruction(std::move(handle));
}
TextureBase::~TextureBase() { graphics->getDestructionManager()->queueResourceForDestruction(std::move(handle)); }
VkImage TextureBase::getImage() const
{
return handle->image;
}
VkImage TextureBase::getImage() const { return handle->image; }
VkImageView TextureBase::getView() const
{
return handle->imageView;
}
VkImageView TextureBase::getView() const { return handle->imageView; }
void TextureBase::changeLayout(Gfx::SeImageLayout newLayout,
VkAccessFlags srcAccess, VkPipelineStageFlags srcStage,
VkAccessFlags dstAccess, VkPipelineStageFlags dstStage)
{
void TextureBase::changeLayout(Gfx::SeImageLayout newLayout, VkAccessFlags srcAccess, VkPipelineStageFlags srcStage,
VkAccessFlags dstAccess, VkPipelineStageFlags dstStage) {
VkImageMemoryBarrier barrier = {
.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,
.pNext = nullptr,
@@ -246,31 +198,28 @@ void TextureBase::changeLayout(Gfx::SeImageLayout newLayout,
.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED,
.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED,
.image = handle->image,
.subresourceRange = {
.aspectMask = aspect,
.baseMipLevel = 0,
.levelCount = mipLevels,
.baseArrayLayer = 0,
.layerCount = layerCount,
},
.subresourceRange =
{
.aspectMask = aspect,
.baseMipLevel = 0,
.levelCount = mipLevels,
.baseArrayLayer = 0,
.layerCount = layerCount,
},
};
PCommandPool commandPool = graphics->getQueueCommands(currentOwner);
vkCmdPipelineBarrier(commandPool->getCommands()->getHandle(),
srcStage, dstStage,
0, 0, nullptr, 0, nullptr, 1, &barrier);
vkCmdPipelineBarrier(commandPool->getCommands()->getHandle(), srcStage, dstStage, 0, 0, nullptr, 0, nullptr, 1, &barrier);
commandPool->getCommands()->bindResource(PTextureHandle(handle));
commandPool->submitCommands();
layout = newLayout;
}
void TextureBase::download(uint32 mipLevel, uint32 arrayLayer, uint32 face, Array<uint8>& buffer)
{
void TextureBase::download(uint32 mipLevel, uint32 arrayLayer, uint32 face, Array<uint8>& buffer) {
uint64 imageSize = width * height * depth * Gfx::getFormatInfo(format).blockSize;
auto prevLayout = layout;
changeLayout(Gfx::SE_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
VK_ACCESS_MEMORY_WRITE_BIT, VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT,
VK_ACCESS_TRANSFER_READ_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT);
changeLayout(Gfx::SE_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, VK_ACCESS_MEMORY_WRITE_BIT, VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT,
VK_ACCESS_TRANSFER_READ_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT);
void* data;
OBufferAllocation stagingAlloc = new BufferAllocation(graphics);
// always create a staging buffer since we do buffer -> image copy and the image may be in any tiling format
@@ -290,33 +239,30 @@ void TextureBase::download(uint32 mipLevel, uint32 arrayLayer, uint32 face, Arra
vmaSetAllocationName(graphics->getAllocator(), stagingAlloc->allocation, "DownloadBuffer");
PCommand cmdBuffer = graphics->getQueueCommands(currentOwner)->getCommands();
//Gfx::FormatCompatibilityInfo formatInfo = Gfx::getFormatInfo(format);
// Gfx::FormatCompatibilityInfo formatInfo = Gfx::getFormatInfo(format);
VkBufferImageCopy region = {
.bufferOffset = 0,
.bufferRowLength = 0,
.bufferImageHeight = 0,
.imageSubresource = {
.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT,
.mipLevel = mipLevel,
.baseArrayLayer = arrayLayer * layerCount + face,
.layerCount = 1,
},
.imageOffset = {
.x = 0,
.y = 0,
.z = 0,
},
.imageExtent = {
.width = width,
.height = height,
.depth = depth
},
.imageSubresource =
{
.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT,
.mipLevel = mipLevel,
.baseArrayLayer = arrayLayer * layerCount + face,
.layerCount = 1,
},
.imageOffset =
{
.x = 0,
.y = 0,
.z = 0,
},
.imageExtent = {.width = width, .height = height, .depth = depth},
};
vkCmdCopyImageToBuffer(cmdBuffer->getHandle(), handle->image, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, stagingAlloc->buffer, 1, &region);
cmdBuffer->bindResource(PBufferAllocation(stagingAlloc));
changeLayout(prevLayout,
VK_ACCESS_TRANSFER_READ_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT,
VK_ACCESS_MEMORY_READ_BIT, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT);
changeLayout(prevLayout, VK_ACCESS_TRANSFER_READ_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_ACCESS_MEMORY_READ_BIT,
VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT);
VK_CHECK(vmaMapMemory(graphics->getAllocator(), stagingAlloc->allocation, &data));
buffer.resize(imageSize);
std::memcpy(buffer.data(), data, buffer.size());
@@ -324,8 +270,7 @@ void TextureBase::download(uint32 mipLevel, uint32 arrayLayer, uint32 face, Arra
graphics->getDestructionManager()->queueResourceForDestruction(std::move(stagingAlloc));
}
void TextureBase::executeOwnershipBarrier(Gfx::QueueType newOwner)
{
void TextureBase::executeOwnershipBarrier(Gfx::QueueType newOwner) {
Gfx::QueueFamilyMapping mapping = graphics->getFamilyMapping();
VkImageMemoryBarrier imageBarrier = {
.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,
@@ -335,52 +280,43 @@ void TextureBase::executeOwnershipBarrier(Gfx::QueueType newOwner)
.srcQueueFamilyIndex = mapping.getQueueTypeFamilyIndex(currentOwner),
.dstQueueFamilyIndex = mapping.getQueueTypeFamilyIndex(newOwner),
.image = handle->image,
.subresourceRange = {
.aspectMask = aspect,
.baseMipLevel = 0,
.levelCount = mipLevels,
.baseArrayLayer = 0,
.layerCount = arrayCount,
},
.subresourceRange =
{
.aspectMask = aspect,
.baseMipLevel = 0,
.levelCount = mipLevels,
.baseArrayLayer = 0,
.layerCount = arrayCount,
},
};
PCommandPool sourcePool = graphics->getQueueCommands(currentOwner);
PCommandPool dstPool = nullptr;
VkPipelineStageFlags srcStage = VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT;
VkPipelineStageFlags dstStage = VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT;
if (currentOwner == Gfx::QueueType::TRANSFER)
{
if (currentOwner == Gfx::QueueType::TRANSFER) {
imageBarrier.srcAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT;
srcStage = VK_PIPELINE_STAGE_TRANSFER_BIT;
}
else if (currentOwner == Gfx::QueueType::COMPUTE)
{
} else if (currentOwner == Gfx::QueueType::COMPUTE) {
imageBarrier.srcAccessMask = VK_ACCESS_MEMORY_WRITE_BIT;
srcStage = VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT;
}
else if (currentOwner == Gfx::QueueType::GRAPHICS)
{
} else if (currentOwner == Gfx::QueueType::GRAPHICS) {
imageBarrier.srcAccessMask = VK_ACCESS_MEMORY_WRITE_BIT;
srcStage = VK_PIPELINE_STAGE_ALL_GRAPHICS_BIT;
}
if (newOwner == Gfx::QueueType::TRANSFER)
{
if (newOwner == Gfx::QueueType::TRANSFER) {
imageBarrier.dstAccessMask = VK_ACCESS_TRANSFER_READ_BIT;
dstStage = VK_PIPELINE_STAGE_TRANSFER_BIT;
dstPool = graphics->getTransferCommands();
}
else if (newOwner == Gfx::QueueType::COMPUTE)
{
} else if (newOwner == Gfx::QueueType::COMPUTE) {
imageBarrier.dstAccessMask = VK_ACCESS_MEMORY_READ_BIT;
dstStage = VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT;
dstPool = graphics->getComputeCommands();
}
else if (newOwner == Gfx::QueueType::GRAPHICS)
{
} else if (newOwner == Gfx::QueueType::GRAPHICS) {
imageBarrier.dstAccessMask = VK_ACCESS_MEMORY_READ_BIT;
dstStage = VK_PIPELINE_STAGE_ALL_GRAPHICS_BIT;
dstPool = graphics->getGraphicsCommands();
}
VkCommandBuffer sourceCmd = sourcePool->getCommands()->getHandle();
VkCommandBuffer destCmd = dstPool->getCommands()->getHandle();
sourcePool->getCommands()->bindResource(PTextureHandle(handle));
@@ -391,9 +327,8 @@ void TextureBase::executeOwnershipBarrier(Gfx::QueueType newOwner)
sourcePool->submitCommands();
}
void TextureBase::executePipelineBarrier(VkAccessFlags srcAccess, VkPipelineStageFlags srcStage,
VkAccessFlags dstAccess, VkPipelineStageFlags dstStage)
{
void TextureBase::executePipelineBarrier(VkAccessFlags srcAccess, VkPipelineStageFlags srcStage, VkAccessFlags dstAccess,
VkPipelineStageFlags dstStage) {
VkImageMemoryBarrier barrier = {
.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,
.pNext = nullptr,
@@ -404,13 +339,14 @@ void TextureBase::executePipelineBarrier(VkAccessFlags srcAccess, VkPipelineStag
.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED,
.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED,
.image = handle->image,
.subresourceRange = {
.aspectMask = aspect,
.baseMipLevel = 0,
.levelCount = 1,
.baseArrayLayer = 0,
.layerCount = 1,
},
.subresourceRange =
{
.aspectMask = aspect,
.baseMipLevel = 0,
.levelCount = 1,
.baseArrayLayer = 0,
.layerCount = 1,
},
};
PCommand command = graphics->getQueueCommands(currentOwner)->getCommands();
vkCmdPipelineBarrier(command->getHandle(), srcStage, dstStage, 0, 0, nullptr, 0, nullptr, 1, &barrier);
@@ -418,101 +354,67 @@ void TextureBase::executePipelineBarrier(VkAccessFlags srcAccess, VkPipelineStag
}
Texture2D::Texture2D(PGraphics graphics, const TextureCreateInfo& createInfo, VkImage existingImage)
: Gfx::Texture2D(graphics->getFamilyMapping(), createInfo.sourceData.owner)
, TextureBase(graphics, createInfo.elements > 1 ? VK_IMAGE_VIEW_TYPE_2D_ARRAY : VK_IMAGE_VIEW_TYPE_2D,
createInfo, Gfx::Texture2D::currentOwner, existingImage)
{
}
: Gfx::Texture2D(graphics->getFamilyMapping(), createInfo.sourceData.owner),
TextureBase(graphics, createInfo.elements > 1 ? VK_IMAGE_VIEW_TYPE_2D_ARRAY : VK_IMAGE_VIEW_TYPE_2D, createInfo,
Gfx::Texture2D::currentOwner, existingImage) {}
Texture2D::~Texture2D()
{
}
Texture2D::~Texture2D() {}
void Texture2D::changeLayout(Gfx::SeImageLayout newLayout,
Gfx::SeAccessFlags srcAccess, Gfx::SePipelineStageFlags srcStage,
Gfx::SeAccessFlags dstAccess, Gfx::SePipelineStageFlags dstStage)
{
void Texture2D::changeLayout(Gfx::SeImageLayout newLayout, Gfx::SeAccessFlags srcAccess, Gfx::SePipelineStageFlags srcStage,
Gfx::SeAccessFlags dstAccess, Gfx::SePipelineStageFlags dstStage) {
TextureBase::changeLayout(newLayout, srcAccess, srcStage, dstAccess, dstStage);
}
void Texture2D::download(uint32 mipLevel, uint32 arrayLayer, uint32 face, Array<uint8>& buffer)
{
void Texture2D::download(uint32 mipLevel, uint32 arrayLayer, uint32 face, Array<uint8>& buffer) {
TextureBase::download(mipLevel, arrayLayer, face, buffer);
}
void Texture2D::executeOwnershipBarrier(Gfx::QueueType newOwner)
{
TextureBase::executeOwnershipBarrier(newOwner);
}
void Texture2D::executeOwnershipBarrier(Gfx::QueueType newOwner) { TextureBase::executeOwnershipBarrier(newOwner); }
void Texture2D::executePipelineBarrier(VkAccessFlags srcAccess, VkPipelineStageFlags srcStage,
VkAccessFlags dstAccess, VkPipelineStageFlags dstStage)
{
void Texture2D::executePipelineBarrier(VkAccessFlags srcAccess, VkPipelineStageFlags srcStage, VkAccessFlags dstAccess,
VkPipelineStageFlags dstStage) {
TextureBase::executePipelineBarrier(srcAccess, srcStage, dstAccess, dstStage);
}
Texture3D::Texture3D(PGraphics graphics, const TextureCreateInfo& createInfo, VkImage existingImage)
: Gfx::Texture3D(graphics->getFamilyMapping(), createInfo.sourceData.owner)
, TextureBase(graphics, VK_IMAGE_VIEW_TYPE_3D,
createInfo, Gfx::Texture3D::currentOwner, existingImage)
{
}
: Gfx::Texture3D(graphics->getFamilyMapping(), createInfo.sourceData.owner),
TextureBase(graphics, VK_IMAGE_VIEW_TYPE_3D, createInfo, Gfx::Texture3D::currentOwner, existingImage) {}
Texture3D::~Texture3D()
{
}
Texture3D::~Texture3D() {}
void Texture3D::changeLayout(Gfx::SeImageLayout newLayout,
Gfx::SeAccessFlags srcAccess, Gfx::SePipelineStageFlags srcStage,
Gfx::SeAccessFlags dstAccess, Gfx::SePipelineStageFlags dstStage)
{
void Texture3D::changeLayout(Gfx::SeImageLayout newLayout, Gfx::SeAccessFlags srcAccess, Gfx::SePipelineStageFlags srcStage,
Gfx::SeAccessFlags dstAccess, Gfx::SePipelineStageFlags dstStage) {
TextureBase::changeLayout(newLayout, srcAccess, srcStage, dstAccess, dstStage);
}
void Texture3D::download(uint32 mipLevel, uint32 arrayLayer, uint32 face, Array<uint8>& buffer)
{
void Texture3D::download(uint32 mipLevel, uint32 arrayLayer, uint32 face, Array<uint8>& buffer) {
TextureBase::download(mipLevel, arrayLayer, face, buffer);
}
void Texture3D::executeOwnershipBarrier(Gfx::QueueType newOwner)
{
TextureBase::executeOwnershipBarrier(newOwner);
}
void Texture3D::executeOwnershipBarrier(Gfx::QueueType newOwner) { TextureBase::executeOwnershipBarrier(newOwner); }
void Texture3D::executePipelineBarrier(VkAccessFlags srcAccess, VkPipelineStageFlags srcStage,
VkAccessFlags dstAccess, VkPipelineStageFlags dstStage)
{
void Texture3D::executePipelineBarrier(VkAccessFlags srcAccess, VkPipelineStageFlags srcStage, VkAccessFlags dstAccess,
VkPipelineStageFlags dstStage) {
TextureBase::executePipelineBarrier(srcAccess, srcStage, dstAccess, dstStage);
}
TextureCube::TextureCube(PGraphics graphics, const TextureCreateInfo& createInfo, VkImage existingImage)
: Gfx::TextureCube(graphics->getFamilyMapping(), createInfo.sourceData.owner)
, TextureBase(graphics, createInfo.elements > 1? VK_IMAGE_VIEW_TYPE_CUBE_ARRAY : VK_IMAGE_VIEW_TYPE_CUBE,
createInfo, Gfx::TextureCube::currentOwner, existingImage)
{
}
: Gfx::TextureCube(graphics->getFamilyMapping(), createInfo.sourceData.owner),
TextureBase(graphics, createInfo.elements > 1 ? VK_IMAGE_VIEW_TYPE_CUBE_ARRAY : VK_IMAGE_VIEW_TYPE_CUBE, createInfo,
Gfx::TextureCube::currentOwner, existingImage) {}
TextureCube::~TextureCube()
{
}
TextureCube::~TextureCube() {}
void TextureCube::changeLayout(Gfx::SeImageLayout newLayout,
Gfx::SeAccessFlags srcAccess, Gfx::SePipelineStageFlags srcStage,
Gfx::SeAccessFlags dstAccess, Gfx::SePipelineStageFlags dstStage)
{
void TextureCube::changeLayout(Gfx::SeImageLayout newLayout, Gfx::SeAccessFlags srcAccess, Gfx::SePipelineStageFlags srcStage,
Gfx::SeAccessFlags dstAccess, Gfx::SePipelineStageFlags dstStage) {
TextureBase::changeLayout(newLayout, srcAccess, srcStage, dstAccess, dstStage);
}
void TextureCube::download(uint32 mipLevel, uint32 arrayLayer, uint32 face, Array<uint8>& buffer)
{
void TextureCube::download(uint32 mipLevel, uint32 arrayLayer, uint32 face, Array<uint8>& buffer) {
TextureBase::download(mipLevel, arrayLayer, face, buffer);
}
void TextureCube::executeOwnershipBarrier(Gfx::QueueType newOwner)
{
TextureBase::executeOwnershipBarrier(newOwner);
}
void TextureCube::executeOwnershipBarrier(Gfx::QueueType newOwner) { TextureBase::executeOwnershipBarrier(newOwner); }
void TextureCube::executePipelineBarrier(VkAccessFlags srcAccess, VkPipelineStageFlags srcStage,
VkAccessFlags dstAccess, VkPipelineStageFlags dstStage)
{
void TextureCube::executePipelineBarrier(VkAccessFlags srcAccess, VkPipelineStageFlags srcStage, VkAccessFlags dstAccess,
VkPipelineStageFlags dstStage) {
TextureBase::executePipelineBarrier(srcAccess, srcStage, dstAccess, dstStage);
}
+70 -171
View File
@@ -1,15 +1,13 @@
#pragma once
#include "Graphics/Texture.h"
#include "Graphics.h"
#include "Graphics/Texture.h"
#include "Resources.h"
namespace Seele
{
namespace Vulkan
{
class TextureHandle : public CommandBoundResource
{
public:
namespace Seele {
namespace Vulkan {
class TextureHandle : public CommandBoundResource {
public:
TextureHandle(PGraphics graphics);
virtual ~TextureHandle();
VkImage image;
@@ -18,73 +16,35 @@ public:
uint8 ownsImage;
};
DECLARE_REF(TextureHandle)
class TextureBase
{
public:
TextureBase(PGraphics graphics, VkImageViewType viewType,
const TextureCreateInfo& createInfo, Gfx::QueueType& owner, VkImage existingImage = VK_NULL_HANDLE);
class TextureBase {
public:
TextureBase(PGraphics graphics, VkImageViewType viewType, const TextureCreateInfo& createInfo, Gfx::QueueType& owner,
VkImage existingImage = VK_NULL_HANDLE);
virtual ~TextureBase();
uint32 getWidth() const
{
return width;
}
uint32 getHeight() const
{
return height;
}
uint32 getDepth() const
{
return depth;
}
PTextureHandle getHandle() const
{
return handle;
}
uint32 getWidth() const { return width; }
uint32 getHeight() const { return height; }
uint32 getDepth() const { return depth; }
PTextureHandle getHandle() const { return handle; }
VkImage getImage() const;
VkImageView getView() const;
constexpr Gfx::SeImageLayout getLayout() const
{
return layout;
}
void setLayout(Gfx::SeImageLayout val)
{
layout = val;
}
constexpr VkImageAspectFlags getAspect() const
{
return aspect;
}
constexpr VkImageUsageFlags getUsage() const
{
return usage;
}
constexpr Gfx::SeFormat getFormat() const
{
return format;
}
constexpr Gfx::SeSampleCountFlags getNumSamples() const
{
return samples;
}
constexpr uint32 getMipLevels() const
{
return mipLevels;
}
constexpr bool isDepthStencil() const
{
return aspect & (VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT);
}
constexpr Gfx::SeImageLayout getLayout() const { return layout; }
void setLayout(Gfx::SeImageLayout val) { layout = val; }
constexpr VkImageAspectFlags getAspect() const { return aspect; }
constexpr VkImageUsageFlags getUsage() const { return usage; }
constexpr Gfx::SeFormat getFormat() const { return format; }
constexpr Gfx::SeSampleCountFlags getNumSamples() const { return samples; }
constexpr uint32 getMipLevels() const { return mipLevels; }
constexpr bool isDepthStencil() const { return aspect & (VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT); }
void executeOwnershipBarrier(Gfx::QueueType newOwner);
void executePipelineBarrier(VkAccessFlags srcAccess, VkPipelineStageFlags srcStage,
VkAccessFlags dstAccess, VkPipelineStageFlags dstStage);
void changeLayout(Gfx::SeImageLayout newLayout,
VkAccessFlags srcAccess, VkPipelineStageFlags srcStage,
VkAccessFlags dstAccess, VkPipelineStageFlags dstStage);
void executePipelineBarrier(VkAccessFlags srcAccess, VkPipelineStageFlags srcStage, VkAccessFlags dstAccess,
VkPipelineStageFlags dstStage);
void changeLayout(Gfx::SeImageLayout newLayout, VkAccessFlags srcAccess, VkPipelineStageFlags srcStage, VkAccessFlags dstAccess,
VkPipelineStageFlags dstStage);
void download(uint32 mipLevel, uint32 arrayLayer, uint32 face, Array<uint8>& buffer);
protected:
protected:
OTextureHandle handle;
//Updates via reference
// Updates via reference
Gfx::QueueType& currentOwner;
PGraphics graphics;
uint32 width;
@@ -102,131 +62,70 @@ protected:
};
DEFINE_REF(TextureBase)
class Texture2D : public Gfx::Texture2D, public TextureBase
{
public:
class Texture2D : public Gfx::Texture2D, public TextureBase {
public:
Texture2D(PGraphics graphics, const TextureCreateInfo& createInfo, VkImage existingImage = VK_NULL_HANDLE);
virtual ~Texture2D();
virtual uint32 getWidth() const override
{
return width;
}
virtual uint32 getHeight() const override
{
return height;
}
virtual uint32 getDepth() const override
{
return depth;
}
virtual Gfx::SeFormat getFormat() const override
{
return format;
}
virtual Gfx::SeSampleCountFlags getNumSamples() const override
{
return samples;
}
virtual uint32 getMipLevels() const override
{
return mipLevels;
}
virtual void changeLayout(Gfx::SeImageLayout newLayout,
Gfx::SeAccessFlags srcAccess, Gfx::SePipelineStageFlags srcStage,
Gfx::SeAccessFlags dstAccess, Gfx::SePipelineStageFlags dstStage) override;
virtual uint32 getWidth() const override { return width; }
virtual uint32 getHeight() const override { return height; }
virtual uint32 getDepth() const override { return depth; }
virtual Gfx::SeFormat getFormat() const override { return format; }
virtual Gfx::SeSampleCountFlags getNumSamples() const override { return samples; }
virtual uint32 getMipLevels() const override { return mipLevels; }
virtual void changeLayout(Gfx::SeImageLayout newLayout, Gfx::SeAccessFlags srcAccess, Gfx::SePipelineStageFlags srcStage,
Gfx::SeAccessFlags dstAccess, Gfx::SePipelineStageFlags dstStage) override;
virtual void download(uint32 mipLevel, uint32 arrayLayer, uint32 face, Array<uint8>& buffer) override;
protected:
protected:
// Inherited via QueueOwnedResource
virtual void executeOwnershipBarrier(Gfx::QueueType newOwner) override;
virtual void executePipelineBarrier(VkAccessFlags srcAccess, VkPipelineStageFlags srcStage,
VkAccessFlags dstAccess, VkPipelineStageFlags dstStage) override;
virtual void executePipelineBarrier(VkAccessFlags srcAccess, VkPipelineStageFlags srcStage, VkAccessFlags dstAccess,
VkPipelineStageFlags dstStage) override;
};
DEFINE_REF(Texture2D)
class Texture3D : public Gfx::Texture3D, public TextureBase
{
public:
class Texture3D : public Gfx::Texture3D, public TextureBase {
public:
Texture3D(PGraphics graphics, const TextureCreateInfo& createInfo, VkImage existingImage = VK_NULL_HANDLE);
virtual ~Texture3D();
virtual uint32 getWidth() const override
{
return width;
}
virtual uint32 getHeight() const override
{
return height;
}
virtual uint32 getDepth() const override
{
return depth;
}
virtual Gfx::SeFormat getFormat() const override
{
return format;
}
virtual Gfx::SeSampleCountFlags getNumSamples() const override
{
return samples;
}
virtual uint32 getMipLevels() const override
{
return mipLevels;
}
virtual void changeLayout(Gfx::SeImageLayout newLayout,
Gfx::SeAccessFlags srcAccess, Gfx::SePipelineStageFlags srcStage,
Gfx::SeAccessFlags dstAccess, Gfx::SePipelineStageFlags dstStage) override;
virtual uint32 getWidth() const override { return width; }
virtual uint32 getHeight() const override { return height; }
virtual uint32 getDepth() const override { return depth; }
virtual Gfx::SeFormat getFormat() const override { return format; }
virtual Gfx::SeSampleCountFlags getNumSamples() const override { return samples; }
virtual uint32 getMipLevels() const override { return mipLevels; }
virtual void changeLayout(Gfx::SeImageLayout newLayout, Gfx::SeAccessFlags srcAccess, Gfx::SePipelineStageFlags srcStage,
Gfx::SeAccessFlags dstAccess, Gfx::SePipelineStageFlags dstStage) override;
virtual void download(uint32 mipLevel, uint32 arrayLayer, uint32 face, Array<uint8>& buffer) override;
protected:
protected:
// Inherited via QueueOwnedResource
virtual void executeOwnershipBarrier(Gfx::QueueType newOwner) override;
virtual void executePipelineBarrier(VkAccessFlags srcAccess, VkPipelineStageFlags srcStage,
VkAccessFlags dstAccess, VkPipelineStageFlags dstStage) override;
virtual void executePipelineBarrier(VkAccessFlags srcAccess, VkPipelineStageFlags srcStage, VkAccessFlags dstAccess,
VkPipelineStageFlags dstStage) override;
};
DEFINE_REF(Texture3D)
class TextureCube : public Gfx::TextureCube, public TextureBase
{
public:
class TextureCube : public Gfx::TextureCube, public TextureBase {
public:
TextureCube(PGraphics graphics, const TextureCreateInfo& createInfo, VkImage existingImage = VK_NULL_HANDLE);
virtual ~TextureCube();
virtual uint32 getWidth() const override
{
return width;
}
virtual uint32 getHeight() const override
{
return height;
}
virtual uint32 getDepth() const override
{
return depth;
}
virtual Gfx::SeFormat getFormat() const override
{
return format;
}
virtual Gfx::SeSampleCountFlags getNumSamples() const override
{
return samples;
}
virtual uint32 getMipLevels() const override
{
return mipLevels;
}
virtual void changeLayout(Gfx::SeImageLayout newLayout,
Gfx::SeAccessFlags srcAccess, Gfx::SePipelineStageFlags srcStage,
Gfx::SeAccessFlags dstAccess, Gfx::SePipelineStageFlags dstStage) override;
virtual uint32 getWidth() const override { return width; }
virtual uint32 getHeight() const override { return height; }
virtual uint32 getDepth() const override { return depth; }
virtual Gfx::SeFormat getFormat() const override { return format; }
virtual Gfx::SeSampleCountFlags getNumSamples() const override { return samples; }
virtual uint32 getMipLevels() const override { return mipLevels; }
virtual void changeLayout(Gfx::SeImageLayout newLayout, Gfx::SeAccessFlags srcAccess, Gfx::SePipelineStageFlags srcStage,
Gfx::SeAccessFlags dstAccess, Gfx::SePipelineStageFlags dstStage) override;
virtual void download(uint32 mipLevel, uint32 arrayLayer, uint32 face, Array<uint8>& buffer) override;
protected:
protected:
// Inherited via QueueOwnedResource
virtual void executeOwnershipBarrier(Gfx::QueueType newOwner) override;
virtual void executePipelineBarrier(VkAccessFlags srcAccess, VkPipelineStageFlags srcStage,
VkAccessFlags dstAccess, VkPipelineStageFlags dstStage) override;
virtual void executePipelineBarrier(VkAccessFlags srcAccess, VkPipelineStageFlags srcStage, VkAccessFlags dstAccess,
VkPipelineStageFlags dstStage) override;
};
DEFINE_REF(TextureCube)
}
}
} // namespace Vulkan
} // namespace Seele
+85 -172
View File
@@ -1,81 +1,64 @@
#include "Window.h"
#include "Resources.h"
#include "Graphics.h"
#include "Enums.h"
#include "Command.h"
#include "Enums.h"
#include "Graphics.h"
#include "Resources.h"
#include <GLFW/glfw3.h>
using namespace Seele;
using namespace Seele::Vulkan;
double currentFrameDelta = 0;
double Gfx::getCurrentFrameDelta()
{
return currentFrameDelta;
}
double Gfx::getCurrentFrameDelta() { return currentFrameDelta; }
uint32 currentFrameIndex = 0;
uint32 Gfx::getCurrentFrameIndex()
{
return currentFrameIndex;
}
uint32 Gfx::getCurrentFrameIndex() { return currentFrameIndex; }
void glfwKeyCallback(GLFWwindow* handle, int key, int, int action, int modifier)
{
if (key == -1)
{
void glfwKeyCallback(GLFWwindow* handle, int key, int, int action, int modifier) {
if (key == -1) {
return;
}
Window* window = (Window*)glfwGetWindowUserPointer(handle);
window->keyPress((KeyCode)key, (InputAction)action, (KeyModifier)modifier);
}
void glfwMouseMoveCallback(GLFWwindow* handle, double xpos, double ypos)
{
void glfwMouseMoveCallback(GLFWwindow* handle, double xpos, double ypos) {
Window* window = (Window*)glfwGetWindowUserPointer(handle);
window->mouseMove(xpos, ypos);
}
void glfwMouseButtonCallback(GLFWwindow* handle, int button, int action, int modifier)
{
void glfwMouseButtonCallback(GLFWwindow* handle, int button, int action, int modifier) {
Window* window = (Window*)glfwGetWindowUserPointer(handle);
window->mouseButton((MouseButton)button, (InputAction)action, (KeyModifier)modifier);
}
void glfwScrollCallback(GLFWwindow* handle, double xoffset, double yoffset)
{
void glfwScrollCallback(GLFWwindow* handle, double xoffset, double yoffset) {
Window* window = (Window*)glfwGetWindowUserPointer(handle);
window->scroll(xoffset, yoffset);
}
void glfwFileCallback(GLFWwindow* handle, int count, const char** paths)
{
void glfwFileCallback(GLFWwindow* handle, int count, const char** paths) {
Window* window = (Window*)glfwGetWindowUserPointer(handle);
window->fileDrop(count, paths);
}
void glfwCloseCallback(GLFWwindow* handle)
{
void glfwCloseCallback(GLFWwindow* handle) {
Window* window = (Window*)glfwGetWindowUserPointer(handle);
window->close();
}
void glfwFramebufferResizeCallback(GLFWwindow* handle, int width, int height)
{
void glfwFramebufferResizeCallback(GLFWwindow* handle, int width, int height) {
Window* window = (Window*)glfwGetWindowUserPointer(handle);
window->resize(width, height);
}
Window::Window(PGraphics graphics, const WindowCreateInfo &createInfo)
: graphics(graphics)
, preferences(createInfo)
, instance(graphics->getInstance())
, swapchain(VK_NULL_HANDLE)
{
Window::Window(PGraphics graphics, const WindowCreateInfo& createInfo)
: graphics(graphics), preferences(createInfo), instance(graphics->getInstance()), swapchain(VK_NULL_HANDLE) {
float xscale, yscale;
glfwGetMonitorContentScale(glfwGetPrimaryMonitor(), &xscale, &yscale);
glfwWindowHint(GLFW_CLIENT_API, GLFW_NO_API);
GLFWwindow *handle = glfwCreateWindow(createInfo.width / xscale, createInfo.height / yscale, createInfo.title, nullptr, nullptr);
GLFWwindow* handle = glfwCreateWindow(createInfo.width / xscale, createInfo.height / yscale, createInfo.title, nullptr, nullptr);
windowHandle = handle;
glfwSetWindowUserPointer(handle, this);
@@ -86,10 +69,10 @@ Window::Window(PGraphics graphics, const WindowCreateInfo &createInfo)
glfwSetDropCallback(handle, &glfwFileCallback);
glfwSetWindowCloseCallback(handle, &glfwCloseCallback);
glfwSetFramebufferSizeCallback(handle, &glfwFramebufferResizeCallback);
//glfwSetWindowSizeCallback(handle, &glfwResizeCallback);
// glfwSetWindowSizeCallback(handle, &glfwResizeCallback);
glfwCreateWindowSurface(instance, handle, nullptr, &surface);
querySurface();
chooseSwapSurfaceFormat();
framebufferFormat = cast(format.format);
@@ -100,31 +83,28 @@ Window::Window(PGraphics graphics, const WindowCreateInfo &createInfo)
createSwapChain();
}
Window::~Window()
{
Window::~Window() {
vkDestroySwapchainKHR(graphics->getDevice(), swapchain, nullptr);
vkDestroySurfaceKHR(instance, surface, nullptr);
glfwDestroyWindow(static_cast<GLFWwindow *>(windowHandle));
glfwDestroyWindow(static_cast<GLFWwindow*>(windowHandle));
}
void Window::pollInput()
{
glfwPollEvents();
}
void Window::pollInput() { glfwPollEvents(); }
void Window::beginFrame()
{
void Window::beginFrame() {
imageAvailableFences[currentSemaphoreIndex]->reset();
vkAcquireNextImageKHR(graphics->getDevice(), swapchain, std::numeric_limits<uint64>::max(), imageAvailableSemaphores[currentSemaphoreIndex]->getHandle(), imageAvailableFences[currentSemaphoreIndex]->getHandle(), &currentImageIndex);
vkAcquireNextImageKHR(graphics->getDevice(), swapchain, std::numeric_limits<uint64>::max(),
imageAvailableSemaphores[currentSemaphoreIndex]->getHandle(),
imageAvailableFences[currentSemaphoreIndex]->getHandle(), &currentImageIndex);
imageAvailableFences[currentSemaphoreIndex]->submit();
graphics->getGraphicsCommands()->getCommands()->waitForSemaphore(VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, imageAvailableSemaphores[currentSemaphoreIndex]);
graphics->getGraphicsCommands()->getCommands()->waitForSemaphore(VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,
imageAvailableSemaphores[currentSemaphoreIndex]);
}
void Window::endFrame()
{
swapChainTextures[currentImageIndex]->changeLayout(Gfx::SE_IMAGE_LAYOUT_PRESENT_SRC_KHR,
Gfx::SE_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, Gfx::SE_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,
Gfx::SE_ACCESS_MEMORY_READ_BIT, Gfx::SE_PIPELINE_STAGE_TOP_OF_PIPE_BIT);
void Window::endFrame() {
swapChainTextures[currentImageIndex]->changeLayout(Gfx::SE_IMAGE_LAYOUT_PRESENT_SRC_KHR, Gfx::SE_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,
Gfx::SE_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, Gfx::SE_ACCESS_MEMORY_READ_BIT,
Gfx::SE_PIPELINE_STAGE_TOP_OF_PIPE_BIT);
graphics->getGraphicsCommands()->submitCommands(renderingDoneSemaphores[currentSemaphoreIndex]);
VkSemaphore renderDoneHandle = renderingDoneSemaphores[currentSemaphoreIndex]->getHandle();
VkPresentInfoKHR presentInfo = {
@@ -138,99 +118,49 @@ void Window::endFrame()
.pResults = nullptr,
};
VkResult r = vkQueuePresentKHR(graphics->getGraphicsCommands()->getQueue()->getHandle(), &presentInfo);
if(r == VK_SUCCESS)
{ }
else if (r == VK_ERROR_OUT_OF_DATE_KHR || r == VK_SUBOPTIMAL_KHR)
{
if (r == VK_SUCCESS) {
} else if (r == VK_ERROR_OUT_OF_DATE_KHR || r == VK_SUBOPTIMAL_KHR) {
createSwapChain();
}
else
{
} else {
VK_CHECK(r);
}
currentSemaphoreIndex = (currentSemaphoreIndex + 1) % Gfx::numFramesBuffered;
currentFrameIndex = currentSemaphoreIndex;
//graphics->waitDeviceIdle();
// graphics->waitDeviceIdle();
}
void Window::onWindowCloseEvent()
{
}
void Window::onWindowCloseEvent() {}
Gfx::PTexture2D Window::getBackBuffer() const
{
return PTexture2D(swapChainTextures[currentImageIndex]);
}
Gfx::PTexture2D Window::getBackBuffer() const { return PTexture2D(swapChainTextures[currentImageIndex]); }
void Window::setKeyCallback(std::function<void(KeyCode, InputAction, KeyModifier)> callback)
{
keyCallback = callback;
}
void Window::setKeyCallback(std::function<void(KeyCode, InputAction, KeyModifier)> callback) { keyCallback = callback; }
void Window::setMouseMoveCallback(std::function<void(double, double)> callback)
{
mouseMoveCallback = callback;
}
void Window::setMouseMoveCallback(std::function<void(double, double)> callback) { mouseMoveCallback = callback; }
void Window::setMouseButtonCallback(std::function<void(MouseButton, InputAction, KeyModifier)> callback)
{
mouseButtonCallback = callback;
}
void Window::setMouseButtonCallback(std::function<void(MouseButton, InputAction, KeyModifier)> callback) { mouseButtonCallback = callback; }
void Window::setScrollCallback(std::function<void(double, double)> callback)
{
scrollCallback = callback;
}
void Window::setScrollCallback(std::function<void(double, double)> callback) { scrollCallback = callback; }
void Window::setFileCallback(std::function<void(int, const char**)> callback)
{
fileCallback = callback;
}
void Window::setFileCallback(std::function<void(int, const char**)> callback) { fileCallback = callback; }
void Window::setCloseCallback(std::function<void()> callback)
{
closeCallback = callback;
}
void Window::setCloseCallback(std::function<void()> callback) { closeCallback = callback; }
void Window::setResizeCallback(std::function<void(uint32, uint32)> callback)
{
resizeCallback = callback;
}
void Window::setResizeCallback(std::function<void(uint32, uint32)> callback) { resizeCallback = callback; }
void Window::keyPress(KeyCode code, InputAction action, KeyModifier modifier)
{
keyCallback(code, action, modifier);
}
void Window::keyPress(KeyCode code, InputAction action, KeyModifier modifier) { keyCallback(code, action, modifier); }
void Window::mouseMove(double x, double y)
{
mouseMoveCallback(x, y);
}
void Window::mouseMove(double x, double y) { mouseMoveCallback(x, y); }
void Window::mouseButton(MouseButton button, InputAction action, KeyModifier modifier)
{
mouseButtonCallback(button, action, modifier);
}
void Window::mouseButton(MouseButton button, InputAction action, KeyModifier modifier) { mouseButtonCallback(button, action, modifier); }
void Window::scroll(double x, double y)
{
scrollCallback(x, y);
}
void Window::scroll(double x, double y) { scrollCallback(x, y); }
void Window::fileDrop(int num, const char** files)
{
fileCallback(num, files);
}
void Window::fileDrop(int num, const char** files) { fileCallback(num, files); }
void Window::close()
{
closeCallback();
}
void Window::close() { closeCallback(); }
void Window::resize(int width, int height)
{
if (width == 0 || height == 0)
{
void Window::resize(int width, int height) {
if (width == 0 || height == 0) {
paused = true;
return;
}
@@ -246,8 +176,7 @@ void Window::resize(int width, int height)
resizeCallback(width, height);
}
void Window::querySurface()
{
void Window::querySurface() {
vkGetPhysicalDeviceSurfaceCapabilitiesKHR(graphics->getPhysicalDevice(), surface, &capabilities);
uint32 numFormats;
@@ -261,20 +190,15 @@ void Window::querySurface()
vkGetPhysicalDeviceSurfacePresentModesKHR(graphics->getPhysicalDevice(), surface, &numPresentModes, supportedPresentModes.data());
}
void Window::chooseSwapSurfaceFormat()
{
for (const auto& supportedFormat : supportedFormats)
{
if (supportedFormat.format == cast(preferences.preferredFormat))
{
void Window::chooseSwapSurfaceFormat() {
for (const auto& supportedFormat : supportedFormats) {
if (supportedFormat.format == cast(preferences.preferredFormat)) {
format = supportedFormat;
return;
}
}
for (const auto& supportedFormat : supportedFormats)
{
if (supportedFormat.format == VK_FORMAT_R8G8B8A8_SRGB && supportedFormat.colorSpace == VK_COLOR_SPACE_SRGB_NONLINEAR_KHR)
{
for (const auto& supportedFormat : supportedFormats) {
if (supportedFormat.format == VK_FORMAT_R8G8B8A8_SRGB && supportedFormat.colorSpace == VK_COLOR_SPACE_SRGB_NONLINEAR_KHR) {
format = supportedFormat;
return;
}
@@ -282,12 +206,9 @@ void Window::chooseSwapSurfaceFormat()
format = supportedFormats[0];
}
void Window::chooseSwapPresentMode()
{
for (const auto& supportedPresentMode : supportedPresentModes)
{
if (supportedPresentMode == VK_PRESENT_MODE_MAILBOX_KHR)
{
void Window::chooseSwapPresentMode() {
for (const auto& supportedPresentMode : supportedPresentModes) {
if (supportedPresentMode == VK_PRESENT_MODE_MAILBOX_KHR) {
presentMode = supportedPresentMode;
return;
}
@@ -295,8 +216,7 @@ void Window::chooseSwapPresentMode()
presentMode = VK_PRESENT_MODE_FIFO_KHR;
}
void Window::chooseSwapExtent()
{
void Window::chooseSwapExtent() {
if (capabilities.currentExtent.width != std::numeric_limits<uint32>::max()) {
extent = capabilities.currentExtent;
return;
@@ -312,8 +232,7 @@ void Window::chooseSwapExtent()
extent.height = std::clamp(extent.height, capabilities.minImageExtent.height, capabilities.maxImageExtent.height);
}
void Window::createSwapChain()
{
void Window::createSwapChain() {
uint32 imageCount = Gfx::numFramesBuffered;
VkSwapchainCreateInfoKHR createInfo = {
.sType = VK_STRUCTURE_TYPE_SWAPCHAIN_CREATE_INFO_KHR,
@@ -336,21 +255,21 @@ void Window::createSwapChain()
VK_CHECK(vkGetSwapchainImagesKHR(graphics->getDevice(), swapchain, &imageCount, swapChainImages.data()));
for (uint32 i = 0; i < imageCount; ++i)
{
swapChainTextures[i] = new Texture2D(graphics, TextureCreateInfo{
.format = cast(format.format),
.width = extent.width,
.height = extent.height,
.depth = 1,
.mipLevels = 1,
.layers = 1,
.elements = 1,
.samples = 1,
.usage = Gfx::SE_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | Gfx::SE_IMAGE_USAGE_TRANSFER_DST_BIT,
}, swapChainImages[i]);
if(imageAvailableFences[i] != nullptr)
{
for (uint32 i = 0; i < imageCount; ++i) {
swapChainTextures[i] = new Texture2D(graphics,
TextureCreateInfo{
.format = cast(format.format),
.width = extent.width,
.height = extent.height,
.depth = 1,
.mipLevels = 1,
.layers = 1,
.elements = 1,
.samples = 1,
.usage = Gfx::SE_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | Gfx::SE_IMAGE_USAGE_TRANSFER_DST_BIT,
},
swapChainImages[i]);
if (imageAvailableFences[i] != nullptr) {
imageAvailableFences[i]->wait(100000);
imageAvailableFences[i]->reset();
}
@@ -360,24 +279,19 @@ void Window::createSwapChain()
}
}
Viewport::Viewport(PWindow owner, const ViewportCreateInfo &viewportInfo)
: Gfx::Viewport(owner, viewportInfo)
{
Viewport::Viewport(PWindow owner, const ViewportCreateInfo& viewportInfo) : Gfx::Viewport(owner, viewportInfo) {
handle.width = static_cast<float>(sizeX);
handle.height = static_cast<float>(sizeY);
handle.x = static_cast<float>(offsetX);
handle.y = static_cast<float>(offsetY) + handle.height;
handle.height = -handle.height;
handle.minDepth = 1.f;
handle.maxDepth = 0.f;
handle.minDepth = 1.f;
handle.maxDepth = 0.f;
}
Viewport::~Viewport()
{
}
Viewport::~Viewport() {}
void Viewport::resize(uint32 newX, uint32 newY)
{
void Viewport::resize(uint32 newX, uint32 newY) {
sizeX = newX;
sizeY = newY;
handle.width = static_cast<float>(sizeX);
@@ -385,8 +299,7 @@ void Viewport::resize(uint32 newX, uint32 newY)
handle.height = -static_cast<float>(sizeY);
}
void Viewport::move(uint32 newOffsetX, uint32 newOffsetY)
{
void Viewport::move(uint32 newOffsetX, uint32 newOffsetY) {
offsetX = newOffsetX;
offsetY = newOffsetY;
handle.x = static_cast<float>(offsetX);
+19 -20
View File
@@ -1,17 +1,15 @@
#pragma once
#include "Graphics/RenderTarget.h"
#include "Graphics.h"
#include "Texture.h"
#include "Graphics/RenderTarget.h"
#include "Resources.h"
#include "Texture.h"
namespace Seele
{
namespace Vulkan
{
class Window : public Gfx::Window
{
public:
Window(PGraphics graphics, const WindowCreateInfo &createInfo);
namespace Seele {
namespace Vulkan {
class Window : public Gfx::Window {
public:
Window(PGraphics graphics, const WindowCreateInfo& createInfo);
virtual ~Window();
virtual void pollInput() override;
virtual void beginFrame() override;
@@ -25,7 +23,7 @@ public:
virtual void setFileCallback(std::function<void(int, const char**)> callback) override;
virtual void setCloseCallback(std::function<void()> callback) override;
virtual void setResizeCallback(std::function<void(uint32, uint32)> callback) override;
void keyPress(KeyCode code, InputAction action, KeyModifier modifier);
void mouseMove(double x, double y);
void mouseButton(MouseButton button, InputAction action, KeyModifier modifier);
@@ -33,7 +31,8 @@ public:
void fileDrop(int num, const char** files);
void close();
void resize(int width, int height);
protected:
protected:
void querySurface();
void chooseSwapSurfaceFormat();
void chooseSwapPresentMode();
@@ -52,7 +51,7 @@ protected:
VkSurfaceFormatKHR format;
VkPresentModeKHR presentMode;
VkExtent2D extent;
void *windowHandle;
void* windowHandle;
StaticArray<VkImage, Gfx::numFramesBuffered> swapChainImages;
StaticArray<OTexture2D, Gfx::numFramesBuffered> swapChainTextures;
StaticArray<OFence, Gfx::numFramesBuffered> imageAvailableFences;
@@ -71,17 +70,17 @@ protected:
};
DEFINE_REF(Window)
class Viewport : public Gfx::Viewport
{
public:
Viewport(PWindow owner, const ViewportCreateInfo &createInfo);
class Viewport : public Gfx::Viewport {
public:
Viewport(PWindow owner, const ViewportCreateInfo& createInfo);
virtual ~Viewport();
virtual void resize(uint32 newX, uint32 newY);
virtual void move(uint32 newOffsetX, uint32 newOffsetY);
VkViewport getHandle() const { return handle; }
private:
private:
VkViewport handle;
};
DECLARE_REF(Viewport)
}
}
} // namespace Vulkan
} // namespace Seele