Formatted EVERYTHING
This commit is contained in:
@@ -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;
|
||||
// }
|
||||
|
||||
|
||||
@@ -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
|
||||
// {
|
||||
|
||||
@@ -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, ®ion);
|
||||
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, ®ion);
|
||||
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, ®ion);
|
||||
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, ®ion);
|
||||
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; }
|
||||
@@ -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)
|
||||
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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
|
||||
@@ -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)) {
|
||||
|
||||
@@ -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)
|
||||
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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;
|
||||
|
||||
@@ -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");
|
||||
|
||||
}
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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(); }
|
||||
@@ -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;
|
||||
};
|
||||
|
||||
@@ -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));
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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() {}
|
||||
@@ -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
|
||||
@@ -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());
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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)); }
|
||||
|
||||
@@ -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;
|
||||
};
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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
|
||||
@@ -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, ®ion);
|
||||
vkCmdCopyBufferToImage(commandPool->getCommands()->getHandle(), stagingAlloc->buffer, handle->image,
|
||||
VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1, ®ion);
|
||||
|
||||
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, ®ion);
|
||||
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);
|
||||
}
|
||||
|
||||
@@ -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
|
||||
@@ -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(), ¤tImageIndex);
|
||||
vkAcquireNextImageKHR(graphics->getDevice(), swapchain, std::numeric_limits<uint64>::max(),
|
||||
imageAvailableSemaphores[currentSemaphoreIndex]->getHandle(),
|
||||
imageAvailableFences[currentSemaphoreIndex]->getHandle(), ¤tImageIndex);
|
||||
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);
|
||||
|
||||
@@ -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
|
||||
Reference in New Issue
Block a user