Adding VMA

This commit is contained in:
Dynamitos
2024-01-17 17:57:59 +01:00
parent 29710de146
commit 524f26d921
18 changed files with 783 additions and 911 deletions
+1 -1
View File
@@ -28,7 +28,7 @@
], ],
"compilerPath": "/usr/bin/clang", "compilerPath": "/usr/bin/clang",
"cppStandard": "c++20", "cppStandard": "c++20",
"intelliSenseMode": "macos-lang-arm64", "intelliSenseMode": "macos-clang-arm64",
"configurationProvider": "ms-vscode.cmake-tools" "configurationProvider": "ms-vscode.cmake-tools"
} }
], ],
+2
View File
@@ -48,6 +48,7 @@ find_package(glm CONFIG REQUIRED)
find_package(Ktx CONFIG REQUIRED) find_package(Ktx CONFIG REQUIRED)
find_package(nlohmann_json CONFIG REQUIRED) find_package(nlohmann_json CONFIG REQUIRED)
find_package(fmt CONFIG REQUIRED) find_package(fmt CONFIG REQUIRED)
find_package(VulkanMemoryAllocator CONFIG REQUIRED)
if(UNIX) if(UNIX)
find_package(Threads REQUIRED) find_package(Threads REQUIRED)
@@ -72,6 +73,7 @@ target_link_libraries(Engine PUBLIC nlohmann_json::nlohmann_json)
target_link_libraries(Engine PUBLIC crcpp) target_link_libraries(Engine PUBLIC crcpp)
target_link_libraries(Engine PUBLIC shader-slang) target_link_libraries(Engine PUBLIC shader-slang)
target_link_libraries(Engine PUBLIC fmt::fmt) target_link_libraries(Engine PUBLIC fmt::fmt)
target_link_libraries(Engine PUBLIC GPUOpen::VulkanMemoryAllocator)
if(UNIX) if(UNIX)
target_link_libraries(Engine PUBLIC Threads::Threads) target_link_libraries(Engine PUBLIC Threads::Threads)
target_link_libraries(Engine PUBLIC dl) target_link_libraries(Engine PUBLIC dl)
+4
View File
@@ -26,6 +26,10 @@ int main()
std::filesystem::path outputPath = "C:/Users/Dynamitos/TrackClearGame"; std::filesystem::path outputPath = "C:/Users/Dynamitos/TrackClearGame";
std::filesystem::path sourcePath= "C:/Users/Dynamitos/TrackClear"; std::filesystem::path sourcePath= "C:/Users/Dynamitos/TrackClear";
std::filesystem::path binaryPath = sourcePath / "bin" / "TrackClear.dll"; std::filesystem::path binaryPath = sourcePath / "bin" / "TrackClear.dll";
#elif __APPLE__
std::filesystem::path outputPath = "/dynamitos/TrackClearGame";
std::filesystem::path sourcePath= "/dynamitos/TrackClear";
std::filesystem::path binaryPath = sourcePath / "cmake" / "libTrackClear.dynlib";
#else #else
std::filesystem::path outputPath = "/home/dynamitos/TrackClearGame"; std::filesystem::path outputPath = "/home/dynamitos/TrackClearGame";
std::filesystem::path sourcePath= "/home/dynamitos/TrackClear"; std::filesystem::path sourcePath= "/home/dynamitos/TrackClear";
+4
View File
@@ -42,6 +42,10 @@ public:
{ {
return p == other.p; return p == other.p;
} }
constexpr bool operator!=(const IteratorBase &other) const
{
return p != other.p;
}
constexpr std::strong_ordering operator<=>(const IteratorBase &other) const constexpr std::strong_ordering operator<=>(const IteratorBase &other) const
{ {
return p <=> other.p; return p <=> other.p;
+2 -2
View File
@@ -81,7 +81,7 @@ public:
} }
constexpr bool operator!=(const IteratorBase& other) constexpr bool operator!=(const IteratorBase& other)
{ {
return node == other.node; return node != other.node;
} }
constexpr bool operator==(const IteratorBase& other) constexpr bool operator==(const IteratorBase& other)
{ {
@@ -89,7 +89,7 @@ public:
} }
constexpr std::strong_ordering operator<=>(const IteratorBase& other) constexpr std::strong_ordering operator<=>(const IteratorBase& other)
{ {
return node == other.node; return node <=> other.node;
} }
constexpr IteratorBase& operator++() constexpr IteratorBase& operator++()
{ {
+1 -1
View File
@@ -24,7 +24,7 @@ struct GraphicsInitializer
: applicationName("SeeleEngine") : applicationName("SeeleEngine")
, engineName("SeeleEngine") , engineName("SeeleEngine")
, windowLayoutFile(nullptr) , windowLayoutFile(nullptr)
, layers{"VK_LAYER_LUNARG_monitor"} , layers{}
, instanceExtensions{} , instanceExtensions{}
, deviceExtensions{"VK_KHR_swapchain"} , deviceExtensions{"VK_KHR_swapchain"}
, windowHandle(nullptr) , windowHandle(nullptr)
+334 -334
View File
@@ -1,371 +1,371 @@
#include "Allocator.h" // #include "Allocator.h"
#include "Graphics.h" // #include "Graphics.h"
#include "Resources.h" // #include "Resources.h"
#include "Enums.h" // #include "Enums.h"
#include "Command.h" // #include "Command.h"
using namespace Seele::Vulkan; // using namespace Seele::Vulkan;
SubAllocation::SubAllocation(PAllocation owner, VkDeviceSize requestedSize, VkDeviceSize allocatedOffset, VkDeviceSize allocatedSize, VkDeviceSize alignedOffset) // SubAllocation::SubAllocation(PAllocation owner, VkDeviceSize requestedSize, VkDeviceSize allocatedOffset, VkDeviceSize allocatedSize, VkDeviceSize alignedOffset)
: owner(owner) // : owner(owner)
, requestedSize(requestedSize) // , requestedSize(requestedSize)
, allocatedOffset(allocatedOffset) // , allocatedOffset(allocatedOffset)
, allocatedSize(allocatedSize) // , allocatedSize(allocatedSize)
, alignedOffset(alignedOffset) // , alignedOffset(alignedOffset)
{ // {
} // }
SubAllocation::~SubAllocation() // SubAllocation::~SubAllocation()
{ // {
owner->markFree(this); // owner->markFree(this);
} // }
VkDeviceMemory SubAllocation::getHandle() const // VkDeviceMemory SubAllocation::getHandle() const
{ // {
return owner->getHandle(); // return owner->getHandle();
} // }
void *SubAllocation::map() // void *SubAllocation::map()
{ // {
return (uint8 *)owner->map() + alignedOffset; // return (uint8 *)owner->map() + alignedOffset;
} // }
void SubAllocation::flushMemory() // void SubAllocation::flushMemory()
{ // {
owner->flushMemory(); // owner->flushMemory();
} // }
void SubAllocation::invalidate() // void SubAllocation::invalidate()
{ // {
owner->invalidate(); // owner->invalidate();
} // }
Allocation::Allocation(PGraphics graphics, PAllocator pool, VkDeviceSize size, uint8 memoryTypeIndex, // Allocation::Allocation(PGraphics graphics, PAllocator pool, VkDeviceSize size, uint8 memoryTypeIndex,
VkMemoryPropertyFlags properties, VkMemoryDedicatedAllocateInfo *dedicatedInfo) // VkMemoryPropertyFlags properties, VkMemoryDedicatedAllocateInfo *dedicatedInfo)
: device(graphics->getDevice()) // : device(graphics->getDevice())
, pool(pool) // , pool(pool)
, bytesAllocated(size) // , bytesAllocated(size)
, bytesUsed(0) // , bytesUsed(0)
, mappedPointer(nullptr) // , mappedPointer(nullptr)
, canMap((properties & VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT) == VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT) // , canMap((properties & VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT) == VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT)
, isMapped(false) // , isMapped(false)
, properties(properties) // , properties(properties)
, memoryTypeIndex(memoryTypeIndex) // , memoryTypeIndex(memoryTypeIndex)
{ // {
VkMemoryAllocateInfo allocInfo = { // VkMemoryAllocateInfo allocInfo = {
.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO, // .sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO,
.pNext = dedicatedInfo, // .pNext = dedicatedInfo,
.allocationSize = size, // .allocationSize = size,
.memoryTypeIndex = memoryTypeIndex, // .memoryTypeIndex = memoryTypeIndex,
}; // };
isDedicated = dedicatedInfo != nullptr; // isDedicated = dedicatedInfo != nullptr;
VK_CHECK(vkAllocateMemory(device, &allocInfo, nullptr, &allocatedMemory)); // VK_CHECK(vkAllocateMemory(device, &allocInfo, nullptr, &allocatedMemory));
freeRanges[0] = size; // freeRanges[0] = size;
} // }
Allocation::~Allocation() // Allocation::~Allocation()
{ // {
vkFreeMemory(device, allocatedMemory, nullptr); // vkFreeMemory(device, allocatedMemory, nullptr);
} // }
OSubAllocation Allocation::getSuballocation(VkDeviceSize requestedSize, VkDeviceSize alignment) // OSubAllocation Allocation::getSuballocation(VkDeviceSize requestedSize, VkDeviceSize alignment)
{ // {
if (isDedicated) // if (isDedicated)
{ // {
if (activeAllocations.empty() && requestedSize == bytesAllocated) // if (activeAllocations.empty() && requestedSize == bytesAllocated)
{ // {
OSubAllocation suballoc = new SubAllocation(this, requestedSize, 0, requestedSize, 0); // OSubAllocation suballoc = new SubAllocation(this, requestedSize, 0, requestedSize, 0);
activeAllocations.add(suballoc); // activeAllocations.add(suballoc);
freeRanges.clear(); // freeRanges.clear();
bytesUsed += requestedSize; // bytesUsed += requestedSize;
return suballoc; // return suballoc;
} // }
else // else
{ // {
return nullptr; // return nullptr;
} // }
} // }
for (const auto& [lower, size] : freeRanges) // for (const auto& [lower, size] : freeRanges)
{ // {
VkDeviceSize alignedOffset = lower + alignment - 1; // VkDeviceSize alignedOffset = lower + alignment - 1;
alignedOffset /= alignment; // alignedOffset /= alignment;
alignedOffset *= alignment; // alignedOffset *= alignment;
VkDeviceSize allocatedSize = requestedSize + (alignedOffset - lower); // VkDeviceSize allocatedSize = requestedSize + (alignedOffset - lower);
if (size >= allocatedSize) // if (size >= allocatedSize)
{ // {
//std::cout << "Allocating " << lower << "-" << lower + allocatedSize << std::endl; // //std::cout << "Allocating " << lower << "-" << lower + allocatedSize << std::endl;
VkDeviceSize newSize = size - allocatedSize; // VkDeviceSize newSize = size - allocatedSize;
VkDeviceSize newLower = lower + allocatedSize; // VkDeviceSize newLower = lower + allocatedSize;
OSubAllocation alloc = new SubAllocation(this, requestedSize, lower, allocatedSize, alignedOffset); // OSubAllocation alloc = new SubAllocation(this, requestedSize, lower, allocatedSize, alignedOffset);
activeAllocations.add(alloc); // activeAllocations.add(alloc);
freeRanges.erase(lower); // freeRanges.erase(lower);
if (newSize > 0) // if (newSize > 0)
{ // {
freeRanges[newLower] = newSize; // freeRanges[newLower] = newSize;
} // }
bytesUsed += allocatedSize; // bytesUsed += allocatedSize;
return alloc; // return alloc;
} // }
} // }
return nullptr; // return nullptr;
} // }
void Allocation::markFree(PSubAllocation allocation) // void Allocation::markFree(PSubAllocation allocation)
{ // {
//std::cout << "Freeing " << allocation->allocatedOffset << "-" << allocation->allocatedOffset + allocation->allocatedSize << std::endl; // //std::cout << "Freeing " << allocation->allocatedOffset << "-" << allocation->allocatedOffset + allocation->allocatedSize << std::endl;
assert(activeAllocations.find(allocation) != activeAllocations.end()); // assert(activeAllocations.find(allocation) != activeAllocations.end());
VkDeviceSize lowerBound = allocation->allocatedOffset; // VkDeviceSize lowerBound = allocation->allocatedOffset;
VkDeviceSize upperBound = allocation->allocatedOffset + allocation->allocatedSize; // VkDeviceSize upperBound = allocation->allocatedOffset + allocation->allocatedSize;
freeRanges[lowerBound] = allocation->allocatedSize; // freeRanges[lowerBound] = allocation->allocatedSize;
for (const auto& [lower, size] : freeRanges) // for (const auto& [lower, size] : freeRanges)
{ // {
if (lower + size == lowerBound) // if (lower + size == lowerBound)
{ // {
freeRanges[lower] = size + allocation->allocatedSize; // freeRanges[lower] = size + allocation->allocatedSize;
freeRanges.erase(lowerBound); // freeRanges.erase(lowerBound);
lowerBound = lower; // lowerBound = lower;
break; // break;
} // }
} // }
if (freeRanges.find(upperBound) != freeRanges.end()) // if (freeRanges.find(upperBound) != freeRanges.end())
{ // {
freeRanges[lowerBound] += freeRanges[upperBound]; // freeRanges[lowerBound] += freeRanges[upperBound];
freeRanges.erase(upperBound); // freeRanges.erase(upperBound);
} // }
activeAllocations.remove(allocation, false); // activeAllocations.remove(allocation, false);
bytesUsed -= allocation->allocatedSize; // bytesUsed -= allocation->allocatedSize;
//if (activeAllocations.size() == 0) // //if (activeAllocations.size() == 0)
//{ // //{
// pool->free(this); // // pool->free(this);
//} // //}
} // }
void Allocation::flushMemory() // void Allocation::flushMemory()
{ // {
VkMappedMemoryRange range = { // VkMappedMemoryRange range = {
.sType = VK_STRUCTURE_TYPE_MAPPED_MEMORY_RANGE, // .sType = VK_STRUCTURE_TYPE_MAPPED_MEMORY_RANGE,
.pNext = 0, // .pNext = 0,
.memory = allocatedMemory, // .memory = allocatedMemory,
.offset = 0, // .offset = 0,
.size = bytesAllocated, // .size = bytesAllocated,
}; // };
vkFlushMappedMemoryRanges(device, 1, &range); // vkFlushMappedMemoryRanges(device, 1, &range);
} // }
void Allocation::invalidate() // void Allocation::invalidate()
{ // {
VkMappedMemoryRange range = { // VkMappedMemoryRange range = {
.sType = VK_STRUCTURE_TYPE_MAPPED_MEMORY_RANGE, // .sType = VK_STRUCTURE_TYPE_MAPPED_MEMORY_RANGE,
.pNext = 0, // .pNext = 0,
.memory = allocatedMemory, // .memory = allocatedMemory,
.size = bytesAllocated, // .size = bytesAllocated,
}; // };
vkInvalidateMappedMemoryRanges(device, 1, &range); // vkInvalidateMappedMemoryRanges(device, 1, &range);
} // }
Allocator::Allocator(PGraphics graphics) // Allocator::Allocator(PGraphics graphics)
: graphics(graphics) // : graphics(graphics)
{ // {
vkGetPhysicalDeviceMemoryProperties(graphics->getPhysicalDevice(), &memProperties); // vkGetPhysicalDeviceMemoryProperties(graphics->getPhysicalDevice(), &memProperties);
heaps.reserve(memProperties.memoryHeapCount); // heaps.reserve(memProperties.memoryHeapCount);
for (size_t i = 0; i < memProperties.memoryHeapCount; ++i) // for (size_t i = 0; i < memProperties.memoryHeapCount; ++i)
{ // {
VkMemoryHeap memoryHeap = memProperties.memoryHeaps[i]; // VkMemoryHeap memoryHeap = memProperties.memoryHeaps[i];
HeapInfo heapInfo; // HeapInfo heapInfo;
heapInfo.maxSize = memoryHeap.size; // heapInfo.maxSize = memoryHeap.size;
//std::cout << "Creating heap " << i << " with properties " << memoryHeap.flags << " size " << memoryHeap.size << std::endl; // //std::cout << "Creating heap " << i << " with properties " << memoryHeap.flags << " size " << memoryHeap.size << std::endl;
heaps.add(std::move(heapInfo)); // heaps.add(std::move(heapInfo));
} // }
} // }
Allocator::~Allocator() // Allocator::~Allocator()
{ // {
} // }
OSubAllocation Allocator::allocate(const VkMemoryRequirements2 &memRequirements2, VkMemoryPropertyFlags properties, VkMemoryDedicatedAllocateInfo *dedicatedInfo) // OSubAllocation Allocator::allocate(const VkMemoryRequirements2 &memRequirements2, VkMemoryPropertyFlags properties, VkMemoryDedicatedAllocateInfo *dedicatedInfo)
{ // {
const VkMemoryRequirements &requirements = memRequirements2.memoryRequirements; // const VkMemoryRequirements &requirements = memRequirements2.memoryRequirements;
uint32 memoryTypeIndex = findMemoryType(requirements.memoryTypeBits, properties); // uint32 memoryTypeIndex = findMemoryType(requirements.memoryTypeBits, properties);
uint32 heapIndex = memProperties.memoryTypes[memoryTypeIndex].heapIndex; // uint32 heapIndex = memProperties.memoryTypes[memoryTypeIndex].heapIndex;
if (memRequirements2.pNext != nullptr) // if (memRequirements2.pNext != nullptr)
{ // {
VkMemoryDedicatedRequirements *dedicatedReq = (VkMemoryDedicatedRequirements *)memRequirements2.pNext; // VkMemoryDedicatedRequirements *dedicatedReq = (VkMemoryDedicatedRequirements *)memRequirements2.pNext;
if (dedicatedReq->prefersDedicatedAllocation) // if (dedicatedReq->prefersDedicatedAllocation)
{ // {
OAllocation newAllocation = new Allocation(graphics, this, requirements.size, memoryTypeIndex, properties, dedicatedInfo); // OAllocation newAllocation = new Allocation(graphics, this, requirements.size, memoryTypeIndex, properties, dedicatedInfo);
heaps[heapIndex].inUse += newAllocation->bytesAllocated; // heaps[heapIndex].inUse += newAllocation->bytesAllocated;
std::cout << "Heap " << heapIndex << ": " << (float)heaps[heapIndex].inUse / heaps[heapIndex].maxSize * 100 << "%" << std::endl; // std::cout << "Heap " << heapIndex << ": " << (float)heaps[heapIndex].inUse / heaps[heapIndex].maxSize * 100 << "%" << std::endl;
heaps[heapIndex].allocations.add(std::move(newAllocation)); // heaps[heapIndex].allocations.add(std::move(newAllocation));
return heaps[heapIndex].allocations.back()->getSuballocation(requirements.size, requirements.alignment); // 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) // if(alloc->memoryTypeIndex == memoryTypeIndex)
{ // {
OSubAllocation suballoc = alloc->getSuballocation(requirements.size, requirements.alignment); // OSubAllocation suballoc = alloc->getSuballocation(requirements.size, requirements.alignment);
if (suballoc != nullptr) // if (suballoc != nullptr)
{ // {
return suballoc; // return suballoc;
} // }
} // }
} // }
// no suitable allocations found, allocate new block // // no suitable allocations found, allocate new block
OAllocation newAllocation = new Allocation(graphics, this, (requirements.size > DEFAULT_ALLOCATION) ? requirements.size : DEFAULT_ALLOCATION, memoryTypeIndex, properties, nullptr); // OAllocation newAllocation = new Allocation(graphics, this, (requirements.size > DEFAULT_ALLOCATION) ? requirements.size : DEFAULT_ALLOCATION, memoryTypeIndex, properties, nullptr);
heaps[heapIndex].inUse += newAllocation->bytesAllocated; // heaps[heapIndex].inUse += newAllocation->bytesAllocated;
std::cout << "Heap " << heapIndex << ": " << (float)heaps[heapIndex].inUse / heaps[heapIndex].maxSize * 100 << "%" << std::endl; // std::cout << "Heap " << heapIndex << ": " << (float)heaps[heapIndex].inUse / heaps[heapIndex].maxSize * 100 << "%" << std::endl;
heaps[heapIndex].allocations.add(std::move(newAllocation)); // heaps[heapIndex].allocations.add(std::move(newAllocation));
return heaps[heapIndex].allocations.back()->getSuballocation(requirements.size, requirements.alignment); // return heaps[heapIndex].allocations.back()->getSuballocation(requirements.size, requirements.alignment);
} // }
void Allocator::free(PAllocation allocation) // void Allocator::free(PAllocation allocation)
{ // {
for (uint32 heapIndex = 0; heapIndex < heaps.size(); ++heapIndex) // for (uint32 heapIndex = 0; heapIndex < heaps.size(); ++heapIndex)
{ // {
for (uint32 alloc = 0; alloc < heaps[heapIndex].allocations.size(); ++alloc) // for (uint32 alloc = 0; alloc < heaps[heapIndex].allocations.size(); ++alloc)
{ // {
if (heaps[heapIndex].allocations[alloc] == allocation) // if (heaps[heapIndex].allocations[alloc] == allocation)
{ // {
heaps[heapIndex].allocations.removeAt(alloc, false); // heaps[heapIndex].allocations.removeAt(alloc, false);
} // }
} // }
} // }
} // }
void Allocator::print() // void Allocator::print()
{ // {
for (uint32 heapIndex = 0; heapIndex < heaps.size(); ++heapIndex) // for (uint32 heapIndex = 0; heapIndex < heaps.size(); ++heapIndex)
{ // {
std::cout << "Heap " << heapIndex << std::endl; // std::cout << "Heap " << heapIndex << std::endl;
for (uint32 alloc = 0; alloc < heaps[heapIndex].allocations.size(); ++alloc) // for (uint32 alloc = 0; alloc < heaps[heapIndex].allocations.size(); ++alloc)
{ // {
std::cout << "[" << alloc << "]: " << (float)heaps[heapIndex].allocations[alloc]->bytesUsed / heaps[heapIndex].allocations[alloc]->bytesAllocated << std::endl; // std::cout << "[" << alloc << "]: " << (float)heaps[heapIndex].allocations[alloc]->bytesUsed / heaps[heapIndex].allocations[alloc]->bytesAllocated << std::endl;
} // }
} // }
} // }
uint32 Allocator::findMemoryType(uint32 typeFilter, VkMemoryPropertyFlags properties) // uint32 Allocator::findMemoryType(uint32 typeFilter, VkMemoryPropertyFlags properties)
{ // {
for (uint32 i = 0; i < memProperties.memoryTypeCount; i++) // for (uint32 i = 0; i < memProperties.memoryTypeCount; i++)
{ // {
if ((typeFilter & (1 << i)) && (memProperties.memoryTypes[i].propertyFlags & properties) == properties) // if ((typeFilter & (1 << i)) && (memProperties.memoryTypes[i].propertyFlags & properties) == properties)
{ // {
return i; // return i;
} // }
} // }
throw std::runtime_error("error finding memory"); // throw std::runtime_error("error finding memory");
} // }
StagingBuffer::StagingBuffer(PGraphics graphics, OSubAllocation allocation, VkBuffer buffer, VkDeviceSize size, Gfx::QueueType owner) // StagingBuffer::StagingBuffer(PGraphics graphics, OSubAllocation allocation, VkBuffer buffer, VkDeviceSize size, Gfx::QueueType owner)
: owner(owner) // : owner(owner)
, allocation(std::move(allocation)) // , allocation(std::move(allocation))
, graphics(graphics) // , graphics(graphics)
, buffer(buffer) // , buffer(buffer)
, size(size) // , size(size)
{ // {
} // }
StagingBuffer::~StagingBuffer() // StagingBuffer::~StagingBuffer()
{ // {
graphics->getDestructionManager()->queueBuffer( // graphics->getDestructionManager()->queueBuffer(
graphics->getQueueCommands(owner)->getCommands(), buffer); // graphics->getQueueCommands(owner)->getCommands(), buffer);
graphics->getDestructionManager()->queueAllocation( // graphics->getDestructionManager()->queueAllocation(
graphics->getQueueCommands(owner)->getCommands(), std::move(allocation)); // graphics->getQueueCommands(owner)->getCommands(), std::move(allocation));
} // }
void* StagingBuffer::map() // void* StagingBuffer::map()
{ // {
return allocation->map(); // return allocation->map();
} // }
void StagingBuffer::flush() // void StagingBuffer::flush()
{ // {
allocation->flushMemory(); // allocation->flushMemory();
} // }
void StagingBuffer::invalidate() // void StagingBuffer::invalidate()
{ // {
allocation->invalidate(); // allocation->invalidate();
} // }
VkDeviceMemory StagingBuffer::getMemory() const // VkDeviceMemory StagingBuffer::getMemory() const
{ // {
return allocation->getHandle(); // return allocation->getHandle();
} // }
VkDeviceSize StagingBuffer::getOffset() const // VkDeviceSize StagingBuffer::getOffset() const
{ // {
return allocation->getOffset(); // return allocation->getOffset();
} // }
StagingManager::StagingManager(PGraphics graphics, PAllocator pool) // StagingManager::StagingManager(PGraphics graphics, PAllocator pool)
: graphics(graphics), pool(pool) // : graphics(graphics), pool(pool)
{ // {
} // }
StagingManager::~StagingManager() // StagingManager::~StagingManager()
{ // {
} // }
OStagingBuffer StagingManager::create(uint64 size, Gfx::QueueType owner) // OStagingBuffer StagingManager::create(uint64 size, Gfx::QueueType owner)
{ // {
//vkDeviceWaitIdle(graphics->getDevice()); // //vkDeviceWaitIdle(graphics->getDevice());
//std::cout << "Creating new stagingbuffer" << std::endl; // //std::cout << "Creating new stagingbuffer" << std::endl;
for (uint32 i = 0; i < freeBuffers.size(); ++i) // for (uint32 i = 0; i < freeBuffers.size(); ++i)
{ // {
if (size <= freeBuffers[i]->getSize() && owner == freeBuffers[i]->getOwner()) // if (size <= freeBuffers[i]->getSize() && owner == freeBuffers[i]->getOwner())
{ // {
OStagingBuffer result = std::move(freeBuffers[i]); // OStagingBuffer result = std::move(freeBuffers[i]);
freeBuffers.removeAt(i); // freeBuffers.removeAt(i);
return result; // return result;
} // }
} // }
uint32 queueIndex = graphics->getFamilyMapping().getQueueTypeFamilyIndex(owner); // uint32 queueIndex = graphics->getFamilyMapping().getQueueTypeFamilyIndex(owner);
VkBufferCreateInfo stagingBufferCreateInfo = { // VkBufferCreateInfo stagingBufferCreateInfo = {
.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO, // .sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,
.pNext = nullptr, // .pNext = nullptr,
.flags = 0, // .flags = 0,
.size = size, // .size = size,
.usage = VK_BUFFER_USAGE_TRANSFER_SRC_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT, // .usage = VK_BUFFER_USAGE_TRANSFER_SRC_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT,
.sharingMode = VK_SHARING_MODE_EXCLUSIVE, // .sharingMode = VK_SHARING_MODE_EXCLUSIVE,
.queueFamilyIndexCount = 1, // .queueFamilyIndexCount = 1,
.pQueueFamilyIndices = &queueIndex, // .pQueueFamilyIndices = &queueIndex,
}; // };
VkBuffer buffer; // VkBuffer buffer;
VK_CHECK(vkCreateBuffer(graphics->getDevice(), &stagingBufferCreateInfo, nullptr, &buffer)); // VK_CHECK(vkCreateBuffer(graphics->getDevice(), &stagingBufferCreateInfo, nullptr, &buffer));
VkMemoryDedicatedRequirements dedicatedReqs = { // VkMemoryDedicatedRequirements dedicatedReqs = {
.sType = VK_STRUCTURE_TYPE_MEMORY_DEDICATED_REQUIREMENTS, // .sType = VK_STRUCTURE_TYPE_MEMORY_DEDICATED_REQUIREMENTS,
.pNext = nullptr, // .pNext = nullptr,
}; // };
VkMemoryRequirements2 memReqs = { // VkMemoryRequirements2 memReqs = {
.sType = VK_STRUCTURE_TYPE_MEMORY_REQUIREMENTS_2, // .sType = VK_STRUCTURE_TYPE_MEMORY_REQUIREMENTS_2,
.pNext = &dedicatedReqs, // .pNext = &dedicatedReqs,
}; // };
VkBufferMemoryRequirementsInfo2 bufferQuery = { // VkBufferMemoryRequirementsInfo2 bufferQuery = {
.sType = VK_STRUCTURE_TYPE_BUFFER_MEMORY_REQUIREMENTS_INFO_2, // .sType = VK_STRUCTURE_TYPE_BUFFER_MEMORY_REQUIREMENTS_INFO_2,
.pNext = nullptr, // .pNext = nullptr,
.buffer = buffer, // .buffer = buffer,
}; // };
vkGetBufferMemoryRequirements2(graphics->getDevice(), &bufferQuery, &memReqs); // vkGetBufferMemoryRequirements2(graphics->getDevice(), &bufferQuery, &memReqs);
OStagingBuffer stagingBuffer = new StagingBuffer( // OStagingBuffer stagingBuffer = new StagingBuffer(
graphics, // graphics,
pool->allocate(memReqs, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_CACHED_BIT, buffer), // pool->allocate(memReqs, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_CACHED_BIT, buffer),
buffer, // buffer,
size, // size,
owner // owner
); // );
vkBindBufferMemory(graphics->getDevice(), buffer, stagingBuffer->getMemory(), stagingBuffer->getOffset()); // vkBindBufferMemory(graphics->getDevice(), buffer, stagingBuffer->getMemory(), stagingBuffer->getOffset());
return stagingBuffer; // return stagingBuffer;
} // }
void StagingManager::release(OStagingBuffer) // void StagingManager::release(OStagingBuffer)
{ // {
//freeBuffers.add(std::move(buffer)); // //freeBuffers.add(std::move(buffer));
} // }
+186 -186
View File
@@ -1,196 +1,196 @@
#pragma once // #pragma once
#include "MinimalEngine.h" // #include "MinimalEngine.h"
#include "Enums.h" // #include "Enums.h"
#include "Containers/Map.h" // #include "Containers/Map.h"
#include "Containers/Array.h" // #include "Containers/Array.h"
#include "Graphics/Resources.h" // #include "Graphics/Resources.h"
#include <mutex> // #include <mutex>
namespace Seele // namespace Seele
{ // {
namespace Vulkan // namespace Vulkan
{ // {
DECLARE_REF(Graphics) // DECLARE_REF(Graphics)
DECLARE_REF(Allocator) // DECLARE_REF(Allocator)
DECLARE_REF(Allocation) // DECLARE_REF(Allocation)
class SubAllocation // class SubAllocation
{ // {
public: // public:
SubAllocation(PAllocation owner, VkDeviceSize requestedSize, VkDeviceSize allocatedOffset, VkDeviceSize allocatedSize, VkDeviceSize alignedOffset); // SubAllocation(PAllocation owner, VkDeviceSize requestedSize, VkDeviceSize allocatedOffset, VkDeviceSize allocatedSize, VkDeviceSize alignedOffset);
~SubAllocation(); // ~SubAllocation();
VkDeviceMemory getHandle() const; // VkDeviceMemory getHandle() const;
constexpr VkDeviceSize getSize() const // constexpr VkDeviceSize getSize() const
{ // {
return requestedSize; // return requestedSize;
} // }
constexpr VkDeviceSize getOffset() const // constexpr VkDeviceSize getOffset() const
{ // {
return alignedOffset; // return alignedOffset;
} // }
void *map(); // void *map();
void flushMemory(); // void flushMemory();
void invalidate(); // void invalidate();
private: // private:
PAllocation owner; // PAllocation owner;
VkDeviceSize requestedSize; // VkDeviceSize requestedSize;
VkDeviceSize allocatedOffset; // VkDeviceSize allocatedOffset;
VkDeviceSize allocatedSize; // VkDeviceSize allocatedSize;
VkDeviceSize alignedOffset; // VkDeviceSize alignedOffset;
friend class Allocation; // friend class Allocation;
friend class Allocator; // friend class Allocator;
}; // };
DEFINE_REF(SubAllocation) // DEFINE_REF(SubAllocation)
class Allocation // class Allocation
{ // {
public: // public:
Allocation(PGraphics graphics, PAllocator pool, VkDeviceSize size, uint8 memoryTypeIndex, // Allocation(PGraphics graphics, PAllocator pool, VkDeviceSize size, uint8 memoryTypeIndex,
VkMemoryPropertyFlags properties, VkMemoryDedicatedAllocateInfo *dedicatedInfo = nullptr); // VkMemoryPropertyFlags properties, VkMemoryDedicatedAllocateInfo *dedicatedInfo = nullptr);
Allocation(const Allocation& other) = delete; // Allocation(const Allocation& other) = delete;
Allocation& operator=(const Allocation& other) = delete; // Allocation& operator=(const Allocation& other) = delete;
~Allocation(); // ~Allocation();
OSubAllocation getSuballocation(VkDeviceSize size, VkDeviceSize alignment); // OSubAllocation getSuballocation(VkDeviceSize size, VkDeviceSize alignment);
void markFree(PSubAllocation alloc); // void markFree(PSubAllocation alloc);
constexpr VkDeviceMemory getHandle() const // constexpr VkDeviceMemory getHandle() const
{ // {
return allocatedMemory; // return allocatedMemory;
} // }
constexpr VkMemoryPropertyFlags getProperties() const // constexpr VkMemoryPropertyFlags getProperties() const
{ // {
return properties; // return properties;
} // }
constexpr void* map() // constexpr void* map()
{ // {
if (!canMap) // if (!canMap)
{ // {
return nullptr; // return nullptr;
} // }
if (!isMapped) // if (!isMapped)
{ // {
vkMapMemory(device, allocatedMemory, 0, bytesAllocated, 0, &mappedPointer); // vkMapMemory(device, allocatedMemory, 0, bytesAllocated, 0, &mappedPointer);
isMapped = true; // isMapped = true;
} // }
return mappedPointer; // return mappedPointer;
} // }
void flushMemory(); // void flushMemory();
void invalidate(); // void invalidate();
private: // private:
VkDevice device; // VkDevice device;
PAllocator pool; // PAllocator pool;
VkDeviceSize bytesAllocated; // VkDeviceSize bytesAllocated;
VkDeviceSize bytesUsed; // VkDeviceSize bytesUsed;
VkDeviceMemory allocatedMemory; // VkDeviceMemory allocatedMemory;
Array<PSubAllocation> activeAllocations; // Array<PSubAllocation> activeAllocations;
Map<VkDeviceSize, VkDeviceSize> freeRanges; // Map<VkDeviceSize, VkDeviceSize> freeRanges;
void *mappedPointer; // void *mappedPointer;
uint8 canMap : 1; // uint8 canMap : 1;
uint8 isMapped : 1; // uint8 isMapped : 1;
uint8 isDedicated : 1; // uint8 isDedicated : 1;
VkMemoryPropertyFlags properties; // VkMemoryPropertyFlags properties;
uint8 memoryTypeIndex; // uint8 memoryTypeIndex;
friend class Allocator; // friend class Allocator;
}; // };
DEFINE_REF(Allocation) // DEFINE_REF(Allocation)
class Allocator // class Allocator
{ // {
public: // public:
Allocator(PGraphics graphics); // Allocator(PGraphics graphics);
~Allocator(); // ~Allocator();
OSubAllocation allocate(const VkMemoryRequirements2 &requirements, VkMemoryPropertyFlags props, // OSubAllocation allocate(const VkMemoryRequirements2 &requirements, VkMemoryPropertyFlags props,
VkMemoryDedicatedAllocateInfo *dedicatedInfo = nullptr); // VkMemoryDedicatedAllocateInfo *dedicatedInfo = nullptr);
OSubAllocation allocate(const VkMemoryRequirements2 &requirements, VkMemoryPropertyFlags props, // OSubAllocation allocate(const VkMemoryRequirements2 &requirements, VkMemoryPropertyFlags props,
VkBuffer buffer) // VkBuffer buffer)
{ // {
VkMemoryDedicatedAllocateInfo allocInfo = { // VkMemoryDedicatedAllocateInfo allocInfo = {
.sType = VK_STRUCTURE_TYPE_MEMORY_DEDICATED_ALLOCATE_INFO, // .sType = VK_STRUCTURE_TYPE_MEMORY_DEDICATED_ALLOCATE_INFO,
.pNext = nullptr, // .pNext = nullptr,
.image = VK_NULL_HANDLE, // .image = VK_NULL_HANDLE,
.buffer = buffer, // .buffer = buffer,
}; // };
return allocate(requirements, props, &allocInfo); // return allocate(requirements, props, &allocInfo);
} // }
OSubAllocation allocate(const VkMemoryRequirements2 &requirements, VkMemoryPropertyFlags props, // OSubAllocation allocate(const VkMemoryRequirements2 &requirements, VkMemoryPropertyFlags props,
VkImage image) // VkImage image)
{ // {
VkMemoryDedicatedAllocateInfo allocInfo = { // VkMemoryDedicatedAllocateInfo allocInfo = {
.sType = VK_STRUCTURE_TYPE_MEMORY_DEDICATED_ALLOCATE_INFO, // .sType = VK_STRUCTURE_TYPE_MEMORY_DEDICATED_ALLOCATE_INFO,
.pNext = nullptr, // .pNext = nullptr,
.image = image, // .image = image,
.buffer = VK_NULL_HANDLE, // .buffer = VK_NULL_HANDLE,
}; // };
return allocate(requirements, props, &allocInfo); // return allocate(requirements, props, &allocInfo);
} // }
void free(PAllocation allocation); // void free(PAllocation allocation);
void print(); // void print();
private: // private:
static constexpr VkDeviceSize DEFAULT_ALLOCATION = 16 * 1024 * 1024; // 16MB // static constexpr VkDeviceSize DEFAULT_ALLOCATION = 16 * 1024 * 1024; // 16MB
struct HeapInfo // struct HeapInfo
{ // {
VkDeviceSize maxSize = 0; // VkDeviceSize maxSize = 0;
VkDeviceSize inUse = 0; // VkDeviceSize inUse = 0;
Array<OAllocation> allocations; // Array<OAllocation> allocations;
HeapInfo() = default; // HeapInfo() = default;
HeapInfo(const HeapInfo& other) = delete; // HeapInfo(const HeapInfo& other) = delete;
HeapInfo(HeapInfo&& other) = default; // HeapInfo(HeapInfo&& other) = default;
HeapInfo& operator=(const HeapInfo& other) = delete; // HeapInfo& operator=(const HeapInfo& other) = delete;
HeapInfo& operator=(HeapInfo&& other) = default; // HeapInfo& operator=(HeapInfo&& other) = default;
}; // };
Array<HeapInfo> heaps; // Array<HeapInfo> heaps;
uint32 findMemoryType(uint32 typeBits, VkMemoryPropertyFlags properties); // uint32 findMemoryType(uint32 typeBits, VkMemoryPropertyFlags properties);
PGraphics graphics; // PGraphics graphics;
VkPhysicalDeviceMemoryProperties memProperties; // VkPhysicalDeviceMemoryProperties memProperties;
}; // };
DEFINE_REF(Allocator) // DEFINE_REF(Allocator)
class StagingBuffer // class StagingBuffer
{ // {
public: // public:
StagingBuffer(PGraphics graphics, OSubAllocation allocation, VkBuffer buffer, VkDeviceSize size, Gfx::QueueType owner); // StagingBuffer(PGraphics graphics, OSubAllocation allocation, VkBuffer buffer, VkDeviceSize size, Gfx::QueueType owner);
~StagingBuffer(); // ~StagingBuffer();
void* map(); // void* map();
void flush(); // void flush();
void invalidate(); // void invalidate();
constexpr VkBuffer getHandle() const // constexpr VkBuffer getHandle() const
{ // {
return buffer; // return buffer;
} // }
VkDeviceMemory getMemory() const; // VkDeviceMemory getMemory() const;
VkDeviceSize getOffset() const; // VkDeviceSize getOffset() const;
constexpr uint64 getSize() const // constexpr uint64 getSize() const
{ // {
return size; // return size;
} // }
constexpr Gfx::QueueType getOwner() const // constexpr Gfx::QueueType getOwner() const
{ // {
return owner; // return owner;
} // }
private: // private:
Gfx::QueueType owner; // Gfx::QueueType owner;
OSubAllocation allocation; // OSubAllocation allocation;
PGraphics graphics; // PGraphics graphics;
VkBuffer buffer; // VkBuffer buffer;
VkDeviceSize size; // VkDeviceSize size;
}; // };
DEFINE_REF(StagingBuffer) // DEFINE_REF(StagingBuffer)
class StagingManager // class StagingManager
{ // {
public: // public:
StagingManager(PGraphics graphics, PAllocator pool); // StagingManager(PGraphics graphics, PAllocator pool);
~StagingManager(); // ~StagingManager();
OStagingBuffer create(uint64 size, Gfx::QueueType owner); // OStagingBuffer create(uint64 size, Gfx::QueueType owner);
void release(OStagingBuffer buffer); // void release(OStagingBuffer buffer);
private: // private:
PGraphics graphics; // PGraphics graphics;
PAllocator pool; // PAllocator pool;
Array<OStagingBuffer> freeBuffers; // Array<OStagingBuffer> freeBuffers;
}; // };
DEFINE_REF(StagingManager) // DEFINE_REF(StagingManager)
} // namespace Vulkan // } // namespace Vulkan
} // namespace Seele // } // namespace Seele
+100 -261
View File
@@ -8,20 +8,19 @@ struct PendingBuffer
{ {
uint64 offset; uint64 offset;
uint64 size; uint64 size;
OStagingBuffer stagingBuffer; VkBuffer stagingBuffer;
VmaAllocation allocation;
void *mappedMemory;
Gfx::QueueType prevQueue; Gfx::QueueType prevQueue;
bool writeOnly; bool writeOnly;
}; };
static Map<Vulkan::Buffer*, PendingBuffer> pendingBuffers; static Map<Vulkan::Buffer *, PendingBuffer> pendingBuffers;
Buffer::Buffer(PGraphics graphics, uint64 size, VkBufferUsageFlags usage, Gfx::QueueType& queueType, bool dynamic) Buffer::Buffer(PGraphics graphics, uint64 size, VkBufferUsageFlags usage, Gfx::QueueType &queueType, bool dynamic)
: graphics(graphics) : graphics(graphics), currentBuffer(0), size(size), owner(queueType)
, currentBuffer(0)
, size(size)
, owner(queueType)
{ {
if(dynamic) if (dynamic)
{ {
numBuffers = Gfx::numFramesBuffered; numBuffers = Gfx::numFramesBuffered;
} }
@@ -29,53 +28,32 @@ Buffer::Buffer(PGraphics graphics, uint64 size, VkBufferUsageFlags usage, Gfx::Q
{ {
numBuffers = 1; numBuffers = 1;
} }
usage |= VK_BUFFER_USAGE_TRANSFER_DST_BIT;
usage |= VK_BUFFER_USAGE_TRANSFER_SRC_BIT;
uint32 queueFamilyIndex = graphics->getFamilyMapping().getQueueTypeFamilyIndex(queueType);
VkBufferCreateInfo info = { VkBufferCreateInfo info = {
.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO, .sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,
.pNext = nullptr, .pNext = nullptr,
.size = size, .size = size,
.usage = usage, .usage = usage,
.sharingMode = VK_SHARING_MODE_EXCLUSIVE, .sharingMode = VK_SHARING_MODE_EXCLUSIVE,
.queueFamilyIndexCount = 1,
.pQueueFamilyIndices = &queueFamilyIndex,
}; };
VkBufferMemoryRequirementsInfo2 bufferReqInfo = { VmaAllocationCreateInfo allocInfo = {
.sType = VK_STRUCTURE_TYPE_BUFFER_MEMORY_REQUIREMENTS_INFO_2, .usage = VMA_MEMORY_USAGE_AUTO,
.pNext = nullptr, .flags = VMA_ALLOCATION_CREATE_HOST_ACCESS_ALLOW_TRANSFER_INSTEAD_BIT | VMA_ALLOCATION_CREATE_HOST_ACCESS_SEQUENTIAL_WRITE_BIT,
};
VkMemoryDedicatedRequirements dedicatedRequirements = {
.sType = VK_STRUCTURE_TYPE_MEMORY_DEDICATED_REQUIREMENTS,
.pNext = nullptr,
};
VkMemoryRequirements2 memRequirements = {
.sType = VK_STRUCTURE_TYPE_MEMORY_REQUIREMENTS_2,
.pNext = &dedicatedRequirements,
}; };
for (uint32 i = 0; i < numBuffers; ++i) for (uint32 i = 0; i < numBuffers; ++i)
{ {
VK_CHECK(vkCreateBuffer(graphics->getDevice(), &info, nullptr, &buffers[i].buffer)); vmaCreateBuffer(graphics->getAllocator(), &info, &allocInfo, &buffers[i].buffer, &buffers[i].allocation, &buffers[i].info);
bufferReqInfo.buffer = buffers[i].buffer; vmaGetAllocationMemoryProperties(graphics->getAllocator(), buffers[i].allocation, &buffers[i].properties);
vkGetBufferMemoryRequirements2(graphics->getDevice(), &bufferReqInfo, &memRequirements);
buffers[i].allocation = graphics->getAllocator()->allocate(memRequirements, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT, buffers[i].buffer);
vkBindBufferMemory(graphics->getDevice(), buffers[i].buffer, buffers[i].allocation->getHandle(), buffers[i].allocation->getOffset());
} }
} }
Buffer::~Buffer() Buffer::~Buffer()
{ {
for(uint32 i = 0; i < numBuffers; ++i) for (uint32 i = 0; i < numBuffers; ++i)
{ {
graphics->getDestructionManager()->queueBuffer(graphics->getQueueCommands(owner)->getCommands(), buffers[i].buffer); graphics->getDestructionManager()->queueBuffer(graphics->getQueueCommands(owner)->getCommands(), buffers[i].buffer);
} }
} }
VkDeviceSize Buffer::getOffset() const
{
return buffers[currentBuffer].allocation->getOffset();
}
void Buffer::executeOwnershipBarrier(Gfx::QueueType newOwner) void Buffer::executeOwnershipBarrier(Gfx::QueueType newOwner)
{ {
Gfx::QueueFamilyMapping mapping = graphics->getFamilyMapping(); Gfx::QueueFamilyMapping mapping = graphics->getFamilyMapping();
@@ -145,7 +123,7 @@ void Buffer::executeOwnershipBarrier(Gfx::QueueType newOwner)
} }
void Buffer::executePipelineBarrier(VkAccessFlags srcAccess, VkPipelineStageFlags srcStage, void Buffer::executePipelineBarrier(VkAccessFlags srcAccess, VkPipelineStageFlags srcStage,
VkAccessFlags dstAccess, VkPipelineStageFlags dstStage) VkAccessFlags dstAccess, VkPipelineStageFlags dstStage)
{ {
PCommand commandBuffer = graphics->getQueueCommands(owner)->getCommands(); PCommand commandBuffer = graphics->getQueueCommands(owner)->getCommands();
VkBufferMemoryBarrier barrier = { VkBufferMemoryBarrier barrier = {
@@ -159,7 +137,7 @@ void Buffer::executePipelineBarrier(VkAccessFlags srcAccess, VkPipelineStageFlag
.size = size, .size = size,
}; };
VkBufferMemoryBarrier dynamicBarriers[Gfx::numFramesBuffered]; VkBufferMemoryBarrier dynamicBarriers[Gfx::numFramesBuffered];
for(uint32 i = 0; i < numBuffers; ++i) for (uint32 i = 0; i < numBuffers; ++i)
{ {
dynamicBarriers[i] = barrier; dynamicBarriers[i] = barrier;
dynamicBarriers[i].buffer = buffers[i].buffer; dynamicBarriers[i].buffer = buffers[i].buffer;
@@ -167,12 +145,12 @@ void Buffer::executePipelineBarrier(VkAccessFlags srcAccess, VkPipelineStageFlag
vkCmdPipelineBarrier(commandBuffer->getHandle(), srcStage, dstStage, 0, 0, nullptr, numBuffers, dynamicBarriers, 0, nullptr); vkCmdPipelineBarrier(commandBuffer->getHandle(), srcStage, dstStage, 0, 0, nullptr, numBuffers, dynamicBarriers, 0, nullptr);
} }
void * Buffer::map(bool writeOnly) void *Buffer::map(bool writeOnly)
{ {
return mapRegion(0, size, writeOnly); return mapRegion(0, size, writeOnly);
} }
void * Buffer::mapRegion(uint64 regionOffset, uint64 regionSize, bool writeOnly) void *Buffer::mapRegion(uint64 regionOffset, uint64 regionSize, bool writeOnly)
{ {
void *data = nullptr; void *data = nullptr;
@@ -183,50 +161,30 @@ void * Buffer::mapRegion(uint64 regionOffset, uint64 regionSize, bool writeOnly)
pending.size = regionSize; pending.size = regionSize;
if (writeOnly) if (writeOnly)
{ {
//requestOwnershipTransfer(Gfx::QueueType::DEDICATED_TRANSFER); if (buffers[currentBuffer].properties & VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT)
OStagingBuffer stagingBuffer = graphics->getStagingManager()->create(regionSize, owner); {
data = stagingBuffer->map(); VK_CHECK(vmaMapMemory(graphics->getAllocator(), buffers[currentBuffer].allocation, &pending.mappedMemory));
pending.stagingBuffer = std::move(stagingBuffer); }
else
{
VkBufferCreateInfo stagingInfo = {
.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,
.pNext = nullptr,
.flags = 0,
.usage = VK_BUFFER_USAGE_TRANSFER_SRC_BIT,
.size = regionSize,
.sharingMode = VK_SHARING_MODE_EXCLUSIVE,
};
VmaAllocationCreateInfo allocInfo = {
.usage = VMA_MEMORY_USAGE_AUTO,
};
VK_CHECK(vmaCreateBuffer(graphics->getAllocator(), &stagingInfo, &allocInfo, &pending.stagingBuffer, &pending.allocation, nullptr));
vmaMapMemory(graphics->getAllocator(), pending.allocation, &pending.mappedMemory);
}
} }
else else
{ {
PCommand current = graphics->getQueueCommands(owner)->getCommands(); assert(false);
current->waitForCommand();
requestOwnershipTransfer(Gfx::QueueType::DEDICATED_TRANSFER);
VkCommandBuffer handle = graphics->getQueueCommands(owner)->getCommands()->getHandle();
VkBufferMemoryBarrier barrier = {
.sType = VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER,
.pNext = nullptr,
.srcAccessMask = VK_ACCESS_MEMORY_WRITE_BIT,
.dstAccessMask = VK_ACCESS_MEMORY_READ_BIT,
.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED,
.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED,
.buffer = buffers[currentBuffer].buffer,
.offset = 0,
.size = size,
};
vkCmdPipelineBarrier(handle, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, 0, 0, nullptr, 1, &barrier, 0, nullptr);
OStagingBuffer stagingBuffer = graphics->getStagingManager()->create(size, owner);
VkBufferCopy regions = {
.srcOffset = 0,
.dstOffset = 0,
.size = size,
};
vkCmdCopyBuffer(handle, buffers[currentBuffer].buffer, stagingBuffer->getHandle(), 1, &regions);
graphics->getQueueCommands(owner)->submitCommands();
vkQueueWaitIdle(graphics->getQueueCommands(owner)->getQueue()->getHandle());
stagingBuffer->map(); // this maps the memory if not mapped already
stagingBuffer->flush();
data = stagingBuffer->map();
pending.stagingBuffer = std::move(stagingBuffer);
} }
pendingBuffers[this] = std::move(pending); pendingBuffers[this] = std::move(pending);
@@ -239,60 +197,62 @@ void Buffer::unmap()
auto found = pendingBuffers.find(this); auto found = pendingBuffers.find(this);
if (found != pendingBuffers.end()) if (found != pendingBuffers.end())
{ {
PendingBuffer& pending = found->value; PendingBuffer &pending = found->value;
pending.stagingBuffer->flush(); vmaFlushAllocation(graphics->getAllocator(), pending.allocation, 0, VK_WHOLE_SIZE);
if (pending.writeOnly) if (pending.writeOnly)
{ {
PStagingBuffer stagingBuffer = pending.stagingBuffer; if (buffers[currentBuffer].properties & VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT)
PCommand command = graphics->getQueueCommands(owner)->getCommands(); {
VkCommandBuffer cmdHandle = command->getHandle(); vmaUnmapMemory(graphics->getAllocator(), buffers[currentBuffer].allocation);
}
else
{
vmaUnmapMemory(graphics->getAllocator(), pending.allocation);
PCommand command = graphics->getQueueCommands(owner)->getCommands();
VkCommandBuffer cmdHandle = command->getHandle();
VkBufferCopy region = { VkBufferCopy region = {
.srcOffset = 0, .srcOffset = 0,
.dstOffset = pending.offset, .dstOffset = pending.offset,
.size = pending.size, .size = pending.size,
}; };
VkBufferMemoryBarrier barrier = { VkBufferMemoryBarrier barrier = {
.sType = VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER, .sType = VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER,
.pNext = nullptr, .pNext = nullptr,
.srcAccessMask = VK_ACCESS_MEMORY_READ_BIT, .srcAccessMask = VK_ACCESS_MEMORY_READ_BIT,
.dstAccessMask = VK_ACCESS_MEMORY_WRITE_BIT, .dstAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT,
.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED, .srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED,
.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED, .dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED,
.buffer = buffers[currentBuffer].buffer, .buffer = buffers[currentBuffer].buffer,
.offset = 0, .offset = 0,
.size = size, .size = size,
}; };
vkCmdPipelineBarrier(cmdHandle, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, 0, 0, nullptr, 1, &barrier, 0, nullptr); vkCmdPipelineBarrier(cmdHandle, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, 0, 0, nullptr, 1, &barrier, 0, nullptr);
vkCmdCopyBuffer(cmdHandle, stagingBuffer->getHandle(), buffers[currentBuffer].buffer, 1, &region); vkCmdCopyBuffer(cmdHandle, pending.stagingBuffer, buffers[currentBuffer].buffer, 1, &region);
barrier = { barrier = {
.sType = VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER, .sType = VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER,
.pNext = nullptr, .pNext = nullptr,
.srcAccessMask = VK_ACCESS_MEMORY_WRITE_BIT, .srcAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT,
.dstAccessMask = VK_ACCESS_MEMORY_READ_BIT, .dstAccessMask = VK_ACCESS_MEMORY_READ_BIT,
.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED, .srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED,
.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED, .dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED,
.buffer = buffers[currentBuffer].buffer, .buffer = buffers[currentBuffer].buffer,
.offset = 0, .offset = 0,
.size = size, .size = size,
}; };
vkCmdPipelineBarrier(cmdHandle, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, 0, 0, nullptr, 1, &barrier, 0, nullptr); vkCmdPipelineBarrier(cmdHandle, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, 0, 0, nullptr, 1, &barrier, 0, nullptr);
vmaDestroyBuffer(graphics->getAllocator(), pending.stagingBuffer, pending.allocation);
}
} }
//requestOwnershipTransfer(pending.prevQueue); // requestOwnershipTransfer(pending.prevQueue);
graphics->getStagingManager()->release(std::move(pending.stagingBuffer));
pendingBuffers.erase(this); pendingBuffers.erase(this);
} }
} }
UniformBuffer::UniformBuffer(PGraphics graphics, const UniformBufferCreateInfo &createInfo) UniformBuffer::UniformBuffer(PGraphics graphics, const UniformBufferCreateInfo &createInfo)
: Gfx::UniformBuffer(graphics->getFamilyMapping(), createInfo.sourceData) : Gfx::UniformBuffer(graphics->getFamilyMapping(), createInfo.sourceData), Vulkan::Buffer(graphics, createInfo.sourceData.size, VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT, currentOwner, createInfo.dynamic)
, Vulkan::Buffer(graphics, createInfo.sourceData.size, VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT, currentOwner, createInfo.dynamic)
, dedicatedStagingBuffer(nullptr)
{ {
if(createInfo.dynamic)
{
dedicatedStagingBuffer = graphics->getStagingManager()->create(createInfo.sourceData.size, owner);
}
if (createInfo.sourceData.data != nullptr) if (createInfo.sourceData.data != nullptr)
{ {
void *data = map(); void *data = map();
@@ -303,75 +263,20 @@ UniformBuffer::UniformBuffer(PGraphics graphics, const UniformBufferCreateInfo &
UniformBuffer::~UniformBuffer() UniformBuffer::~UniformBuffer()
{ {
if (dedicatedStagingBuffer != nullptr)
{
graphics->getStagingManager()->release(std::move(dedicatedStagingBuffer));
}
} }
bool UniformBuffer::updateContents(const DataSource &sourceData) bool UniformBuffer::updateContents(const DataSource &sourceData)
{ {
if(!Gfx::UniformBuffer::updateContents(sourceData)) if (!Gfx::UniformBuffer::updateContents(sourceData))
{ {
// no update was performed, skip // no update was performed, skip
return false; return false;
} }
void* data = map(); void *data = map();
std::memcpy(data, sourceData.data, sourceData.size); std::memcpy(data, sourceData.data, sourceData.size);
unmap(); unmap();
return true; return true;
} }
void* UniformBuffer::map(bool writeOnly)
{
if(dedicatedStagingBuffer != nullptr)
{
return dedicatedStagingBuffer->map();
}
return Vulkan::Buffer::map(writeOnly);
}
void UniformBuffer::unmap()
{
if(dedicatedStagingBuffer != nullptr)
{
dedicatedStagingBuffer->flush();
PCommand command = graphics->getQueueCommands(currentOwner)->getCommands();
VkCommandBuffer cmdHandle = command->getHandle();
VkBufferCopy region;
std::memset(&region, 0, sizeof(VkBufferCopy));
region.size = Vulkan::Buffer::size;
VkBufferMemoryBarrier barrier = {
.sType = VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER,
.pNext = nullptr,
.srcAccessMask = VK_ACCESS_MEMORY_READ_BIT,
.dstAccessMask = VK_ACCESS_MEMORY_WRITE_BIT,
.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED,
.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED,
.buffer = buffers[currentBuffer].buffer,
.offset = 0,
.size = size,
};
vkCmdPipelineBarrier(cmdHandle, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, 0, 0, nullptr, 1, &barrier, 0, nullptr);
vkCmdCopyBuffer(cmdHandle, dedicatedStagingBuffer->getHandle(), buffers[currentBuffer].buffer, 1, &region);
barrier = {
.sType = VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER,
.pNext = nullptr,
.srcAccessMask = VK_ACCESS_MEMORY_WRITE_BIT,
.dstAccessMask = VK_ACCESS_MEMORY_READ_BIT,
.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED,
.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED,
.buffer = buffers[currentBuffer].buffer,
.offset = 0,
.size = size,
};
vkCmdPipelineBarrier(cmdHandle, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, 0, 0, nullptr, 1, &barrier, 0, nullptr);
}
else
{
Vulkan::Buffer::unmap();
}
}
void UniformBuffer::requestOwnershipTransfer(Gfx::QueueType newOwner) void UniformBuffer::requestOwnershipTransfer(Gfx::QueueType newOwner)
{ {
@@ -384,7 +289,7 @@ void UniformBuffer::executeOwnershipBarrier(Gfx::QueueType newOwner)
} }
void UniformBuffer::executePipelineBarrier(VkAccessFlags srcAccess, VkPipelineStageFlags srcStage, void UniformBuffer::executePipelineBarrier(VkAccessFlags srcAccess, VkPipelineStageFlags srcStage,
VkAccessFlags dstAccess, VkPipelineStageFlags dstStage) VkAccessFlags dstAccess, VkPipelineStageFlags dstStage)
{ {
Vulkan::Buffer::executePipelineBarrier(srcAccess, srcStage, dstAccess, dstStage); Vulkan::Buffer::executePipelineBarrier(srcAccess, srcStage, dstAccess, dstStage);
} }
@@ -400,14 +305,8 @@ VkAccessFlags UniformBuffer::getDestAccessMask()
} }
ShaderBuffer::ShaderBuffer(PGraphics graphics, const ShaderBufferCreateInfo &sourceData) ShaderBuffer::ShaderBuffer(PGraphics graphics, const ShaderBufferCreateInfo &sourceData)
: Gfx::ShaderBuffer(graphics->getFamilyMapping(), sourceData.numElements, sourceData.sourceData) : Gfx::ShaderBuffer(graphics->getFamilyMapping(), sourceData.numElements, sourceData.sourceData), Vulkan::Buffer(graphics, sourceData.sourceData.size, VK_BUFFER_USAGE_STORAGE_BUFFER_BIT, currentOwner, sourceData.dynamic)
, Vulkan::Buffer(graphics, sourceData.sourceData.size, VK_BUFFER_USAGE_STORAGE_BUFFER_BIT, currentOwner, sourceData.dynamic)
, dedicatedStagingBuffer(nullptr)
{ {
if(sourceData.dynamic)
{
dedicatedStagingBuffer = graphics->getStagingManager()->create(sourceData.sourceData.size, currentOwner);
}
if (sourceData.sourceData.data != nullptr) if (sourceData.sourceData.data != nullptr)
{ {
void *data = map(); void *data = map();
@@ -418,76 +317,18 @@ ShaderBuffer::ShaderBuffer(PGraphics graphics, const ShaderBufferCreateInfo &sou
ShaderBuffer::~ShaderBuffer() ShaderBuffer::~ShaderBuffer()
{ {
if (dedicatedStagingBuffer != nullptr)
{
graphics->getStagingManager()->release(std::move(dedicatedStagingBuffer));
}
} }
bool ShaderBuffer::updateContents(const DataSource &sourceData) bool ShaderBuffer::updateContents(const DataSource &sourceData)
{ {
assert(sourceData.size <= getSize()); assert(sourceData.size <= getSize());
Gfx::ShaderBuffer::updateContents(sourceData); Gfx::ShaderBuffer::updateContents(sourceData);
//We always want to update, as the contents could be different on the GPU // We always want to update, as the contents could be different on the GPU
void* data = map(); void *data = map();
std::memcpy(data, sourceData.data, sourceData.size); std::memcpy(data, sourceData.data, sourceData.size);
unmap(); unmap();
return true; return true;
} }
void* ShaderBuffer::map(bool writeOnly)
{
if(dedicatedStagingBuffer != nullptr)
{
return dedicatedStagingBuffer->map();
}
return Vulkan::Buffer::map(writeOnly);
}
void ShaderBuffer::unmap()
{
if(dedicatedStagingBuffer != nullptr)
{
dedicatedStagingBuffer->flush();
PCommand command = graphics->getQueueCommands(currentOwner)->getCommands();
VkCommandBuffer cmdHandle = command->getHandle();
VkBufferCopy region = {
.srcOffset = 0,
.dstOffset = 0,
.size = Vulkan::Buffer::size,
};
VkBufferMemoryBarrier barrier = {
.sType = VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER,
.pNext = nullptr,
.srcAccessMask = VK_ACCESS_MEMORY_READ_BIT,
.dstAccessMask = VK_ACCESS_MEMORY_WRITE_BIT,
.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED,
.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED,
.buffer = buffers[currentBuffer].buffer,
.offset = 0,
.size = size,
};
vkCmdPipelineBarrier(cmdHandle, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, 0, 0, nullptr, 1, &barrier, 0, nullptr);
vkCmdCopyBuffer(cmdHandle, dedicatedStagingBuffer->getHandle(), buffers[currentBuffer].buffer, 1, &region);
barrier = {
.sType = VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER,
.pNext = nullptr,
.srcAccessMask = VK_ACCESS_MEMORY_WRITE_BIT,
.dstAccessMask = VK_ACCESS_MEMORY_READ_BIT,
.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED,
.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED,
.buffer = buffers[currentBuffer].buffer,
.offset = 0,
.size = size,
};
vkCmdPipelineBarrier(cmdHandle, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, 0, 0, nullptr, 1, &barrier, 0, nullptr);
}
else
{
Vulkan::Buffer::unmap();
}
}
void ShaderBuffer::requestOwnershipTransfer(Gfx::QueueType newOwner) void ShaderBuffer::requestOwnershipTransfer(Gfx::QueueType newOwner)
{ {
@@ -500,7 +341,7 @@ void ShaderBuffer::executeOwnershipBarrier(Gfx::QueueType newOwner)
} }
void ShaderBuffer::executePipelineBarrier(VkAccessFlags srcAccess, VkPipelineStageFlags srcStage, void ShaderBuffer::executePipelineBarrier(VkAccessFlags srcAccess, VkPipelineStageFlags srcStage,
VkAccessFlags dstAccess, VkPipelineStageFlags dstStage) VkAccessFlags dstAccess, VkPipelineStageFlags dstStage)
{ {
Vulkan::Buffer::executePipelineBarrier(srcAccess, srcStage, dstAccess, dstStage); Vulkan::Buffer::executePipelineBarrier(srcAccess, srcStage, dstAccess, dstStage);
} }
@@ -516,8 +357,7 @@ VkAccessFlags ShaderBuffer::getDestAccessMask()
} }
VertexBuffer::VertexBuffer(PGraphics graphics, const VertexBufferCreateInfo &sourceData) VertexBuffer::VertexBuffer(PGraphics graphics, const VertexBufferCreateInfo &sourceData)
: Gfx::VertexBuffer(graphics->getFamilyMapping(), sourceData.numVertices, sourceData.vertexSize, sourceData.sourceData.owner) : Gfx::VertexBuffer(graphics->getFamilyMapping(), sourceData.numVertices, sourceData.vertexSize, sourceData.sourceData.owner), Vulkan::Buffer(graphics, sourceData.sourceData.size, VK_BUFFER_USAGE_VERTEX_BUFFER_BIT, currentOwner)
, Vulkan::Buffer(graphics, sourceData.sourceData.size, VK_BUFFER_USAGE_VERTEX_BUFFER_BIT, currentOwner)
{ {
if (sourceData.sourceData.data != nullptr) if (sourceData.sourceData.data != nullptr)
{ {
@@ -533,14 +373,14 @@ VertexBuffer::~VertexBuffer()
void VertexBuffer::updateRegion(DataSource update) void VertexBuffer::updateRegion(DataSource update)
{ {
void* data = mapRegion(update.offset, update.size); void *data = mapRegion(update.offset, update.size);
std::memcpy(data, update.data, update.size); std::memcpy(data, update.data, update.size);
unmap(); unmap();
} }
void VertexBuffer::download(Array<uint8>& buffer) void VertexBuffer::download(Array<uint8> &buffer)
{ {
void* data = map(false); void *data = map(false);
buffer.resize(size); buffer.resize(size);
std::memcpy(buffer.data(), data, size); std::memcpy(buffer.data(), data, size);
unmap(); unmap();
@@ -557,7 +397,7 @@ void VertexBuffer::executeOwnershipBarrier(Gfx::QueueType newOwner)
} }
void VertexBuffer::executePipelineBarrier(VkAccessFlags srcAccess, VkPipelineStageFlags srcStage, void VertexBuffer::executePipelineBarrier(VkAccessFlags srcAccess, VkPipelineStageFlags srcStage,
VkAccessFlags dstAccess, VkPipelineStageFlags dstStage) VkAccessFlags dstAccess, VkPipelineStageFlags dstStage)
{ {
Vulkan::Buffer::executePipelineBarrier(srcAccess, srcStage, dstAccess, dstStage); Vulkan::Buffer::executePipelineBarrier(srcAccess, srcStage, dstAccess, dstStage);
} }
@@ -573,8 +413,7 @@ VkAccessFlags VertexBuffer::getDestAccessMask()
} }
IndexBuffer::IndexBuffer(PGraphics graphics, const IndexBufferCreateInfo &sourceData) IndexBuffer::IndexBuffer(PGraphics graphics, const IndexBufferCreateInfo &sourceData)
: Gfx::IndexBuffer(graphics->getFamilyMapping(), sourceData.sourceData.size, sourceData.indexType, sourceData.sourceData.owner) : Gfx::IndexBuffer(graphics->getFamilyMapping(), sourceData.sourceData.size, sourceData.indexType, sourceData.sourceData.owner), Vulkan::Buffer(graphics, sourceData.sourceData.size, VK_BUFFER_USAGE_INDEX_BUFFER_BIT, currentOwner)
, Vulkan::Buffer(graphics, sourceData.sourceData.size, VK_BUFFER_USAGE_INDEX_BUFFER_BIT, currentOwner)
{ {
if (sourceData.sourceData.data != nullptr) if (sourceData.sourceData.data != nullptr)
{ {
@@ -588,9 +427,9 @@ IndexBuffer::~IndexBuffer()
{ {
} }
void IndexBuffer::download(Array<uint8>& buffer) void IndexBuffer::download(Array<uint8> &buffer)
{ {
void* data = map(false); void *data = map(false);
buffer.resize(size); buffer.resize(size);
std::memcpy(buffer.data(), data, size); std::memcpy(buffer.data(), data, size);
unmap(); unmap();
@@ -607,7 +446,7 @@ void IndexBuffer::executeOwnershipBarrier(Gfx::QueueType newOwner)
} }
void IndexBuffer::executePipelineBarrier(VkAccessFlags srcAccess, VkPipelineStageFlags srcStage, void IndexBuffer::executePipelineBarrier(VkAccessFlags srcAccess, VkPipelineStageFlags srcStage,
VkAccessFlags dstAccess, VkPipelineStageFlags dstStage) VkAccessFlags dstAccess, VkPipelineStageFlags dstStage)
{ {
Vulkan::Buffer::executePipelineBarrier(srcAccess, srcStage, dstAccess, dstStage); Vulkan::Buffer::executePipelineBarrier(srcAccess, srcStage, dstAccess, dstStage);
} }
+6 -13
View File
@@ -1,7 +1,6 @@
#pragma once #pragma once
#include "Graphics/Buffer.h" #include "Graphics/Buffer.h"
#include "Graphics.h" #include "Graphics.h"
#include "Allocator.h"
namespace Seele namespace Seele
{ {
@@ -20,20 +19,21 @@ public:
{ {
return size; return size;
} }
VkDeviceSize getOffset() const;
void advanceBuffer() void advanceBuffer()
{ {
currentBuffer = (currentBuffer + 1) % numBuffers; currentBuffer = (currentBuffer + 1) % numBuffers;
} }
virtual void *map(bool writeOnly = true); void *map(bool writeOnly = true);
virtual void *mapRegion(uint64 regionOffset, uint64 regionSize, bool writeOnly = true); void *mapRegion(uint64 regionOffset, uint64 regionSize, bool writeOnly = true);
virtual void unmap(); void unmap();
protected: protected:
struct BufferAllocation struct BufferAllocation
{ {
VkBuffer buffer; VkBuffer buffer;
OSubAllocation allocation; VmaAllocation allocation;
VmaAllocationInfo info;
VkMemoryPropertyFlags properties;
}; };
PGraphics graphics; PGraphics graphics;
uint32 currentBuffer; uint32 currentBuffer;
@@ -53,7 +53,6 @@ protected:
}; };
DEFINE_REF(Buffer) DEFINE_REF(Buffer)
DECLARE_REF(StagingBuffer)
class UniformBuffer : public Gfx::UniformBuffer, public Buffer class UniformBuffer : public Gfx::UniformBuffer, public Buffer
{ {
public: public:
@@ -61,8 +60,6 @@ public:
virtual ~UniformBuffer(); virtual ~UniformBuffer();
virtual bool updateContents(const DataSource &sourceData) override; virtual bool updateContents(const DataSource &sourceData) override;
virtual void* map(bool writeOnly = true) override;
virtual void unmap() override;
protected: protected:
// Inherited via Vulkan::Buffer // Inherited via Vulkan::Buffer
virtual VkAccessFlags getSourceAccessMask() override; virtual VkAccessFlags getSourceAccessMask() override;
@@ -74,7 +71,6 @@ protected:
VkAccessFlags dstAccess, VkPipelineStageFlags dstStage) override; VkAccessFlags dstAccess, VkPipelineStageFlags dstStage) override;
private: private:
OStagingBuffer dedicatedStagingBuffer;
}; };
DEFINE_REF(UniformBuffer) DEFINE_REF(UniformBuffer)
@@ -85,8 +81,6 @@ public:
virtual ~ShaderBuffer(); virtual ~ShaderBuffer();
virtual bool updateContents(const DataSource &sourceData) override; virtual bool updateContents(const DataSource &sourceData) override;
virtual void* map(bool writeOnly = true) override;
virtual void unmap() override;
protected: protected:
// Inherited via Vulkan::Buffer // Inherited via Vulkan::Buffer
virtual VkAccessFlags getSourceAccessMask() override; virtual VkAccessFlags getSourceAccessMask() override;
@@ -97,7 +91,6 @@ protected:
virtual void executePipelineBarrier(VkAccessFlags srcAccess, VkPipelineStageFlags srcStage, virtual void executePipelineBarrier(VkAccessFlags srcAccess, VkPipelineStageFlags srcStage,
VkAccessFlags dstAccess, VkPipelineStageFlags dstStage) override; VkAccessFlags dstAccess, VkPipelineStageFlags dstStage) override;
private: private:
OStagingBuffer dedicatedStagingBuffer;
}; };
DEFINE_REF(ShaderBuffer) DEFINE_REF(ShaderBuffer)
+34 -14
View File
@@ -13,6 +13,8 @@
#include <GLFW/glfw3.h> #include <GLFW/glfw3.h>
#include <cstring> #include <cstring>
#include <vulkan/vulkan_core.h> #include <vulkan/vulkan_core.h>
#define VMA_IMPLEMENTATION
#include "vk_mem_alloc.h"
using namespace Seele; using namespace Seele;
using namespace Seele::Vulkan; using namespace Seele::Vulkan;
@@ -40,7 +42,6 @@ Graphics::~Graphics()
pipelineCache = nullptr; pipelineCache = nullptr;
allocator = nullptr; allocator = nullptr;
destructionManager = nullptr; destructionManager = nullptr;
stagingManager = nullptr;
allocatedFramebuffers.clear(); allocatedFramebuffers.clear();
shaderCompiler = nullptr; shaderCompiler = nullptr;
vkDestroyDevice(handle, nullptr); vkDestroyDevice(handle, nullptr);
@@ -56,8 +57,19 @@ void Graphics::init(GraphicsInitializer initInfo)
#endif #endif
pickPhysicalDevice(); pickPhysicalDevice();
createDevice(initInfo); createDevice(initInfo);
allocator = new Allocator(this); VmaAllocatorCreateInfo createInfo = {
stagingManager = new StagingManager(this, allocator); .device = handle,
.instance = instance,
.pAllocationCallbacks = nullptr,
.pDeviceMemoryCallbacks = nullptr,
.pHeapSizeLimit = nullptr,
.physicalDevice = physicalDevice,
.preferredLargeHeapBlockSize = 0,
.pTypeExternalMemoryHandleTypes = nullptr,
.pVulkanFunctions = nullptr,
.vulkanApiVersion = VK_API_VERSION_1_3,
};
vmaCreateAllocator(&createInfo, &allocator);
pipelineCache = new PipelineCache(this, "pipeline.cache"); pipelineCache = new PipelineCache(this, "pipeline.cache");
destructionManager = new DestructionManager(this); destructionManager = new DestructionManager(this);
} }
@@ -326,16 +338,12 @@ PCommandPool Graphics::getDedicatedTransferCommands()
} }
return dedicatedTransferCommands; return dedicatedTransferCommands;
} }
PAllocator Graphics::getAllocator()
VmaAllocator Graphics::getAllocator()
{ {
return allocator; return allocator;
} }
PStagingManager Graphics::getStagingManager()
{
return stagingManager;
}
PDestructionManager Graphics::getDestructionManager() PDestructionManager Graphics::getDestructionManager()
{ {
return destructionManager; return destructionManager;
@@ -374,11 +382,17 @@ void Graphics::initInstance(GraphicsInitializer initInfo)
{ {
extensions.add(initInfo.instanceExtensions[i]); extensions.add(initInfo.instanceExtensions[i]);
} }
#ifdef __APPLE__
extensions.add("VK_KHR_portability_enumeration");
#endif
#if ENABLE_VALIDATION #if ENABLE_VALIDATION
initInfo.layers.add("VK_LAYER_KHRONOS_validation"); initInfo.layers.add("VK_LAYER_KHRONOS_validation");
#endif #endif
VkInstanceCreateInfo info = { VkInstanceCreateInfo info = {
.sType = VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO, .sType = VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO,
#if __APPLE__
.flags = VK_INSTANCE_CREATE_ENUMERATE_PORTABILITY_BIT_KHR,
#endif
.pApplicationInfo = &appInfo, .pApplicationInfo = &appInfo,
.enabledLayerCount = (uint32)initInfo.layers.size(), .enabledLayerCount = (uint32)initInfo.layers.size(),
.ppEnabledLayerNames = initInfo.layers.data(), .ppEnabledLayerNames = initInfo.layers.data(),
@@ -480,6 +494,13 @@ void Graphics::createDevice(GraphicsInitializer initializer)
auto checkFamilyProperty = [](VkQueueFamilyProperties currProps, uint32 checkBit){ auto checkFamilyProperty = [](VkQueueFamilyProperties currProps, uint32 checkBit){
return (currProps.queueFlags & checkBit) == checkBit; return (currProps.queueFlags & checkBit) == checkBit;
}; };
auto updateQueueInfo = [&queueProperties](uint32 familyIndex, QueueCreateInfo& info, uint32& numQueues) {
if(info.familyIndex == -1) {
info.familyIndex = familyIndex;
numQueues = std::min(numQueues + 1, queueProperties[familyIndex].queueCount);
info.queueIndex = numQueues - 1;
}
};
for (uint32 familyIndex = 0; familyIndex < queueProperties.size(); ++familyIndex) for (uint32 familyIndex = 0; familyIndex < queueProperties.size(); ++familyIndex)
{ {
uint32 numQueuesForFamily = 0; uint32 numQueuesForFamily = 0;
@@ -487,11 +508,7 @@ void Graphics::createDevice(GraphicsInitializer initializer)
if (checkFamilyProperty(currProps, VK_QUEUE_GRAPHICS_BIT)) if (checkFamilyProperty(currProps, VK_QUEUE_GRAPHICS_BIT))
{ {
if (graphicsQueueInfo.familyIndex == -1) updateQueueInfo(familyIndex, graphicsQueueInfo, numQueueFamilies);
{
graphicsQueueInfo.familyIndex = familyIndex;
numQueuesForFamily++;
}
} }
if (currProps.queueFlags & VK_QUEUE_COMPUTE_BIT) if (currProps.queueFlags & VK_QUEUE_COMPUTE_BIT)
{ {
@@ -568,6 +585,9 @@ void Graphics::createDevice(GraphicsInitializer initializer)
features12.pNext = &enabledMeshShaderFeatures; features12.pNext = &enabledMeshShaderFeatures;
initializer.deviceExtensions.add(VK_EXT_MESH_SHADER_EXTENSION_NAME); initializer.deviceExtensions.add(VK_EXT_MESH_SHADER_EXTENSION_NAME);
} }
#ifdef __APPLE__
initializer.deviceExtensions.add("VK_KHR_portability_subset");
#endif
VkDeviceCreateInfo deviceInfo = { VkDeviceCreateInfo deviceInfo = {
.sType = VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO, .sType = VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO,
.pNext = &features11, .pNext = &features11,
+4 -6
View File
@@ -1,13 +1,12 @@
#pragma once #pragma once
#include "Enums.h" #include "Enums.h"
#include "Graphics/Graphics.h" #include "Graphics/Graphics.h"
#include <vk_mem_alloc.h>
namespace Seele namespace Seele
{ {
namespace Vulkan namespace Vulkan
{ {
DECLARE_REF(Allocator)
DECLARE_REF(StagingManager)
DECLARE_REF(DestructionManager) DECLARE_REF(DestructionManager)
DECLARE_REF(CommandPool) DECLARE_REF(CommandPool)
DECLARE_REF(Queue) DECLARE_REF(Queue)
@@ -28,8 +27,7 @@ public:
PCommandPool getTransferCommands(); PCommandPool getTransferCommands();
PCommandPool getDedicatedTransferCommands(); PCommandPool getDedicatedTransferCommands();
PAllocator getAllocator(); VmaAllocator getAllocator();
PStagingManager getStagingManager();
PDestructionManager getDestructionManager(); PDestructionManager getDestructionManager();
// Inherited via Graphics // Inherited via Graphics
@@ -71,6 +69,7 @@ public:
virtual void resolveTexture(Gfx::PTexture source, Gfx::PTexture destination) override; virtual void resolveTexture(Gfx::PTexture source, Gfx::PTexture destination) override;
void vkCmdDrawMeshTasksEXT(VkCommandBuffer handle, uint32 groupX, uint32 groupY, uint32 groupZ); void vkCmdDrawMeshTasksEXT(VkCommandBuffer handle, uint32 groupX, uint32 groupY, uint32 groupZ);
protected: protected:
PFN_vkCmdDrawMeshTasksEXT cmdDrawMeshTasks; PFN_vkCmdDrawMeshTasksEXT cmdDrawMeshTasks;
Array<const char *> getRequiredExtensions(); Array<const char *> getRequiredExtensions();
@@ -97,9 +96,8 @@ protected:
VkPhysicalDeviceVulkan12Features features12; VkPhysicalDeviceVulkan12Features features12;
VkDebugReportCallbackEXT callback; VkDebugReportCallbackEXT callback;
Map<uint32, OFramebuffer> allocatedFramebuffers; Map<uint32, OFramebuffer> allocatedFramebuffers;
OAllocator allocator; VmaAllocator allocator;
OPipelineCache pipelineCache; OPipelineCache pipelineCache;
OStagingManager stagingManager;
ODestructionManager destructionManager; ODestructionManager destructionManager;
friend class Window; friend class Window;
-6
View File
@@ -129,11 +129,6 @@ void DestructionManager::queueDescriptorPool(PCommand cmd, VkDescriptorPool pool
pools[cmd].add(pool); pools[cmd].add(pool);
} }
void DestructionManager::queueAllocation(PCommand cmd, OSubAllocation alloc)
{
allocs[cmd].add(std::move(alloc));
}
void DestructionManager::notifyCmdComplete(PCommand cmd) void DestructionManager::notifyCmdComplete(PCommand cmd)
{ {
for(auto buf : buffers[cmd]) for(auto buf : buffers[cmd])
@@ -166,5 +161,4 @@ void DestructionManager::notifyCmdComplete(PCommand cmd)
sems[cmd].clear(); sems[cmd].clear();
pools[cmd].clear(); pools[cmd].clear();
renderPasses[cmd].clear(); renderPasses[cmd].clear();
allocs[cmd].clear();
} }
-3
View File
@@ -12,7 +12,6 @@ DECLARE_REF(DescriptorPool)
DECLARE_REF(CommandPool) DECLARE_REF(CommandPool)
DECLARE_REF(Command) DECLARE_REF(Command)
DECLARE_REF(Graphics) DECLARE_REF(Graphics)
DECLARE_REF(SubAllocation)
class Semaphore class Semaphore
{ {
public: public:
@@ -63,7 +62,6 @@ public:
void queueSemaphore(PCommand cmd, VkSemaphore sem); void queueSemaphore(PCommand cmd, VkSemaphore sem);
void queueRenderPass(PCommand cmd, VkRenderPass renderPass); void queueRenderPass(PCommand cmd, VkRenderPass renderPass);
void queueDescriptorPool(PCommand cmd, VkDescriptorPool pool); void queueDescriptorPool(PCommand cmd, VkDescriptorPool pool);
void queueAllocation(PCommand cmd, OSubAllocation alloc);
void notifyCmdComplete(PCommand cmdbuffer); void notifyCmdComplete(PCommand cmdbuffer);
private: private:
PGraphics graphics; PGraphics graphics;
@@ -73,7 +71,6 @@ private:
Map<PCommand, List<VkSemaphore>> sems; Map<PCommand, List<VkSemaphore>> sems;
Map<PCommand, List<VkRenderPass>> renderPasses; Map<PCommand, List<VkRenderPass>> renderPasses;
Map<PCommand, List<VkDescriptorPool>> pools; Map<PCommand, List<VkDescriptorPool>> pools;
Map<PCommand, List<OSubAllocation>> allocs;
}; };
DEFINE_REF(DestructionManager) DEFINE_REF(DestructionManager)
+92 -66
View File
@@ -46,7 +46,6 @@ TextureBase::TextureBase(PGraphics graphics, VkImageViewType viewType,
if (existingImage == VK_NULL_HANDLE) if (existingImage == VK_NULL_HANDLE)
{ {
ownsImage = true; ownsImage = true;
PAllocator pool = graphics->getAllocator();
VkImageType type = VK_IMAGE_TYPE_MAX_ENUM; VkImageType type = VK_IMAGE_TYPE_MAX_ENUM;
VkImageCreateFlags flags = 0; VkImageCreateFlags flags = 0;
switch (viewType) switch (viewType)
@@ -97,69 +96,79 @@ TextureBase::TextureBase(PGraphics graphics, VkImageViewType viewType,
.sharingMode = VK_SHARING_MODE_EXCLUSIVE, .sharingMode = VK_SHARING_MODE_EXCLUSIVE,
.initialLayout = cast(layout), .initialLayout = cast(layout),
}; };
VmaAllocationCreateInfo allocInfo = {
.usage = VMA_MEMORY_USAGE_AUTO,
VK_CHECK(vkCreateImage(graphics->getDevice(), &info, nullptr, &image));
VkMemoryDedicatedRequirements memDedicatedRequirements = {
.sType = VK_STRUCTURE_TYPE_MEMORY_DEDICATED_REQUIREMENTS,
.pNext = nullptr,
}; };
VkImageMemoryRequirementsInfo2 reqInfo = { VK_CHECK(vmaCreateImage(graphics->getAllocator(), &info, &allocInfo, &image, &allocation, nullptr));
.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_REQUIREMENTS_INFO_2,
.pNext = nullptr,
.image = image,
};
VkMemoryRequirements2 requirements = {
.sType = VK_STRUCTURE_TYPE_MEMORY_REQUIREMENTS_2,
.pNext = &memDedicatedRequirements,
};
vkGetImageMemoryRequirements2(graphics->getDevice(), &reqInfo, &requirements);
allocation = pool->allocate(requirements, createInfo.memoryProps, image); const DataSource& sourceData = createInfo.sourceData;
vkBindImageMemory(graphics->getDevice(), image, allocation->getHandle(), allocation->getOffset()); if(sourceData.size > 0)
{
changeLayout(Gfx::SE_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL);
void* data;
VkMemoryPropertyFlags memProps;
VkBuffer stagingBuffer = VK_NULL_HANDLE;
VmaAllocation stagingAlloc = VK_NULL_HANDLE;
vmaGetAllocationMemoryProperties(graphics->getAllocator(), allocation, &memProps);
if(memProps & VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT)
{
vmaMapMemory(graphics->getAllocator(), allocation, &data);
}
else
{
VkBufferCreateInfo stagingInfo = {
.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,
.pNext = nullptr,
.flags = 0,
.size = sourceData.size,
.usage = VK_BUFFER_USAGE_TRANSFER_SRC_BIT,
.sharingMode = VK_SHARING_MODE_EXCLUSIVE,
};
VmaAllocationCreateInfo alloc = {
.usage = VMA_MEMORY_USAGE_AUTO,
};
VK_CHECK(vmaCreateBuffer(graphics->getAllocator(), &stagingInfo, &alloc, &stagingBuffer, &stagingAlloc, nullptr));
vmaMapMemory(graphics->getAllocator(), stagingAlloc, &data);
}
std::memcpy(data, sourceData.data, sourceData.size);
vmaFlushAllocation(graphics->getAllocator(), stagingAlloc, 0, VK_WHOLE_SIZE);
PCommandPool commandPool = graphics->getQueueCommands(currentOwner);
VkBufferImageCopy region = {
.bufferOffset = 0,
.bufferRowLength = 0,
.bufferImageHeight = 0,
.imageSubresource = {
.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT,
.mipLevel = 0,
.baseArrayLayer = 0,
.layerCount = arrayCount * layerCount,
},
.imageOffset = {
.x = 0,
.y = 0,
.z = 0,
},
.imageExtent = {
.width = width,
.height = height,
.depth = depth
},
};
vkCmdCopyBufferToImage(commandPool->getCommands()->getHandle(),
stagingBuffer, image, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1, &region);
// When loading a texture from a file, we will almost always use it as a texture map for fragment shaders
changeLayout(Gfx::SE_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL);
if(stagingBuffer != VK_NULL_HANDLE)
{
vmaDestroyBuffer(graphics->getAllocator(), stagingBuffer, stagingAlloc);
}
}
} }
const DataSource& sourceData = createInfo.sourceData; if(usage & VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT)
if(sourceData.size > 0)
{
changeLayout(Gfx::SE_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL);
OStagingBuffer staging = graphics->getStagingManager()->create(sourceData.size, owner);
void* data = staging->map();
std::memcpy(data, sourceData.data, sourceData.size);
staging->flush();
PCommandPool commandPool = graphics->getQueueCommands(currentOwner);
VkBufferImageCopy region = {
.bufferOffset = 0,
.bufferRowLength = 0,
.bufferImageHeight = 0,
.imageSubresource = {
.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT,
.mipLevel = 0,
.baseArrayLayer = 0,
.layerCount = arrayCount * layerCount,
},
.imageOffset = {
.x = 0,
.y = 0,
.z = 0,
},
.imageExtent = {
.width = width,
.height = height,
.depth = depth
},
};
vkCmdCopyBufferToImage(commandPool->getCommands()->getHandle(),
staging->getHandle(), image, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1, &region);
// When loading a texture from a file, we will almost always use it as a texture map for fragment shaders
changeLayout(Gfx::SE_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL);
graphics->getStagingManager()->release(std::move(staging));
}
else if(usage & VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT)
{ {
changeLayout(Gfx::SE_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL); changeLayout(Gfx::SE_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL);
} }
@@ -231,9 +240,25 @@ void TextureBase::download(uint32 mipLevel, uint32 arrayLayer, uint32 face, Arra
{ {
uint64 imageSize = width * height * depth * Gfx::getFormatInfo(format).blockSize; uint64 imageSize = width * height * depth * Gfx::getFormatInfo(format).blockSize;
OStagingBuffer stagingbuffer = graphics->getStagingManager()->create(imageSize, currentOwner); auto prevLayout = layout;
auto prevlayout = layout;
changeLayout(Gfx::SE_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL); changeLayout(Gfx::SE_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL);
void* data;
VkBuffer stagingBuffer = VK_NULL_HANDLE;
VmaAllocation stagingAlloc;
VkBufferCreateInfo stagingInfo = {
.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,
.pNext = nullptr,
.flags = 0,
.size = imageSize,
.usage = VK_BUFFER_USAGE_TRANSFER_SRC_BIT,
.sharingMode = VK_SHARING_MODE_EXCLUSIVE,
};
VmaAllocationCreateInfo alloc = {
.usage = VMA_MEMORY_USAGE_AUTO,
};
VK_CHECK(vmaCreateBuffer(graphics->getAllocator(), &stagingInfo, &alloc, &stagingBuffer, &stagingAlloc, nullptr));
PCommand cmdBuffer = graphics->getQueueCommands(currentOwner)->getCommands(); PCommand cmdBuffer = graphics->getQueueCommands(currentOwner)->getCommands();
//Gfx::FormatCompatibilityInfo formatInfo = Gfx::getFormatInfo(format); //Gfx::FormatCompatibilityInfo formatInfo = Gfx::getFormatInfo(format);
VkBufferImageCopy region = { VkBufferImageCopy region = {
@@ -257,11 +282,12 @@ void TextureBase::download(uint32 mipLevel, uint32 arrayLayer, uint32 face, Arra
.depth = depth .depth = depth
}, },
}; };
vkCmdCopyImageToBuffer(cmdBuffer->getHandle(), image, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, stagingbuffer->getHandle(), 1, &region); vkCmdCopyImageToBuffer(cmdBuffer->getHandle(), image, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, stagingBuffer, 1, &region);
changeLayout(prevlayout); changeLayout(prevLayout);
buffer.resize(stagingbuffer->getSize()); buffer.resize(imageSize);
void* data = stagingbuffer->map();
std::memcpy(buffer.data(), data, buffer.size()); std::memcpy(buffer.data(), data, buffer.size());
vmaUnmapMemory(graphics->getAllocator(), stagingAlloc);
vmaDestroyBuffer(graphics->getAllocator(), stagingBuffer, stagingAlloc);
} }
void TextureBase::executeOwnershipBarrier(Gfx::QueueType newOwner) void TextureBase::executeOwnershipBarrier(Gfx::QueueType newOwner)
+1 -3
View File
@@ -1,13 +1,11 @@
#pragma once #pragma once
#include "Graphics/Texture.h" #include "Graphics/Texture.h"
#include "Graphics.h" #include "Graphics.h"
#include "Allocator.h"
namespace Seele namespace Seele
{ {
namespace Vulkan namespace Vulkan
{ {
class TextureBase class TextureBase
{ {
public: public:
@@ -72,7 +70,7 @@ protected:
//Updates via reference //Updates via reference
Gfx::QueueType& currentOwner; Gfx::QueueType& currentOwner;
PGraphics graphics; PGraphics graphics;
OSubAllocation allocation; VmaAllocation allocation;
uint32 width; uint32 width;
uint32 height; uint32 height;
uint32 depth; uint32 depth;
-4
View File
@@ -95,10 +95,6 @@ void GameView::reloadGame()
void GameView::keyCallback(KeyCode code, InputAction action, KeyModifier modifier) void GameView::keyCallback(KeyCode code, InputAction action, KeyModifier modifier)
{ {
if (code == KeyCode::KEY_P && action == InputAction::PRESS)
{
((Vulkan::Graphics*)graphics.getHandle())->getAllocator()->print();
}
keyboardSystem->keyCallback(code, action, modifier); keyboardSystem->keyCallback(code, action, modifier);
} }
+2 -1
View File
@@ -11,6 +11,7 @@
"nlohmann-json", "nlohmann-json",
"fmt", "fmt",
"shader-slang", "shader-slang",
"gtest" "gtest",
"vulkan-memory-allocator"
] ]
} }