More refactoring
This commit is contained in:
@@ -1,6 +1,7 @@
|
||||
#include "Allocator.h"
|
||||
#include "Graphics.h"
|
||||
#include "Initializer.h"
|
||||
#include "Resources.h"
|
||||
|
||||
using namespace Seele::Vulkan;
|
||||
|
||||
@@ -28,9 +29,9 @@ bool SubAllocation::isReadable() const
|
||||
return owner->isReadable();
|
||||
}
|
||||
|
||||
void *SubAllocation::getMappedPointer()
|
||||
void *SubAllocation::map()
|
||||
{
|
||||
return (uint8 *)owner->getMappedPointer() + alignedOffset;
|
||||
return (uint8 *)owner->map() + alignedOffset;
|
||||
}
|
||||
|
||||
void SubAllocation::flushMemory()
|
||||
@@ -38,9 +39,9 @@ void SubAllocation::flushMemory()
|
||||
owner->flushMemory();
|
||||
}
|
||||
|
||||
void SubAllocation::invalidateMemory()
|
||||
void SubAllocation::invalidate()
|
||||
{
|
||||
owner->invalidateMemory();
|
||||
owner->invalidate();
|
||||
}
|
||||
|
||||
Allocation::Allocation(PGraphics graphics, PAllocator allocator, VkDeviceSize size, uint8 memoryTypeIndex,
|
||||
@@ -49,23 +50,22 @@ Allocation::Allocation(PGraphics graphics, PAllocator allocator, VkDeviceSize si
|
||||
, allocator(allocator)
|
||||
, bytesAllocated(0)
|
||||
, bytesUsed(0)
|
||||
, readable(properties & VK_MEMORY_PROPERTY_HOST_COHERENT_BIT)
|
||||
, canMap((properties & VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT) == VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT),
|
||||
, isMapped(false),
|
||||
, properties(properties)
|
||||
, memoryTypeIndex(memoryTypeIndex)
|
||||
{
|
||||
VkMemoryAllocateInfo allocInfo =
|
||||
init::MemoryAllocateInfo();
|
||||
allocInfo.allocationSize = size;
|
||||
allocInfo.memoryTypeIndex = memoryTypeIndex;
|
||||
VkMemoryAllocateInfo allocInfo = {
|
||||
.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO,
|
||||
.pNext = dedicatedInfo,
|
||||
.allocationSize = size,
|
||||
.memoryTypeIndex = memoryTypeIndex,
|
||||
};
|
||||
isDedicated = dedicatedInfo != nullptr;
|
||||
allocInfo.pNext = dedicatedInfo;
|
||||
//std::cout << "New allocation" << std::endl;
|
||||
VK_CHECK(vkAllocateMemory(device, &allocInfo, nullptr, &allocatedMemory));
|
||||
bytesAllocated = size;
|
||||
freeRanges[0] = size;
|
||||
|
||||
canMap = (properties & VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT) == VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT;
|
||||
isMapped = false;
|
||||
}
|
||||
|
||||
Allocation::~Allocation()
|
||||
@@ -97,24 +97,19 @@ OSubAllocation Allocation::getSuballocation(VkDeviceSize requestedSize, VkDevice
|
||||
alignedOffset /= alignment;
|
||||
alignedOffset *= alignment;
|
||||
VkDeviceSize allocatedSize = requestedSize + (alignedOffset - lower);
|
||||
if (size == allocatedSize)
|
||||
{
|
||||
OSubAllocation alloc = new SubAllocation(this, requestedSize, lower, allocatedSize, alignedOffset);
|
||||
activeAllocations.add(alloc);
|
||||
freeRanges.erase(lower);
|
||||
bytesUsed += allocatedSize;
|
||||
return alloc;
|
||||
}
|
||||
else if (allocatedSize < size)
|
||||
if (size <= allocatedSize)
|
||||
{
|
||||
VkDeviceSize newSize = size - allocatedSize;
|
||||
VkDeviceSize newLower = lower + allocatedSize;
|
||||
OSubAllocation subAlloc = new SubAllocation(this, requestedSize, lower, allocatedSize, alignedOffset);
|
||||
activeAllocations.add(subAlloc);
|
||||
OSubAllocation alloc = new SubAllocation(this, requestedSize, lower, allocatedSize, alignedOffset);
|
||||
activeAllocations.add(alloc);
|
||||
freeRanges.erase(lower);
|
||||
freeRanges[newLower] = newSize;
|
||||
if (newSize > 0)
|
||||
{
|
||||
freeRanges[newLower] = newSize;
|
||||
}
|
||||
bytesUsed += allocatedSize;
|
||||
return subAlloc;
|
||||
return alloc;
|
||||
}
|
||||
}
|
||||
return nullptr;
|
||||
@@ -161,7 +156,7 @@ void Allocation::flushMemory()
|
||||
vkFlushMappedMemoryRanges(device, 1, &range);
|
||||
}
|
||||
|
||||
void Allocation::invalidateMemory()
|
||||
void Allocation::invalidate()
|
||||
{
|
||||
VkMappedMemoryRange range = {
|
||||
.sType = VK_STRUCTURE_TYPE_MAPPED_MEMORY_RANGE,
|
||||
@@ -232,7 +227,7 @@ OSubAllocation Allocator::allocate(const VkMemoryRequirements2 &memRequirements2
|
||||
}
|
||||
|
||||
// no suitable allocations found, allocate new block
|
||||
OAllocation newAllocation = new Allocation(graphics, this, (requirements.size > MemoryBlockSize) ? requirements.size : (VkDeviceSize)MemoryBlockSize, 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;
|
||||
//std::cout << "Heap " << heapIndex << ": " << (float)heaps[heapIndex].inUse / heaps[heapIndex].maxSize << "%" << std::endl;
|
||||
heaps[heapIndex].allocations.add(std::move(newAllocation));
|
||||
@@ -269,37 +264,37 @@ uint32 Allocator::findMemoryType(uint32 typeFilter, VkMemoryPropertyFlags proper
|
||||
throw std::runtime_error("error finding memory");
|
||||
}
|
||||
|
||||
StagingBuffer::StagingBuffer(OSubAllocation allocation, VkBuffer buffer, VkDeviceSize size, VkBufferUsageFlags usage, uint8 readable)
|
||||
: allocation(std::move(allocation))
|
||||
StagingBuffer::StagingBuffer(PGraphics graphics, OSubAllocation allocation, VkBuffer buffer, VkDeviceSize size)
|
||||
: QueueOwnedResource(graphics->getFamilyMapping(), Gfx::QueueType::DEDICATED_TRANSFER)
|
||||
, graphics(graphics)
|
||||
, allocation(std::move(allocation))
|
||||
, buffer(buffer)
|
||||
, size(size)
|
||||
, usage(usage)
|
||||
, readable(readable)
|
||||
{
|
||||
}
|
||||
|
||||
StagingBuffer::~StagingBuffer()
|
||||
{
|
||||
assert(allocation == nullptr);
|
||||
// buffer went out of scope without being cleaned up
|
||||
graphics->getDestructionManager()->queueBuffer(
|
||||
graphics->getDedicatedTransferCommands()->getCommands(), buffer);
|
||||
}
|
||||
|
||||
void* StagingBuffer::getMappedPointer()
|
||||
void* StagingBuffer::map()
|
||||
{
|
||||
return allocation->getMappedPointer();
|
||||
return allocation->map();
|
||||
}
|
||||
|
||||
void StagingBuffer::flushMappedMemory()
|
||||
void StagingBuffer::flush()
|
||||
{
|
||||
allocation->flushMemory();
|
||||
}
|
||||
|
||||
void StagingBuffer::invalidateMemory()
|
||||
void StagingBuffer::invalidate()
|
||||
{
|
||||
allocation->invalidateMemory();
|
||||
allocation->invalidate();
|
||||
}
|
||||
|
||||
VkDeviceMemory StagingBuffer::getMemoryHandle() const
|
||||
VkDeviceMemory StagingBuffer::getMemory() const
|
||||
{
|
||||
return allocation->getHandle();
|
||||
}
|
||||
@@ -309,9 +304,14 @@ VkDeviceSize StagingBuffer::getOffset() const
|
||||
return allocation->getOffset();
|
||||
}
|
||||
|
||||
uint64 StagingBuffer::getSize() const
|
||||
void StagingBuffer::executeOwnershipBarrier(Gfx::QueueType newOwner)
|
||||
{
|
||||
return size;
|
||||
assert(false);
|
||||
}
|
||||
void StagingBuffer::executePipelineBarrier(Gfx::SeAccessFlags srcAccess, Gfx::SePipelineStageFlags srcStage,
|
||||
Gfx::SeAccessFlags dstAccess, Gfx::SePipelineStageFlags dstStage)
|
||||
{
|
||||
assert(false);
|
||||
}
|
||||
|
||||
StagingManager::StagingManager(PGraphics graphics, PAllocator allocator)
|
||||
@@ -323,34 +323,23 @@ StagingManager::~StagingManager()
|
||||
{
|
||||
}
|
||||
|
||||
void StagingManager::clearPending()
|
||||
OStagingBuffer StagingManager::create(uint64 size)
|
||||
{
|
||||
}
|
||||
|
||||
OStagingBuffer StagingManager::allocateStagingBuffer(uint64 size, VkBufferUsageFlags usage, bool readable)
|
||||
{
|
||||
for (auto it = freeBuffers.begin(); it != freeBuffers.end(); ++it)
|
||||
{
|
||||
auto& freeBuffer = *it;
|
||||
if (freeBuffer->getSize() == size && freeBuffer->isReadable() == readable && freeBuffer->getUsage() == usage)
|
||||
{
|
||||
//std::cout << "Reusing staging buffer" << std::endl;
|
||||
activeBuffers.add(freeBuffer);
|
||||
OStagingBuffer owner = std::move(freeBuffer);
|
||||
freeBuffers.remove(it, false);
|
||||
return std::move(owner);
|
||||
}
|
||||
}
|
||||
//std::cout << "Creating new stagingbuffer" << std::endl;
|
||||
VkBuffer buffer;
|
||||
VkBufferCreateInfo stagingBufferCreateInfo = init::BufferCreateInfo(usage, size);
|
||||
stagingBufferCreateInfo.sharingMode = VK_SHARING_MODE_EXCLUSIVE;
|
||||
uint32 queueIndex = graphics->getFamilyMapping().getQueueTypeFamilyIndex(Gfx::QueueType::DEDICATED_TRANSFER);
|
||||
stagingBufferCreateInfo.queueFamilyIndexCount = 1;
|
||||
stagingBufferCreateInfo.pQueueFamilyIndices = &queueIndex;
|
||||
VkDevice vulkanDevice = graphics->getDevice();
|
||||
|
||||
VK_CHECK(vkCreateBuffer(vulkanDevice, &stagingBufferCreateInfo, nullptr, &buffer));
|
||||
VkBufferCreateInfo stagingBufferCreateInfo = {
|
||||
.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,
|
||||
.pNext = nullptr,
|
||||
.flags = 0,
|
||||
.size = size,
|
||||
.usage = VK_IMAGE_USAGE_TRANSFER_SRC_BIT,
|
||||
.sharingMode = VK_SHARING_MODE_EXCLUSIVE,
|
||||
.queueFamilyIndexCount = 1,
|
||||
.pQueueFamilyIndices = &queueIndex,
|
||||
};
|
||||
|
||||
VkBuffer buffer;
|
||||
VK_CHECK(vkCreateBuffer(graphics->getDevice(), &stagingBufferCreateInfo, nullptr, &buffer));
|
||||
|
||||
VkMemoryDedicatedRequirements dedicatedReqs = {
|
||||
.sType = VK_STRUCTURE_TYPE_MEMORY_DEDICATED_REQUIREMENTS,
|
||||
@@ -365,31 +354,15 @@ OStagingBuffer StagingManager::allocateStagingBuffer(uint64 size, VkBufferUsageF
|
||||
.pNext = nullptr,
|
||||
.buffer = buffer,
|
||||
};
|
||||
vkGetBufferMemoryRequirements2(vulkanDevice, &bufferQuery, &memReqs);
|
||||
|
||||
memReqs.memoryRequirements.alignment =
|
||||
(16 > memReqs.memoryRequirements.alignment) ? 16 : memReqs.memoryRequirements.alignment;
|
||||
vkGetBufferMemoryRequirements2(graphics->getDevice(), &bufferQuery, &memReqs);
|
||||
|
||||
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),
|
||||
graphics,
|
||||
allocator->allocate(memReqs, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_CACHED_BIT, buffer),
|
||||
buffer,
|
||||
size,
|
||||
usage,
|
||||
readable
|
||||
size
|
||||
);
|
||||
vkBindBufferMemory(graphics->getDevice(), buffer, stagingBuffer->getMemoryHandle(), stagingBuffer->getOffset());
|
||||
|
||||
activeBuffers.add(stagingBuffer);
|
||||
vkBindBufferMemory(graphics->getDevice(), buffer, stagingBuffer->getMemory(), stagingBuffer->getOffset());
|
||||
|
||||
return std::move(stagingBuffer);
|
||||
return stagingBuffer;
|
||||
}
|
||||
|
||||
void StagingManager::releaseStagingBuffer(OStagingBuffer buffer)
|
||||
{
|
||||
if (buffer == nullptr)
|
||||
{
|
||||
return;
|
||||
}
|
||||
activeBuffers.remove(buffer);
|
||||
freeBuffers.add(std::move(buffer));
|
||||
}
|
||||
@@ -3,6 +3,7 @@
|
||||
#include "Enums.h"
|
||||
#include "Containers/Map.h"
|
||||
#include "Containers/Array.h"
|
||||
#include "Graphics/Resources.h"
|
||||
#include <mutex>
|
||||
|
||||
namespace Seele
|
||||
@@ -31,9 +32,9 @@ public:
|
||||
|
||||
bool isReadable() const;
|
||||
|
||||
void *getMappedPointer();
|
||||
void *map();
|
||||
void flushMemory();
|
||||
void invalidateMemory();
|
||||
void invalidate();
|
||||
|
||||
private:
|
||||
PAllocation owner;
|
||||
@@ -58,7 +59,7 @@ public:
|
||||
return allocatedMemory;
|
||||
}
|
||||
|
||||
constexpr void* getMappedPointer()
|
||||
constexpr void* map()
|
||||
{
|
||||
if (!canMap)
|
||||
{
|
||||
@@ -72,13 +73,8 @@ public:
|
||||
return mappedPointer;
|
||||
}
|
||||
|
||||
constexpr bool isReadable() const
|
||||
{
|
||||
return readable;
|
||||
}
|
||||
|
||||
void flushMemory();
|
||||
void invalidateMemory();
|
||||
void invalidate();
|
||||
|
||||
private:
|
||||
VkDevice device;
|
||||
@@ -92,7 +88,6 @@ private:
|
||||
uint8 isDedicated : 1;
|
||||
uint8 canMap : 1;
|
||||
uint8 isMapped : 1;
|
||||
uint8 readable : 1;
|
||||
VkMemoryPropertyFlags properties;
|
||||
uint8 memoryTypeIndex;
|
||||
friend class Allocator;
|
||||
@@ -129,16 +124,13 @@ public:
|
||||
|
||||
void free(PAllocation allocation);
|
||||
private:
|
||||
enum
|
||||
{
|
||||
MemoryBlockSize = 16 * 1024 * 1024 // 16MB
|
||||
};
|
||||
static constexpr VkDeviceSize DEFAULT_ALLOCATION = 16 * 1024 * 1024; // 16MB
|
||||
struct HeapInfo
|
||||
{
|
||||
VkDeviceSize maxSize = 0;
|
||||
VkDeviceSize inUse = 0;
|
||||
Array<OAllocation> allocations;
|
||||
HeapInfo() {}
|
||||
HeapInfo() = default;
|
||||
HeapInfo(const HeapInfo& other) = delete;
|
||||
HeapInfo(HeapInfo&& other) = default;
|
||||
HeapInfo& operator=(const HeapInfo& other) = delete;
|
||||
@@ -150,38 +142,32 @@ private:
|
||||
VkPhysicalDeviceMemoryProperties memProperties;
|
||||
};
|
||||
DEFINE_REF(Allocator)
|
||||
DECLARE_REF(StagingManager)
|
||||
class StagingBuffer
|
||||
class StagingBuffer : public Gfx::QueueOwnedResource
|
||||
{
|
||||
public:
|
||||
StagingBuffer(OSubAllocation allocation, VkBuffer buffer, VkDeviceSize size, VkBufferUsageFlags usage, uint8 readable);
|
||||
StagingBuffer(PGraphics graphics, OSubAllocation allocation, VkBuffer buffer, VkDeviceSize size);
|
||||
~StagingBuffer();
|
||||
void* getMappedPointer();
|
||||
void flushMappedMemory();
|
||||
void invalidateMemory();
|
||||
void* map();
|
||||
void flush();
|
||||
void invalidate();
|
||||
constexpr VkBuffer getHandle() const
|
||||
{
|
||||
return buffer;
|
||||
}
|
||||
VkDeviceMemory getMemoryHandle() const;
|
||||
VkDeviceMemory getMemory() const;
|
||||
VkDeviceSize getOffset() const;
|
||||
uint64 getSize() const;
|
||||
constexpr bool isReadable() const
|
||||
constexpr uint64 getSize() const
|
||||
{
|
||||
return readable;
|
||||
return size;
|
||||
}
|
||||
|
||||
constexpr VkBufferUsageFlags getUsage() const
|
||||
{
|
||||
return usage;
|
||||
}
|
||||
|
||||
private:
|
||||
virtual void executeOwnershipBarrier(Gfx::QueueType newOwner) override;
|
||||
virtual void executePipelineBarrier(Gfx::SeAccessFlags srcAccess, Gfx::SePipelineStageFlags srcStage,
|
||||
Gfx::SeAccessFlags dstAccess, Gfx::SePipelineStageFlags dstStage) override;
|
||||
OSubAllocation allocation;
|
||||
PGraphics graphics;
|
||||
VkBuffer buffer;
|
||||
VkDeviceSize size;
|
||||
VkBufferUsageFlags usage;
|
||||
uint8 readable;
|
||||
};
|
||||
DEFINE_REF(StagingBuffer)
|
||||
|
||||
@@ -190,15 +176,11 @@ class StagingManager
|
||||
public:
|
||||
StagingManager(PGraphics graphics, PAllocator allocator);
|
||||
~StagingManager();
|
||||
OStagingBuffer allocateStagingBuffer(uint64 size, VkBufferUsageFlags usageFlags = VK_BUFFER_USAGE_TRANSFER_SRC_BIT, bool bCPURead = false);
|
||||
void releaseStagingBuffer(OStagingBuffer buffer);
|
||||
void clearPending();
|
||||
OStagingBuffer create(uint64 size);
|
||||
|
||||
private:
|
||||
PGraphics graphics;
|
||||
PAllocator allocator;
|
||||
Array<OStagingBuffer> freeBuffers;
|
||||
Array<PStagingBuffer> activeBuffers;
|
||||
};
|
||||
DEFINE_REF(StagingManager)
|
||||
} // namespace Vulkan
|
||||
|
||||
@@ -32,23 +32,28 @@ Buffer::Buffer(PGraphics graphics, uint64 size, VkBufferUsageFlags usage, Gfx::Q
|
||||
}
|
||||
usage |= VK_BUFFER_USAGE_TRANSFER_DST_BIT;
|
||||
usage |= VK_BUFFER_USAGE_TRANSFER_SRC_BIT;
|
||||
VkBufferCreateInfo info =
|
||||
init::BufferCreateInfo(
|
||||
usage,
|
||||
size);
|
||||
info.sharingMode = VK_SHARING_MODE_EXCLUSIVE;
|
||||
uint32 queueFamilyIndex = graphics->getFamilyMapping().getQueueTypeFamilyIndex(queueType);
|
||||
info.pQueueFamilyIndices = &queueFamilyIndex;
|
||||
info.queueFamilyIndexCount = 1;
|
||||
VkBufferMemoryRequirementsInfo2 bufferReqInfo;
|
||||
bufferReqInfo.sType = VK_STRUCTURE_TYPE_BUFFER_MEMORY_REQUIREMENTS_INFO_2;
|
||||
bufferReqInfo.pNext = nullptr;
|
||||
VkMemoryDedicatedRequirements dedicatedRequirements;
|
||||
dedicatedRequirements.sType = VK_STRUCTURE_TYPE_MEMORY_DEDICATED_REQUIREMENTS;
|
||||
dedicatedRequirements.pNext = nullptr;
|
||||
VkMemoryRequirements2 memRequirements;
|
||||
memRequirements.sType = VK_STRUCTURE_TYPE_MEMORY_REQUIREMENTS_2;
|
||||
memRequirements.pNext = &dedicatedRequirements;
|
||||
VkBufferCreateInfo info = {
|
||||
.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,
|
||||
.pNext = nullptr,
|
||||
.size = size,
|
||||
.usage = usage,
|
||||
.sharingMode = VK_SHARING_MODE_EXCLUSIVE,
|
||||
.queueFamilyIndexCount = 1,
|
||||
.pQueueFamilyIndices = &queueFamilyIndex,
|
||||
};
|
||||
VkBufferMemoryRequirementsInfo2 bufferReqInfo = {
|
||||
.sType = VK_STRUCTURE_TYPE_BUFFER_MEMORY_REQUIREMENTS_INFO_2,
|
||||
.pNext = nullptr,
|
||||
};
|
||||
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)
|
||||
{
|
||||
VK_CHECK(vkCreateBuffer(graphics->getDevice(), &info, nullptr, &buffers[i].buffer));
|
||||
@@ -158,12 +163,12 @@ void Buffer::executePipelineBarrier(VkAccessFlags srcAccess, VkPipelineStageFlag
|
||||
vkCmdPipelineBarrier(commandBuffer->getHandle(), srcStage, dstStage, 0, 0, nullptr, numBuffers, dynamicBarriers, 0, nullptr);
|
||||
}
|
||||
|
||||
void * Buffer::lock(bool writeOnly)
|
||||
void * Buffer::map(bool writeOnly)
|
||||
{
|
||||
return lockRegion(0, size, writeOnly);
|
||||
return mapRegion(0, size, writeOnly);
|
||||
}
|
||||
|
||||
void * Buffer::lockRegion(uint64 regionOffset, uint64 regionSize, bool writeOnly)
|
||||
void * Buffer::mapRegion(uint64 regionOffset, uint64 regionSize, bool writeOnly)
|
||||
{
|
||||
void *data = nullptr;
|
||||
|
||||
@@ -189,8 +194,8 @@ void * Buffer::lockRegion(uint64 regionOffset, uint64 regionSize, bool writeOnly
|
||||
if (writeOnly)
|
||||
{
|
||||
//requestOwnershipTransfer(Gfx::QueueType::DEDICATED_TRANSFER);
|
||||
OStagingBuffer stagingBuffer = graphics->getStagingManager()->allocateStagingBuffer(regionSize, VK_BUFFER_USAGE_TRANSFER_SRC_BIT);
|
||||
data = stagingBuffer->getMappedPointer();
|
||||
OStagingBuffer stagingBuffer = graphics->getStagingManager()->create(regionSize, VK_BUFFER_USAGE_TRANSFER_SRC_BIT);
|
||||
data = stagingBuffer->map();
|
||||
pending.stagingBuffer = std::move(stagingBuffer);
|
||||
}
|
||||
else
|
||||
@@ -212,7 +217,7 @@ void * Buffer::lockRegion(uint64 regionOffset, uint64 regionSize, bool writeOnly
|
||||
barrier.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()->allocateStagingBuffer(size, VK_BUFFER_USAGE_TRANSFER_DST_BIT, true);
|
||||
OStagingBuffer stagingBuffer = graphics->getStagingManager()->create(size, VK_BUFFER_USAGE_TRANSFER_DST_BIT, true);
|
||||
|
||||
VkBufferCopy regions;
|
||||
regions.size = size;
|
||||
@@ -223,9 +228,9 @@ void * Buffer::lockRegion(uint64 regionOffset, uint64 regionSize, bool writeOnly
|
||||
|
||||
graphics->getQueueCommands(owner)->submitCommands();
|
||||
vkQueueWaitIdle(graphics->getQueueCommands(owner)->getQueue()->getHandle());
|
||||
stagingBuffer->getMappedPointer(); // this maps the memory if not mapped already
|
||||
stagingBuffer->flushMappedMemory();
|
||||
data = stagingBuffer->getMappedPointer();
|
||||
stagingBuffer->map(); // this maps the memory if not mapped already
|
||||
stagingBuffer->flush();
|
||||
data = stagingBuffer->map();
|
||||
|
||||
pending.stagingBuffer = std::move(stagingBuffer);
|
||||
|
||||
@@ -236,13 +241,13 @@ void * Buffer::lockRegion(uint64 regionOffset, uint64 regionSize, bool writeOnly
|
||||
return data;
|
||||
}
|
||||
|
||||
void Buffer::unlock()
|
||||
void Buffer::unmap()
|
||||
{
|
||||
auto found = pendingBuffers.find(this);
|
||||
if (found != pendingBuffers.end())
|
||||
{
|
||||
PendingBuffer& pending = found->second;
|
||||
pending.stagingBuffer->flushMappedMemory();
|
||||
pending.stagingBuffer->flush();
|
||||
if (pending.writeOnly)
|
||||
{
|
||||
PStagingBuffer stagingBuffer = pending.stagingBuffer;
|
||||
@@ -257,7 +262,7 @@ void Buffer::unlock()
|
||||
graphics->getQueueCommands(owner)->submitCommands();
|
||||
}
|
||||
//requestOwnershipTransfer(pending.prevQueue);
|
||||
graphics->getStagingManager()->releaseStagingBuffer(std::move(pending.stagingBuffer));
|
||||
graphics->getStagingManager()->release(std::move(pending.stagingBuffer));
|
||||
pendingBuffers.erase(this);
|
||||
}
|
||||
}
|
||||
@@ -269,19 +274,19 @@ UniformBuffer::UniformBuffer(PGraphics graphics, const UniformBufferCreateInfo &
|
||||
{
|
||||
if(createInfo.dynamic)
|
||||
{
|
||||
dedicatedStagingBuffer = graphics->getStagingManager()->allocateStagingBuffer(createInfo.sourceData.size, VK_BUFFER_USAGE_TRANSFER_SRC_BIT);
|
||||
dedicatedStagingBuffer = graphics->getStagingManager()->create(createInfo.sourceData.size, VK_BUFFER_USAGE_TRANSFER_SRC_BIT);
|
||||
}
|
||||
if (createInfo.sourceData.data != nullptr)
|
||||
{
|
||||
void *data = lock();
|
||||
void *data = map();
|
||||
std::memcpy(data, createInfo.sourceData.data, createInfo.sourceData.size);
|
||||
unlock();
|
||||
unmap();
|
||||
}
|
||||
}
|
||||
|
||||
UniformBuffer::~UniformBuffer()
|
||||
{
|
||||
graphics->getStagingManager()->releaseStagingBuffer(std::move(dedicatedStagingBuffer));
|
||||
graphics->getStagingManager()->release(std::move(dedicatedStagingBuffer));
|
||||
}
|
||||
|
||||
bool UniformBuffer::updateContents(const DataSource &sourceData)
|
||||
@@ -291,25 +296,25 @@ bool UniformBuffer::updateContents(const DataSource &sourceData)
|
||||
// no update was performed, skip
|
||||
return false;
|
||||
}
|
||||
void* data = lock();
|
||||
void* data = map();
|
||||
std::memcpy(data, sourceData.data, sourceData.size);
|
||||
unlock();
|
||||
unmap();
|
||||
return true;
|
||||
}
|
||||
void* UniformBuffer::lock(bool writeOnly)
|
||||
void* UniformBuffer::map(bool writeOnly)
|
||||
{
|
||||
if(dedicatedStagingBuffer != nullptr)
|
||||
{
|
||||
return dedicatedStagingBuffer->getMappedPointer();
|
||||
return dedicatedStagingBuffer->map();
|
||||
}
|
||||
return Vulkan::Buffer::lock(writeOnly);
|
||||
return Vulkan::Buffer::map(writeOnly);
|
||||
}
|
||||
|
||||
void UniformBuffer::unlock()
|
||||
void UniformBuffer::unmap()
|
||||
{
|
||||
if(dedicatedStagingBuffer != nullptr)
|
||||
{
|
||||
dedicatedStagingBuffer->flushMappedMemory();
|
||||
dedicatedStagingBuffer->flush();
|
||||
PCmdBuffer cmdBuffer = graphics->getQueueCommands(currentOwner)->getCommands();
|
||||
VkCommandBuffer cmdHandle = cmdBuffer->getHandle();
|
||||
|
||||
@@ -321,7 +326,7 @@ void UniformBuffer::unlock()
|
||||
}
|
||||
else
|
||||
{
|
||||
Vulkan::Buffer::unlock();
|
||||
Vulkan::Buffer::unmap();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -358,19 +363,19 @@ ShaderBuffer::ShaderBuffer(PGraphics graphics, const ShaderBufferCreateInfo &sou
|
||||
{
|
||||
if(sourceData.dynamic)
|
||||
{
|
||||
dedicatedStagingBuffer = graphics->getStagingManager()->allocateStagingBuffer(sourceData.sourceData.size, VK_BUFFER_USAGE_TRANSFER_SRC_BIT);
|
||||
dedicatedStagingBuffer = graphics->getStagingManager()->create(sourceData.sourceData.size, VK_BUFFER_USAGE_TRANSFER_SRC_BIT);
|
||||
}
|
||||
if (sourceData.sourceData.data != nullptr)
|
||||
{
|
||||
void *data = lock();
|
||||
void *data = map();
|
||||
std::memcpy(data, sourceData.sourceData.data, sourceData.sourceData.size);
|
||||
unlock();
|
||||
unmap();
|
||||
}
|
||||
}
|
||||
|
||||
ShaderBuffer::~ShaderBuffer()
|
||||
{
|
||||
graphics->getStagingManager()->releaseStagingBuffer(std::move(dedicatedStagingBuffer));
|
||||
graphics->getStagingManager()->release(std::move(dedicatedStagingBuffer));
|
||||
}
|
||||
|
||||
bool ShaderBuffer::updateContents(const DataSource &sourceData)
|
||||
@@ -378,25 +383,25 @@ bool ShaderBuffer::updateContents(const DataSource &sourceData)
|
||||
assert(sourceData.size <= getSize());
|
||||
Gfx::ShaderBuffer::updateContents(sourceData);
|
||||
//We always want to update, as the contents could be different on the GPU
|
||||
void* data = lock();
|
||||
void* data = map();
|
||||
std::memcpy(data, sourceData.data, sourceData.size);
|
||||
unlock();
|
||||
unmap();
|
||||
return true;
|
||||
}
|
||||
void* ShaderBuffer::lock(bool writeOnly)
|
||||
void* ShaderBuffer::map(bool writeOnly)
|
||||
{
|
||||
if(dedicatedStagingBuffer != nullptr)
|
||||
{
|
||||
return dedicatedStagingBuffer->getMappedPointer();
|
||||
return dedicatedStagingBuffer->map();
|
||||
}
|
||||
return Vulkan::Buffer::lock(writeOnly);
|
||||
return Vulkan::Buffer::map(writeOnly);
|
||||
}
|
||||
|
||||
void ShaderBuffer::unlock()
|
||||
void ShaderBuffer::unmap()
|
||||
{
|
||||
if(dedicatedStagingBuffer != nullptr)
|
||||
{
|
||||
dedicatedStagingBuffer->flushMappedMemory();
|
||||
dedicatedStagingBuffer->flush();
|
||||
PCmdBuffer cmdBuffer = graphics->getQueueCommands(currentOwner)->getCommands();
|
||||
VkCommandBuffer cmdHandle = cmdBuffer->getHandle();
|
||||
|
||||
@@ -408,7 +413,7 @@ void ShaderBuffer::unlock()
|
||||
}
|
||||
else
|
||||
{
|
||||
Vulkan::Buffer::unlock();
|
||||
Vulkan::Buffer::unmap();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -444,9 +449,9 @@ VertexBuffer::VertexBuffer(PGraphics graphics, const VertexBufferCreateInfo &sou
|
||||
{
|
||||
if (sourceData.sourceData.data != nullptr)
|
||||
{
|
||||
void *data = lock();
|
||||
void *data = map();
|
||||
std::memcpy(data, sourceData.sourceData.data, sourceData.sourceData.size);
|
||||
unlock();
|
||||
unmap();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -456,17 +461,17 @@ VertexBuffer::~VertexBuffer()
|
||||
|
||||
void VertexBuffer::updateRegion(DataSource update)
|
||||
{
|
||||
void* data = lockRegion(update.offset, update.size);
|
||||
void* data = mapRegion(update.offset, update.size);
|
||||
std::memcpy(data, update.data, update.size);
|
||||
unlock();
|
||||
unmap();
|
||||
}
|
||||
|
||||
void VertexBuffer::download(Array<uint8>& buffer)
|
||||
{
|
||||
void* data = lock(false);
|
||||
void* data = map(false);
|
||||
buffer.resize(size);
|
||||
std::memcpy(buffer.data(), data, size);
|
||||
unlock();
|
||||
unmap();
|
||||
}
|
||||
|
||||
void VertexBuffer::requestOwnershipTransfer(Gfx::QueueType newOwner)
|
||||
@@ -501,9 +506,9 @@ IndexBuffer::IndexBuffer(PGraphics graphics, const IndexBufferCreateInfo &source
|
||||
{
|
||||
if (sourceData.sourceData.data != nullptr)
|
||||
{
|
||||
void *data = lock();
|
||||
void *data = map();
|
||||
std::memcpy(data, sourceData.sourceData.data, sourceData.sourceData.size);
|
||||
unlock();
|
||||
unmap();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -513,10 +518,10 @@ IndexBuffer::~IndexBuffer()
|
||||
|
||||
void IndexBuffer::download(Array<uint8>& buffer)
|
||||
{
|
||||
void* data = lock(false);
|
||||
void* data = map(false);
|
||||
buffer.resize(size);
|
||||
std::memcpy(buffer.data(), data, size);
|
||||
unlock();
|
||||
unmap();
|
||||
}
|
||||
|
||||
void IndexBuffer::requestOwnershipTransfer(Gfx::QueueType newOwner)
|
||||
|
||||
@@ -25,9 +25,9 @@ public:
|
||||
{
|
||||
currentBuffer = (currentBuffer + 1) % numBuffers;
|
||||
}
|
||||
virtual void *lock(bool writeOnly = true);
|
||||
virtual void *lockRegion(uint64 regionOffset, uint64 regionSize, bool writeOnly = true);
|
||||
virtual void unlock();
|
||||
virtual void *map(bool writeOnly = true);
|
||||
virtual void *mapRegion(uint64 regionOffset, uint64 regionSize, bool writeOnly = true);
|
||||
virtual void unmap();
|
||||
|
||||
protected:
|
||||
struct BufferAllocation
|
||||
@@ -61,8 +61,8 @@ public:
|
||||
virtual ~UniformBuffer();
|
||||
virtual bool updateContents(const DataSource &sourceData);
|
||||
|
||||
virtual void* lock(bool writeOnly = true) override;
|
||||
virtual void unlock() override;
|
||||
virtual void* map(bool writeOnly = true) override;
|
||||
virtual void unmap() override;
|
||||
protected:
|
||||
// Inherited via Vulkan::Buffer
|
||||
virtual VkAccessFlags getSourceAccessMask();
|
||||
@@ -85,8 +85,8 @@ public:
|
||||
virtual ~ShaderBuffer();
|
||||
virtual bool updateContents(const DataSource &sourceData);
|
||||
|
||||
virtual void* lock(bool writeOnly = true) override;
|
||||
virtual void unlock() override;
|
||||
virtual void* map(bool writeOnly = true) override;
|
||||
virtual void unmap() override;
|
||||
protected:
|
||||
// Inherited via Vulkan::Buffer
|
||||
virtual VkAccessFlags getSourceAccessMask();
|
||||
|
||||
@@ -4,10 +4,10 @@ target_sources(Engine
|
||||
Allocator.cpp
|
||||
Buffer.h
|
||||
Buffer.cpp
|
||||
CommandBuffer.h
|
||||
CommandBuffer.cpp
|
||||
DescriptorSets.h
|
||||
DescriptorSets.cpp
|
||||
Command.h
|
||||
Command.cpp
|
||||
Descriptor.h
|
||||
Descriptor.cpp
|
||||
Enums.h
|
||||
Enums.cpp
|
||||
Framebuffer.h
|
||||
@@ -38,7 +38,7 @@ target_sources(Engine
|
||||
FILES
|
||||
Allocator.h
|
||||
Buffer.h
|
||||
CommandBuffer.h
|
||||
Command.h
|
||||
DescriptorSets.h
|
||||
Enums.h
|
||||
Framebuffer.h
|
||||
|
||||
+102
-110
@@ -14,87 +14,87 @@ using namespace Seele;
|
||||
using namespace Seele::Vulkan;
|
||||
|
||||
|
||||
CmdBuffer::CmdBuffer(PGraphics graphics, VkCommandPool cmdPool, PCommandBufferManager manager)
|
||||
Command::Command(PGraphics graphics, VkCommandPool cmdPool, PCommandBufferManager manager)
|
||||
: graphics(graphics)
|
||||
, manager(manager)
|
||||
, owner(cmdPool)
|
||||
{
|
||||
VkCommandBufferAllocateInfo allocInfo =
|
||||
init::CommandBufferAllocateInfo(cmdPool,
|
||||
VK_COMMAND_BUFFER_LEVEL_PRIMARY,
|
||||
1);
|
||||
std::scoped_lock lock(handleLock);
|
||||
VkCommandBufferAllocateInfo allocInfo = {
|
||||
.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO,
|
||||
.pNext = nullptr,
|
||||
.commandPool = owner,
|
||||
.level = VK_COMMAND_BUFFER_LEVEL_PRIMARY,
|
||||
.commandBufferCount = 1,
|
||||
};
|
||||
VK_CHECK(vkAllocateCommandBuffers(graphics->getDevice(), &allocInfo, &handle))
|
||||
|
||||
fence = new Fence(graphics);
|
||||
state = State::ReadyBegin;
|
||||
state = State::Init;
|
||||
}
|
||||
|
||||
CmdBuffer::~CmdBuffer()
|
||||
Command::~Command()
|
||||
{
|
||||
std::scoped_lock lock(handleLock);
|
||||
vkFreeCommandBuffers(graphics->getDevice(), owner, 1, &handle);
|
||||
waitSemaphores.clear();
|
||||
}
|
||||
|
||||
void CmdBuffer::begin()
|
||||
void Command::begin()
|
||||
{
|
||||
VkCommandBufferBeginInfo beginInfo =
|
||||
init::CommandBufferBeginInfo();
|
||||
beginInfo.pInheritanceInfo = nullptr;
|
||||
std::scoped_lock lock(handleLock);
|
||||
VkCommandBufferBeginInfo beginInfo = {
|
||||
.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO,
|
||||
.pNext = nullptr,
|
||||
.flags = 0,
|
||||
.pInheritanceInfo = nullptr,
|
||||
};
|
||||
VK_CHECK(vkBeginCommandBuffer(handle, &beginInfo));
|
||||
state = State::InsideBegin;
|
||||
state = State::Begin;
|
||||
}
|
||||
|
||||
void CmdBuffer::end()
|
||||
void Command::end()
|
||||
{
|
||||
std::scoped_lock lock(handleLock);
|
||||
VK_CHECK(vkEndCommandBuffer(handle));
|
||||
state = State::Ended;
|
||||
state = State::End;
|
||||
}
|
||||
|
||||
void CmdBuffer::beginRenderPass(PRenderPass renderPass, PFramebuffer framebuffer)
|
||||
void Command::beginRenderPass(PRenderPass renderPass, PFramebuffer framebuffer)
|
||||
{
|
||||
assert(state == State::InsideBegin);
|
||||
std::scoped_lock lock(handleLock);
|
||||
assert(state == State::Begin);
|
||||
|
||||
VkRenderPassBeginInfo beginInfo =
|
||||
init::RenderPassBeginInfo();
|
||||
beginInfo.clearValueCount = (uint32)renderPass->getClearValueCount();
|
||||
beginInfo.pClearValues = renderPass->getClearValues();
|
||||
beginInfo.renderArea = renderPass->getRenderArea();
|
||||
beginInfo.renderPass = renderPass->getHandle();
|
||||
beginInfo.framebuffer = framebuffer->getHandle();
|
||||
VkRenderPassBeginInfo beginInfo = {
|
||||
.sType = VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO,
|
||||
.pNext = nullptr,
|
||||
.renderPass = renderPass->getHandle(),
|
||||
.framebuffer = framebuffer->getHandle(),
|
||||
.renderArea = renderPass->getRenderArea(),
|
||||
.clearValueCount = (uint32)renderPass->getClearValueCount(),
|
||||
.pClearValues = renderPass->getClearValues(),
|
||||
};
|
||||
vkCmdBeginRenderPass(handle, &beginInfo, renderPass->getSubpassContents());
|
||||
state = State::RenderPassActive;
|
||||
state = State::RenderPass;
|
||||
}
|
||||
|
||||
void CmdBuffer::endRenderPass()
|
||||
void Command::endRenderPass()
|
||||
{
|
||||
std::scoped_lock lock(handleLock);
|
||||
vkCmdEndRenderPass(handle);
|
||||
state = State::InsideBegin;
|
||||
state = State::Begin;
|
||||
}
|
||||
|
||||
void CmdBuffer::executeCommands(const Array<Gfx::PRenderCommand>& commands)
|
||||
void Command::executeCommands(const Array<Gfx::PRenderCommand>& commands)
|
||||
{
|
||||
assert(state == State::RenderPassActive);
|
||||
assert(state == State::RenderPass);
|
||||
if(commands.size() == 0)
|
||||
{
|
||||
//std::cout << "No commands provided" << std::endl;
|
||||
return;
|
||||
}
|
||||
std::scoped_lock lock(handleLock);
|
||||
Array<VkCommandBuffer> cmdBuffers(commands.size());
|
||||
for (uint32 i = 0; i < commands.size(); ++i)
|
||||
{
|
||||
auto command = commands[i].cast<RenderCommand>();
|
||||
command->end();
|
||||
executingRenders.add(command);
|
||||
for(auto descriptor : command->boundDescriptors)
|
||||
for(auto& descriptor : command->boundDescriptors)
|
||||
{
|
||||
descriptor->free();
|
||||
boundDescriptors.add(descriptor);
|
||||
}
|
||||
cmdBuffers[i] = command->getHandle();
|
||||
@@ -102,9 +102,8 @@ void CmdBuffer::executeCommands(const Array<Gfx::PRenderCommand>& commands)
|
||||
vkCmdExecuteCommands(handle, (uint32)cmdBuffers.size(), cmdBuffers.data());
|
||||
}
|
||||
|
||||
void CmdBuffer::executeCommands(const Array<Gfx::PComputeCommand>& commands)
|
||||
void Command::executeCommands(const Array<Gfx::PComputeCommand>& commands)
|
||||
{
|
||||
std::scoped_lock lock(handleLock);
|
||||
if(commands.size() == 0)
|
||||
{
|
||||
return;
|
||||
@@ -115,9 +114,8 @@ void CmdBuffer::executeCommands(const Array<Gfx::PComputeCommand>& commands)
|
||||
auto command = commands[i].cast<ComputeCommand>();
|
||||
command->end();
|
||||
executingComputes.add(command);
|
||||
for(auto descriptor : command->boundDescriptors)
|
||||
for(auto& descriptor : command->boundDescriptors)
|
||||
{
|
||||
descriptor->free();
|
||||
boundDescriptors.add(descriptor);
|
||||
}
|
||||
cmdBuffers[i] = command->getHandle();
|
||||
@@ -125,65 +123,58 @@ void CmdBuffer::executeCommands(const Array<Gfx::PComputeCommand>& commands)
|
||||
vkCmdExecuteCommands(handle, (uint32)cmdBuffers.size(), cmdBuffers.data());
|
||||
}
|
||||
|
||||
void CmdBuffer::addWaitSemaphore(VkPipelineStageFlags flags, PSemaphore semaphore)
|
||||
void Command::waitForSemaphore(VkPipelineStageFlags flags, PSemaphore semaphore)
|
||||
{
|
||||
std::scoped_lock lock(handleLock);
|
||||
waitSemaphores.add(semaphore);
|
||||
waitFlags.add(flags);
|
||||
}
|
||||
|
||||
void CmdBuffer::refreshFence()
|
||||
void Command::checkFence()
|
||||
{
|
||||
std::scoped_lock lock(handleLock);
|
||||
if (state == State::Submitted)
|
||||
assert(state == State::Submit || !fence->isSignaled());
|
||||
if (fence->isSignaled())
|
||||
{
|
||||
if (fence->isSignaled())
|
||||
vkResetCommandBuffer(handle, VK_COMMAND_BUFFER_RESET_RELEASE_RESOURCES_BIT);
|
||||
fence->reset();
|
||||
for(auto& command : executingComputes)
|
||||
{
|
||||
vkResetCommandBuffer(handle, VK_COMMAND_BUFFER_RESET_RELEASE_RESOURCES_BIT);
|
||||
fence->reset();
|
||||
for(auto command : executingComputes)
|
||||
{
|
||||
command->reset();
|
||||
}
|
||||
executingComputes.clear();
|
||||
for(auto command : executingRenders)
|
||||
{
|
||||
command->reset();
|
||||
}
|
||||
executingRenders.clear();
|
||||
for(auto descriptor : boundDescriptors)
|
||||
{
|
||||
descriptor->unbind();
|
||||
}
|
||||
boundDescriptors.clear();
|
||||
graphics->getDestructionManager()->notifyCmdComplete(this);
|
||||
state = State::ReadyBegin;
|
||||
command->reset();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
assert(!fence->isSignaled());
|
||||
executingComputes.clear();
|
||||
for(auto& command : executingRenders)
|
||||
{
|
||||
command->reset();
|
||||
}
|
||||
executingRenders.clear();
|
||||
for(auto& descriptor : boundDescriptors)
|
||||
{
|
||||
descriptor->unbind();
|
||||
}
|
||||
boundDescriptors.clear();
|
||||
graphics->getDestructionManager()->notifyCmdComplete(this);
|
||||
state = State::Init;
|
||||
}
|
||||
}
|
||||
|
||||
void CmdBuffer::waitForCommand(uint32 timeout)
|
||||
|
||||
void Command::waitForCommand(uint32 timeout)
|
||||
{
|
||||
manager->submitCommands();
|
||||
if (state == State::InsideBegin)
|
||||
if (state == State::Begin)
|
||||
{
|
||||
// is already done
|
||||
return;
|
||||
}
|
||||
fence->wait(timeout);
|
||||
refreshFence();
|
||||
checkFence();
|
||||
}
|
||||
|
||||
PFence CmdBuffer::getFence()
|
||||
PFence Command::getFence()
|
||||
{
|
||||
return fence;
|
||||
}
|
||||
|
||||
PCommandBufferManager CmdBuffer::getManager()
|
||||
PCommandBufferManager Command::getManager()
|
||||
{
|
||||
return manager;
|
||||
}
|
||||
@@ -192,10 +183,13 @@ RenderCommand::RenderCommand(PGraphics graphics, VkCommandPool cmdPool)
|
||||
: graphics(graphics)
|
||||
, owner(cmdPool)
|
||||
{
|
||||
VkCommandBufferAllocateInfo allocInfo =
|
||||
init::CommandBufferAllocateInfo(cmdPool,
|
||||
VK_COMMAND_BUFFER_LEVEL_SECONDARY,
|
||||
1);
|
||||
VkCommandBufferAllocateInfo allocInfo = {
|
||||
.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO,
|
||||
.pNext = nullptr,
|
||||
.commandPool = owner,
|
||||
.level = VK_COMMAND_BUFFER_LEVEL_SECONDARY,
|
||||
.commandBufferCount = 1,
|
||||
};
|
||||
VK_CHECK(vkAllocateCommandBuffers(graphics->getDevice(), &allocInfo, &handle));
|
||||
}
|
||||
|
||||
@@ -242,7 +236,7 @@ void RenderCommand::setViewport(Gfx::PViewport viewport)
|
||||
{
|
||||
assert(threadId == std::this_thread::get_id());
|
||||
VkViewport vp = viewport.cast<Viewport>()->getHandle();
|
||||
VkRect2D scissors = init::Rect2D(viewport->getSizeX(), viewport->getSizeY(), viewport->getOffsetX(), viewport->getOffsetY());
|
||||
VkRect2D scissors = init::Rect2D(viewport->getWidth(), viewport->getHeight(), viewport->getOffsetX(), viewport->getOffsetY());
|
||||
vkCmdSetViewport(handle, 0, 1, &vp);
|
||||
vkCmdSetScissor(handle, 0, 1, &scissors);
|
||||
}
|
||||
@@ -422,7 +416,7 @@ void ComputeCommand::dispatch(uint32 threadX, uint32 threadY, uint32 threadZ)
|
||||
vkCmdDispatch(handle, threadX, threadY, threadZ);
|
||||
}
|
||||
|
||||
CommandBufferManager::CommandBufferManager(PGraphics graphics, PQueue queue)
|
||||
CommandPool::CommandPool(PGraphics graphics, PQueue queue)
|
||||
: graphics(graphics), queue(queue), queueFamilyIndex(queue->getFamilyIndex())
|
||||
{
|
||||
VkCommandPoolCreateInfo info =
|
||||
@@ -432,28 +426,26 @@ CommandBufferManager::CommandBufferManager(PGraphics graphics, PQueue queue)
|
||||
|
||||
VK_CHECK(vkCreateCommandPool(graphics->getDevice(), &info, nullptr, &commandPool));
|
||||
|
||||
{
|
||||
std::scoped_lock lock(allocatedBufferLock);
|
||||
allocatedBuffers.add(new CmdBuffer(graphics, commandPool, this));
|
||||
}
|
||||
allocatedBuffers.add(new Command(graphics, commandPool, this));
|
||||
|
||||
|
||||
activeCmdBuffer = allocatedBuffers.back();
|
||||
activeCmdBuffer->begin();
|
||||
command = allocatedBuffers.back();
|
||||
command->begin();
|
||||
}
|
||||
|
||||
CommandBufferManager::~CommandBufferManager()
|
||||
CommandPool::~CommandPool()
|
||||
{
|
||||
vkDestroyCommandPool(graphics->getDevice(), commandPool, nullptr);
|
||||
graphics = nullptr;
|
||||
queue = nullptr;
|
||||
}
|
||||
|
||||
PCmdBuffer CommandBufferManager::getCommands()
|
||||
PCmdBuffer CommandPool::getCommands()
|
||||
{
|
||||
return activeCmdBuffer;
|
||||
return command;
|
||||
}
|
||||
|
||||
PRenderCommand CommandBufferManager::createRenderCommand(PRenderPass renderPass, PFramebuffer framebuffer, const std::string& name)
|
||||
PRenderCommand CommandPool::createRenderCommand(PRenderPass renderPass, PFramebuffer framebuffer, const std::string& name)
|
||||
{
|
||||
std::scoped_lock lck(allocatedRenderLock);
|
||||
for (uint32 i = 0; i < allocatedRenderCommands.size(); ++i)
|
||||
@@ -473,7 +465,7 @@ PRenderCommand CommandBufferManager::createRenderCommand(PRenderPass renderPass,
|
||||
return result;
|
||||
}
|
||||
|
||||
PComputeCommand CommandBufferManager::createComputeCommand(const std::string& name)
|
||||
PComputeCommand CommandPool::createComputeCommand(const std::string& name)
|
||||
{
|
||||
std::scoped_lock lck(allocatedComputeLock);
|
||||
for (uint32 i = 0; i < allocatedComputeCommands.size(); ++i)
|
||||
@@ -482,53 +474,53 @@ PComputeCommand CommandBufferManager::createComputeCommand(const std::string& na
|
||||
if (cmdBuffer->isReady())
|
||||
{
|
||||
cmdBuffer->name = name;
|
||||
cmdBuffer->begin(activeCmdBuffer);
|
||||
cmdBuffer->begin(command);
|
||||
return cmdBuffer;
|
||||
}
|
||||
}
|
||||
allocatedComputeCommands.add(new ComputeCommand(graphics, commandPool));
|
||||
PComputeCommand result = allocatedComputeCommands.back();
|
||||
result->name = name;
|
||||
result->begin(activeCmdBuffer);
|
||||
result->begin(command);
|
||||
return result;
|
||||
}
|
||||
|
||||
void CommandBufferManager::submitCommands(PSemaphore signalSemaphore)
|
||||
void CommandPool::submitCommands(PSemaphore signalSemaphore)
|
||||
{
|
||||
if (activeCmdBuffer->state == CmdBuffer::State::InsideBegin || activeCmdBuffer->state == CmdBuffer::State::RenderPassActive)
|
||||
if (command->state == Command::State::Begin || command->state == Command::State::RenderPass)
|
||||
{
|
||||
if (activeCmdBuffer->state == CmdBuffer::State::RenderPassActive)
|
||||
if (command->state == Command::State::RenderPass)
|
||||
{
|
||||
std::cout << "End of renderpass forced" << std::endl;
|
||||
activeCmdBuffer->endRenderPass();
|
||||
command->endRenderPass();
|
||||
}
|
||||
activeCmdBuffer->end();
|
||||
command->end();
|
||||
if (signalSemaphore != nullptr)
|
||||
{
|
||||
queue->submitCommandBuffer(activeCmdBuffer, signalSemaphore->getHandle());
|
||||
queue->submitCommandBuffer(command, signalSemaphore->getHandle());
|
||||
}
|
||||
else
|
||||
{
|
||||
queue->submitCommandBuffer(activeCmdBuffer);
|
||||
queue->submitCommandBuffer(command);
|
||||
}
|
||||
}
|
||||
std::scoped_lock lock(allocatedBufferLock);
|
||||
std::scoped_lock map(allocatedBufferLock);
|
||||
for (uint32 i = 0; i < allocatedBuffers.size(); ++i)
|
||||
{
|
||||
PCmdBuffer cmdBuffer = allocatedBuffers[i];
|
||||
cmdBuffer->refreshFence();
|
||||
if (cmdBuffer->state == CmdBuffer::State::ReadyBegin)
|
||||
cmdBuffer->checkFence();
|
||||
if (cmdBuffer->state == Command::State::Init)
|
||||
{
|
||||
activeCmdBuffer = cmdBuffer;
|
||||
activeCmdBuffer->begin();
|
||||
command = cmdBuffer;
|
||||
command->begin();
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
assert(cmdBuffer->state == CmdBuffer::State::Submitted);
|
||||
assert(cmdBuffer->state == Command::State::Submit);
|
||||
}
|
||||
}
|
||||
allocatedBuffers.add(new CmdBuffer(graphics, commandPool, this));
|
||||
activeCmdBuffer = allocatedBuffers.back();
|
||||
activeCmdBuffer->begin();
|
||||
allocatedBuffers.add(new Command(graphics, commandPool, this));
|
||||
command = allocatedBuffers.back();
|
||||
command->begin();
|
||||
}
|
||||
@@ -13,13 +13,13 @@ DECLARE_REF(Framebuffer)
|
||||
DECLARE_REF(RenderCommand)
|
||||
DECLARE_REF(ComputeCommand)
|
||||
DECLARE_REF(DescriptorSet)
|
||||
DECLARE_REF(CommandBufferManager)
|
||||
class CmdBuffer
|
||||
DECLARE_REF(CommandPool)
|
||||
class Command
|
||||
{
|
||||
public:
|
||||
CmdBuffer(PGraphics graphics, VkCommandPool cmdPool, PCommandBufferManager manager);
|
||||
virtual ~CmdBuffer();
|
||||
inline VkCommandBuffer getHandle()
|
||||
Command(PGraphics graphics, VkCommandPool cmdPool, PCommandBufferManager manager);
|
||||
virtual ~Command();
|
||||
constexpr VkCommandBuffer getHandle()
|
||||
{
|
||||
return handle;
|
||||
}
|
||||
@@ -30,18 +30,18 @@ public:
|
||||
void endRenderPass();
|
||||
void executeCommands(const Array<Gfx::PRenderCommand>& secondaryCommands);
|
||||
void executeCommands(const Array<Gfx::PComputeCommand>& secondaryCommands);
|
||||
void addWaitSemaphore(VkPipelineStageFlags stages, PSemaphore waitSemaphore);
|
||||
void refreshFence();
|
||||
void waitForSemaphore(VkPipelineStageFlags stages, PSemaphore waitSemaphore);
|
||||
void checkFence();
|
||||
void waitForCommand(uint32 timeToWait = 1000000u);
|
||||
PFence getFence();
|
||||
PCommandBufferManager getManager();
|
||||
enum State
|
||||
{
|
||||
ReadyBegin,
|
||||
InsideBegin,
|
||||
RenderPassActive,
|
||||
Ended,
|
||||
Submitted,
|
||||
Init,
|
||||
Begin,
|
||||
RenderPass,
|
||||
End,
|
||||
Submit,
|
||||
};
|
||||
|
||||
private:
|
||||
@@ -51,7 +51,6 @@ private:
|
||||
State state;
|
||||
VkViewport currentViewport;
|
||||
VkRect2D currentScissor;
|
||||
std::mutex handleLock;
|
||||
VkCommandBuffer handle;
|
||||
VkCommandPool owner;
|
||||
Array<PSemaphore> waitSemaphores;
|
||||
@@ -60,10 +59,10 @@ private:
|
||||
Array<PComputeCommand> executingComputes;
|
||||
Array<PDescriptorSet> boundDescriptors;
|
||||
friend class RenderCommand;
|
||||
friend class CommandBufferManager;
|
||||
friend class CommandPool;
|
||||
friend class Queue;
|
||||
};
|
||||
DEFINE_REF(CmdBuffer)
|
||||
DEFINE_REF(Command)
|
||||
|
||||
DECLARE_REF(GraphicsPipeline)
|
||||
DECLARE_REF(ComputePipeline)
|
||||
@@ -72,7 +71,7 @@ class RenderCommand : public Gfx::RenderCommand
|
||||
public:
|
||||
RenderCommand(PGraphics graphics, VkCommandPool cmdPool);
|
||||
virtual ~RenderCommand();
|
||||
inline VkCommandBuffer getHandle()
|
||||
constexpr VkCommandBuffer getHandle()
|
||||
{
|
||||
return handle;
|
||||
}
|
||||
@@ -100,7 +99,7 @@ private:
|
||||
std::thread::id threadId;
|
||||
VkCommandBuffer handle;
|
||||
VkCommandPool owner;
|
||||
friend class CmdBuffer;
|
||||
friend class Command;
|
||||
};
|
||||
DEFINE_REF(RenderCommand)
|
||||
|
||||
@@ -132,22 +131,22 @@ private:
|
||||
std::thread::id threadId;
|
||||
VkCommandBuffer handle;
|
||||
VkCommandPool owner;
|
||||
friend class CmdBuffer;
|
||||
friend class Command;
|
||||
};
|
||||
DEFINE_REF(ComputeCommand)
|
||||
class CommandBufferManager
|
||||
class CommandPool
|
||||
{
|
||||
public:
|
||||
CommandBufferManager(PGraphics graphics, PQueue queue);
|
||||
virtual ~CommandBufferManager();
|
||||
inline PQueue getQueue() const
|
||||
CommandPool(PGraphics graphics, PQueue queue);
|
||||
virtual ~CommandPool();
|
||||
constexpr PQueue getQueue() const
|
||||
{
|
||||
return queue;
|
||||
}
|
||||
PCmdBuffer getCommands();
|
||||
PCommand getCommands();
|
||||
PRenderCommand createRenderCommand(PRenderPass renderPass, PFramebuffer framebuffer, const std::string& name);
|
||||
PComputeCommand createComputeCommand(const std::string& name);
|
||||
VkCommandPool getPoolHandle() const
|
||||
constexpr VkCommandPool getHandle() const
|
||||
{
|
||||
return commandPool;
|
||||
}
|
||||
@@ -158,14 +157,11 @@ private:
|
||||
VkCommandPool commandPool;
|
||||
PQueue queue;
|
||||
uint32 queueFamilyIndex;
|
||||
PCmdBuffer activeCmdBuffer;
|
||||
std::mutex allocatedBufferLock;
|
||||
PCommand command;
|
||||
Array<OCmdBuffer> allocatedBuffers;
|
||||
std::mutex allocatedRenderLock;
|
||||
std::mutex allocatedComputeLock;
|
||||
Array<ORenderCommand> allocatedRenderCommands;
|
||||
Array<OComputeCommand> allocatedComputeCommands;
|
||||
};
|
||||
DEFINE_REF(CommandBufferManager)
|
||||
DEFINE_REF(CommandPool)
|
||||
} // namespace Vulkan
|
||||
} // namespace Seele
|
||||
+3
-3
@@ -153,8 +153,8 @@ void DescriptorSet::updateBuffer(uint32_t binding, Gfx::PShaderBuffer shaderBuff
|
||||
|
||||
void DescriptorSet::updateSampler(uint32_t binding, Gfx::PSamplerState samplerState)
|
||||
{
|
||||
PSamplerState vulkanSampler = samplerState.cast<SamplerState>();
|
||||
SamplerState* cachedSampler = reinterpret_cast<SamplerState*>(cachedData[binding]);
|
||||
PSamplerState vulkanSampler = samplerState.cast<Sampler>();
|
||||
Sampler* cachedSampler = reinterpret_cast<Sampler*>(cachedData[binding]);
|
||||
if(vulkanSampler.getHandle() == cachedSampler)
|
||||
{
|
||||
return;
|
||||
@@ -188,7 +188,7 @@ void DescriptorSet::updateTexture(uint32_t binding, Gfx::PTexture texture, Gfx::
|
||||
cast(vulkanTexture->getLayout()));
|
||||
if (samplerState != nullptr)
|
||||
{
|
||||
PSamplerState vulkanSampler = samplerState.cast<SamplerState>();
|
||||
PSamplerState vulkanSampler = samplerState.cast<Sampler>();
|
||||
imageInfo.sampler = vulkanSampler->sampler;
|
||||
}
|
||||
imageInfos.add(imageInfo);
|
||||
+1
-1
@@ -120,7 +120,7 @@ private:
|
||||
bool currentlyBound;
|
||||
bool currentlyInUse;
|
||||
friend class DescriptorAllocator;
|
||||
friend class CmdBuffer;
|
||||
friend class Command;
|
||||
friend class RenderCommand;
|
||||
friend class ComputeCommand;
|
||||
};
|
||||
@@ -23,24 +23,24 @@ Framebuffer::Framebuffer(PGraphics graphics, PRenderPass renderPass, Gfx::PRende
|
||||
PTexture2D vkInputAttachment = inputAttachment->getTexture().cast<Texture2D>();
|
||||
attachments.add(vkInputAttachment->getView());
|
||||
description.inputAttachments[description.numInputAttachments++] = vkInputAttachment->getView();
|
||||
sizeX = std::max(sizeX, vkInputAttachment->getSizeX());
|
||||
sizeY = std::max(sizeY, vkInputAttachment->getSizeY());
|
||||
sizeX = std::max(sizeX, vkInputAttachment->getWidth());
|
||||
sizeY = std::max(sizeY, vkInputAttachment->getHeight());
|
||||
}
|
||||
for (auto colorAttachment : layout->colorAttachments)
|
||||
{
|
||||
PTexture2D vkColorAttachment = colorAttachment->getTexture().cast<Texture2D>();
|
||||
attachments.add(vkColorAttachment->getView());
|
||||
description.colorAttachments[description.numColorAttachments++] = vkColorAttachment->getView();
|
||||
sizeX = std::max(sizeX, vkColorAttachment->getSizeX());
|
||||
sizeY = std::max(sizeY, vkColorAttachment->getSizeY());
|
||||
sizeX = std::max(sizeX, vkColorAttachment->getWidth());
|
||||
sizeY = std::max(sizeY, vkColorAttachment->getHeight());
|
||||
}
|
||||
if (layout->depthAttachment != nullptr)
|
||||
{
|
||||
PTexture2D vkDepthAttachment = layout->depthAttachment->getTexture().cast<Texture2D>();
|
||||
attachments.add(vkDepthAttachment->getView());
|
||||
description.depthAttachment = vkDepthAttachment->getView();
|
||||
sizeX = std::max(sizeX, vkDepthAttachment->getSizeX());
|
||||
sizeY = std::max(sizeY, vkDepthAttachment->getSizeY());
|
||||
sizeX = std::max(sizeX, vkDepthAttachment->getWidth());
|
||||
sizeY = std::max(sizeY, vkDepthAttachment->getHeight());
|
||||
}
|
||||
VkFramebufferCreateInfo createInfo =
|
||||
init::FramebufferCreateInfo(
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
#include "Buffer.h"
|
||||
#include "Graphics/Enums.h"
|
||||
#include "PipelineCache.h"
|
||||
#include "CommandBuffer.h"
|
||||
#include "Command.h"
|
||||
#include "Initializer.h"
|
||||
#include "RenderTarget.h"
|
||||
#include "RenderPass.h"
|
||||
@@ -241,77 +241,11 @@ Gfx::OPipelineLayout Graphics::createPipelineLayout(Gfx::PPipelineLayout baseLay
|
||||
return new PipelineLayout(this, baseLayout);
|
||||
}
|
||||
|
||||
void Graphics::copyTexture(Gfx::PTexture srcTexture, Gfx::PTexture dstTexture)
|
||||
{
|
||||
Texture2D* src = (Texture2D*)srcTexture->getTexture2D();
|
||||
Texture2D* dst = (Texture2D*)dstTexture->getTexture2D();
|
||||
TextureHandle* srcHandle = (TextureHandle*)src->getNativeHandle();
|
||||
TextureHandle* dstHandle = (TextureHandle*)dst->getNativeHandle();
|
||||
Gfx::SeImageLayout srcLayout = srcHandle->getLayout();
|
||||
Gfx::SeImageLayout dstLayout = dstHandle->getLayout();
|
||||
Gfx::QueueType dstOwner = dstHandle->currentOwner;
|
||||
src->changeLayout(Gfx::SE_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL);
|
||||
dst->changeLayout(Gfx::SE_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL);
|
||||
dstTexture->transferOwnership(srcHandle->currentOwner);
|
||||
PCmdBuffer cmdBuffer = getQueueCommands(srcHandle->currentOwner)->getCommands();
|
||||
if(srcHandle->getAspect() != dstHandle->getAspect())
|
||||
{
|
||||
/*VkMemoryRequirements imageRequirements;
|
||||
vkGetImageMemoryRequirements(handle, srcHandle->getImage(), &imageRequirements);
|
||||
PShaderBuffer tempBuffer = createShaderBuffer();
|
||||
VkBufferImageCopy bufferImageCopy;
|
||||
bufferImageCopy.bufferOffset = 0;
|
||||
bufferImageCopy.bufferRowLength = srcTexture->getSizeX();
|
||||
bufferImageCopy.bufferImageHeight = srcTexture->getSizeY();
|
||||
bufferImageCopy.imageExtent.width = srcTexture->getSizeX();
|
||||
bufferImageCopy.imageExtent.height = srcTexture->getSizeY();
|
||||
bufferImageCopy.imageExtent.depth = 1;
|
||||
bufferImageCopy.imageOffset.x = 0;
|
||||
bufferImageCopy.imageOffset.y = 0;
|
||||
bufferImageCopy.imageOffset.z = 0;
|
||||
bufferImageCopy.imageSubresource.aspectMask = VK_IMAGE_ASPECT_DEPTH_BIT;
|
||||
bufferImageCopy.imageSubresource.baseArrayLayer = 0;
|
||||
bufferImageCopy.imageSubresource.layerCount = 1;
|
||||
bufferImageCopy.imageSubresource.mipLevel = 0;
|
||||
|
||||
vkCmdCopyImageToBuffer(cmdBuffer->getHandle(), srcHandle->getImage(), VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, tempBufferAllocation->getHandle(), 1, &bufferImageCopy);
|
||||
|
||||
bufferImageCopy.imageSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
|
||||
|
||||
vkCmdCopyBufferToImage(cmdBuffer->getHandle(), tempBufferAllocation->getHandle(), dstHandle->getImage(), VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1, &bufferImageCopy);
|
||||
delete tempBufferAllocation;*/
|
||||
throw new std::logic_error("Not yet implemented!");
|
||||
}
|
||||
else if (src->getSizeX() != dst->getSizeX()
|
||||
|| src->getSizeY() != dst->getSizeY())
|
||||
{
|
||||
throw new std::logic_error("Not yet implemented!");
|
||||
}
|
||||
else
|
||||
{
|
||||
VkImageCopy copy;
|
||||
std::memset(©, 0, sizeof(VkImageCopy));
|
||||
copy.extent.width = srcTexture->getSizeX();
|
||||
copy.extent.height = srcTexture->getSizeY();
|
||||
copy.extent.depth = 1;
|
||||
copy.srcSubresource.aspectMask = srcHandle->getAspect();
|
||||
copy.srcSubresource.layerCount = 1;
|
||||
copy.dstSubresource.aspectMask = dstHandle->getAspect();
|
||||
copy.dstSubresource.layerCount = 1;
|
||||
vkCmdCopyImage(cmdBuffer->getHandle(),
|
||||
srcHandle->getImage(), VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
|
||||
dstHandle->getImage(), VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
|
||||
1, ©);
|
||||
src->changeLayout(srcLayout);
|
||||
dst->changeLayout(dstLayout);
|
||||
dstTexture->transferOwnership(dstOwner);
|
||||
}
|
||||
}
|
||||
|
||||
void Graphics::vkCmdDrawMeshTasksEXT(VkCommandBuffer handle, uint32 groupX, uint32 groupY, uint32 groupZ)
|
||||
{
|
||||
cmdDrawMeshTasks(handle, groupX, groupY, groupZ);
|
||||
}
|
||||
|
||||
PCommandBufferManager Graphics::getQueueCommands(Gfx::QueueType queueType)
|
||||
{
|
||||
switch (queueType)
|
||||
@@ -332,7 +266,7 @@ PCommandBufferManager Graphics::getGraphicsCommands()
|
||||
{
|
||||
if(graphicsCommands == nullptr)
|
||||
{
|
||||
graphicsCommands = new CommandBufferManager(this, graphicsQueue);
|
||||
graphicsCommands = new CommandPool(this, graphicsQueue);
|
||||
}
|
||||
return graphicsCommands;
|
||||
}
|
||||
@@ -340,7 +274,7 @@ PCommandBufferManager Graphics::getComputeCommands()
|
||||
{
|
||||
if(computeCommands == nullptr)
|
||||
{
|
||||
computeCommands = new CommandBufferManager(this, computeQueue);
|
||||
computeCommands = new CommandPool(this, computeQueue);
|
||||
}
|
||||
return computeCommands;
|
||||
}
|
||||
@@ -348,7 +282,7 @@ PCommandBufferManager Graphics::getTransferCommands()
|
||||
{
|
||||
if(transferCommands == nullptr)
|
||||
{
|
||||
transferCommands = new CommandBufferManager(this, transferQueue);
|
||||
transferCommands = new CommandPool(this, transferQueue);
|
||||
}
|
||||
return transferCommands;
|
||||
}
|
||||
@@ -356,7 +290,7 @@ PCommandBufferManager Graphics::getDedicatedTransferCommands()
|
||||
{
|
||||
if(dedicatedTransferCommands == nullptr)
|
||||
{
|
||||
dedicatedTransferCommands = new CommandBufferManager(this, dedicatedTransferQueue != nullptr ? dedicatedTransferQueue : transferQueue);
|
||||
dedicatedTransferCommands = new CommandPool(this, dedicatedTransferQueue != nullptr ? dedicatedTransferQueue : transferQueue);
|
||||
}
|
||||
return dedicatedTransferCommands;
|
||||
}
|
||||
|
||||
@@ -9,15 +9,9 @@ namespace Vulkan
|
||||
DECLARE_REF(Allocator)
|
||||
DECLARE_REF(StagingManager)
|
||||
DECLARE_REF(DestructionManager)
|
||||
DECLARE_REF(CommandBufferManager)
|
||||
DECLARE_REF(CommandPool)
|
||||
DECLARE_REF(Queue)
|
||||
DECLARE_REF(RenderPass)
|
||||
DECLARE_REF(Framebuffer)
|
||||
DECLARE_REF(RenderCommand)
|
||||
DECLARE_REF(PipelineCache)
|
||||
DECLARE_REF(Window)
|
||||
DECLARE_REF(RenderTargetLayout)
|
||||
DECLARE_REF(Viewport)
|
||||
class Graphics : public Gfx::Graphics
|
||||
{
|
||||
public:
|
||||
@@ -60,7 +54,6 @@ public:
|
||||
virtual Gfx::PRenderCommand createRenderCommand(const std::string& name) override;
|
||||
virtual Gfx::PComputeCommand createComputeCommand(const std::string& name) override;
|
||||
|
||||
virtual Gfx::OVertexDeclaration createVertexDeclaration(const Array<Gfx::VertexElement>& element) override;
|
||||
virtual Gfx::OVertexShader createVertexShader(const ShaderCreateInfo& createInfo) override;
|
||||
virtual Gfx::OFragmentShader createFragmentShader(const ShaderCreateInfo& createInfo) override;
|
||||
virtual Gfx::OComputeShader createComputeShader(const ShaderCreateInfo& createInfo) override;
|
||||
@@ -69,7 +62,7 @@ public:
|
||||
virtual Gfx::PGraphicsPipeline createGraphicsPipeline(Gfx::LegacyPipelineCreateInfo createInfo) override;
|
||||
virtual Gfx::PGraphicsPipeline createGraphicsPipeline(Gfx::MeshPipelineCreateInfo createInfo) override;
|
||||
virtual Gfx::PComputePipeline createComputePipeline(Gfx::ComputePipelineCreateInfo createInfo) override;
|
||||
virtual Gfx::OSamplerState createSamplerState(const SamplerCreateInfo& createInfo) override;
|
||||
virtual Gfx::OSampler createSamplerState(const SamplerCreateInfo& createInfo) override;
|
||||
|
||||
virtual Gfx::ODescriptorLayout createDescriptorLayout(const std::string& name = "") override;
|
||||
virtual Gfx::OPipelineLayout createPipelineLayout(Gfx::PPipelineLayout baseLayout = nullptr) override;
|
||||
@@ -93,9 +86,6 @@ protected:
|
||||
OQueue transferQueue;
|
||||
OQueue dedicatedTransferQueue;
|
||||
OPipelineCache pipelineCache;
|
||||
std::mutex renderPassLock;
|
||||
PRenderPass activeRenderPass;
|
||||
PFramebuffer activeFramebuffer;
|
||||
thread_local static OCommandBufferManager graphicsCommands;
|
||||
thread_local static OCommandBufferManager computeCommands;
|
||||
thread_local static OCommandBufferManager transferCommands;
|
||||
@@ -103,7 +93,6 @@ protected:
|
||||
VkPhysicalDeviceProperties props;
|
||||
VkPhysicalDeviceFeatures features;
|
||||
VkDebugReportCallbackEXT callback;
|
||||
std::mutex viewportLock;
|
||||
Array<PViewport> viewports;
|
||||
std::mutex allocatedFrameBufferLock;
|
||||
Map<uint32, OFramebuffer> allocatedFramebuffers;
|
||||
|
||||
@@ -22,7 +22,7 @@ Queue::~Queue()
|
||||
void Queue::submitCommandBuffer(PCmdBuffer cmdBuffer, uint32 numSignalSemaphores, VkSemaphore *signalSemaphores)
|
||||
{
|
||||
std::scoped_lock lck(queueLock);
|
||||
assert(cmdBuffer->state == CmdBuffer::State::Ended);
|
||||
assert(cmdBuffer->state == Command::State::End);
|
||||
|
||||
PFence fence = cmdBuffer->fence;
|
||||
assert(!fence->isSignaled());
|
||||
@@ -48,7 +48,7 @@ void Queue::submitCommandBuffer(PCmdBuffer cmdBuffer, uint32 numSignalSemaphores
|
||||
submitInfo.pWaitDstStageMask = cmdBuffer->waitFlags.data();
|
||||
}
|
||||
VK_CHECK(vkQueueSubmit(queue, 1, &submitInfo, fence->getHandle()));
|
||||
cmdBuffer->state = CmdBuffer::State::Submitted;
|
||||
cmdBuffer->state = Command::State::Submit;
|
||||
cmdBuffer->waitFlags.clear();
|
||||
cmdBuffer->waitSemaphores.clear();
|
||||
|
||||
@@ -57,7 +57,7 @@ void Queue::submitCommandBuffer(PCmdBuffer cmdBuffer, uint32 numSignalSemaphores
|
||||
fence->wait(200 * 1000ull);
|
||||
}
|
||||
|
||||
cmdBuffer->refreshFence();
|
||||
cmdBuffer->checkFence();
|
||||
graphics->getStagingManager()->clearPending();
|
||||
|
||||
}
|
||||
@@ -5,7 +5,7 @@ namespace Seele
|
||||
{
|
||||
namespace Vulkan
|
||||
{
|
||||
DECLARE_REF(CmdBuffer)
|
||||
DECLARE_REF(Command)
|
||||
DECLARE_REF(Graphics)
|
||||
class Queue
|
||||
{
|
||||
|
||||
@@ -12,8 +12,8 @@ RenderPass::RenderPass(PGraphics graphics, Gfx::ORenderTargetLayout _layout, Gfx
|
||||
: Gfx::RenderPass(std::move(_layout))
|
||||
, graphics(graphics)
|
||||
{
|
||||
renderArea.extent.width = viewport->getSizeX();
|
||||
renderArea.extent.height = viewport->getSizeY();
|
||||
renderArea.extent.width = viewport->getWidth();
|
||||
renderArea.extent.height = viewport->getHeight();
|
||||
renderArea.offset.x = viewport->getOffsetX();
|
||||
renderArea.offset.y = viewport->getOffsetY();
|
||||
subpassContents = VK_SUBPASS_CONTENTS_SECONDARY_COMMAND_BUFFERS;
|
||||
|
||||
@@ -195,7 +195,7 @@ void Window::advanceBackBuffer()
|
||||
&range);
|
||||
|
||||
backBufferImages[currentImageIndex]->changeLayout(Gfx::SE_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL);
|
||||
graphics->getGraphicsCommands()->getCommands()->addWaitSemaphore(VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT, imageAcquiredSemaphore);
|
||||
graphics->getGraphicsCommands()->getCommands()->waitForSemaphore(VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT, imageAcquiredSemaphore);
|
||||
graphics->getGraphicsCommands()->submitCommands();
|
||||
}
|
||||
|
||||
@@ -264,9 +264,10 @@ void Window::createSwapchain()
|
||||
throw new std::logic_error("Trying to buffer more than the maximum number of frames");
|
||||
}
|
||||
|
||||
VkExtent2D extent;
|
||||
extent.width = getSizeX();
|
||||
extent.height = getSizeY();
|
||||
VkExtent2D extent = {
|
||||
.width = getWidth(),
|
||||
.height = getHeight(),
|
||||
};
|
||||
VkSwapchainCreateInfoKHR swapchainInfo =
|
||||
init::SwapchainCreateInfo(
|
||||
surface,
|
||||
@@ -289,8 +290,8 @@ void Window::createSwapchain()
|
||||
|
||||
|
||||
TextureCreateInfo backBufferCreateInfo;
|
||||
backBufferCreateInfo.width = getSizeX();
|
||||
backBufferCreateInfo.height = getSizeY();
|
||||
backBufferCreateInfo.width = getWidth();
|
||||
backBufferCreateInfo.height = getHeight();
|
||||
backBufferCreateInfo.usage = Gfx::SE_IMAGE_USAGE_COLOR_ATTACHMENT_BIT;
|
||||
backBufferCreateInfo.sourceData.owner = Gfx::QueueType::GRAPHICS;
|
||||
backBufferCreateInfo.format = cast(surfaceFormat.format);
|
||||
@@ -304,8 +305,8 @@ void Window::createSwapchain()
|
||||
std::memset(&clearColor, 0, sizeof(VkClearColorValue));
|
||||
backBufferImages[i]->changeLayout(Gfx::SE_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL);
|
||||
VkImageSubresourceRange range = init::ImageSubresourceRange(VK_IMAGE_ASPECT_COLOR_BIT);
|
||||
PCmdBuffer cmdBuffer = graphics->getGraphicsCommands()->getCommands();
|
||||
vkCmdClearColorImage(cmdBuffer->getHandle(), backBufferImages[i]->getHandle(), VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, &clearColor, 1, &range);
|
||||
PCommand command = graphics->getGraphicsCommands()->getCommands();
|
||||
vkCmdClearColorImage(command->getHandle(), backBufferImages[i]->getHandle(), VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, &clearColor, 1, &range);
|
||||
backBufferImages[i]->changeLayout(Gfx::SE_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL);
|
||||
}
|
||||
graphics->getGraphicsCommands()->submitCommands();
|
||||
|
||||
@@ -8,7 +8,6 @@ namespace Seele
|
||||
{
|
||||
namespace Vulkan
|
||||
{
|
||||
|
||||
class Window : public Gfx::Window
|
||||
{
|
||||
public:
|
||||
|
||||
@@ -9,13 +9,26 @@ using namespace Seele::Vulkan;
|
||||
Semaphore::Semaphore(PGraphics graphics)
|
||||
: graphics(graphics)
|
||||
{
|
||||
VkSemaphoreCreateInfo info =
|
||||
init::SemaphoreCreateInfo();
|
||||
VkSemaphoreCreateInfo info = {
|
||||
.sType = VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO,
|
||||
.pNext = nullptr,
|
||||
.flags = 0,
|
||||
};
|
||||
VK_CHECK(vkCreateSemaphore(graphics->getDevice(), &info, nullptr, &handle));
|
||||
}
|
||||
|
||||
Semaphore::~Semaphore()
|
||||
{
|
||||
uint64 value = 0;
|
||||
VkSemaphoreWaitInfo waitInfo = {
|
||||
.sType = VK_STRUCTURE_TYPE_SEMAPHORE_WAIT_INFO,
|
||||
.pNext = nullptr,
|
||||
.flags = 0,
|
||||
.semaphoreCount = 1,
|
||||
.pSemaphores = &handle,
|
||||
.pValues = &value,
|
||||
};
|
||||
VK_CHECK(vkWaitSemaphores(graphics->getDevice(), &waitInfo, 10000));
|
||||
vkDestroySemaphore(graphics->getDevice(), handle, nullptr);
|
||||
}
|
||||
|
||||
@@ -23,8 +36,11 @@ Fence::Fence(PGraphics graphics)
|
||||
: graphics(graphics)
|
||||
, signaled(false)
|
||||
{
|
||||
VkFenceCreateInfo info =
|
||||
init::FenceCreateInfo(0);
|
||||
VkFenceCreateInfo info = {
|
||||
.sType = VK_STRUCTURE_TYPE_FENCE_CREATE_INFO,
|
||||
.pNext = nullptr,
|
||||
.flags = 0
|
||||
};
|
||||
VK_CHECK(vkCreateFence(graphics->getDevice(), &info, nullptr, &fence));
|
||||
}
|
||||
|
||||
@@ -40,17 +56,15 @@ bool Fence::isSignaled()
|
||||
return true;
|
||||
}
|
||||
VkResult res = vkGetFenceStatus(graphics->getDevice(), fence);
|
||||
switch (res)
|
||||
if (res == VK_SUCCESS)
|
||||
{
|
||||
case VK_SUCCESS:
|
||||
signaled = true;
|
||||
return signaled;
|
||||
case VK_NOT_READY:
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
return true;
|
||||
}
|
||||
if (res == VK_NOT_READY)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void Fence::reset()
|
||||
@@ -65,17 +79,14 @@ void Fence::reset()
|
||||
void Fence::wait(uint32 timeout)
|
||||
{
|
||||
VkFence fences[] = {fence};
|
||||
VkResult r = vkWaitForFences(graphics->getDevice(), 1, fences, true, timeout * 1000ull);
|
||||
switch (r)
|
||||
VkResult res = vkWaitForFences(graphics->getDevice(), 1, fences, true, timeout);
|
||||
if (res == VK_SUCCESS)
|
||||
{
|
||||
case VK_SUCCESS:
|
||||
signaled = true;
|
||||
break;
|
||||
case VK_TIMEOUT:
|
||||
break;
|
||||
default:
|
||||
VK_CHECK(r);
|
||||
break;
|
||||
}
|
||||
if (res != VK_NOT_READY)
|
||||
{
|
||||
VK_CHECK(res);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -88,22 +99,27 @@ DestructionManager::~DestructionManager()
|
||||
{
|
||||
}
|
||||
|
||||
void DestructionManager::queueBuffer(PCmdBuffer cmd, VkBuffer buffer)
|
||||
void DestructionManager::queueBuffer(PCommand cmd, VkBuffer buffer)
|
||||
{
|
||||
buffers[cmd].add(buffer);
|
||||
}
|
||||
|
||||
void DestructionManager::queueImage(PCmdBuffer cmd, VkImage image)
|
||||
void DestructionManager::queueImage(PCommand cmd, VkImage image)
|
||||
{
|
||||
images[cmd].add(image);
|
||||
}
|
||||
|
||||
void DestructionManager::queueImageView(PCmdBuffer cmd, VkImageView image)
|
||||
void DestructionManager::queueImageView(PCommand cmd, VkImageView image)
|
||||
{
|
||||
views[cmd].add(image);
|
||||
}
|
||||
|
||||
void DestructionManager::notifyCmdComplete(PCmdBuffer cmdbuffer)
|
||||
void DestructionManager::queueSemaphore(PCommand cmd, VkSemaphore sem)
|
||||
{
|
||||
sems[cmd].add(sem);
|
||||
}
|
||||
|
||||
void DestructionManager::notifyCmdComplete(PCommand cmdbuffer)
|
||||
{
|
||||
for(auto buf : buffers[cmdbuffer])
|
||||
{
|
||||
@@ -117,16 +133,12 @@ void DestructionManager::notifyCmdComplete(PCmdBuffer cmdbuffer)
|
||||
{
|
||||
vkDestroyImage(graphics->getDevice(), img, nullptr);
|
||||
}
|
||||
for (auto sem : sems[cmdbuffer])
|
||||
{
|
||||
vkDestroySemaphore(graphics->getDevice(), sem, nullptr);
|
||||
}
|
||||
buffers[cmdbuffer].clear();
|
||||
images[cmdbuffer].clear();
|
||||
views[cmdbuffer].clear();
|
||||
}
|
||||
|
||||
VertexDeclaration::VertexDeclaration(const Array<Gfx::VertexElement>& elementList)
|
||||
: elementList(elementList)
|
||||
{
|
||||
}
|
||||
|
||||
VertexDeclaration::~VertexDeclaration()
|
||||
{
|
||||
sems[cmdbuffer].clear();
|
||||
}
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
#pragma once
|
||||
#include <vulkan/vulkan.h>
|
||||
#include <functional>
|
||||
#include "Containers/List.h"
|
||||
#include "Graphics/Resources.h"
|
||||
#include "Allocator.h"
|
||||
@@ -9,10 +8,9 @@ namespace Seele
|
||||
{
|
||||
namespace Vulkan
|
||||
{
|
||||
|
||||
DECLARE_REF(DescriptorAllocator)
|
||||
DECLARE_REF(CommandBufferManager)
|
||||
DECLARE_REF(CmdBuffer)
|
||||
DECLARE_REF(CommandPool)
|
||||
DECLARE_REF(Command)
|
||||
DECLARE_REF(Graphics)
|
||||
DECLARE_REF(SubAllocation)
|
||||
class Semaphore
|
||||
@@ -20,11 +18,10 @@ class Semaphore
|
||||
public:
|
||||
Semaphore(PGraphics graphics);
|
||||
virtual ~Semaphore();
|
||||
inline VkSemaphore getHandle() const
|
||||
constexpr VkSemaphore getHandle() const
|
||||
{
|
||||
return handle;
|
||||
}
|
||||
|
||||
private:
|
||||
VkSemaphore handle;
|
||||
PGraphics graphics;
|
||||
@@ -38,7 +35,7 @@ public:
|
||||
~Fence();
|
||||
bool isSignaled();
|
||||
void reset();
|
||||
inline VkFence getHandle() const
|
||||
constexpr VkFence getHandle() const
|
||||
{
|
||||
return fence;
|
||||
}
|
||||
@@ -60,35 +57,26 @@ class DestructionManager
|
||||
public:
|
||||
DestructionManager(PGraphics graphics);
|
||||
~DestructionManager();
|
||||
void queueBuffer(PCmdBuffer cmd, VkBuffer buffer);
|
||||
void queueImage(PCmdBuffer cmd, VkImage image);
|
||||
void queueImageView(PCmdBuffer cmd, VkImageView view);
|
||||
void notifyCmdComplete(PCmdBuffer cmdbuffer);
|
||||
void queueBuffer(PCommand cmd, VkBuffer buffer);
|
||||
void queueImage(PCommand cmd, VkImage image);
|
||||
void queueImageView(PCommand cmd, VkImageView view);
|
||||
void queueSemaphore(PCommand cmd, VkSemaphore sem);
|
||||
void notifyCmdComplete(PCommand cmdbuffer);
|
||||
private:
|
||||
PGraphics graphics;
|
||||
Map<PCmdBuffer, List<VkBuffer>> buffers;
|
||||
Map<PCmdBuffer, List<VkImage>> images;
|
||||
Map<PCmdBuffer, List<VkImageView>> views;
|
||||
Map<PCommand, List<VkBuffer>> buffers;
|
||||
Map<PCommand, List<VkImage>> images;
|
||||
Map<PCommand, List<VkImageView>> views;
|
||||
Map<PCommand, List<VkSemaphore>> sems;
|
||||
};
|
||||
DEFINE_REF(DestructionManager)
|
||||
|
||||
class VertexDeclaration : public Gfx::VertexDeclaration
|
||||
{
|
||||
public:
|
||||
Array<Gfx::VertexElement> elementList;
|
||||
|
||||
VertexDeclaration(const Array<Gfx::VertexElement>& elementList);
|
||||
virtual ~VertexDeclaration();
|
||||
private:
|
||||
};
|
||||
DEFINE_REF(VertexDeclaration)
|
||||
|
||||
class SamplerState : public Gfx::SamplerState
|
||||
class Sampler : public Gfx::Sampler
|
||||
{
|
||||
public:
|
||||
VkSampler sampler;
|
||||
};
|
||||
DEFINE_REF(SamplerState)
|
||||
DEFINE_REF(Sampler)
|
||||
|
||||
} // namespace Vulkan
|
||||
} // namespace Seele
|
||||
|
||||
@@ -110,10 +110,10 @@ TextureHandle::TextureHandle(PGraphics graphics, VkImageViewType viewType,
|
||||
if(sourceData.size > 0)
|
||||
{
|
||||
changeLayout(Gfx::SE_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL);
|
||||
OStagingBuffer staging = graphics->getStagingManager()->allocateStagingBuffer(sourceData.size, VK_BUFFER_USAGE_TRANSFER_SRC_BIT);
|
||||
void* data = staging->getMappedPointer();
|
||||
OStagingBuffer staging = graphics->getStagingManager()->create(sourceData.size, VK_BUFFER_USAGE_TRANSFER_SRC_BIT);
|
||||
void* data = staging->map();
|
||||
std::memcpy(data, sourceData.data, sourceData.size);
|
||||
staging->flushMappedMemory();
|
||||
staging->flush();
|
||||
|
||||
PCommandBufferManager cmdBufferManager = graphics->getQueueCommands(currentOwner);
|
||||
VkBufferImageCopy region;
|
||||
@@ -134,7 +134,7 @@ TextureHandle::TextureHandle(PGraphics graphics, VkImageViewType viewType,
|
||||
|
||||
// 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()->releaseStagingBuffer(std::move(staging));
|
||||
graphics->getStagingManager()->release(std::move(staging));
|
||||
}
|
||||
else if(usage & VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT)
|
||||
{
|
||||
@@ -209,7 +209,7 @@ void TextureHandle::download(uint32 mipLevel, uint32 arrayLayer, uint32 face, Ar
|
||||
{
|
||||
uint64 imageSize = sizeX * sizeY * sizeZ * Gfx::getFormatInfo(format).blockSize;
|
||||
|
||||
OStagingBuffer stagingbuffer = graphics->getStagingManager()->allocateStagingBuffer(imageSize, VK_BUFFER_USAGE_TRANSFER_DST_BIT, true);
|
||||
OStagingBuffer stagingbuffer = graphics->getStagingManager()->create(imageSize, VK_BUFFER_USAGE_TRANSFER_DST_BIT, true);
|
||||
auto prevlayout = layout;
|
||||
changeLayout(Gfx::SE_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL);
|
||||
PCmdBuffer cmdBuffer = graphics->getQueueCommands(currentOwner)->getCommands();
|
||||
@@ -230,9 +230,9 @@ void TextureHandle::download(uint32 mipLevel, uint32 arrayLayer, uint32 face, Ar
|
||||
vkCmdCopyImageToBuffer(cmdBuffer->getHandle(), image, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, stagingbuffer->getHandle(), 1, ®ion);
|
||||
changeLayout(prevlayout);
|
||||
buffer.resize(stagingbuffer->getSize());
|
||||
void* data = stagingbuffer->getMappedPointer();
|
||||
void* data = stagingbuffer->map();
|
||||
std::memcpy(buffer.data(), data, buffer.size());
|
||||
graphics->getStagingManager()->releaseStagingBuffer(std::move(stagingbuffer));
|
||||
graphics->getStagingManager()->release(std::move(stagingbuffer));
|
||||
}
|
||||
|
||||
void TextureHandle::executeOwnershipBarrier(Gfx::QueueType newOwner)
|
||||
|
||||
@@ -97,15 +97,15 @@ class Texture2D : public Gfx::Texture2D, public TextureBase
|
||||
public:
|
||||
Texture2D(PGraphics graphics, const TextureCreateInfo& createInfo, VkImage existingImage = VK_NULL_HANDLE);
|
||||
virtual ~Texture2D();
|
||||
virtual uint32 getSizeX() const override
|
||||
virtual uint32 getWidth() const override
|
||||
{
|
||||
return textureHandle->sizeX;
|
||||
}
|
||||
virtual uint32 getSizeY() const override
|
||||
virtual uint32 getHeight() const override
|
||||
{
|
||||
return textureHandle->sizeY;
|
||||
}
|
||||
virtual uint32 getSizeZ() const override
|
||||
virtual uint32 getDepth() const override
|
||||
{
|
||||
return textureHandle->sizeZ;
|
||||
}
|
||||
@@ -153,15 +153,15 @@ class Texture3D : public Gfx::Texture3D, public TextureBase
|
||||
public:
|
||||
Texture3D(PGraphics graphics, const TextureCreateInfo& createInfo, VkImage existingImage = VK_NULL_HANDLE);
|
||||
virtual ~Texture3D();
|
||||
virtual uint32 getSizeX() const override
|
||||
virtual uint32 getWidth() const override
|
||||
{
|
||||
return textureHandle->sizeX;
|
||||
}
|
||||
virtual uint32 getSizeY() const override
|
||||
virtual uint32 getHeight() const override
|
||||
{
|
||||
return textureHandle->sizeY;
|
||||
}
|
||||
virtual uint32 getSizeZ() const override
|
||||
virtual uint32 getDepth() const override
|
||||
{
|
||||
return textureHandle->sizeZ;
|
||||
}
|
||||
@@ -209,15 +209,15 @@ class TextureCube : public Gfx::TextureCube, public TextureBase
|
||||
public:
|
||||
TextureCube(PGraphics graphics, const TextureCreateInfo& createInfo, VkImage existingImage = VK_NULL_HANDLE);
|
||||
virtual ~TextureCube();
|
||||
virtual uint32 getSizeX() const override
|
||||
virtual uint32 getWidth() const override
|
||||
{
|
||||
return textureHandle->sizeX;
|
||||
}
|
||||
virtual uint32 getSizeY() const override
|
||||
virtual uint32 getHeight() const override
|
||||
{
|
||||
return textureHandle->sizeY;
|
||||
}
|
||||
virtual uint32 getSizeZ() const override
|
||||
virtual uint32 getDepth() const override
|
||||
{
|
||||
return textureHandle->sizeZ;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user