compiles again

This commit is contained in:
Dynamitos
2023-11-05 10:36:01 +01:00
parent 4746c0f838
commit 77eb92838c
112 changed files with 1717 additions and 1540 deletions
+188 -80
View File
@@ -4,7 +4,7 @@
using namespace Seele::Vulkan;
SubAllocation::SubAllocation(Allocation *owner, VkDeviceSize allocatedOffset, VkDeviceSize size, VkDeviceSize alignedOffset, VkDeviceSize allocatedSize)
SubAllocation::SubAllocation(PAllocation owner, VkDeviceSize allocatedOffset, VkDeviceSize size, VkDeviceSize alignedOffset, VkDeviceSize allocatedSize)
: owner(owner)
, size(size)
, allocatedOffset(allocatedOffset)
@@ -18,12 +18,22 @@ SubAllocation::~SubAllocation()
owner->markFree(this);
}
VkDeviceMemory SubAllocation::getHandle() const
constexpr VkDeviceMemory SubAllocation::getHandle() const
{
return owner->getHandle();
}
bool SubAllocation::isReadable() const
constexpr VkDeviceSize SubAllocation::getSize() const
{
return size;
}
constexpr VkDeviceSize SubAllocation::getOffset() const
{
return alignedOffset;
}
constexpr bool SubAllocation::isReadable() const
{
return owner->isReadable();
}
@@ -61,8 +71,7 @@ Allocation::Allocation(PGraphics graphics, PAllocator allocator, VkDeviceSize si
allocInfo.pNext = dedicatedInfo;
VK_CHECK(vkAllocateMemory(device, &allocInfo, nullptr, &allocatedMemory));
bytesAllocated = size;
PSubAllocation freeRange = new SubAllocation(this, 0, size, 0, size);
freeRanges[0] = freeRange;
freeRanges[0] = new SubAllocation(this, 0, size, 0, size);
canMap = (properties & VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT) == VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT;
isMapped = false;
@@ -72,15 +81,15 @@ Allocation::~Allocation()
{
}
PSubAllocation Allocation::getSuballocation(VkDeviceSize requestedSize, VkDeviceSize alignment)
OSubAllocation Allocation::getSuballocation(VkDeviceSize requestedSize, VkDeviceSize alignment)
{
std::scoped_lock lck(lock);
if (isDedicated)
{
if (activeAllocations.empty() && requestedSize == bytesAllocated)
{
PSubAllocation suballoc = freeRanges[0];
activeAllocations[0] = suballoc.getHandle();
OSubAllocation suballoc = std::move(freeRanges[0]);
activeAllocations.add(suballoc);
freeRanges.clear();
bytesUsed += requestedSize;
return suballoc;
@@ -92,37 +101,38 @@ PSubAllocation Allocation::getSuballocation(VkDeviceSize requestedSize, VkDevice
}
for (auto& it : freeRanges)
{
VkDeviceSize allocatedOffset = it.first;
PSubAllocation freeAllocation = it.second;
VkDeviceSize allocatedOffset = it.key;
OSubAllocation& freeAllocation = it.value;
assert(allocatedOffset == freeAllocation->allocatedOffset);
VkDeviceSize alignedOffset = align(allocatedOffset, alignment);
VkDeviceSize alignmentAdjustment = alignedOffset - allocatedOffset;
VkDeviceSize size = alignmentAdjustment + requestedSize;
if (freeAllocation->size == size)
VkDeviceSize alignedOffset = allocatedOffset + alignment - 1;
alignedOffset /= alignment;
alignedOffset *= alignment;
VkDeviceSize allocatedSize = requestedSize + (alignedOffset - allocatedOffset);
if (freeAllocation->size == allocatedSize)
{
activeAllocations[allocatedOffset] = freeAllocation.getHandle();
activeAllocations.add(freeAllocation);
freeRanges.erase(allocatedOffset);
bytesUsed += size;
return freeAllocation;
bytesUsed += allocatedSize;
return std::move(freeAllocation);
}
else if (size < freeAllocation->allocatedSize)
else if (allocatedSize < freeAllocation->allocatedSize)
{
freeAllocation->size -= size;
freeAllocation->allocatedSize -= size;
freeAllocation->allocatedOffset += size;
freeAllocation->alignedOffset += size;
PSubAllocation subAlloc = new SubAllocation(this, allocatedOffset, size, alignedOffset, size);
activeAllocations[allocatedOffset] = subAlloc.getHandle();
freeAllocation->size -= allocatedSize;
freeAllocation->allocatedSize -= allocatedSize;
freeAllocation->allocatedOffset += allocatedSize;
freeAllocation->alignedOffset += allocatedSize;
OSubAllocation subAlloc = new SubAllocation(this, allocatedOffset, allocatedSize, alignedOffset, allocatedSize);
activeAllocations.add(subAlloc);
freeRanges[freeAllocation->allocatedOffset] = std::move(freeAllocation);
freeRanges.erase(allocatedOffset);
freeRanges[freeAllocation->allocatedOffset] = freeAllocation;
bytesUsed += size;
bytesUsed += allocatedSize;
return subAlloc;
}
}
return nullptr;
}
void Allocation::markFree(SubAllocation *allocation)
void Allocation::markFree(PSubAllocation allocation)
{
// Dont free if it is already a free allocation, since they also mark themselves on deletion
if (freeRanges.find(allocation->allocatedOffset) != freeRanges.end())
@@ -143,7 +153,7 @@ void Allocation::markFree(SubAllocation *allocation)
&& freeAlloc->allocatedOffset + freeAlloc->allocatedSize >= upperBound)
{
// allocation is already in a free region
return;
assert(false);
}
if (freeAlloc->allocatedOffset + freeAlloc->allocatedSize == lowerBound)
{
@@ -157,35 +167,34 @@ void Allocation::markFree(SubAllocation *allocation)
auto foundAlloc = freeRanges.find(upperBound);
if (foundAlloc != freeRanges.end())
{
freeRangeToDelete = foundAlloc->second;
// There is a free allocation ending where the new free one ends
freeRangeToDelete = foundAlloc->value;
if (allocHandle != nullptr)
{
// extend allocHandle by another foundAlloc->allocatedSize bytes
allocHandle->allocatedSize += foundAlloc->second->allocatedSize;
freeRanges.erase(foundAlloc->first);
allocHandle->allocatedSize += foundAlloc->value->allocatedSize;
freeRanges.erase(foundAlloc->key);
}
else
{
// set foundAlloc back by size amount
allocHandle = foundAlloc->second;
allocHandle = foundAlloc->value;
allocHandle->allocatedOffset -= allocation->allocatedSize;
allocHandle->alignedOffset -= allocation->allocatedSize;
allocHandle->size += allocation->allocatedSize;
allocHandle->allocatedSize += allocation->allocatedSize;
// place back at correct offset
freeRanges[allocHandle->allocatedOffset] = allocHandle;
// place back at correct offset, move original owning pointer
freeRanges[allocHandle->allocatedOffset] = std::move(foundAlloc->value);
// remove from offset map since key changes
freeRanges.erase(foundAlloc->first);
freeRanges.erase(foundAlloc->key);
}
}
if (allocHandle == nullptr)
{
allocHandle = new SubAllocation(this, allocation->allocatedOffset, allocation->size, allocation->alignedOffset, allocation->allocatedSize);
freeRanges[allocation->allocatedOffset] = allocHandle;
freeRanges[allocation->allocatedOffset] = new SubAllocation(this, allocation->allocatedOffset, allocation->size, allocation->alignedOffset, allocation->allocatedSize);
}
activeAllocations.erase(allocation->allocatedOffset);
activeAllocations.remove_if([&](const PSubAllocation& a) {return a.getHandle() == allocation.getHandle(); });
}
bytesUsed -= allocation->allocatedSize;
if(bytesUsed == 0)
@@ -194,25 +203,73 @@ void Allocation::markFree(SubAllocation *allocation)
}
}
constexpr VkDeviceMemory Allocation::getHandle() const
{
return allocatedMemory;
}
constexpr void* Allocation::getMappedPointer()
{
if (!canMap)
{
return nullptr;
}
if (!isMapped)
{
vkMapMemory(device, allocatedMemory, 0, bytesAllocated, 0, &mappedPointer);
isMapped = true;
}
return mappedPointer;
}
constexpr bool Allocation::isReadable() const
{
return readable;
}
void Allocation::flushMemory()
{
VkMappedMemoryRange range = {
.sType = VK_STRUCTURE_TYPE_MAPPED_MEMORY_RANGE,
.pNext = 0,
.memory = allocatedMemory,
.offset = 0,
.size = bytesAllocated,
};
vkFlushMappedMemoryRanges(device, 1, &range);
}
void Allocation::invalidateMemory()
{
VkMappedMemoryRange range = {
.sType = VK_STRUCTURE_TYPE_MAPPED_MEMORY_RANGE,
.pNext = 0,
.memory = allocatedMemory,
.size = bytesAllocated,
};
vkInvalidateMappedMemoryRanges(device, 1, &range);
}
Allocator::Allocator(PGraphics graphics)
: graphics(graphics)
{
vkGetPhysicalDeviceMemoryProperties(graphics->getPhysicalDevice(), &memProperties);
heaps.resize(memProperties.memoryHeapCount);
heaps.reserve(memProperties.memoryHeapCount);
for (size_t i = 0; i < memProperties.memoryHeapCount; ++i)
{
VkMemoryHeap memoryHeap = memProperties.memoryHeaps[i];
HeapInfo &heapInfo = heaps[i];
HeapInfo heapInfo;
heapInfo.maxSize = memoryHeap.size;
heaps.add(std::move(heapInfo));
}
}
Allocator::~Allocator()
{
std::scoped_lock lck(lock);
for (auto heap : heaps)
for (auto& heap : heaps)
{
for (auto alloc : heap.allocations)
for (auto& alloc : heap.allocations)
{
assert(alloc->activeAllocations.empty());
assert(alloc->freeRanges.size() == 1);
@@ -222,7 +279,7 @@ Allocator::~Allocator()
graphics = nullptr;
}
PSubAllocation Allocator::allocate(const VkMemoryRequirements2 &memRequirements2, VkMemoryPropertyFlags properties, VkMemoryDedicatedAllocateInfo *dedicatedInfo)
OSubAllocation Allocator::allocate(const VkMemoryRequirements2 &memRequirements2, VkMemoryPropertyFlags properties, VkMemoryDedicatedAllocateInfo *dedicatedInfo)
{
std::scoped_lock lck(lock);
const VkMemoryRequirements &requirements = memRequirements2.memoryRequirements;
@@ -234,17 +291,17 @@ PSubAllocation Allocator::allocate(const VkMemoryRequirements2 &memRequirements2
VkMemoryDedicatedRequirements *dedicatedReq = (VkMemoryDedicatedRequirements *)memRequirements2.pNext;
if (dedicatedReq->prefersDedicatedAllocation)
{
PAllocation newAllocation = new Allocation(graphics, this, requirements.size, memoryTypeIndex, properties, dedicatedInfo);
heaps[heapIndex].allocations.add(newAllocation);
OAllocation newAllocation = new Allocation(graphics, this, requirements.size, memoryTypeIndex, properties, dedicatedInfo);
heaps[heapIndex].inUse += newAllocation->bytesAllocated;
return newAllocation->getSuballocation(requirements.size, requirements.alignment);
heaps[heapIndex].allocations.add(std::move(newAllocation));
return heaps[heapIndex].allocations.back()->getSuballocation(requirements.size, requirements.alignment);
}
}
for (auto alloc : heaps[heapIndex].allocations)
for (auto& alloc : heaps[heapIndex].allocations)
{
if(alloc->memoryTypeIndex == memoryTypeIndex)
{
PSubAllocation suballoc = alloc->getSuballocation(requirements.size, requirements.alignment);
OSubAllocation suballoc = alloc->getSuballocation(requirements.size, requirements.alignment);
if (suballoc != nullptr)
{
return suballoc;
@@ -253,16 +310,16 @@ PSubAllocation Allocator::allocate(const VkMemoryRequirements2 &memRequirements2
}
// no suitable allocations found, allocate new block
PAllocation newAllocation = new Allocation(graphics, this, (requirements.size > MemoryBlockSize) ? requirements.size : (VkDeviceSize)MemoryBlockSize, memoryTypeIndex, properties, nullptr);
heaps[heapIndex].allocations.add(newAllocation);
OAllocation newAllocation = new Allocation(graphics, this, (requirements.size > MemoryBlockSize) ? requirements.size : (VkDeviceSize)MemoryBlockSize, memoryTypeIndex, properties, nullptr);
heaps[heapIndex].inUse += newAllocation->bytesAllocated;
return newAllocation->getSuballocation(requirements.size, requirements.alignment);
heaps[heapIndex].allocations.add(std::move(newAllocation));
return heaps[heapIndex].allocations.back()->getSuballocation(requirements.size, requirements.alignment);
}
void Allocator::free(Allocation *allocation)
{
std::scoped_lock lck(lock);
for (auto heap : heaps)
for (auto& heap : heaps)
{
for (uint32 i = 0; i < heap.allocations.size(); ++i)
{
@@ -288,12 +345,58 @@ uint32 Allocator::findMemoryType(uint32 typeFilter, VkMemoryPropertyFlags proper
throw std::runtime_error("error finding memory");
}
StagingBuffer::StagingBuffer()
StagingBuffer::StagingBuffer(OSubAllocation allocation, VkBuffer buffer, VkBufferUsageFlags usage, uint8 readable)
: allocation(std::move(allocation))
, buffer(buffer)
, usage(usage)
, readable(readable)
{
}
StagingBuffer::~StagingBuffer()
{
assert(allocation == nullptr);
// buffer went out of scope without being cleaned up
}
void* StagingBuffer::getMappedPointer()
{
return allocation->getMappedPointer();
}
void StagingBuffer::flushMappedMemory()
{
allocation->flushMemory();
}
void StagingBuffer::invalidateMemory()
{
allocation->invalidateMemory();
}
constexpr VkDeviceMemory StagingBuffer::getMemoryHandle() const
{
return allocation->getHandle();
}
constexpr VkDeviceSize StagingBuffer::getOffset() const
{
return allocation->getOffset();
}
constexpr uint64 StagingBuffer::getSize() const
{
return allocation->getSize();
}
constexpr bool StagingBuffer::isReadable() const
{
return readable;
}
constexpr VkBufferUsageFlags StagingBuffer::getUsage() const
{
return usage;
}
StagingManager::StagingManager(PGraphics graphics, PAllocator allocator)
@@ -309,22 +412,22 @@ void StagingManager::clearPending()
{
}
PStagingBuffer StagingManager::allocateStagingBuffer(uint64 size, VkBufferUsageFlags usage, bool bCPURead)
OStagingBuffer StagingManager::allocateStagingBuffer(uint64 size, VkBufferUsageFlags usage, bool readable)
{
std::scoped_lock l(lock);
for (auto it = freeBuffers.begin(); it != freeBuffers.end(); ++it)
{
auto freeBuffer = *it;
if (freeBuffer->getSize() == size && freeBuffer->isReadable() == bCPURead && freeBuffer->usage == usage)
auto& freeBuffer = *it;
if (freeBuffer->getSize() == size && freeBuffer->isReadable() == readable && freeBuffer->getUsage() == usage)
{
//std::cout << "Reusing staging buffer" << std::endl;
activeBuffers.add(freeBuffer.getHandle());
activeBuffers.add(freeBuffer);
freeBuffers.remove(it, false);
return freeBuffer;
return std::move(freeBuffer);
}
}
//std::cout << "Creating new stagingbuffer" << std::endl;
PStagingBuffer stagingBuffer = new StagingBuffer();
VkBuffer buffer;
VkBufferCreateInfo stagingBufferCreateInfo = init::BufferCreateInfo(usage, size);
stagingBufferCreateInfo.sharingMode = VK_SHARING_MODE_EXCLUSIVE;
uint32 queueIndex = graphics->getFamilyMapping().getQueueTypeFamilyIndex(Gfx::QueueType::DEDICATED_TRANSFER);
@@ -332,37 +435,42 @@ PStagingBuffer StagingManager::allocateStagingBuffer(uint64 size, VkBufferUsageF
stagingBufferCreateInfo.pQueueFamilyIndices = &queueIndex;
VkDevice vulkanDevice = graphics->getDevice();
VK_CHECK(vkCreateBuffer(vulkanDevice, &stagingBufferCreateInfo, nullptr, &stagingBuffer->buffer));
VK_CHECK(vkCreateBuffer(vulkanDevice, &stagingBufferCreateInfo, nullptr, &buffer));
VkMemoryDedicatedRequirements dedicatedReqs;
dedicatedReqs.sType = VK_STRUCTURE_TYPE_MEMORY_DEDICATED_REQUIREMENTS;
dedicatedReqs.pNext = nullptr;
VkMemoryRequirements2 memReqs;
memReqs.sType = VK_STRUCTURE_TYPE_MEMORY_REQUIREMENTS_2;
memReqs.pNext = &dedicatedReqs;
VkBufferMemoryRequirementsInfo2 bufferQuery;
bufferQuery.sType = VK_STRUCTURE_TYPE_BUFFER_MEMORY_REQUIREMENTS_INFO_2;
bufferQuery.pNext = nullptr;
bufferQuery.buffer = stagingBuffer->buffer;
VkMemoryDedicatedRequirements dedicatedReqs = {
.sType = VK_STRUCTURE_TYPE_MEMORY_DEDICATED_REQUIREMENTS,
.pNext = nullptr,
};
VkMemoryRequirements2 memReqs = {
.sType = VK_STRUCTURE_TYPE_MEMORY_REQUIREMENTS_2,
.pNext = &dedicatedReqs,
};
VkBufferMemoryRequirementsInfo2 bufferQuery = {
.sType = VK_STRUCTURE_TYPE_BUFFER_MEMORY_REQUIREMENTS_INFO_2,
.pNext = nullptr,
.buffer = buffer,
};
vkGetBufferMemoryRequirements2(vulkanDevice, &bufferQuery, &memReqs);
memReqs.memoryRequirements.alignment =
(16 > memReqs.memoryRequirements.alignment) ? 16 : memReqs.memoryRequirements.alignment;
stagingBuffer->allocation = allocator->allocate(memReqs, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | (bCPURead ? VK_MEMORY_PROPERTY_HOST_COHERENT_BIT : VK_MEMORY_PROPERTY_HOST_CACHED_BIT), stagingBuffer->buffer);
stagingBuffer->bReadable = bCPURead;
stagingBuffer->size = size;
stagingBuffer->usage = usage;
vkBindBufferMemory(graphics->getDevice(), stagingBuffer->buffer, stagingBuffer->getMemoryHandle(), stagingBuffer->getOffset());
activeBuffers.add(stagingBuffer.getHandle());
OStagingBuffer stagingBuffer = new StagingBuffer(
allocator->allocate(memReqs, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | (readable ? VK_MEMORY_PROPERTY_HOST_COHERENT_BIT : VK_MEMORY_PROPERTY_HOST_CACHED_BIT), buffer),
buffer,
usage,
readable
);
vkBindBufferMemory(graphics->getDevice(), buffer, stagingBuffer->getMemoryHandle(), stagingBuffer->getOffset());
activeBuffers.add(stagingBuffer);
return stagingBuffer;
}
void StagingManager::releaseStagingBuffer(PStagingBuffer buffer)
void StagingManager::releaseStagingBuffer(OStagingBuffer buffer)
{
std::scoped_lock l(lock);
freeBuffers.add(buffer);
activeBuffers.remove(activeBuffers.find(buffer.getHandle()));
activeBuffers.remove(buffer);
freeBuffers.add(std::move(buffer));
}
+41 -104
View File
@@ -10,29 +10,23 @@ namespace Seele
namespace Vulkan
{
DECLARE_REF(Graphics)
class Allocation;
class Allocator;
DECLARE_REF(Allocator)
DECLARE_REF(Allocation)
class SubAllocation
{
public:
SubAllocation(Allocation *owner, VkDeviceSize allocatedOffset, VkDeviceSize size, VkDeviceSize alignedOffset, VkDeviceSize allocatedSize);
SubAllocation(PAllocation owner, VkDeviceSize allocatedOffset, VkDeviceSize size, VkDeviceSize alignedOffset, VkDeviceSize allocatedSize);
~SubAllocation();
VkDeviceMemory getHandle() const;
inline VkDeviceSize getSize() const
{
return size;
}
inline VkDeviceSize getOffset() const
{
return alignedOffset;
}
inline bool isReadable() const;
constexpr VkDeviceMemory getHandle() const;
constexpr VkDeviceSize getSize() const;
constexpr VkDeviceSize getOffset() const;
constexpr bool isReadable() const;
void *getMappedPointer();
void flushMemory();
void invalidateMemory();
private:
Allocation *owner;
PAllocation owner;
VkDeviceSize size;
VkDeviceSize allocatedOffset;
VkDeviceSize alignedOffset;
@@ -44,54 +38,16 @@ DEFINE_REF(SubAllocation)
class Allocation
{
public:
Allocation(PGraphics graphics, Allocator *allocator, VkDeviceSize size, uint8 memoryTypeIndex,
Allocation(PGraphics graphics, PAllocator allocator, VkDeviceSize size, uint8 memoryTypeIndex,
VkMemoryPropertyFlags properties, VkMemoryDedicatedAllocateInfo *dedicatedInfo = nullptr);
~Allocation();
PSubAllocation getSuballocation(VkDeviceSize size, VkDeviceSize alignment);
void markFree(SubAllocation *alloc);
inline VkDeviceMemory getHandle() const
{
return allocatedMemory;
}
inline void *getMappedPointer()
{
if (!canMap)
{
return nullptr;
}
if (!isMapped)
{
vkMapMemory(device, allocatedMemory, 0, bytesAllocated, 0, &mappedPointer);
isMapped = true;
}
return mappedPointer;
}
inline bool isReadable() const
{
return readable;
}
void flushMemory()
{
VkMappedMemoryRange range;
range.sType = VK_STRUCTURE_TYPE_MAPPED_MEMORY_RANGE;
range.pNext = 0;
range.memory = allocatedMemory;
range.size = bytesAllocated;
range.offset = 0;
vkFlushMappedMemoryRanges(device, 1, &range);
}
void invalidateMemory()
{
VkMappedMemoryRange range;
range.sType = VK_STRUCTURE_TYPE_MAPPED_MEMORY_RANGE;
range.pNext = 0;
range.memory = allocatedMemory;
range.size = bytesAllocated;
vkInvalidateMappedMemoryRanges(device, 1, &range);
}
OSubAllocation getSuballocation(VkDeviceSize size, VkDeviceSize alignment);
void markFree(PSubAllocation alloc);
constexpr VkDeviceMemory getHandle() const;
constexpr void* getMappedPointer();
constexpr bool isReadable() const;
void flushMemory();
void invalidateMemory();
private:
VkDevice device;
@@ -99,8 +55,8 @@ private:
VkDeviceSize bytesAllocated;
VkDeviceSize bytesUsed;
VkDeviceMemory allocatedMemory;
std::map<VkDeviceSize, PSubAllocation> activeAllocations;
std::map<VkDeviceSize, PSubAllocation> freeRanges;
Array<PSubAllocation> activeAllocations;
Map<VkDeviceSize, OSubAllocation> freeRanges;
std::mutex lock;
void *mappedPointer;
uint8 isDedicated : 1;
@@ -142,7 +98,6 @@ public:
}
void free(Allocation *allocation);
void notifyUsageChanged(int64 usageChange);
private:
enum
{
@@ -152,7 +107,12 @@ private:
{
VkDeviceSize maxSize = 0;
VkDeviceSize inUse = 0;
Array<PAllocation> allocations;
Array<OAllocation> allocations;
HeapInfo() {}
HeapInfo(const HeapInfo& other) = delete;
HeapInfo(HeapInfo&& other) = default;
HeapInfo& operator=(const HeapInfo& other) = delete;
HeapInfo& operator=(HeapInfo&& other) = default;
};
Array<HeapInfo> heaps;
uint32 findMemoryType(uint32 typeBits, VkMemoryPropertyFlags properties);
@@ -161,52 +121,29 @@ private:
VkPhysicalDeviceMemoryProperties memProperties;
};
DEFINE_REF(Allocator)
DECLARE_REF(StagingManager)
class StagingBuffer
{
public:
StagingBuffer();
StagingBuffer(OSubAllocation allocation, VkBuffer buffer, VkBufferUsageFlags usage, uint8 readable);
~StagingBuffer();
void *getMappedPointer()
{
return allocation->getMappedPointer();
}
void flushMappedMemory()
{
allocation->flushMemory();
}
void invalidateMemory()
{
allocation->invalidateMemory();
}
VkBuffer getHandle() const
void* getMappedPointer();
void flushMappedMemory();
void invalidateMemory();
constexpr VkBuffer getHandle() const
{
return buffer;
}
VkDeviceMemory getMemoryHandle() const
{
return allocation->getHandle();
}
VkDeviceSize getOffset() const
{
return allocation->getOffset();
}
uint64 getSize() const
{
return size;
}
bool isReadable() const
{
return bReadable;
}
constexpr VkDeviceMemory getMemoryHandle() const;
constexpr VkDeviceSize getOffset() const;
constexpr uint64 getSize() const;
constexpr bool isReadable() const;
constexpr VkBufferUsageFlags getUsage() const;
private:
PSubAllocation allocation;
OSubAllocation allocation;
VkBuffer buffer;
uint64 size;
VkBufferUsageFlags usage;
uint8 bReadable;
friend class StagingManager;
uint8 readable;
};
DEFINE_REF(StagingBuffer)
@@ -215,15 +152,15 @@ class StagingManager
public:
StagingManager(PGraphics graphics, PAllocator allocator);
~StagingManager();
PStagingBuffer allocateStagingBuffer(uint64 size, VkBufferUsageFlags usageFlags = VK_BUFFER_USAGE_TRANSFER_SRC_BIT, bool bCPURead = false);
void releaseStagingBuffer(PStagingBuffer buffer);
OStagingBuffer allocateStagingBuffer(uint64 size, VkBufferUsageFlags usageFlags = VK_BUFFER_USAGE_TRANSFER_SRC_BIT, bool bCPURead = false);
void releaseStagingBuffer(OStagingBuffer buffer);
void clearPending();
private:
PGraphics graphics;
PAllocator allocator;
Array<PStagingBuffer> freeBuffers;
Array<StagingBuffer *> activeBuffers;
Array<OStagingBuffer> freeBuffers;
Array<PStagingBuffer> activeBuffers;
std::mutex lock;
};
DEFINE_REF(StagingManager)
+29 -26
View File
@@ -1,4 +1,6 @@
#include "Buffer.h"
#include "Initializer.h"
#include "CommandBuffer.h"
using namespace Seele;
using namespace Seele::Vulkan;
@@ -7,20 +9,20 @@ struct PendingBuffer
{
uint64 offset;
uint64 size;
PStagingBuffer stagingBuffer;
OStagingBuffer stagingBuffer;
Gfx::QueueType prevQueue;
bool bWriteOnly;
bool writeOnly;
};
static std::map<Vulkan::Buffer*, PendingBuffer> pendingBuffers;
Buffer::Buffer(PGraphics graphics, uint64 size, VkBufferUsageFlags usage, Gfx::QueueType& queueType, bool bDynamic)
Buffer::Buffer(PGraphics graphics, uint64 size, VkBufferUsageFlags usage, Gfx::QueueType& queueType, bool dynamic)
: graphics(graphics)
, currentBuffer(0)
, size(size)
, owner(queueType)
{
if(bDynamic)
if(dynamic)
{
numBuffers = Gfx::numFramesBuffered;
}
@@ -166,12 +168,12 @@ void Buffer::executePipelineBarrier(VkAccessFlags srcAccess, VkPipelineStageFlag
vkCmdPipelineBarrier(commandBuffer->getHandle(), srcStage, dstStage, 0, 0, nullptr, numBuffers, dynamicBarriers, 0, nullptr);
}
void * Buffer::lock(bool bWriteOnly)
void * Buffer::lock(bool writeOnly)
{
return lockRegion(0, size, bWriteOnly);
return lockRegion(0, size, writeOnly);
}
void * Buffer::lockRegion(uint64 regionOffset, uint64 regionSize, bool bWriteOnly)
void * Buffer::lockRegion(uint64 regionOffset, uint64 regionSize, bool writeOnly)
{
void *data = nullptr;
@@ -190,16 +192,16 @@ void * Buffer::lockRegion(uint64 regionOffset, uint64 regionSize, bool bWriteOnl
//assert(bStatic || bDynamic || bUAV);
PendingBuffer pending;
pending.bWriteOnly = bWriteOnly;
pending.writeOnly = writeOnly;
pending.prevQueue = owner;
pending.offset = regionOffset;
pending.size = regionSize;
if (bWriteOnly)
if (writeOnly)
{
//requestOwnershipTransfer(Gfx::QueueType::DEDICATED_TRANSFER);
PStagingBuffer stagingBuffer = graphics->getStagingManager()->allocateStagingBuffer(regionSize, VK_BUFFER_USAGE_TRANSFER_SRC_BIT);
OStagingBuffer stagingBuffer = graphics->getStagingManager()->allocateStagingBuffer(regionSize, VK_BUFFER_USAGE_TRANSFER_SRC_BIT);
data = stagingBuffer->getMappedPointer();
pending.stagingBuffer = stagingBuffer;
pending.stagingBuffer = std::move(stagingBuffer);
}
else
{
@@ -220,7 +222,7 @@ void * Buffer::lockRegion(uint64 regionOffset, uint64 regionSize, bool bWriteOnl
barrier.size = size;
vkCmdPipelineBarrier(handle, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, 0, 0, nullptr, 1, &barrier, 0, nullptr);
PStagingBuffer stagingBuffer = graphics->getStagingManager()->allocateStagingBuffer(size, VK_BUFFER_USAGE_TRANSFER_DST_BIT, true);
OStagingBuffer stagingBuffer = graphics->getStagingManager()->allocateStagingBuffer(size, VK_BUFFER_USAGE_TRANSFER_DST_BIT, true);
VkBufferCopy regions;
regions.size = size;
@@ -233,11 +235,12 @@ void * Buffer::lockRegion(uint64 regionOffset, uint64 regionSize, bool bWriteOnl
vkQueueWaitIdle(graphics->getQueueCommands(owner)->getQueue()->getHandle());
stagingBuffer->getMappedPointer(); // this maps the memory if not mapped already
stagingBuffer->flushMappedMemory();
pending.stagingBuffer = stagingBuffer;
data = stagingBuffer->getMappedPointer();
pending.stagingBuffer = std::move(stagingBuffer);
}
pendingBuffers[this] = pending;
pendingBuffers[this] = std::move(pending);
assert(data);
return data;
@@ -248,10 +251,9 @@ void Buffer::unlock()
auto found = pendingBuffers.find(this);
if (found != pendingBuffers.end())
{
PendingBuffer pending = found->second;
PendingBuffer& pending = found->second;
pending.stagingBuffer->flushMappedMemory();
pendingBuffers.erase(this);
if (pending.bWriteOnly)
if (pending.writeOnly)
{
PStagingBuffer stagingBuffer = pending.stagingBuffer;
PCmdBuffer cmdBuffer = graphics->getQueueCommands(owner)->getCommands();
@@ -265,16 +267,17 @@ void Buffer::unlock()
graphics->getQueueCommands(owner)->submitCommands();
}
//requestOwnershipTransfer(pending.prevQueue);
graphics->getStagingManager()->releaseStagingBuffer(pending.stagingBuffer);
graphics->getStagingManager()->releaseStagingBuffer(std::move(pending.stagingBuffer));
pendingBuffers.erase(this);
}
}
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.bDynamic)
, Vulkan::Buffer(graphics, createInfo.sourceData.size, VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT, currentOwner, createInfo.dynamic)
, dedicatedStagingBuffer(nullptr)
{
if(createInfo.bDynamic)
if(createInfo.dynamic)
{
dedicatedStagingBuffer = graphics->getStagingManager()->allocateStagingBuffer(createInfo.sourceData.size, VK_BUFFER_USAGE_TRANSFER_SRC_BIT);
}
@@ -302,13 +305,13 @@ bool UniformBuffer::updateContents(const DataSource &sourceData)
unlock();
return true;
}
void* UniformBuffer::lock(bool bWriteOnly)
void* UniformBuffer::lock(bool writeOnly)
{
if(dedicatedStagingBuffer != nullptr)
{
return dedicatedStagingBuffer->getMappedPointer();
}
return Vulkan::Buffer::lock(bWriteOnly);
return Vulkan::Buffer::lock(writeOnly);
}
void UniformBuffer::unlock()
@@ -359,7 +362,7 @@ VkAccessFlags UniformBuffer::getDestAccessMask()
ShaderBuffer::ShaderBuffer(PGraphics graphics, const ShaderBufferCreateInfo &sourceData)
: Gfx::ShaderBuffer(graphics->getFamilyMapping(), sourceData.stride, sourceData.sourceData.size / sourceData.stride, sourceData.sourceData)
, Vulkan::Buffer(graphics, sourceData.sourceData.size, VK_BUFFER_USAGE_STORAGE_BUFFER_BIT, currentOwner, sourceData.bDynamic)
, Vulkan::Buffer(graphics, sourceData.sourceData.size, VK_BUFFER_USAGE_STORAGE_BUFFER_BIT, currentOwner, sourceData.dynamic)
{
if (sourceData.sourceData.data != nullptr)
{
@@ -383,13 +386,13 @@ bool ShaderBuffer::updateContents(const DataSource &sourceData)
unlock();
return true;
}
void* ShaderBuffer::lock(bool bWriteOnly)
void* ShaderBuffer::lock(bool writeOnly)
{
if(dedicatedStagingBuffer != nullptr)
{
return dedicatedStagingBuffer->getMappedPointer();
}
return ShaderBuffer::lock(bWriteOnly);
return ShaderBuffer::lock(writeOnly);
}
void ShaderBuffer::unlock()
+7 -7
View File
@@ -11,7 +11,7 @@ namespace Vulkan
class Buffer
{
public:
Buffer(PGraphics graphics, uint64 size, VkBufferUsageFlags usage, Gfx::QueueType& queueType, bool bDynamic = false);
Buffer(PGraphics graphics, uint64 size, VkBufferUsageFlags usage, Gfx::QueueType& queueType, bool dynamic = false);
virtual ~Buffer();
VkBuffer getHandle() const
{
@@ -26,8 +26,8 @@ public:
{
currentBuffer = (currentBuffer + 1) % numBuffers;
}
virtual void *lock(bool bWriteOnly = true);
virtual void *lockRegion(uint64 regionOffset, uint64 regionSize, bool bWriteOnly = true);
virtual void *lock(bool writeOnly = true);
virtual void *lockRegion(uint64 regionOffset, uint64 regionSize, bool writeOnly = true);
virtual void unlock();
protected:
@@ -62,7 +62,7 @@ public:
virtual ~UniformBuffer();
virtual bool updateContents(const DataSource &sourceData);
virtual void* lock(bool bWriteOnly = true) override;
virtual void* lock(bool writeOnly = true) override;
virtual void unlock() override;
protected:
// Inherited via Vulkan::Buffer
@@ -75,7 +75,7 @@ protected:
VkAccessFlags dstAccess, VkPipelineStageFlags dstStage);
private:
PStagingBuffer dedicatedStagingBuffer;
OStagingBuffer dedicatedStagingBuffer;
};
DEFINE_REF(UniformBuffer)
@@ -86,7 +86,7 @@ public:
virtual ~ShaderBuffer();
virtual bool updateContents(const DataSource &sourceData);
virtual void* lock(bool bWriteOnly = true) override;
virtual void* lock(bool writeOnly = true) override;
virtual void unlock() override;
protected:
// Inherited via Vulkan::Buffer
@@ -98,7 +98,7 @@ protected:
virtual void executePipelineBarrier(VkAccessFlags srcAccess, VkPipelineStageFlags srcStage,
VkAccessFlags dstAccess, VkPipelineStageFlags dstStage);
private:
PStagingBuffer dedicatedStagingBuffer;
OStagingBuffer dedicatedStagingBuffer;
};
DEFINE_REF(ShaderBuffer)
+2 -2
View File
@@ -313,7 +313,7 @@ void RenderCommand::draw(uint32 vertexCount, uint32 instanceCount, int32 firstVe
void RenderCommand::dispatch(uint32 groupX, uint32 groupY, uint32 groupZ)
{
assert(threadId == std::this_thread::get_id());
vkCmdDrawMeshTasksEXT(handle, groupX, groupY, groupZ);
graphics->vkCmdDrawMeshTasksEXT(handle, groupX, groupY, groupZ);
}
ComputeCommand::ComputeCommand(PGraphics graphics, VkCommandPool cmdPool)
@@ -524,4 +524,4 @@ void CommandBufferManager::submitCommands(PSemaphore signalSemaphore)
allocatedBuffers.add(new CmdBuffer(graphics, commandPool, this));
activeCmdBuffer = allocatedBuffers.back();
activeCmdBuffer->begin();
}
}
@@ -2,6 +2,7 @@
#include "Graphics.h"
#include "Initializer.h"
#include "CommandBuffer.h"
#include "Texture.h"
using namespace Seele;
using namespace Seele::Vulkan;
@@ -130,12 +131,12 @@ void DescriptorSet::updateBuffer(uint32_t binding, Gfx::PUniformBuffer uniformBu
VkWriteDescriptorSet writeDescriptor = init::WriteDescriptorSet(setHandle, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, binding, &bufferInfos.back());
writeDescriptors.add(writeDescriptor);
cachedData[binding] = new UniformBuffer(*vulkanBuffer.getHandle());
cachedData[binding] = vulkanBuffer.getHandle();
}
void DescriptorSet::updateBuffer(uint32_t binding, Gfx::PShaderBuffer ShaderBuffer)
void DescriptorSet::updateBuffer(uint32_t binding, Gfx::PShaderBuffer shaderBuffer)
{
PShaderBuffer vulkanBuffer = ShaderBuffer.cast<ShaderBuffer>();
PShaderBuffer vulkanBuffer = shaderBuffer.cast<ShaderBuffer>();
ShaderBuffer* cachedBuffer = reinterpret_cast<ShaderBuffer*>(cachedData[binding]);
if(vulkanBuffer.getHandle() == cachedBuffer)
{
@@ -349,21 +350,20 @@ Gfx::PDescriptorSet DescriptorAllocator::allocateDescriptorSet()
VK_CHECK(vkAllocateDescriptorSets(graphics->getDevice(), &allocInfo, &cachedHandles[setIndex]->setHandle));
}
cachedHandles[setIndex]->allocate();
descriptorSet = cachedHandles[setIndex];
PDescriptorSet vulkanSet = descriptorSet.cast<DescriptorSet>();
PDescriptorSet vulkanSet = cachedHandles[setIndex];
vulkanSet->cachedData.resize(layout.bindings.size());
// Not really pretty, but this way the set knows which ones are valid
std::memset(vulkanSet->cachedData.data(), 0, sizeof(void*) * vulkanSet->cachedData.size());
//Found set, stop searching
return;
return vulkanSet;
}
if(nextAlloc == nullptr)
{
nextAlloc = new DescriptorAllocator(graphics, layout);
}
nextAlloc->allocateDescriptorSet(descriptorSet);
return nextAlloc->allocateDescriptorSet();
//throw std::logic_error("Out of descriptor sets");
}
+1 -1
View File
@@ -1,4 +1,4 @@
#include "VulkanGraphicsEnums.h"
#include "Enums.h"
using namespace Seele;
using namespace Seele::Vulkan;
+57 -43
View File
@@ -8,6 +8,7 @@
#include "RenderTarget.h"
#include "RenderPass.h"
#include "Framebuffer.h"
#include "Shader.h"
#include <GLFW/glfw3.h>
using namespace Seele;
@@ -134,8 +135,8 @@ Gfx::OUniformBuffer Graphics::createUniformBuffer(const UniformBufferCreateInfo
Gfx::OShaderBuffer Graphics::createShaderBuffer(const ShaderBufferCreateInfo &bulkData)
{
OShaderBuffer ShaderBuffer = new ShaderBuffer(this, bulkData);
return ShaderBuffer;
OShaderBuffer shaderBuffer = new ShaderBuffer(this, bulkData);
return shaderBuffer;
}
Gfx::OVertexBuffer Graphics::createVertexBuffer(const VertexBufferCreateInfo &bulkData)
{
@@ -150,13 +151,13 @@ Gfx::OIndexBuffer Graphics::createIndexBuffer(const IndexBufferCreateInfo &bulkD
}
Gfx::PRenderCommand Graphics::createRenderCommand(const std::string& name)
{
ORenderCommand cmdBuffer = getGraphicsCommands()->createRenderCommand(activeRenderPass, activeFramebuffer, name);
PRenderCommand cmdBuffer = getGraphicsCommands()->createRenderCommand(activeRenderPass, activeFramebuffer, name);
return cmdBuffer;
}
Gfx::PComputeCommand Graphics::createComputeCommand(const std::string& name)
{
OComputeCommand cmdBuffer = getComputeCommands()->createComputeCommand(name);
PComputeCommand cmdBuffer = getComputeCommands()->createComputeCommand(name);
return cmdBuffer;
}
@@ -172,52 +173,51 @@ Gfx::OVertexShader Graphics::createVertexShader(const ShaderCreateInfo& createIn
shader->create(createInfo);
return shader;
}
Gfx::PControlShader Graphics::createControlShader(const ShaderCreateInfo& createInfo)
Gfx::OFragmentShader Graphics::createFragmentShader(const ShaderCreateInfo& createInfo)
{
PControlShader shader = new ControlShader(this);
OFragmentShader shader = new FragmentShader(this);
shader->create(createInfo);
return shader;
}
Gfx::PEvaluationShader Graphics::createEvaluationShader(const ShaderCreateInfo& createInfo)
Gfx::OComputeShader Graphics::createComputeShader(const ShaderCreateInfo& createInfo)
{
PEvaluationShader shader = new EvaluationShader(this);
OComputeShader shader = new ComputeShader(this);
shader->create(createInfo);
return shader;
}
Gfx::PGeometryShader Graphics::createGeometryShader(const ShaderCreateInfo& createInfo)
Gfx::OTaskShader Graphics::createTaskShader(const ShaderCreateInfo& createInfo)
{
PGeometryShader shader = new GeometryShader(this);
OTaskShader shader = new TaskShader(this);
shader->create(createInfo);
return shader;
}
Gfx::PFragmentShader Graphics::createFragmentShader(const ShaderCreateInfo& createInfo)
Gfx::OMeshShader Graphics::createMeshShader(const ShaderCreateInfo& createInfo)
{
PFragmentShader shader = new FragmentShader(this);
shader->create(createInfo);
return shader;
}
Gfx::PComputeShader Graphics::createComputeShader(const ShaderCreateInfo& createInfo)
{
PComputeShader shader = new ComputeShader(this);
OMeshShader shader = new MeshShader(this);
shader->create(createInfo);
return shader;
}
Gfx::PGraphicsPipeline Graphics::createGraphicsPipeline(const GraphicsPipelineCreateInfo& createInfo)
Gfx::OGraphicsPipeline Graphics::createGraphicsPipeline(const Gfx::LegacyPipelineCreateInfo& createInfo)
{
PGraphicsPipeline pipeline = pipelineCache->createPipeline(createInfo);
OGraphicsPipeline pipeline = pipelineCache->createPipeline(createInfo);
return pipeline;
}
Gfx::OGraphicsPipeline Graphics::createGraphicsPipeline(const Gfx::MeshPipelineCreateInfo& createInfo)
{
OGraphicsPipeline pipeline = pipelineCache->createPipeline(createInfo);
return pipeline;
}
Gfx::PComputePipeline Graphics::createComputePipeline(const ComputePipelineCreateInfo& createInfo)
Gfx::OComputePipeline Graphics::createComputePipeline(const Gfx::ComputePipelineCreateInfo& createInfo)
{
PComputePipeline pipeline = pipelineCache->createPipeline(createInfo);
OComputePipeline pipeline = pipelineCache->createPipeline(createInfo);
return pipeline;
}
Gfx::PSamplerState Graphics::createSamplerState(const SamplerCreateInfo& createInfo)
Gfx::OSamplerState Graphics::createSamplerState(const SamplerCreateInfo& createInfo)
{
PSamplerState sampler = new SamplerState();
OSamplerState sampler = new SamplerState();
VkSamplerCreateInfo vkInfo =
init::SamplerCreateInfo();
vkInfo.addressModeU = cast(createInfo.addressModeU);
@@ -239,14 +239,14 @@ Gfx::PSamplerState Graphics::createSamplerState(const SamplerCreateInfo& createI
VK_CHECK(vkCreateSampler(handle, &vkInfo, nullptr, &sampler->sampler));
return sampler;
}
Gfx::PDescriptorLayout Graphics::createDescriptorLayout(const std::string& name)
Gfx::ODescriptorLayout Graphics::createDescriptorLayout(const std::string& name)
{
PDescriptorLayout layout = new DescriptorLayout(this, name);
ODescriptorLayout layout = new DescriptorLayout(this, name);
return layout;
}
Gfx::PPipelineLayout Graphics::createPipelineLayout(Gfx::PPipelineLayout baseLayout)
Gfx::OPipelineLayout Graphics::createPipelineLayout(Gfx::PPipelineLayout baseLayout)
{
PPipelineLayout layout = new PipelineLayout(this, baseLayout);
OPipelineLayout layout = new PipelineLayout(this, baseLayout);
return layout;
}
@@ -317,6 +317,10 @@ void Graphics::copyTexture(Gfx::PTexture srcTexture, Gfx::PTexture dstTexture)
}
}
void Graphics::vkCmdDrawMeshTasksEXT(VkCommandBuffer handle, uint32 groupX, uint32 groupY, uint32 groupZ)
{
cmdDrawMeshTasks(handle, groupX, groupY, groupZ);
}
PCommandBufferManager Graphics::getQueueCommands(Gfx::QueueType queueType)
{
switch (queueType)
@@ -361,7 +365,7 @@ PCommandBufferManager Graphics::getDedicatedTransferCommands()
{
if(dedicatedTransferCommands == nullptr)
{
dedicatedTransferCommands = new CommandBufferManager(this, dedicatedTransferQueue);
dedicatedTransferCommands = new CommandBufferManager(this, dedicatedTransferQueue != nullptr ? dedicatedTransferQueue : transferQueue);
}
return dedicatedTransferCommands;
}
@@ -441,7 +445,7 @@ void Graphics::pickPhysicalDevice()
{
uint32 currentRating = 0;
vkGetPhysicalDeviceProperties(dev, &props);
vkGetPhysicalDeviceFeatures(dev, &features);
vkGetPhysicalDeviceFeatures2(dev, &features);
if (props.deviceType == VK_PHYSICAL_DEVICE_TYPE_DISCRETE_GPU)
{
std::cout << "found dedicated gpu " << props.deviceName << std::endl;
@@ -461,7 +465,7 @@ void Graphics::pickPhysicalDevice()
}
physicalDevice = bestDevice;
vkGetPhysicalDeviceProperties(physicalDevice, &props);
vkGetPhysicalDeviceFeatures(physicalDevice, &features);
vkGetPhysicalDeviceFeatures2(physicalDevice, &features);
}
void Graphics::createDevice(GraphicsInitializer initializer)
@@ -563,13 +567,13 @@ void Graphics::createDevice(GraphicsInitializer initializer)
(uint32)queueInfos.size(),
&features);
VkPhysicalDeviceDescriptorIndexingFeatures descriptorIndexing = {};
std::memset(&descriptorIndexing, 0, sizeof(descriptorIndexing));
descriptorIndexing.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DESCRIPTOR_INDEXING_FEATURES;
descriptorIndexing.shaderSampledImageArrayNonUniformIndexing = VK_TRUE;
descriptorIndexing.runtimeDescriptorArray = VK_TRUE;
descriptorIndexing.descriptorBindingVariableDescriptorCount = VK_TRUE;
descriptorIndexing.descriptorBindingPartiallyBound = VK_TRUE;
VkPhysicalDeviceDescriptorIndexingFeatures descriptorIndexing = {
.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DESCRIPTOR_INDEXING_FEATURES,
.shaderSampledImageArrayNonUniformIndexing = VK_TRUE,
.descriptorBindingPartiallyBound = VK_TRUE,
.descriptorBindingVariableDescriptorCount = VK_TRUE,
.runtimeDescriptorArray = VK_TRUE,
};
deviceInfo.pNext = &descriptorIndexing;
#if ENABLE_VALIDATION
VkDeviceDiagnosticsConfigCreateInfoNV crashDiagInfo;
@@ -581,6 +585,18 @@ void Graphics::createDevice(GraphicsInitializer initializer)
VK_DEVICE_DIAGNOSTICS_CONFIG_ENABLE_SHADER_DEBUG_INFO_BIT_NV;
descriptorIndexing.pNext = &crashDiagInfo;
#endif
VkPhysicalDeviceMeshShaderFeaturesEXT enabledMeshShaderFeatures = {
.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MESH_SHADER_FEATURES_EXT,
.taskShader = VK_TRUE,
.meshShader = VK_TRUE,
};
if (Gfx::useMeshShading)
{
descriptorIndexing.pNext = &enabledMeshShaderFeatures;
initializer.deviceExtensions.add("VK_EXT_mesh_shader");
initializer.deviceExtensions.add("VK_KHR_SPIRV_1_4_EXTENSION_NAME");
initializer.deviceExtensions.add("VK_KHR_SHADER_FLOAT_CONTROLS_EXTENSION_NAME");
}
deviceInfo.enabledExtensionCount = (uint32)initializer.deviceExtensions.size();
deviceInfo.ppEnabledExtensionNames = initializer.deviceExtensions.data();
deviceInfo.enabledLayerCount = (uint32_t)initializer.layers.size();
@@ -590,6 +606,8 @@ void Graphics::createDevice(GraphicsInitializer initializer)
VK_CHECK(vkCreateDevice(physicalDevice, &deviceInfo, nullptr, &handle));
std::cout << "Vulkan handle: " << handle << std::endl;
cmdDrawMeshTasks = (PFN_vkCmdDrawMeshTasksEXT)vkGetDeviceProcAddr(handle, "vkCmdDrawMeshTasksEXT");
graphicsQueue = new Queue(this, Gfx::QueueType::GRAPHICS, graphicsQueueInfo.familyIndex, 0);
if (Gfx::useAsyncCompute && asyncComputeInfo.familyIndex != -1)
{
@@ -613,12 +631,8 @@ void Graphics::createDevice(GraphicsInitializer initializer)
{
dedicatedTransferQueue = new Queue(this, Gfx::QueueType::DEDICATED_TRANSFER, dedicatedTransferQueueInfo.familyIndex, 0);
}
else
{
dedicatedTransferQueue = transferQueue;
}
queueMapping.graphicsFamily = graphicsQueue->getFamilyIndex();
queueMapping.computeFamily = computeQueue->getFamilyIndex();
queueMapping.transferFamily = transferQueue->getFamilyIndex();
queueMapping.dedicatedTransferFamily = dedicatedTransferQueue->getFamilyIndex();
queueMapping.dedicatedTransferFamily = dedicatedTransferQueue != nullptr ? dedicatedTransferQueue->getFamilyIndex() : transferQueue->getFamilyIndex();
}
+3 -1
View File
@@ -73,7 +73,9 @@ public:
virtual Gfx::OPipelineLayout createPipelineLayout(Gfx::PPipelineLayout baseLayout = nullptr) override;
virtual void copyTexture(Gfx::PTexture srcTexture, Gfx::PTexture dstTexture) override;
void vkCmdDrawMeshTasksEXT(VkCommandBuffer handle, uint32 groupX, uint32 groupY, uint32 groupZ);
protected:
PFN_vkCmdDrawMeshTasksEXT cmdDrawMeshTasks;
Array<const char *> getRequiredExtensions();
void initInstance(GraphicsInitializer initInfo);
void setupDebugCallback();
@@ -97,7 +99,7 @@ protected:
thread_local static OCommandBufferManager transferCommands;
thread_local static OCommandBufferManager dedicatedTransferCommands;
VkPhysicalDeviceProperties props;
VkPhysicalDeviceFeatures features;
VkPhysicalDeviceFeatures2 features;
VkDebugReportCallbackEXT callback;
std::mutex viewportLock;
Array<PViewport> viewports;
@@ -1,6 +1,7 @@
#include "Initializer.h"
#include <iostream>
#include "Initializer.h"
#include "Initializer.h"
using namespace Seele::Vulkan;
+5
View File
@@ -51,6 +51,11 @@ VkDeviceCreateInfo DeviceCreateInfo(
uint32_t queueCount,
VkPhysicalDeviceFeatures *features);
VkDeviceCreateInfo DeviceCreateInfo(
VkDeviceQueueCreateInfo* queueInfos,
uint32_t queueCount,
VkPhysicalDeviceFeatures2* features);
VkSwapchainCreateInfoKHR SwapchainCreateInfo(
VkSurfaceKHR surface,
uint32_t minImageCount,
+21 -19
View File
@@ -48,7 +48,7 @@ PipelineCache::~PipelineCache()
std::cout << "Written " << cacheSize << " bytes to cache" << std::endl;
}
PGraphicsPipeline PipelineCache::createPipeline(const Gfx::LegacyPipelineCreateInfo& gfxInfo)
OGraphicsPipeline PipelineCache::createPipeline(const Gfx::LegacyPipelineCreateInfo& gfxInfo)
{
uint32 stageCount = 0;
@@ -99,7 +99,7 @@ PGraphicsPipeline PipelineCache::createPipeline(const Gfx::LegacyPipelineCreateI
*res = VkVertexInputBindingDescription{
.binding = elem.binding,
.stride = elem.stride,
.inputRate = elem.bInstanced ? VK_VERTEX_INPUT_RATE_INSTANCE : VK_VERTEX_INPUT_RATE_VERTEX,
.inputRate = elem.instanced ? VK_VERTEX_INPUT_RATE_INSTANCE : VK_VERTEX_INPUT_RATE_VERTEX,
};
}
vertexInput.pVertexAttributeDescriptions = attributes.data();
@@ -217,12 +217,12 @@ PGraphicsPipeline PipelineCache::createPipeline(const Gfx::LegacyPipelineCreateI
std::cout << "Gfx creation time: " << delta << std::endl;
PGraphicsPipeline result = new GraphicsPipeline(graphics, pipelineHandle, layout);
OGraphicsPipeline result = new GraphicsPipeline(graphics, pipelineHandle, layout);
return result;
}
PGraphicsPipeline PipelineCache::createPipeline(const Gfx::MeshPipelineCreateInfo& gfxInfo)
OGraphicsPipeline PipelineCache::createPipeline(const Gfx::MeshPipelineCreateInfo& gfxInfo)
{
uint32 stageCount = 0;
@@ -361,33 +361,35 @@ PGraphicsPipeline PipelineCache::createPipeline(const Gfx::MeshPipelineCreateInf
int64 delta = std::chrono::duration_cast<std::chrono::microseconds>(endTime - beginTime).count();
std::cout << "Gfx creation time: " << delta << std::endl;
PGraphicsPipeline result = new GraphicsPipeline(graphics, pipelineHandle, layout);
OGraphicsPipeline result = new GraphicsPipeline(graphics, pipelineHandle, layout);
return result;
}
PComputePipeline PipelineCache::createPipeline(const Gfx::ComputePipelineCreateInfo& computeInfo)
OComputePipeline PipelineCache::createPipeline(const Gfx::ComputePipelineCreateInfo& computeInfo)
{
VkComputePipelineCreateInfo createInfo;
createInfo.sType = VK_STRUCTURE_TYPE_COMPUTE_PIPELINE_CREATE_INFO;
createInfo.pNext = 0;
createInfo.flags = 0;
createInfo.basePipelineIndex = 0;
createInfo.basePipelineHandle = VK_NULL_HANDLE;
auto layout = computeInfo.pipelineLayout.cast<PipelineLayout>();
createInfo.layout = layout->getHandle();
auto computeStage = computeInfo.computeShader.cast<ComputeShader>();
createInfo.stage = init::PipelineShaderStageCreateInfo(
VK_SHADER_STAGE_COMPUTE_BIT,
computeStage->getModuleHandle(),
computeStage->getEntryPointName());
VkComputePipelineCreateInfo createInfo = {
.sType = VK_STRUCTURE_TYPE_COMPUTE_PIPELINE_CREATE_INFO,
.pNext = 0,
.flags = 0,
.stage = init::PipelineShaderStageCreateInfo(
VK_SHADER_STAGE_COMPUTE_BIT,
computeStage->getModuleHandle(),
computeStage->getEntryPointName()),
.layout = layout->getHandle(),
.basePipelineHandle = VK_NULL_HANDLE,
.basePipelineIndex = 0,
};
VkPipeline pipelineHandle;
auto beginTime = std::chrono::high_resolution_clock::now();
VK_CHECK(vkCreateComputePipelines(graphics->getDevice(), cache, 1, &createInfo, nullptr, &pipelineHandle));
auto endTime = std::chrono::high_resolution_clock::now();
int64 delta = std::chrono::duration_cast<std::chrono::microseconds>(endTime - beginTime).count();
std::cout << "Compute creation time: " << delta << std::endl;
PComputePipeline result = new ComputePipeline(graphics, pipelineHandle, layout);
OComputePipeline result = new ComputePipeline(graphics, pipelineHandle, layout);
return result;
}
+3 -3
View File
@@ -10,9 +10,9 @@ class PipelineCache
public:
PipelineCache(PGraphics graphics, const std::string& cacheFilePath);
~PipelineCache();
PGraphicsPipeline createPipeline(const Gfx::LegacyPipelineCreateInfo& createInfo);
PGraphicsPipeline createPipeline(const Gfx::MeshPipelineCreateInfo& createInfo);
PComputePipeline createPipeline(const Gfx::ComputePipelineCreateInfo& createInfo);
OGraphicsPipeline createPipeline(const Gfx::LegacyPipelineCreateInfo& createInfo);
OGraphicsPipeline createPipeline(const Gfx::MeshPipelineCreateInfo& createInfo);
OComputePipeline createPipeline(const Gfx::ComputePipelineCreateInfo& createInfo);
private:
VkPipelineCache cache;
PGraphics graphics;
+3 -1
View File
@@ -3,6 +3,7 @@
#include "Graphics.h"
#include "Framebuffer.h"
#include "Texture.h"
#include "RenderPass.h"
using namespace Seele;
using namespace Seele::Vulkan;
@@ -143,4 +144,5 @@ uint32 RenderPass::getFramebufferHash()
description.depthAttachment = tex->getView();
}
return CRC::Calculate(&description, sizeof(FramebufferDescription), CRC::CRC_32());
}
}
+3 -7
View File
@@ -1,10 +1,6 @@
#include "VulkanGraphicsResources.h"
#include "VulkanGraphics.h"
#include "VulkanInitializer.h"
#include "VulkanGraphicsEnums.h"
#include "VulkanAllocator.h"
#include "VulkanCommandBuffer.h"
#include "Graphics/GraphicsEnums.h"
#include "Texture.h"
#include "Initializer.h"
#include "CommandBuffer.h"
#include <math.h>
using namespace Seele;