compiles again
This commit is contained in:
@@ -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));
|
||||
}
|
||||
@@ -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)
|
||||
|
||||
@@ -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()
|
||||
|
||||
@@ -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)
|
||||
|
||||
|
||||
@@ -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,4 +1,4 @@
|
||||
#include "VulkanGraphicsEnums.h"
|
||||
#include "Enums.h"
|
||||
|
||||
using namespace Seele;
|
||||
using namespace Seele::Vulkan;
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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,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());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
Reference in New Issue
Block a user