Lots of refactoring

This commit is contained in:
Dynamitos
2024-06-13 15:43:03 +02:00
parent df7fbef8bd
commit 42b4d43a6d
19 changed files with 566 additions and 482 deletions
+2
View File
@@ -498,6 +498,8 @@ void MeshLoader::loadGlobalMeshes(const aiScene* scene, const Array<PMaterialIns
globalMeshes[meshIndex]->meshlets = std::move(meshlets);
globalMeshes[meshIndex]->indices = std::move(indices);
globalMeshes[meshIndex]->vertexCount = mesh->mNumVertices;
globalMeshes[meshIndex]->blas =
graphics->createBottomLevelAccelerationStructure(Gfx::BottomLevelASCreateInfo(globalMeshes[meshIndex]));
}
}
+11 -10
View File
@@ -1,24 +1,25 @@
#include "Buffer.h"
#include "Initializer.h"
using namespace Seele;
using namespace Seele::Gfx;
Buffer::Buffer(QueueFamilyMapping mapping, QueueType startQueue) : QueueOwnedResource(mapping, startQueue) {}
Buffer::Buffer(QueueFamilyMapping mapping) : QueueOwnedResource(mapping) {}
Buffer::~Buffer() {}
VertexBuffer::VertexBuffer(QueueFamilyMapping mapping, uint32 numVertices, uint32 vertexSize, QueueType startQueueType)
: Buffer(mapping, startQueueType), numVertices(numVertices), vertexSize(vertexSize) {}
VertexBuffer::VertexBuffer(QueueFamilyMapping mapping, const VertexBufferCreateInfo& createInfo)
: Buffer(mapping), numVertices(createInfo.numVertices), vertexSize(createInfo.vertexSize) {}
VertexBuffer::~VertexBuffer() {}
IndexBuffer::IndexBuffer(QueueFamilyMapping mapping, uint64 size, Gfx::SeIndexType indexType, QueueType startQueueType)
: Buffer(mapping, startQueueType), indexType(indexType) {
IndexBuffer::IndexBuffer(QueueFamilyMapping mapping, const IndexBufferCreateInfo& createInfo)
: Buffer(mapping), indexType(createInfo.indexType) {
switch (indexType) {
case SE_INDEX_TYPE_UINT16:
numIndices = size / sizeof(uint16);
numIndices = createInfo.sourceData.size / sizeof(uint16);
break;
case SE_INDEX_TYPE_UINT32:
numIndices = size / sizeof(uint32);
numIndices = createInfo.sourceData.size / sizeof(uint32);
break;
default:
break;
@@ -26,11 +27,11 @@ IndexBuffer::IndexBuffer(QueueFamilyMapping mapping, uint64 size, Gfx::SeIndexTy
}
IndexBuffer::~IndexBuffer() {}
UniformBuffer::UniformBuffer(QueueFamilyMapping mapping, const DataSource& sourceData) : Buffer(mapping, sourceData.owner) {}
UniformBuffer::UniformBuffer(QueueFamilyMapping mapping, const UniformBufferCreateInfo&) : Buffer(mapping) {}
UniformBuffer::~UniformBuffer() {}
ShaderBuffer::ShaderBuffer(QueueFamilyMapping mapping, uint32 numElements, const DataSource& sourceData)
: Buffer(mapping, sourceData.owner), numElements(numElements) {}
ShaderBuffer::ShaderBuffer(QueueFamilyMapping mapping, const ShaderBufferCreateInfo& createInfo)
: Buffer(mapping), numElements(createInfo.numElements) {}
ShaderBuffer::~ShaderBuffer() {}
+7 -6
View File
@@ -2,22 +2,23 @@
#include "Initializer.h"
#include "Resources.h"
namespace Seele {
namespace Gfx {
class Buffer : public QueueOwnedResource {
public:
Buffer(QueueFamilyMapping mapping, QueueType startQueueType);
Buffer(QueueFamilyMapping mapping);
virtual ~Buffer();
protected:
// Inherited via QueueOwnedResource
virtual void executeOwnershipBarrier(QueueType newOwner) = 0;
virtual void executePipelineBarrier(SeAccessFlags srcAccess, SePipelineStageFlags srcStage, SeAccessFlags dstAccess,
SePipelineStageFlags dstStage) = 0;
};
class VertexBuffer : public Buffer {
public:
VertexBuffer(QueueFamilyMapping mapping, uint32 numVertices, uint32 vertexSize, QueueType startQueueType);
VertexBuffer(QueueFamilyMapping mapping, const VertexBufferCreateInfo& createInfo);
virtual ~VertexBuffer();
constexpr uint32 getNumVertices() const { return numVertices; }
// Size of one vertex in bytes
@@ -38,7 +39,7 @@ DEFINE_REF(VertexBuffer)
class IndexBuffer : public Buffer {
public:
IndexBuffer(QueueFamilyMapping mapping, uint64 size, Gfx::SeIndexType index, QueueType startQueueType);
IndexBuffer(QueueFamilyMapping mapping, const IndexBufferCreateInfo& createInfo);
virtual ~IndexBuffer();
constexpr uint64 getNumIndices() const { return numIndices; }
constexpr Gfx::SeIndexType getIndexType() const { return indexType; }
@@ -58,7 +59,7 @@ DEFINE_REF(IndexBuffer)
DECLARE_REF(UniformBuffer)
class UniformBuffer : public Buffer {
public:
UniformBuffer(QueueFamilyMapping mapping, const DataSource& sourceData);
UniformBuffer(QueueFamilyMapping mapping, const UniformBufferCreateInfo& createInfo);
virtual ~UniformBuffer();
virtual void rotateBuffer(uint64 size) = 0;
@@ -73,7 +74,7 @@ class UniformBuffer : public Buffer {
DEFINE_REF(UniformBuffer)
class ShaderBuffer : public Buffer {
public:
ShaderBuffer(QueueFamilyMapping mapping, uint32 numElements, const DataSource& bulkResourceData);
ShaderBuffer(QueueFamilyMapping mapping, const ShaderBufferCreateInfo& createInfo);
virtual ~ShaderBuffer();
virtual void rotateBuffer(uint64 size, bool preserveContents = false) = 0;
virtual void updateContents(const ShaderBufferCreateInfo& sourceData) = 0;
+2 -1
View File
@@ -2,7 +2,7 @@
#include "Asset/MaterialInstanceAsset.h"
#include "Graphics/Buffer.h"
#include "VertexData.h"
#include "Graphics/RayTracing.h"
namespace Seele {
class Mesh {
@@ -18,6 +18,7 @@ class Mesh {
PMaterialInstanceAsset referencedMaterial;
Array<uint32> indices;
Array<Meshlet> meshlets;
Gfx::OBottomLevelAS blas;
void save(ArchiveBuffer& buffer) const;
void load(ArchiveBuffer& buffer);
+3 -10
View File
@@ -1,22 +1,15 @@
#include "Resources.h"
#include "Graphics.h"
#include "Material/Material.h"
#include "Resources.h"
using namespace Seele;
using namespace Seele::Gfx;
QueueOwnedResource::QueueOwnedResource(QueueFamilyMapping mapping, QueueType startQueueType)
: currentOwner(startQueueType), mapping(mapping) {}
QueueOwnedResource::QueueOwnedResource(QueueFamilyMapping mapping)
: mapping(mapping) {}
QueueOwnedResource::~QueueOwnedResource() {}
void QueueOwnedResource::transferOwnership(QueueType newOwner) {
if (mapping.needsTransfer(currentOwner, newOwner)) {
executeOwnershipBarrier(newOwner);
}
currentOwner = newOwner;
executeOwnershipBarrier(newOwner);
}
void QueueOwnedResource::pipelineBarrier(SeAccessFlags srcAccess, SePipelineStageFlags srcStage, SeAccessFlags dstAccess,
+1 -2
View File
@@ -48,7 +48,7 @@ struct QueueFamilyMapping {
class QueueOwnedResource {
public:
QueueOwnedResource(QueueFamilyMapping mapping, QueueType startQueueType);
QueueOwnedResource(QueueFamilyMapping mapping);
virtual ~QueueOwnedResource();
// Preliminary checks to see if the barrier should be executed at all
@@ -59,7 +59,6 @@ class QueueOwnedResource {
virtual void executeOwnershipBarrier(QueueType newOwner) = 0;
virtual void executePipelineBarrier(SeAccessFlags srcAccess, SePipelineStageFlags srcStage, SeAccessFlags dstAccess,
SePipelineStageFlags dstStage) = 0;
Gfx::QueueType currentOwner;
QueueFamilyMapping mapping;
};
DEFINE_REF(QueueOwnedResource)
@@ -37,6 +37,7 @@ class StaticMeshVertexData : public VertexData {
virtual Gfx::PDescriptorSet getVertexDataSet() override;
virtual std::string getTypeName() const override { return "StaticMeshVertexData"; }
virtual Gfx::PShaderBuffer getPositionBuffer() const override { return positions; }
virtual Vector* getPositionData() const override { return positionData.data(); }
constexpr const Array<StaticMatData>& getStaticMeshes() const { return staticData; }
private:
+4 -4
View File
@@ -4,18 +4,18 @@
using namespace Seele;
using namespace Seele::Gfx;
Texture::Texture(QueueFamilyMapping mapping, Gfx::QueueType startQueueType) : QueueOwnedResource(mapping, startQueueType) {}
Texture::Texture(QueueFamilyMapping mapping) : QueueOwnedResource(mapping) {}
Texture::~Texture() {}
Texture2D::Texture2D(QueueFamilyMapping mapping, Gfx::QueueType startQueueType) : Texture(mapping, startQueueType) {}
Texture2D::Texture2D(QueueFamilyMapping mapping) : Texture(mapping) {}
Texture2D::~Texture2D() {}
Texture3D::Texture3D(QueueFamilyMapping mapping, Gfx::QueueType startQueueType) : Texture(mapping, startQueueType) {}
Texture3D::Texture3D(QueueFamilyMapping mapping) : Texture(mapping) {}
Texture3D::~Texture3D() {}
TextureCube::TextureCube(QueueFamilyMapping mapping, Gfx::QueueType startQueueType) : Texture(mapping, startQueueType) {}
TextureCube::TextureCube(QueueFamilyMapping mapping) : Texture(mapping) {}
TextureCube::~TextureCube() {}
+4 -4
View File
@@ -5,7 +5,7 @@ namespace Seele {
namespace Gfx {
class Texture : public QueueOwnedResource {
public:
Texture(QueueFamilyMapping mapping, QueueType startQueueType);
Texture(QueueFamilyMapping mapping);
virtual ~Texture();
virtual SeFormat getFormat() const = 0;
@@ -29,7 +29,7 @@ DEFINE_REF(Texture)
class Texture2D : public Texture {
public:
Texture2D(QueueFamilyMapping mapping, QueueType startQueueType);
Texture2D(QueueFamilyMapping mapping);
virtual ~Texture2D();
virtual SeFormat getFormat() const = 0;
@@ -52,7 +52,7 @@ DEFINE_REF(Texture2D)
class Texture3D : public Texture {
public:
Texture3D(QueueFamilyMapping mapping, QueueType startQueueType);
Texture3D(QueueFamilyMapping mapping);
virtual ~Texture3D();
virtual SeFormat getFormat() const = 0;
@@ -75,7 +75,7 @@ DEFINE_REF(Texture3D)
class TextureCube : public Texture {
public:
TextureCube(QueueFamilyMapping mapping, QueueType startQueueType);
TextureCube(QueueFamilyMapping mapping);
virtual ~TextureCube();
virtual SeFormat getFormat() const = 0;
+3 -1
View File
@@ -52,7 +52,9 @@ class VertexData {
virtual Gfx::PDescriptorSet getVertexDataSet() = 0;
virtual std::string getTypeName() const = 0;
virtual Gfx::PShaderBuffer getPositionBuffer() const = 0;
Gfx::PIndexBuffer getIndexBuffer() { return indexBuffer; }
virtual Vector* getPositionData() const = 0;
Gfx::PIndexBuffer getIndexBuffer() const { return indexBuffer; }
uint32* getIndexData() const { return indices.data(); }
Gfx::PDescriptorLayout getInstanceDataLayout() { return instanceDataLayout; }
Gfx::PDescriptorSet getInstanceDataSet() { return descriptorSet; }
const Array<MaterialData>& getMaterialData() const { return materialData; }
+138 -158
View File
@@ -1,19 +1,12 @@
#include "Buffer.h"
#include "Command.h"
#include "Enums.h"
#include "Graphics/Enums.h"
#include <vulkan/vulkan_core.h>
using namespace Seele;
using namespace Seele::Vulkan;
BufferAllocation::BufferAllocation(PGraphics graphics) : CommandBoundResource(graphics) {}
BufferAllocation::~BufferAllocation() {
if (buffer != VK_NULL_HANDLE) {
vmaDestroyBuffer(graphics->getAllocator(), buffer, allocation);
}
}
struct PendingBuffer {
OBufferAllocation allocation;
uint64 offset;
@@ -21,71 +14,30 @@ struct PendingBuffer {
bool writeOnly;
};
static Map<Vulkan::Buffer*, PendingBuffer> pendingBuffers;
static Map<BufferAllocation*, PendingBuffer> pendingBuffers;
Buffer::Buffer(PGraphics graphics, uint64 size, VkBufferUsageFlags usage, Gfx::QueueType& queueType, bool dynamic, std::string name)
: graphics(graphics), currentBuffer(0), owner(queueType),
usage(usage | VK_BUFFER_USAGE_TRANSFER_DST_BIT | VK_BUFFER_USAGE_TRANSFER_SRC_BIT | VK_BUFFER_USAGE_SHADER_DEVICE_ADDRESS_BIT), dynamic(dynamic), name(name) {
createBuffer(size);
}
Buffer::~Buffer() {
for (uint32 i = 0; i < buffers.size(); ++i) {
graphics->getDestructionManager()->queueResourceForDestruction(std::move(buffers[i]));
}
}
void Buffer::executeOwnershipBarrier(Gfx::QueueType newOwner) {
if (getSize() == 0)
return;
Gfx::QueueFamilyMapping mapping = graphics->getFamilyMapping();
VkBufferMemoryBarrier barrier = {
.sType = VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER,
BufferAllocation::BufferAllocation(PGraphics graphics, VkBufferCreateInfo bufferInfo, VmaAllocationCreateInfo allocInfo,
Gfx::QueueType owner)
: CommandBoundResource(graphics), size(bufferInfo.size), owner(owner) {
VK_CHECK(vmaCreateBuffer(graphics->getAllocator(), &bufferInfo, &allocInfo, &buffer, &allocation, nullptr));
vmaGetAllocationMemoryProperties(graphics->getAllocator(), allocation, &properties);
VkBufferDeviceAddressInfo addrInfo = {
.sType = VK_STRUCTURE_TYPE_BUFFER_DEVICE_ADDRESS_INFO_KHR,
.pNext = nullptr,
.srcQueueFamilyIndex = mapping.getQueueTypeFamilyIndex(owner),
.dstQueueFamilyIndex = mapping.getQueueTypeFamilyIndex(newOwner),
.buffer = getHandle(),
.offset = 0,
.size = getSize(),
.buffer = buffer,
};
PCommandPool sourcePool = graphics->getQueueCommands(owner);
PCommandPool dstPool = nullptr;
VkPipelineStageFlags srcStage = VK_PIPELINE_STAGE_ALL_COMMANDS_BIT;
VkPipelineStageFlags dstStage = VK_PIPELINE_STAGE_ALL_COMMANDS_BIT;
assert(barrier.srcQueueFamilyIndex != barrier.dstQueueFamilyIndex);
if (owner == Gfx::QueueType::TRANSFER) {
barrier.srcAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT;
srcStage = VK_PIPELINE_STAGE_TRANSFER_BIT;
} else if (owner == Gfx::QueueType::COMPUTE) {
barrier.srcAccessMask = VK_ACCESS_SHADER_WRITE_BIT;
srcStage = VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT;
} else if (owner == Gfx::QueueType::GRAPHICS) {
barrier.srcAccessMask = getSourceAccessMask();
srcStage = VK_PIPELINE_STAGE_ALL_GRAPHICS_BIT;
}
if (newOwner == Gfx::QueueType::TRANSFER) {
barrier.dstAccessMask = VK_ACCESS_TRANSFER_READ_BIT;
dstStage = VK_PIPELINE_STAGE_TRANSFER_BIT;
dstPool = graphics->getTransferCommands();
} else if (newOwner == Gfx::QueueType::COMPUTE) {
barrier.dstAccessMask = VK_ACCESS_SHADER_READ_BIT;
dstStage = VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT;
dstPool = graphics->getComputeCommands();
} else if (newOwner == Gfx::QueueType::GRAPHICS) {
barrier.dstAccessMask = getDestAccessMask();
dstStage = VK_PIPELINE_STAGE_ALL_GRAPHICS_BIT;
dstPool = graphics->getGraphicsCommands();
}
VkCommandBuffer srcCommand = sourcePool->getCommands()->getHandle();
VkCommandBuffer dstCommand = dstPool->getCommands()->getHandle();
vkCmdPipelineBarrier(srcCommand, srcStage, srcStage, 0, 0, nullptr, 1, &barrier, 0, nullptr);
vkCmdPipelineBarrier(dstCommand, dstStage, dstStage, 0, 0, nullptr, 1, &barrier, 0, nullptr);
sourcePool->submitCommands();
deviceAddress = vkGetBufferDeviceAddress(graphics->getDevice(), &addrInfo);
}
void Buffer::executePipelineBarrier(VkAccessFlags srcAccess, VkPipelineStageFlags srcStage, VkAccessFlags dstAccess,
VkPipelineStageFlags dstStage) {
if (getSize() == 0)
BufferAllocation::~BufferAllocation() {
if (buffer != VK_NULL_HANDLE) {
vmaDestroyBuffer(graphics->getAllocator(), buffer, allocation);
}
}
void BufferAllocation::pipelineBarrier(VkAccessFlags srcAccess, VkPipelineStageFlags srcStage, VkAccessFlags dstAccess,
VkPipelineStageFlags dstStage) {
if (size == 0)
return;
PCommand commandBuffer = graphics->getQueueCommands(owner)->getCommands();
VkBufferMemoryBarrier barrier = {
@@ -95,29 +47,49 @@ void Buffer::executePipelineBarrier(VkAccessFlags srcAccess, VkPipelineStageFlag
.dstAccessMask = dstAccess,
.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED,
.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED,
.buffer = getHandle(),
.buffer = buffer,
.offset = 0,
.size = getSize(),
.size = size,
};
vkCmdPipelineBarrier(commandBuffer->getHandle(), srcStage, dstStage, 0, 0, nullptr, 1, &barrier, 0, nullptr);
}
void* Buffer::map(bool writeOnly) { return mapRegion(0, getSize(), writeOnly); }
void BufferAllocation::transferOwnership(Gfx::QueueType newOwner) {
if (size == 0)
return;
Gfx::QueueFamilyMapping mapping = graphics->getFamilyMapping();
VkBufferMemoryBarrier barrier = {
.sType = VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER,
.pNext = nullptr,
.srcAccessMask = VK_ACCESS_MEMORY_READ_BIT | VK_ACCESS_MEMORY_WRITE_BIT,
.dstAccessMask = VK_ACCESS_MEMORY_READ_BIT | VK_ACCESS_MEMORY_WRITE_BIT,
.srcQueueFamilyIndex = mapping.getQueueTypeFamilyIndex(owner),
.dstQueueFamilyIndex = mapping.getQueueTypeFamilyIndex(newOwner),
.buffer = buffer,
.offset = 0,
.size = size,
};
PCommandPool sourcePool = graphics->getQueueCommands(owner);
PCommandPool dstPool = graphics->getQueueCommands(newOwner);
assert(barrier.srcQueueFamilyIndex != barrier.dstQueueFamilyIndex);
vkCmdPipelineBarrier(sourcePool->getCommands()->getHandle(), VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, 0,
0, nullptr, 1, &barrier, 0, nullptr);
vkCmdPipelineBarrier(dstPool->getCommands()->getHandle(), VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, 0, 0,
nullptr, 1, &barrier, 0, nullptr);
sourcePool->submitCommands();
owner = newOwner;
}
void* Buffer::mapRegion(uint64 regionOffset, uint64 regionSize, bool writeOnly) {
if (regionSize == 0)
return nullptr;
void* BufferAllocation::mapRegion(uint64 regionOffset, uint64 regionSize, bool writeOnly) {
void* data = nullptr;
PendingBuffer pending;
pending.allocation = new BufferAllocation(graphics);
pending.allocation->size = regionSize;
pending.writeOnly = writeOnly;
pending.prevQueue = owner;
pending.offset = regionOffset;
transferOwnership(Gfx::QueueType::TRANSFER);
if (writeOnly) {
if (buffers[currentBuffer]->properties & VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT) {
VK_CHECK(vmaMapMemory(graphics->getAllocator(), buffers[currentBuffer]->allocation, &data));
if (properties & VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT) {
VK_CHECK(vmaMapMemory(graphics->getAllocator(), allocation, &data));
} else {
VkBufferCreateInfo stagingInfo = {
.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,
@@ -132,8 +104,7 @@ void* Buffer::mapRegion(uint64 regionOffset, uint64 regionSize, bool writeOnly)
.usage = VMA_MEMORY_USAGE_AUTO,
.requiredFlags = VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT,
};
VK_CHECK(vmaCreateBuffer(graphics->getAllocator(), &stagingInfo, &allocInfo, &pending.allocation->buffer,
&pending.allocation->allocation, nullptr));
pending.allocation = new BufferAllocation(graphics, stagingInfo, allocInfo, Gfx::QueueType::TRANSFER);
vmaMapMemory(graphics->getAllocator(), pending.allocation->allocation, &data);
vmaSetAllocationName(graphics->getAllocator(), pending.allocation->allocation, "MappingStaging");
}
@@ -141,18 +112,16 @@ void* Buffer::mapRegion(uint64 regionOffset, uint64 regionSize, bool writeOnly)
assert(false);
}
pendingBuffers[this] = std::move(pending);
assert(data);
return data;
}
void Buffer::unmap() {
void BufferAllocation::unmap() {
auto found = pendingBuffers.find(this);
if (found != pendingBuffers.end()) {
PendingBuffer& pending = found->value;
if (pending.writeOnly) {
if (buffers[currentBuffer]->properties & VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT) {
vmaUnmapMemory(graphics->getAllocator(), buffers[currentBuffer]->allocation);
if (properties & VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT) {
vmaUnmapMemory(graphics->getAllocator(), allocation);
} else {
vmaFlushAllocation(graphics->getAllocator(), pending.allocation->allocation, 0, VK_WHOLE_SIZE);
vmaUnmapMemory(graphics->getAllocator(), pending.allocation->allocation);
@@ -172,13 +141,13 @@ void Buffer::unmap() {
.dstAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT,
.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED,
.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED,
.buffer = buffers[currentBuffer]->buffer,
.buffer = buffer,
.offset = 0,
.size = buffers[currentBuffer]->size,
.size = size,
};
vkCmdPipelineBarrier(cmdHandle, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, 0, 0, nullptr, 1,
&barrier, 0, nullptr);
vkCmdCopyBuffer(cmdHandle, pending.allocation->buffer, buffers[currentBuffer]->buffer, 1, &region);
vkCmdCopyBuffer(cmdHandle, pending.allocation->buffer, buffer, 1, &region);
barrier = {
.sType = VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER,
.pNext = nullptr,
@@ -186,34 +155,64 @@ void Buffer::unmap() {
.dstAccessMask = VK_ACCESS_MEMORY_READ_BIT,
.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED,
.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED,
.buffer = buffers[currentBuffer]->buffer,
.buffer = buffer,
.offset = 0,
.size = buffers[currentBuffer]->size,
.size = size,
};
vkCmdPipelineBarrier(cmdHandle, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, 0, 0, nullptr, 1,
&barrier, 0, nullptr);
graphics->getDestructionManager()->queueResourceForDestruction(std::move(pending.allocation));
}
}
transferOwnership(pending.prevQueue);
pendingBuffers.erase(this);
}
}
Buffer::Buffer(PGraphics graphics, uint64 size, VkBufferUsageFlags usage, Gfx::QueueType queueType, bool dynamic, std::string name)
: graphics(graphics), currentBuffer(0), initialOwner(queueType),
usage(usage | VK_BUFFER_USAGE_TRANSFER_DST_BIT | VK_BUFFER_USAGE_TRANSFER_SRC_BIT | VK_BUFFER_USAGE_SHADER_DEVICE_ADDRESS_BIT),
dynamic(dynamic), name(name) {
createBuffer(size);
}
Buffer::~Buffer() {
for (uint32 i = 0; i < buffers.size(); ++i) {
graphics->getDestructionManager()->queueResourceForDestruction(std::move(buffers[i]));
}
}
void* Buffer::map(bool writeOnly) { return mapRegion(0, getSize(), writeOnly); }
void* Buffer::mapRegion(uint64 regionOffset, uint64 regionSize, bool writeOnly) {
if (regionSize == 0)
return nullptr;
void* data = getAlloc()->mapRegion(regionOffset, regionSize, writeOnly);
assert(data);
return data;
}
void Buffer::unmap() { getAlloc()->unmap(); }
void Buffer::rotateBuffer(uint64 size, bool preserveContents) {
assert(dynamic);
size = std::max(getSize(), size);
for (size_t i = 0; i < buffers.size(); ++i) {
for (uint32 i = 0; i < buffers.size(); ++i) {
if (buffers[i]->isCurrentlyBound()) {
continue;
}
if (buffers[i]->size < size) {
vmaDestroyBuffer(graphics->getAllocator(), buffers[i]->buffer, buffers[i]->allocation);
uint32 family = graphics->getFamilyMapping().getQueueTypeFamilyIndex(initialOwner);
VkBufferCreateInfo info = {
.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,
.pNext = nullptr,
.flags = 0,
.size = size,
.usage = usage,
.sharingMode = VK_SHARING_MODE_EXCLUSIVE,
.queueFamilyIndexCount = 1,
.pQueueFamilyIndices = &family,
};
VmaAllocationCreateInfo allocInfo = {
.flags =
@@ -229,7 +228,7 @@ void Buffer::rotateBuffer(uint64 size, bool preserveContents) {
.objectType = VK_OBJECT_TYPE_BUFFER,
.objectHandle = (uint64)buffers[i]->buffer,
.pObjectName = this->name.c_str()};
graphics->vkSetDebugUtilsObjectNameEXT(&nameInfo);
vkSetDebugUtilsObjectNameEXT(graphics->getDevice(), &nameInfo);
}
buffers[i]->size = size;
}
@@ -247,36 +246,32 @@ void Buffer::rotateBuffer(uint64 size, bool preserveContents) {
}
void Buffer::createBuffer(uint64 size) {
uint32 family = graphics->getFamilyMapping().getQueueTypeFamilyIndex(initialOwner);
VkBufferCreateInfo info = {
.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,
.pNext = nullptr,
.flags = 0,
.size = size,
.usage = usage,
.sharingMode = VK_SHARING_MODE_EXCLUSIVE,
.queueFamilyIndexCount = 1,
.pQueueFamilyIndices = &family,
};
VmaAllocationCreateInfo allocInfo = {
.flags = VMA_ALLOCATION_CREATE_HOST_ACCESS_ALLOW_TRANSFER_INSTEAD_BIT | VMA_ALLOCATION_CREATE_HOST_ACCESS_SEQUENTIAL_WRITE_BIT,
.usage = VMA_MEMORY_USAGE_AUTO,
};
buffers.add(new BufferAllocation(graphics));
buffers.add(new BufferAllocation(graphics, info, allocInfo, initialOwner));
if (size > 0) {
VK_CHECK(vmaCreateBuffer(graphics->getAllocator(), &info, &allocInfo, &buffers.back()->buffer, &buffers.back()->allocation,
&buffers.back()->info));
buffers.back()->size = size;
vmaGetAllocationMemoryProperties(graphics->getAllocator(), buffers.back()->allocation, &buffers.back()->properties);
VkBufferDeviceAddressInfo addrInfo = {
.sType = VK_STRUCTURE_TYPE_BUFFER_DEVICE_ADDRESS_INFO_KHR,
.pNext = nullptr,
.buffer = buffers.back()->buffer,
};
buffers.back()->deviceAddress = vkGetBufferDeviceAddress(graphics->getDevice(), &addrInfo);
if (!name.empty()) {
VkDebugUtilsObjectNameInfoEXT nameInfo = {.sType = VK_STRUCTURE_TYPE_DEBUG_UTILS_OBJECT_NAME_INFO_EXT,
.pNext = nullptr,
.objectType = VK_OBJECT_TYPE_BUFFER,
.objectHandle = (uint64)buffers.back()->buffer,
.pObjectName = this->name.c_str()};
graphics->vkSetDebugUtilsObjectNameEXT(&nameInfo);
vkSetDebugUtilsObjectNameEXT(graphics->getDevice(), &nameInfo);
}
}
}
@@ -285,7 +280,7 @@ void Buffer::copyBuffer(uint64 src, uint64 dst) {
if (src == dst) {
return;
}
PCommand command = graphics->getQueueCommands(owner)->getCommands();
PCommand command = graphics->getQueueCommands(getAlloc()->owner)->getCommands();
VkBufferMemoryBarrier srcBarrier = {
.sType = VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER,
.pNext = nullptr,
@@ -316,10 +311,17 @@ void Buffer::copyBuffer(uint64 src, uint64 dst) {
&dstBarrier, 0, nullptr);
}
void Buffer::transferOwnership(Gfx::QueueType newOwner) { getAlloc()->transferOwnership(newOwner); }
void Buffer::pipelineBarrier(VkAccessFlags srcAccess, VkPipelineStageFlags srcStage, VkAccessFlags dstAccess,
VkPipelineStageFlags dstStage) {
getAlloc()->pipelineBarrier(srcAccess, srcStage, dstAccess, dstStage);
}
UniformBuffer::UniformBuffer(PGraphics graphics, const UniformBufferCreateInfo& createInfo)
: Gfx::UniformBuffer(graphics->getFamilyMapping(), createInfo.sourceData),
Vulkan::Buffer(graphics, createInfo.sourceData.size, VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT, currentOwner, createInfo.dynamic,
createInfo.name) {
: Gfx::UniformBuffer(graphics->getFamilyMapping(), createInfo),
Vulkan::Buffer(graphics, createInfo.sourceData.size, VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT, createInfo.sourceData.owner,
createInfo.dynamic, createInfo.name) {
if (getSize() > 0 && createInfo.sourceData.data != nullptr) {
void* data = map();
std::memcpy(data, createInfo.sourceData.data, createInfo.sourceData.size);
@@ -337,30 +339,24 @@ void UniformBuffer::updateContents(const DataSource& sourceData) {
void UniformBuffer::rotateBuffer(uint64 size) { Vulkan::Buffer::rotateBuffer(size); }
void UniformBuffer::requestOwnershipTransfer(Gfx::QueueType newOwner) { Gfx::QueueOwnedResource::transferOwnership(newOwner); }
void UniformBuffer::executeOwnershipBarrier(Gfx::QueueType newOwner) { Vulkan::Buffer::executeOwnershipBarrier(newOwner); }
void UniformBuffer::executeOwnershipBarrier(Gfx::QueueType newOwner) { Vulkan::Buffer::transferOwnership(newOwner); }
void UniformBuffer::executePipelineBarrier(VkAccessFlags srcAccess, VkPipelineStageFlags srcStage, VkAccessFlags dstAccess,
VkPipelineStageFlags dstStage) {
Vulkan::Buffer::executePipelineBarrier(srcAccess, srcStage, dstAccess, dstStage);
Vulkan::Buffer::pipelineBarrier(srcAccess, srcStage, dstAccess, dstStage);
}
VkAccessFlags UniformBuffer::getSourceAccessMask() { return VK_ACCESS_MEMORY_WRITE_BIT; }
VkAccessFlags UniformBuffer::getDestAccessMask() { return VK_ACCESS_UNIFORM_READ_BIT; }
ShaderBuffer::ShaderBuffer(PGraphics graphics, const ShaderBufferCreateInfo& sourceData)
: Gfx::ShaderBuffer(graphics->getFamilyMapping(), sourceData.numElements, sourceData.sourceData),
Vulkan::Buffer(graphics, sourceData.sourceData.size,
ShaderBuffer::ShaderBuffer(PGraphics graphics, const ShaderBufferCreateInfo& createInfo)
: Gfx::ShaderBuffer(graphics->getFamilyMapping(), createInfo),
Vulkan::Buffer(graphics, createInfo.sourceData.size,
VK_BUFFER_USAGE_STORAGE_BUFFER_BIT |
(sourceData.vertexBuffer ? VK_BUFFER_USAGE_ACCELERATION_STRUCTURE_BUILD_INPUT_READ_ONLY_BIT_KHR |
(createInfo.vertexBuffer ? VK_BUFFER_USAGE_ACCELERATION_STRUCTURE_BUILD_INPUT_READ_ONLY_BIT_KHR |
VK_BUFFER_USAGE_SHADER_DEVICE_ADDRESS_BIT
: 0),
currentOwner, sourceData.dynamic, sourceData.name) {
if (getSize() > 0 && sourceData.sourceData.data != nullptr) {
createInfo.sourceData.owner, createInfo.dynamic, createInfo.name) {
if (getSize() > 0 && createInfo.sourceData.data != nullptr) {
void* data = map();
std::memcpy(data, sourceData.sourceData.data, sourceData.sourceData.size);
std::memcpy(data, createInfo.sourceData.data, createInfo.sourceData.size);
unmap();
}
}
@@ -387,28 +383,24 @@ void* ShaderBuffer::mapRegion(uint64 offset, uint64 size, bool writeOnly) { retu
void ShaderBuffer::unmap() { Vulkan::Buffer::unmap(); }
void ShaderBuffer::clear() {
vkCmdFillBuffer(graphics->getQueueCommands(owner)->getCommands()->getHandle(), Vulkan::Buffer::getHandle(), 0, VK_WHOLE_SIZE, 0);
vkCmdFillBuffer(graphics->getQueueCommands(getAlloc()->owner)->getCommands()->getHandle(), Vulkan::Buffer::getHandle(), 0,
VK_WHOLE_SIZE, 0);
}
void ShaderBuffer::requestOwnershipTransfer(Gfx::QueueType newOwner) { Gfx::QueueOwnedResource::transferOwnership(newOwner); }
void ShaderBuffer::executeOwnershipBarrier(Gfx::QueueType newOwner) { Vulkan::Buffer::executeOwnershipBarrier(newOwner); }
void ShaderBuffer::executeOwnershipBarrier(Gfx::QueueType newOwner) { Vulkan::Buffer::transferOwnership(newOwner); }
void ShaderBuffer::executePipelineBarrier(VkAccessFlags srcAccess, VkPipelineStageFlags srcStage, VkAccessFlags dstAccess,
VkPipelineStageFlags dstStage) {
Vulkan::Buffer::executePipelineBarrier(srcAccess, srcStage, dstAccess, dstStage);
Vulkan::Buffer::pipelineBarrier(srcAccess, srcStage, dstAccess, dstStage);
}
VkAccessFlags ShaderBuffer::getSourceAccessMask() { return VK_ACCESS_MEMORY_WRITE_BIT; }
VkAccessFlags ShaderBuffer::getDestAccessMask() { return VK_ACCESS_MEMORY_READ_BIT; }
VertexBuffer::VertexBuffer(PGraphics graphics, const VertexBufferCreateInfo& sourceData)
: Gfx::VertexBuffer(graphics->getFamilyMapping(), sourceData.numVertices, sourceData.vertexSize, sourceData.sourceData.owner),
Vulkan::Buffer(graphics, sourceData.sourceData.size, VK_BUFFER_USAGE_VERTEX_BUFFER_BIT, currentOwner, false, sourceData.name) {
if (sourceData.sourceData.data != nullptr) {
VertexBuffer::VertexBuffer(PGraphics graphics, const VertexBufferCreateInfo& createInfo)
: Gfx::VertexBuffer(graphics->getFamilyMapping(), createInfo),
Vulkan::Buffer(graphics, createInfo.sourceData.size, VK_BUFFER_USAGE_VERTEX_BUFFER_BIT, createInfo.sourceData.owner, false,
createInfo.name) {
if (createInfo.sourceData.data != nullptr) {
void* data = map();
std::memcpy(data, sourceData.sourceData.data, sourceData.sourceData.size);
std::memcpy(data, createInfo.sourceData.data, createInfo.sourceData.size);
unmap();
}
}
@@ -428,28 +420,22 @@ void VertexBuffer::download(Array<uint8>& buffer) {
unmap();
}
void VertexBuffer::requestOwnershipTransfer(Gfx::QueueType newOwner) { Gfx::QueueOwnedResource::transferOwnership(newOwner); }
void VertexBuffer::executeOwnershipBarrier(Gfx::QueueType newOwner) { Vulkan::Buffer::executeOwnershipBarrier(newOwner); }
void VertexBuffer::executeOwnershipBarrier(Gfx::QueueType newOwner) { Vulkan::Buffer::transferOwnership(newOwner); }
void VertexBuffer::executePipelineBarrier(VkAccessFlags srcAccess, VkPipelineStageFlags srcStage, VkAccessFlags dstAccess,
VkPipelineStageFlags dstStage) {
Vulkan::Buffer::executePipelineBarrier(srcAccess, srcStage, dstAccess, dstStage);
Vulkan::Buffer::pipelineBarrier(srcAccess, srcStage, dstAccess, dstStage);
}
VkAccessFlags VertexBuffer::getSourceAccessMask() { return VK_ACCESS_MEMORY_WRITE_BIT; }
VkAccessFlags VertexBuffer::getDestAccessMask() { return VK_ACCESS_VERTEX_ATTRIBUTE_READ_BIT; }
IndexBuffer::IndexBuffer(PGraphics graphics, const IndexBufferCreateInfo& sourceData)
: Gfx::IndexBuffer(graphics->getFamilyMapping(), sourceData.sourceData.size, sourceData.indexType, sourceData.sourceData.owner),
Vulkan::Buffer(graphics, sourceData.sourceData.size,
IndexBuffer::IndexBuffer(PGraphics graphics, const IndexBufferCreateInfo& createInfo)
: Gfx::IndexBuffer(graphics->getFamilyMapping(), createInfo),
Vulkan::Buffer(graphics, createInfo.sourceData.size,
VK_BUFFER_USAGE_INDEX_BUFFER_BIT | VK_BUFFER_USAGE_ACCELERATION_STRUCTURE_BUILD_INPUT_READ_ONLY_BIT_KHR |
VK_BUFFER_USAGE_SHADER_DEVICE_ADDRESS_BIT,
currentOwner, false, sourceData.name) {
if (sourceData.sourceData.data != nullptr) {
createInfo.sourceData.owner, false, createInfo.name) {
if (createInfo.sourceData.data != nullptr) {
void* data = map();
std::memcpy(data, sourceData.sourceData.data, sourceData.sourceData.size);
std::memcpy(data, createInfo.sourceData.data, createInfo.sourceData.size);
unmap();
}
}
@@ -463,15 +449,9 @@ void IndexBuffer::download(Array<uint8>& buffer) {
unmap();
}
void IndexBuffer::requestOwnershipTransfer(Gfx::QueueType newOwner) { Gfx::QueueOwnedResource::transferOwnership(newOwner); }
void IndexBuffer::executeOwnershipBarrier(Gfx::QueueType newOwner) { Vulkan::Buffer::executeOwnershipBarrier(newOwner); }
void IndexBuffer::executeOwnershipBarrier(Gfx::QueueType newOwner) { Vulkan::Buffer::transferOwnership(newOwner); }
void IndexBuffer::executePipelineBarrier(VkAccessFlags srcAccess, VkPipelineStageFlags srcStage, VkAccessFlags dstAccess,
VkPipelineStageFlags dstStage) {
Vulkan::Buffer::executePipelineBarrier(srcAccess, srcStage, dstAccess, dstStage);
Vulkan::Buffer::pipelineBarrier(srcAccess, srcStage, dstAccess, dstStage);
}
VkAccessFlags IndexBuffer::getSourceAccessMask() { return VK_ACCESS_MEMORY_WRITE_BIT; }
VkAccessFlags IndexBuffer::getDestAccessMask() { return VK_ACCESS_INDEX_READ_BIT; }
+12 -26
View File
@@ -1,6 +1,7 @@
#pragma once
#include "Graphics.h"
#include "Graphics/Buffer.h"
#include "Graphics/Enums.h"
#include "Resources.h"
namespace Seele {
@@ -9,19 +10,25 @@ DECLARE_REF(Command)
DECLARE_REF(Fence)
class BufferAllocation : public CommandBoundResource {
public:
BufferAllocation(PGraphics graphics);
BufferAllocation(PGraphics graphics, VkBufferCreateInfo bufferInfo, VmaAllocationCreateInfo allocInfo, Gfx::QueueType owner);
virtual ~BufferAllocation();
void pipelineBarrier(VkAccessFlags srcAccess, VkPipelineStageFlags srcStage, VkAccessFlags dstAccess,
VkPipelineStageFlags dstStage);
void transferOwnership(Gfx::QueueType newOwner);
void* mapRegion(uint64 regionOffset, uint64 regionSize, bool writeOnly = true);
void unmap();
VkBuffer buffer = VK_NULL_HANDLE;
VmaAllocation allocation = VmaAllocation();
VmaAllocationInfo info = VmaAllocationInfo();
VkMemoryPropertyFlags properties = 0;
uint64 size = 0;
VkDeviceAddress deviceAddress;
Gfx::QueueType owner;
};
DEFINE_REF(BufferAllocation);
class Buffer {
public:
Buffer(PGraphics graphics, uint64 size, VkBufferUsageFlags usage, Gfx::QueueType& queueType, bool dynamic, std::string name);
Buffer(PGraphics graphics, uint64 size, VkBufferUsageFlags usage, Gfx::QueueType initialOwner, bool dynamic, std::string name);
virtual ~Buffer();
VkBuffer getHandle() const { return buffers[currentBuffer]->buffer; }
VkDeviceAddress getDeviceAddress() const { return buffers[currentBuffer]->deviceAddress; }
@@ -34,7 +41,7 @@ class Buffer {
protected:
PGraphics graphics;
uint32 currentBuffer;
Gfx::QueueType& owner;
Gfx::QueueType initialOwner;
Array<OBufferAllocation> buffers;
VkBufferUsageFlags usage;
bool dynamic;
@@ -43,14 +50,9 @@ class Buffer {
void createBuffer(uint64 size);
void copyBuffer(uint64 src, uint64 dest);
void executeOwnershipBarrier(Gfx::QueueType newOwner);
void executePipelineBarrier(VkAccessFlags srcAccess, VkPipelineStageFlags srcStage, VkAccessFlags dstAccess,
void transferOwnership(Gfx::QueueType newOwner);
void pipelineBarrier(VkAccessFlags srcAccess, VkPipelineStageFlags srcStage, VkAccessFlags dstAccess,
VkPipelineStageFlags dstStage);
virtual void requestOwnershipTransfer(Gfx::QueueType newOwner) = 0;
virtual VkAccessFlags getSourceAccessMask() = 0;
virtual VkAccessFlags getDestAccessMask() = 0;
};
DEFINE_REF(Buffer)
@@ -63,10 +65,6 @@ class VertexBuffer : public Gfx::VertexBuffer, public Buffer {
virtual void download(Array<uint8>& buffer) override;
protected:
// Inherited via Vulkan::Buffer
virtual VkAccessFlags getSourceAccessMask() override;
virtual VkAccessFlags getDestAccessMask() override;
virtual void requestOwnershipTransfer(Gfx::QueueType newOwner) override;
// Inherited via QueueOwnedResource
virtual void executeOwnershipBarrier(Gfx::QueueType newOwner) override;
virtual void executePipelineBarrier(Gfx::SeAccessFlags srcAccess, Gfx::SePipelineStageFlags srcStage, Gfx::SeAccessFlags dstAccess,
@@ -82,10 +80,6 @@ class IndexBuffer : public Gfx::IndexBuffer, public Buffer {
virtual void download(Array<uint8>& buffer) override;
protected:
// Inherited via Vulkan::Buffer
virtual VkAccessFlags getSourceAccessMask() override;
virtual VkAccessFlags getDestAccessMask() override;
virtual void requestOwnershipTransfer(Gfx::QueueType newOwner) override;
// Inherited via QueueOwnedResource
virtual void executeOwnershipBarrier(Gfx::QueueType newOwner) override;
virtual void executePipelineBarrier(Gfx::SeAccessFlags srcAccess, Gfx::SePipelineStageFlags srcStage, Gfx::SeAccessFlags dstAccess,
@@ -100,10 +94,6 @@ class UniformBuffer : public Gfx::UniformBuffer, public Buffer {
virtual void rotateBuffer(uint64 size) override;
protected:
// Inherited via Vulkan::Buffer
virtual VkAccessFlags getSourceAccessMask() override;
virtual VkAccessFlags getDestAccessMask() override;
virtual void requestOwnershipTransfer(Gfx::QueueType newOwner) override;
// Inherited via QueueOwnedResource
virtual void executeOwnershipBarrier(Gfx::QueueType newOwner) override;
virtual void executePipelineBarrier(Gfx::SeAccessFlags srcAccess, Gfx::SePipelineStageFlags srcStage, Gfx::SeAccessFlags dstAccess,
@@ -125,10 +115,6 @@ class ShaderBuffer : public Gfx::ShaderBuffer, public Buffer {
virtual void clear() override;
protected:
// Inherited via Vulkan::Buffer
virtual VkAccessFlags getSourceAccessMask() override;
virtual VkAccessFlags getDestAccessMask() override;
virtual void requestOwnershipTransfer(Gfx::QueueType newOwner) override;
// Inherited via QueueOwnedResource
virtual void executeOwnershipBarrier(Gfx::QueueType newOwner) override;
virtual void executePipelineBarrier(Gfx::SeAccessFlags srcAccess, Gfx::SePipelineStageFlags srcStage, Gfx::SeAccessFlags dstAccess,
+2 -2
View File
@@ -302,12 +302,12 @@ void RenderCommand::drawIndexed(uint32 indexCount, uint32 instanceCount, int32 f
}
void RenderCommand::drawMesh(uint32 groupX, uint32 groupY, uint32 groupZ) {
assert(threadId == std::this_thread::get_id());
graphics->vkCmdDrawMeshTasksEXT(handle, groupX, groupY, groupZ);
vkCmdDrawMeshTasksEXT(handle, groupX, groupY, groupZ);
}
void RenderCommand::drawMeshIndirect(Gfx::PShaderBuffer buffer, uint64 offset, uint32 drawCount, uint32 stride) {
assert(threadId == std::this_thread::get_id());
graphics->vkCmdDrawMeshTasksIndirectEXT(handle, buffer.cast<ShaderBuffer>()->getHandle(), offset, drawCount, stride);
vkCmdDrawMeshTasksIndirectEXT(handle, buffer.cast<ShaderBuffer>()->getHandle(), offset, drawCount, stride);
}
ComputeCommand::ComputeCommand(PGraphics graphics, VkCommandPool cmdPool) : graphics(graphics), owner(cmdPool) {
+88 -42
View File
@@ -9,10 +9,10 @@
#include "Graphics/Graphics.h"
#include "Graphics/Initializer.h"
#include "PipelineCache.h"
#include "Query.h"
#include "RayTracing.h"
#include "RenderPass.h"
#include "Shader.h"
#include "Query.h"
#include "Window.h"
#include <GLFW/glfw3.h>
#include <cstring>
@@ -28,6 +28,42 @@ thread_local PCommandPool Seele::Vulkan::Graphics::graphicsCommands = nullptr;
thread_local PCommandPool Seele::Vulkan::Graphics::computeCommands = nullptr;
thread_local PCommandPool Seele::Vulkan::Graphics::transferCommands = nullptr;
PFN_vkCmdDrawMeshTasksEXT cmdDrawMeshTasks;
PFN_vkCmdDrawMeshTasksIndirectEXT cmdDrawMeshTasksIndirect;
PFN_vkSetDebugUtilsObjectNameEXT setDebugUtilsObjectName;
PFN_vkCreateAccelerationStructureKHR createAccelerationStructure;
PFN_vkCmdBuildAccelerationStructuresKHR cmdBuildAccelerationStructures;
PFN_vkGetAccelerationStructureBuildSizesKHR getAccelerationStructureBuildSize;
void vkCmdDrawMeshTasksEXT(VkCommandBuffer command, uint32 groupX, uint32 groupY, uint32 groupZ) {
cmdDrawMeshTasks(command, groupX, groupY, groupZ);
}
void vkCmdDrawMeshTasksIndirectEXT(VkCommandBuffer commandBuffer, VkBuffer buffer, VkDeviceSize offset, uint32_t drawCount,
uint32_t stride) {
cmdDrawMeshTasksIndirect(commandBuffer, buffer, offset, drawCount, stride);
}
VkResult vkSetDebugUtilsObjectNameEXT(VkDevice device, const VkDebugUtilsObjectNameInfoEXT* pNameInfo) {
return setDebugUtilsObjectName(device, pNameInfo);
}
VkResult vkCreateAccelerationStructureKHR(VkDevice device, const VkAccelerationStructureCreateInfoKHR* pCreateInfo,
const VkAllocationCallbacks* pAllocator, VkAccelerationStructureKHR* pAccelerationStructure) {
return createAccelerationStructure(device, pCreateInfo, pAllocator, pAccelerationStructure);
}
void vkCmdBuildAccelerationStructuresKHR(VkCommandBuffer commandBuffer, uint32_t infoCount,
const VkAccelerationStructureBuildGeometryInfoKHR* pInfos,
const VkAccelerationStructureBuildRangeInfoKHR* const* ppBuildRangeInfos) {
cmdBuildAccelerationStructures(commandBuffer, infoCount, pInfos, ppBuildRangeInfos);
}
void vkGetAccelerationStructureBuildSizesKHR(VkDevice device, VkAccelerationStructureBuildTypeKHR buildType,
const VkAccelerationStructureBuildGeometryInfoKHR* pBuildInfo,
const uint32_t* pMaxPrimitiveCounts, VkAccelerationStructureBuildSizesInfoKHR* pSizeInfo) {
getAccelerationStructureBuildSize(device, buildType, pBuildInfo, pMaxPrimitiveCounts, pSizeInfo);
}
Graphics::Graphics() : instance(VK_NULL_HANDLE), handle(VK_NULL_HANDLE), physicalDevice(VK_NULL_HANDLE), callback(VK_NULL_HANDLE) {}
Graphics::~Graphics() {
@@ -95,9 +131,7 @@ void Graphics::beginRenderPass(Gfx::PRenderPass renderPass) {
getGraphicsCommands()->getCommands()->beginRenderPass(rp, framebuffer);
}
void Graphics::endRenderPass() {
getGraphicsCommands()->getCommands()->endRenderPass();
}
void Graphics::endRenderPass() { getGraphicsCommands()->getCommands()->endRenderPass(); }
void Graphics::waitDeviceIdle() { vkDeviceWaitIdle(handle); }
@@ -241,13 +275,25 @@ void Graphics::resolveTexture(Gfx::PTexture source, Gfx::PTexture destination) {
void Graphics::copyTexture(Gfx::PTexture source, Gfx::PTexture destination) {
PTextureBase src = source.cast<TextureBase>();
PTextureBase dst = destination.cast<TextureBase>();
VkImageBlit blit = {.srcSubresource = {.aspectMask = src->getAspect(), .mipLevel = 0, .baseArrayLayer = 0, .layerCount = 1},
VkImageBlit blit = {.srcSubresource =
{
.aspectMask = src->getAspect(),
.mipLevel = 0,
.baseArrayLayer = 0,
.layerCount = 1,
},
.srcOffsets =
{
{0, 0, 0},
{(int32)src->getWidth(), (int32)src->getHeight(), (int32)src->getDepth()},
},
.dstSubresource = {.aspectMask = dst->aspect, .mipLevel = 0, .baseArrayLayer = 0, .layerCount = 1},
.dstSubresource =
{
.aspectMask = dst->getAspect(),
.mipLevel = 0,
.baseArrayLayer = 0,
.layerCount = 1,
},
.dstOffsets = {
{0, 0, 0},
{(int32)dst->getWidth(), (int32)dst->getHeight(), (int32)dst->getDepth()},
@@ -255,7 +301,7 @@ void Graphics::copyTexture(Gfx::PTexture source, Gfx::PTexture destination) {
PCommand command = getGraphicsCommands()->getCommands();
vkCmdBlitImage(command->getHandle(), src->getImage(), VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, dst->getImage(),
VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1, &blit,
src->aspect & VK_IMAGE_ASPECT_DEPTH_BIT ? VK_FILTER_NEAREST : VK_FILTER_LINEAR);
src->getAspect() & VK_IMAGE_ASPECT_DEPTH_BIT ? VK_FILTER_NEAREST : VK_FILTER_LINEAR);
}
Gfx::OBottomLevelAS Graphics::createBottomLevelAccelerationStructure(const Gfx::BottomLevelASCreateInfo& createInfo) {
@@ -266,16 +312,6 @@ Gfx::OTopLevelAS Graphics::createTopLevelAccelerationStructure(const Gfx::TopLev
return new TopLevelAS(this, createInfo);
}
void Graphics::vkCmdDrawMeshTasksEXT(VkCommandBuffer cmd, uint32 groupX, uint32 groupY, uint32 groupZ) {
cmdDrawMeshTasks(cmd, groupX, groupY, groupZ);
}
void Graphics::vkCmdDrawMeshTasksIndirectEXT(VkCommandBuffer cmd, VkBuffer buffer, uint64 offset, uint32 drawCount, uint32 stride) {
cmdDrawMeshTasksIndirect(cmd, buffer, offset, drawCount, stride);
}
void Graphics::vkSetDebugUtilsObjectNameEXT(VkDebugUtilsObjectNameInfoEXT* info) { VK_CHECK(setDebugUtilsObjectName(handle, info)); }
PCommandPool Graphics::getQueueCommands(Gfx::QueueType queueType) {
switch (queueType) {
case Gfx::QueueType::GRAPHICS:
@@ -394,20 +430,9 @@ void Graphics::pickPhysicalDevice() {
vkEnumeratePhysicalDevices(instance, &physicalDeviceCount, physicalDevices.data());
VkPhysicalDevice bestDevice = VK_NULL_HANDLE;
uint32 deviceRating = 0;
features.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FEATURES_2;
features.pNext = &robustness;
robustness.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_ROBUSTNESS_2_FEATURES_EXT;
robustness.pNext = &features11;
features11.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_1_FEATURES;
features11.pNext = &features12;
features12.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_2_FEATURES;
features12.pNext = &features13;
features13.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_3_FEATURES;
features13.pNext = nullptr;
for (auto dev : physicalDevices) {
uint32 currentRating = 0;
vkGetPhysicalDeviceProperties(dev, &props);
vkGetPhysicalDeviceFeatures2(dev, &features);
if (props.deviceType == VK_PHYSICAL_DEVICE_TYPE_DISCRETE_GPU) {
std::cout << "found dedicated gpu " << props.deviceName << std::endl;
currentRating += 100;
@@ -424,9 +449,29 @@ void Graphics::pickPhysicalDevice() {
physicalDevice = bestDevice;
vkGetPhysicalDeviceProperties(physicalDevice, &props);
vkGetPhysicalDeviceFeatures2(physicalDevice, &features);
features.features.robustBufferAccess = 0;
features.features.inheritedQueries = true;
acceleration = {
.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_ACCELERATION_STRUCTURE_FEATURES_KHR,
.pNext = nullptr,
.accelerationStructure = true,
};
meshShaderFeatures = {
.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MESH_SHADER_FEATURES_EXT,
.pNext = &acceleration,
.taskShader = true,
.meshShader = true,
.meshShaderQueries = true,
};
features12 = {
.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_2_FEATURES,
.pNext = &meshShaderFeatures,
.bufferDeviceAddress = true,
};
features = {.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FEATURES_2,
.pNext = &features12,
.features = {
.occlusionQueryPrecise = true,
.inheritedQueries = true,
}};
if (Gfx::useMeshShading) {
uint32 count = 0;
vkEnumerateDeviceExtensionProperties(physicalDevice, NULL, &count, nullptr);
@@ -508,14 +553,8 @@ void Graphics::createDevice(GraphicsInitializer initializer) {
*currentPriority++ = 1.0f;
}
}
VkPhysicalDeviceMeshShaderFeaturesEXT enabledMeshShaderFeatures = {
.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MESH_SHADER_FEATURES_EXT,
.pNext = nullptr,
.taskShader = VK_TRUE,
.meshShader = VK_TRUE,
};
if (supportMeshShading()) {
features12.pNext = &enabledMeshShaderFeatures;
initializer.deviceExtensions.add(VK_EXT_MESH_SHADER_EXTENSION_NAME);
}
#ifdef __APPLE__
@@ -525,19 +564,17 @@ void Graphics::createDevice(GraphicsInitializer initializer) {
initializer.deviceExtensions.add(VK_KHR_ACCELERATION_STRUCTURE_EXTENSION_NAME);
VkDeviceCreateInfo deviceInfo = {
.sType = VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO,
.pNext = &features11,
.pNext = &features,
.queueCreateInfoCount = (uint32)queueInfos.size(),
.pQueueCreateInfos = queueInfos.data(),
.enabledExtensionCount = (uint32)initializer.deviceExtensions.size(),
.ppEnabledExtensionNames = initializer.deviceExtensions.data(),
.pEnabledFeatures = &features.features,
.pEnabledFeatures = nullptr,
};
VK_CHECK(vkCreateDevice(physicalDevice, &deviceInfo, nullptr, &handle));
// std::cout << "Vulkan handle: " << handle << std::endl;
cmdDrawMeshTasks = (PFN_vkCmdDrawMeshTasksEXT)vkGetDeviceProcAddr(handle, "vkCmdDrawMeshTasksEXT");
graphicsQueue = 0;
computeQueue = 0;
transferQueue = 0;
@@ -554,5 +591,14 @@ void Graphics::createDevice(GraphicsInitializer initializer) {
queueMapping.graphicsFamily = queues[graphicsQueue]->getFamilyIndex();
queueMapping.computeFamily = queues[computeQueue]->getFamilyIndex();
queueMapping.transferFamily = queues[transferQueue]->getFamilyIndex();
cmdDrawMeshTasks = (PFN_vkCmdDrawMeshTasksEXT)vkGetDeviceProcAddr(handle, "vkCmdDrawMeshTasksEXT");
cmdDrawMeshTasksIndirect = (PFN_vkCmdDrawMeshTasksIndirectEXT)vkGetDeviceProcAddr(handle, "vkCmdDrawMeshTasksIndirectEXT");
setDebugUtilsObjectName = (PFN_vkSetDebugUtilsObjectNameEXT)vkGetInstanceProcAddr(instance, "vkSetDebugUtilsObjectNameEXT");
createAccelerationStructure = (PFN_vkCreateAccelerationStructureKHR)vkGetDeviceProcAddr(handle, "vkCreateAccelerationStructureKHR");
cmdBuildAccelerationStructures =
(PFN_vkCmdBuildAccelerationStructuresKHR)vkGetDeviceProcAddr(handle, "vkCmdBuildAccelerationStructuresKHR");
getAccelerationStructureBuildSize =
(PFN_vkGetAccelerationStructureBuildSizesKHR)vkGetDeviceProcAddr(handle, "vkGetAccelerationStructureBuildSizesKHR");
}
+2 -10
View File
@@ -74,14 +74,7 @@ class Graphics : public Gfx::Graphics {
virtual Gfx::OBottomLevelAS createBottomLevelAccelerationStructure(const Gfx::BottomLevelASCreateInfo& createInfo) override;
virtual Gfx::OTopLevelAS createTopLevelAccelerationStructure(const Gfx::TopLevelASCreateInfo& createInfo) override;
void vkCmdDrawMeshTasksEXT(VkCommandBuffer handle, uint32 groupX, uint32 groupY, uint32 groupZ);
void vkCmdDrawMeshTasksIndirectEXT(VkCommandBuffer handle, VkBuffer buffer, uint64 offset, uint32 drawCount, uint32 stride);
void vkSetDebugUtilsObjectNameEXT(VkDebugUtilsObjectNameInfoEXT* info);
protected:
PFN_vkCmdDrawMeshTasksEXT cmdDrawMeshTasks;
PFN_vkCmdDrawMeshTasksIndirectEXT cmdDrawMeshTasksIndirect;
PFN_vkSetDebugUtilsObjectNameEXT setDebugUtilsObjectName;
Array<const char*> getRequiredExtensions();
void initInstance(GraphicsInitializer initInfo);
void setupDebugCallback();
@@ -103,10 +96,9 @@ class Graphics : public Gfx::Graphics {
Array<OCommandPool> pools;
VkPhysicalDeviceProperties props;
VkPhysicalDeviceFeatures2 features;
VkPhysicalDeviceVulkan11Features features11;
VkPhysicalDeviceVulkan12Features features12;
VkPhysicalDeviceVulkan13Features features13;
VkPhysicalDeviceRobustness2FeaturesEXT robustness;
VkPhysicalDeviceMeshShaderFeaturesEXT meshShaderFeatures;
VkPhysicalDeviceAccelerationStructureFeaturesKHR acceleration;
VkDebugUtilsMessengerEXT callback;
Map<uint32, OFramebuffer> allocatedFramebuffers;
VmaAllocator allocator;
+101 -15
View File
@@ -1,6 +1,10 @@
#include "RayTracing.h"
#include "Buffer.h"
#include "Command.h"
#include "Enums.h"
#include "Graphics/Buffer.h"
#include "Graphics/Enums.h"
#include "Graphics/Graphics.h"
#include "Graphics/Initializer.h"
#include "Graphics/Mesh.h"
#include "Graphics/VertexData.h"
@@ -10,15 +14,37 @@ using namespace Seele::Vulkan;
BottomLevelAS::BottomLevelAS(PGraphics graphics, const Gfx::BottomLevelASCreateInfo& createInfo) : graphics(graphics) {
VertexData* vertexData = createInfo.mesh->vertexData;
MeshData meshData = vertexData->getMeshData(createInfo.mesh->id);
Gfx::PShaderBuffer positionBuffer = vertexData->getPositionBuffer();
Gfx::PIndexBuffer indexBuffer = vertexData->getIndexBuffer();
VkDeviceOrHostAddressConstKHR vertexDataDeviceAddress = {
.deviceAddress = positionBuffer.cast<Buffer>()->getDeviceAddress(),
VkTransformMatrixKHR matrix = {
createInfo.mesh->transform[0][0], createInfo.mesh->transform[1][0], createInfo.mesh->transform[2][0],
createInfo.mesh->transform[3][0], createInfo.mesh->transform[0][1], createInfo.mesh->transform[1][1],
createInfo.mesh->transform[2][1], createInfo.mesh->transform[3][1], createInfo.mesh->transform[0][2],
createInfo.mesh->transform[1][2], createInfo.mesh->transform[2][2], createInfo.mesh->transform[3][2],
};
VkDeviceOrHostAddressConstKHR indexDataDeviceAddress = {
.deviceAddress = indexBuffer.cast<Buffer>()->getDeviceAddress(),
VkBufferCreateInfo transformBufferInfo = {
.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,
.pNext = nullptr,
.flags = 0,
.size = sizeof(VkTransformMatrixKHR),
.usage = VK_BUFFER_USAGE_STORAGE_BUFFER_BIT | VK_BUFFER_USAGE_SHADER_DEVICE_ADDRESS_BIT,
};
VkAccelerationStructureGeometryKHR accelerationStructureGeometry = {
VmaAllocationCreateInfo transformAllocInfo = {
.flags = VMA_ALLOCATION_CREATE_HOST_ACCESS_ALLOW_TRANSFER_INSTEAD_BIT | VMA_ALLOCATION_CREATE_HOST_ACCESS_SEQUENTIAL_WRITE_BIT,
.usage = VMA_MEMORY_USAGE_AUTO,
};
OBufferAllocation transformBuffer = new BufferAllocation(graphics, transformBufferInfo, transformAllocInfo, Gfx::QueueType::GRAPHICS);
VkDeviceOrHostAddressConstKHR vertexDataAddress = {
.deviceAddress = positionBuffer.cast<ShaderBuffer>()->getDeviceAddress() + vertexData->getMeshOffset(createInfo.mesh->id),
};
VkDeviceOrHostAddressConstKHR indexDataAddress = {
.deviceAddress = indexBuffer.cast<ShaderBuffer>()->getDeviceAddress() + meshData.firstIndex,
};
VkDeviceOrHostAddressConstKHR transformDataAddress = {
.deviceAddress = transformBuffer->deviceAddress,
};
VkAccelerationStructureGeometryKHR geometry = {
.sType = VK_STRUCTURE_TYPE_ACCELERATION_STRUCTURE_GEOMETRY_KHR,
.pNext = nullptr,
.geometryType = VK_GEOMETRY_TYPE_TRIANGLES_KHR,
@@ -27,32 +53,92 @@ BottomLevelAS::BottomLevelAS(PGraphics graphics, const Gfx::BottomLevelASCreateI
.sType = VK_STRUCTURE_TYPE_ACCELERATION_STRUCTURE_GEOMETRY_TRIANGLES_DATA_KHR,
.pNext = nullptr,
.vertexFormat = VK_FORMAT_R32G32B32_SFLOAT,
.vertexData = vertexDataDeviceAddress,
.vertexData = vertexDataAddress,
.vertexStride = sizeof(Vector),
.maxVertex = static_cast<uint32_t>(createInfo.mesh->vertexCount),
.indexType = VK_INDEX_TYPE_UINT32,
.indexData = indexDataDeviceAddress,
.indexData = indexDataAddress,
.transformData = transformDataAddress,
}},
.flags = VK_GEOMETRY_OPAQUE_BIT_KHR,
};
VkAccelerationStructureBuildRangeInfoKHR buildRangeInfo = {.primitiveCount = static_cast<uint32_t>(createInfo.mesh->indices.size()),
.primitiveOffset = 0,
.firstVertex = 0,
.transformOffset = 0};
VkAccelerationStructureBuildGeometryInfoKHR buildGeometry = {
VkAccelerationStructureBuildGeometryInfoKHR structureBuildGeometry = {
.sType = VK_STRUCTURE_TYPE_ACCELERATION_STRUCTURE_BUILD_GEOMETRY_INFO_KHR,
.pNext = nullptr,
.type = VK_ACCELERATION_STRUCTURE_TYPE_BOTTOM_LEVEL_KHR,
.flags = VK_BUILD_ACCELERATION_STRUCTURE_PREFER_FAST_TRACE_BIT_KHR,
.geometryCount = 1,
.pGeometries = &geometry,
};
VkAccelerationStructureCreateInfoKHR info = {
const uint32 primitiveCount = 1;
VkAccelerationStructureBuildSizesInfoKHR buildSizesInfo = {
.sType = VK_STRUCTURE_TYPE_ACCELERATION_STRUCTURE_BUILD_SIZES_INFO_KHR,
.pNext = nullptr,
};
vkGetAccelerationStructureBuildSizesKHR(graphics->getDevice(), VK_ACCELERATION_STRUCTURE_BUILD_TYPE_HOST_KHR, &structureBuildGeometry,
&primitiveCount, &buildSizesInfo);
VkBufferCreateInfo tempBufferInfo = {
.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,
.pNext = nullptr,
.flags = 0,
.size = buildSizesInfo.accelerationStructureSize,
.usage = VK_BUFFER_USAGE_ACCELERATION_STRUCTURE_STORAGE_BIT_KHR | VK_BUFFER_USAGE_SHADER_DEVICE_ADDRESS_BIT,
};
VmaAllocationCreateInfo tempBufferAllocInfo = {
.usage = VMA_MEMORY_USAGE_AUTO,
};
OBufferAllocation tempAlloc = new BufferAllocation(graphics, tempBufferInfo, tempBufferAllocInfo, Gfx::QueueType::GRAPHICS);
VkAccelerationStructureCreateInfoKHR tempInfo = {
.sType = VK_STRUCTURE_TYPE_ACCELERATION_STRUCTURE_CREATE_INFO_KHR,
.pNext = nullptr,
.createFlags = 0,
.buffer = tempAlloc->buffer,
.offset = 0,
.size = buildSizesInfo.accelerationStructureSize,
.type = VK_ACCELERATION_STRUCTURE_TYPE_BOTTOM_LEVEL_KHR,
};
VkAccelerationStructureKHR tempAS;
VK_CHECK(vkCreateAccelerationStructureKHR(graphics->getDevice(), &tempInfo, nullptr, &tempAS));
VkBufferCreateInfo scratchInfo = {
.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,
.pNext = nullptr,
.flags = 0,
.size = buildSizesInfo.buildScratchSize,
.usage = VK_BUFFER_USAGE_STORAGE_BUFFER_BIT | VK_BUFFER_USAGE_SHADER_DEVICE_ADDRESS_BIT,
};
VmaAllocationCreateInfo scratchAllocInfo = {
.usage = VMA_MEMORY_USAGE_AUTO,
};
OBufferAllocation scratchAlloc = new BufferAllocation(graphics, scratchInfo, scratchAllocInfo, Gfx::QueueType::GRAPHICS);
VkAccelerationStructureBuildGeometryInfoKHR buildGeometry = {.sType = VK_STRUCTURE_TYPE_ACCELERATION_STRUCTURE_BUILD_GEOMETRY_INFO_KHR,
.pNext = nullptr,
.type = VK_ACCELERATION_STRUCTURE_TYPE_BOTTOM_LEVEL_KHR,
.flags = VK_BUILD_ACCELERATION_STRUCTURE_PREFER_FAST_TRACE_BIT_KHR,
.mode = VK_BUILD_ACCELERATION_STRUCTURE_MODE_BUILD_KHR,
.dstAccelerationStructure = tempAS,
.geometryCount = 1,
.pGeometries = &geometry,
.scratchData = {.deviceAddress = scratchAlloc->deviceAddress}};
VkAccelerationStructureBuildRangeInfoKHR buildRangeInfo = {
.primitiveCount = meshData.numIndices / 3, .primitiveOffset = 0, .firstVertex = 0, .transformOffset = 0};
Array<VkAccelerationStructureBuildRangeInfoKHR*> ranges = {&buildRangeInfo};
PCommand cmd = graphics->getGraphicsCommands()->getCommands();
vkCmdBuildAccelerationStructuresKHR(cmd->getHandle(), 1, &buildGeometry, ranges.data());
cmd->bindResource(PBufferAllocation(transformBuffer));
cmd->bindResource(PBufferAllocation(tempAlloc));
cmd->bindResource(PBufferAllocation(scratchAlloc));
graphics->getDestructionManager()->queueResourceForDestruction(std::move(transformBuffer));
graphics->getDestructionManager()->queueResourceForDestruction(std::move(tempAlloc));
graphics->getDestructionManager()->queueResourceForDestruction(std::move(scratchAlloc));
}
BottomLevelAS::~BottomLevelAS() {}
+1
View File
@@ -15,6 +15,7 @@ class BottomLevelAS : public Gfx::BottomLevelAS {
private:
PGraphics graphics;
VkAccelerationStructureKHR handle;
Gfx::OShaderBuffer buffer;
};
DEFINE_REF(BottomLevelAS)
class TopLevelAS : public Gfx::TopLevelAS {
+120 -138
View File
@@ -1,7 +1,10 @@
#include "Texture.h"
#include "Command.h"
#include "Enums.h"
#include "Graphics/Enums.h"
#include "Graphics/Initializer.h"
#include <math.h>
#include <vulkan/vulkan_core.h>
using namespace Seele;
using namespace Seele::Vulkan;
@@ -24,25 +27,12 @@ VkImageAspectFlags getAspectFromFormat(Gfx::SeFormat format) {
}
}
TextureHandle::TextureHandle(PGraphics graphics) : CommandBoundResource(graphics) {}
TextureHandle::~TextureHandle() {
vkDestroyImageView(graphics->getDevice(), imageView, nullptr);
if (ownsImage) {
vmaDestroyImage(graphics->getAllocator(), image, allocation);
}
}
TextureBase::TextureBase(PGraphics graphics, VkImageViewType viewType, const TextureCreateInfo& createInfo, Gfx::QueueType& owner,
VkImage existingImage)
: currentOwner(owner), graphics(graphics), width(createInfo.width), height(createInfo.height), depth(createInfo.depth),
TextureHandle::TextureHandle(PGraphics graphics, VkImageViewType viewType, const TextureCreateInfo& createInfo, VkImage existingImage)
: CommandBoundResource(graphics), image(existingImage), width(createInfo.width), height(createInfo.height), depth(createInfo.depth),
arrayCount(createInfo.elements), layerCount(createInfo.layers), mipLevels(createInfo.mipLevels), samples(createInfo.samples),
format(createInfo.format), usage(createInfo.usage), handle(new TextureHandle(graphics)),
aspect(getAspectFromFormat(createInfo.format)), layout(Gfx::SE_IMAGE_LAYOUT_UNDEFINED) {
handle->image = existingImage;
handle->ownsImage = false;
format(createInfo.format), usage(createInfo.usage), layout(Gfx::SE_IMAGE_LAYOUT_UNDEFINED),
aspect(getAspectFromFormat(createInfo.format)), ownsImage(false) {
if (existingImage == VK_NULL_HANDLE) {
handle->ownsImage = true;
VkImageType type = VK_IMAGE_TYPE_MAX_ENUM;
VkImageCreateFlags flags = 0;
switch (viewType) {
@@ -92,15 +82,14 @@ TextureBase::TextureBase(PGraphics graphics, VkImageViewType viewType, const Tex
VmaAllocationCreateInfo allocInfo = {
.usage = VMA_MEMORY_USAGE_AUTO,
};
VK_CHECK(vmaCreateImage(graphics->getAllocator(), &info, &allocInfo, &handle->image, &handle->allocation, nullptr));
VK_CHECK(vmaCreateImage(graphics->getAllocator(), &info, &allocInfo, &image, &allocation, nullptr));
ownsImage = true;
}
const DataSource& sourceData = createInfo.sourceData;
if (sourceData.size > 0) {
changeLayout(Gfx::SE_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, VK_ACCESS_NONE, VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT,
VK_ACCESS_MEMORY_WRITE_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT);
void* data;
OBufferAllocation stagingAlloc = new BufferAllocation(graphics);
VkBufferCreateInfo stagingInfo = {
.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,
.pNext = nullptr,
@@ -113,15 +102,14 @@ TextureBase::TextureBase(PGraphics graphics, VkImageViewType viewType, const Tex
.flags = VMA_ALLOCATION_CREATE_HOST_ACCESS_SEQUENTIAL_WRITE_BIT | VMA_ALLOCATION_CREATE_MAPPED_BIT,
.usage = VMA_MEMORY_USAGE_AUTO,
};
VK_CHECK(
vmaCreateBuffer(graphics->getAllocator(), &stagingInfo, &alloc, &stagingAlloc->buffer, &stagingAlloc->allocation, nullptr));
OBufferAllocation stagingAlloc = new BufferAllocation(graphics, stagingInfo, alloc, Gfx::QueueType::TRANSFER);
vmaMapMemory(graphics->getAllocator(), stagingAlloc->allocation, &data);
vmaSetAllocationName(graphics->getAllocator(), stagingAlloc->allocation, "TextureStaging");
std::memcpy(data, sourceData.data, sourceData.size);
vmaUnmapMemory(graphics->getAllocator(), stagingAlloc->allocation);
PCommandPool commandPool = graphics->getQueueCommands(currentOwner);
PCommandPool commandPool = graphics->getQueueCommands(owner);
VkBufferImageCopy region = {
.bufferOffset = 0,
.bufferRowLength = 0,
@@ -142,8 +130,8 @@ TextureBase::TextureBase(PGraphics graphics, VkImageViewType viewType, const Tex
.imageExtent = {.width = width, .height = height, .depth = depth},
};
vkCmdCopyBufferToImage(commandPool->getCommands()->getHandle(), stagingAlloc->buffer, handle->image,
VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1, &region);
vkCmdCopyBufferToImage(commandPool->getCommands()->getHandle(), stagingAlloc->buffer, image, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
1, &region);
commandPool->getCommands()->bindResource(PBufferAllocation(stagingAlloc));
generateMipmaps();
@@ -167,7 +155,7 @@ TextureBase::TextureBase(PGraphics graphics, VkImageViewType viewType, const Tex
.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,
.pNext = nullptr,
.flags = 0,
.image = handle->image,
.image = image,
.viewType = viewType,
.format = cast(format),
.subresourceRange =
@@ -178,17 +166,76 @@ TextureBase::TextureBase(PGraphics graphics, VkImageViewType viewType, const Tex
},
};
VK_CHECK(vkCreateImageView(graphics->getDevice(), &viewInfo, nullptr, &handle->imageView));
VK_CHECK(vkCreateImageView(graphics->getDevice(), &viewInfo, nullptr, &imageView));
}
TextureBase::~TextureBase() { graphics->getDestructionManager()->queueResourceForDestruction(std::move(handle)); }
TextureHandle::~TextureHandle() {
vkDestroyImageView(graphics->getDevice(), imageView, nullptr);
if (ownsImage) {
vmaDestroyImage(graphics->getAllocator(), image, allocation);
}
}
VkImage TextureBase::getImage() const { return handle->image; }
void TextureHandle::pipelineBarrier(VkAccessFlags srcAccess, VkPipelineStageFlags srcStage, VkAccessFlags dstAccess,
VkPipelineStageFlags dstStage) {
VkImageMemoryBarrier barrier = {
.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,
.pNext = nullptr,
.srcAccessMask = srcAccess,
.dstAccessMask = dstAccess,
.oldLayout = cast(layout),
.newLayout = cast(layout),
.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED,
.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED,
.image = image,
.subresourceRange =
{
.aspectMask = aspect,
.baseMipLevel = 0,
.levelCount = mipLevels,
.baseArrayLayer = 0,
.layerCount = 1,
},
};
PCommand command = graphics->getQueueCommands(owner)->getCommands();
vkCmdPipelineBarrier(command->getHandle(), srcStage, dstStage, 0, 0, nullptr, 0, nullptr, 1, &barrier);
command->bindResource(PTextureHandle(this));
}
VkImageView TextureBase::getView() const { return handle->imageView; }
void TextureHandle::transferOwnership(Gfx::QueueType newOwner) {
Gfx::QueueFamilyMapping mapping = graphics->getFamilyMapping();
VkImageMemoryBarrier barrier = {
.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,
.pNext = nullptr,
.srcAccessMask = VK_ACCESS_MEMORY_READ_BIT | VK_ACCESS_MEMORY_WRITE_BIT,
.dstAccessMask = VK_ACCESS_MEMORY_READ_BIT | VK_ACCESS_MEMORY_WRITE_BIT,
.oldLayout = cast(layout),
.newLayout = cast(layout),
.srcQueueFamilyIndex = mapping.getQueueTypeFamilyIndex(owner),
.dstQueueFamilyIndex = mapping.getQueueTypeFamilyIndex(newOwner),
.image = image,
.subresourceRange =
{
.aspectMask = aspect,
.baseMipLevel = 0,
.levelCount = mipLevels,
.baseArrayLayer = 0,
.layerCount = arrayCount,
},
};
PCommandPool sourcePool = graphics->getQueueCommands(owner);
PCommandPool dstPool = graphics->getQueueCommands(newOwner);
assert(barrier.srcQueueFamilyIndex != barrier.dstQueueFamilyIndex);
vkCmdPipelineBarrier(sourcePool->getCommands()->getHandle(), VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, 0,
0, nullptr, 0, nullptr, 1, &barrier);
vkCmdPipelineBarrier(dstPool->getCommands()->getHandle(), VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, 0, 0,
nullptr, 0, nullptr, 1, &barrier);
sourcePool->submitCommands();
owner = newOwner;
}
void TextureBase::changeLayout(Gfx::SeImageLayout newLayout, VkAccessFlags srcAccess, VkPipelineStageFlags srcStage,
VkAccessFlags dstAccess, VkPipelineStageFlags dstStage) {
void TextureHandle::changeLayout(Gfx::SeImageLayout newLayout, VkAccessFlags srcAccess, VkPipelineStageFlags srcStage,
VkAccessFlags dstAccess, VkPipelineStageFlags dstStage) {
VkImageMemoryBarrier barrier = {
.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,
.pNext = nullptr,
@@ -198,7 +245,7 @@ void TextureBase::changeLayout(Gfx::SeImageLayout newLayout, VkAccessFlags srcAc
.newLayout = cast(newLayout),
.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED,
.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED,
.image = handle->image,
.image = image,
.subresourceRange =
{
.aspectMask = aspect,
@@ -208,21 +255,20 @@ void TextureBase::changeLayout(Gfx::SeImageLayout newLayout, VkAccessFlags srcAc
.layerCount = layerCount,
},
};
PCommandPool commandPool = graphics->getQueueCommands(currentOwner);
PCommandPool commandPool = graphics->getQueueCommands(owner);
vkCmdPipelineBarrier(commandPool->getCommands()->getHandle(), srcStage, dstStage, 0, 0, nullptr, 0, nullptr, 1, &barrier);
commandPool->getCommands()->bindResource(PTextureHandle(handle));
commandPool->getCommands()->bindResource(PTextureHandle(this));
commandPool->submitCommands();
layout = newLayout;
}
void TextureBase::download(uint32 mipLevel, uint32 arrayLayer, uint32 face, Array<uint8>& buffer) {
void TextureHandle::download(uint32 mipLevel, uint32 arrayLayer, uint32 face, Array<uint8>& buffer) {
uint64 imageSize = width * height * depth * Gfx::getFormatInfo(format).blockSize;
auto prevLayout = layout;
changeLayout(Gfx::SE_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, VK_ACCESS_MEMORY_WRITE_BIT, VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT,
VK_ACCESS_TRANSFER_READ_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT);
void* data;
OBufferAllocation stagingAlloc = new BufferAllocation(graphics);
// always create a staging buffer since we do buffer -> image copy and the image may be in any tiling format
VkBufferCreateInfo stagingInfo = {
.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,
@@ -236,10 +282,11 @@ void TextureBase::download(uint32 mipLevel, uint32 arrayLayer, uint32 face, Arra
.flags = VMA_ALLOCATION_CREATE_MAPPED_BIT | VMA_ALLOCATION_CREATE_HOST_ACCESS_RANDOM_BIT,
.usage = VMA_MEMORY_USAGE_AUTO,
};
VK_CHECK(vmaCreateBuffer(graphics->getAllocator(), &stagingInfo, &alloc, &stagingAlloc->buffer, &stagingAlloc->allocation, nullptr));
OBufferAllocation stagingAlloc = new BufferAllocation(graphics, stagingInfo, alloc, owner);
vmaSetAllocationName(graphics->getAllocator(), stagingAlloc->allocation, "DownloadBuffer");
PCommand cmdBuffer = graphics->getQueueCommands(currentOwner)->getCommands();
PCommand cmdBuffer = graphics->getQueueCommands(owner)->getCommands();
// Gfx::FormatCompatibilityInfo formatInfo = Gfx::getFormatInfo(format);
VkBufferImageCopy region = {
.bufferOffset = 0,
@@ -260,7 +307,7 @@ void TextureBase::download(uint32 mipLevel, uint32 arrayLayer, uint32 face, Arra
},
.imageExtent = {.width = width, .height = height, .depth = depth},
};
vkCmdCopyImageToBuffer(cmdBuffer->getHandle(), handle->image, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, stagingAlloc->buffer, 1, &region);
vkCmdCopyImageToBuffer(cmdBuffer->getHandle(), image, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, stagingAlloc->buffer, 1, &region);
cmdBuffer->bindResource(PBufferAllocation(stagingAlloc));
changeLayout(prevLayout, VK_ACCESS_TRANSFER_READ_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_ACCESS_MEMORY_READ_BIT,
VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT);
@@ -271,8 +318,8 @@ void TextureBase::download(uint32 mipLevel, uint32 arrayLayer, uint32 face, Arra
graphics->getDestructionManager()->queueResourceForDestruction(std::move(stagingAlloc));
}
void TextureBase::generateMipmaps() {
PCommandPool commandPool = graphics->getQueueCommands(currentOwner);
void TextureHandle::generateMipmaps() {
PCommandPool commandPool = graphics->getQueueCommands(owner);
VkImageMemoryBarrier barrier = {
.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,
.srcAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT,
@@ -281,7 +328,7 @@ void TextureBase::generateMipmaps() {
.newLayout = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED,
.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED,
.image = handle->image,
.image = image,
.subresourceRange =
{
.aspectMask = aspect,
@@ -318,8 +365,9 @@ void TextureBase::generateMipmaps() {
{mipWidth > 1 ? mipWidth / 2 : 1, mipHeight > 1 ? mipHeight / 2 : 1, 1},
},
};
vkCmdBlitImage(commandPool->getCommands()->getHandle(), handle->image, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, handle->image,
VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1, &blit, aspect & VK_IMAGE_ASPECT_DEPTH_BIT ? VK_FILTER_NEAREST : VK_FILTER_LINEAR);
vkCmdBlitImage(commandPool->getCommands()->getHandle(), image, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, image,
VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1, &blit,
aspect & VK_IMAGE_ASPECT_DEPTH_BIT ? VK_FILTER_NEAREST : VK_FILTER_LINEAR);
if (mipWidth > 1)
mipWidth /= 2;
@@ -334,93 +382,29 @@ void TextureBase::generateMipmaps() {
layout = Gfx::SE_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
}
void TextureBase::executeOwnershipBarrier(Gfx::QueueType newOwner) {
Gfx::QueueFamilyMapping mapping = graphics->getFamilyMapping();
VkImageMemoryBarrier imageBarrier = {
.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,
.pNext = nullptr,
.oldLayout = cast(layout),
.newLayout = cast(layout),
.srcQueueFamilyIndex = mapping.getQueueTypeFamilyIndex(currentOwner),
.dstQueueFamilyIndex = mapping.getQueueTypeFamilyIndex(newOwner),
.image = handle->image,
.subresourceRange =
{
.aspectMask = aspect,
.baseMipLevel = 0,
.levelCount = mipLevels,
.baseArrayLayer = 0,
.layerCount = arrayCount,
},
};
PCommandPool sourcePool = graphics->getQueueCommands(currentOwner);
PCommandPool dstPool = nullptr;
VkPipelineStageFlags srcStage = VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT;
VkPipelineStageFlags dstStage = VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT;
if (currentOwner == Gfx::QueueType::TRANSFER) {
imageBarrier.srcAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT;
srcStage = VK_PIPELINE_STAGE_TRANSFER_BIT;
} else if (currentOwner == Gfx::QueueType::COMPUTE) {
imageBarrier.srcAccessMask = VK_ACCESS_MEMORY_WRITE_BIT;
srcStage = VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT;
} else if (currentOwner == Gfx::QueueType::GRAPHICS) {
imageBarrier.srcAccessMask = VK_ACCESS_MEMORY_WRITE_BIT;
srcStage = VK_PIPELINE_STAGE_ALL_GRAPHICS_BIT;
}
if (newOwner == Gfx::QueueType::TRANSFER) {
imageBarrier.dstAccessMask = VK_ACCESS_TRANSFER_READ_BIT;
dstStage = VK_PIPELINE_STAGE_TRANSFER_BIT;
dstPool = graphics->getTransferCommands();
} else if (newOwner == Gfx::QueueType::COMPUTE) {
imageBarrier.dstAccessMask = VK_ACCESS_MEMORY_READ_BIT;
dstStage = VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT;
dstPool = graphics->getComputeCommands();
} else if (newOwner == Gfx::QueueType::GRAPHICS) {
imageBarrier.dstAccessMask = VK_ACCESS_MEMORY_READ_BIT;
dstStage = VK_PIPELINE_STAGE_ALL_GRAPHICS_BIT;
dstPool = graphics->getGraphicsCommands();
}
TextureBase::TextureBase(PGraphics graphics, VkImageViewType viewType, const TextureCreateInfo& createInfo, VkImage existingImage)
: handle(new TextureHandle(graphics, viewType, createInfo, existingImage)), graphics(graphics),
initialOwner(createInfo.sourceData.owner) {}
VkCommandBuffer sourceCmd = sourcePool->getCommands()->getHandle();
VkCommandBuffer destCmd = dstPool->getCommands()->getHandle();
sourcePool->getCommands()->bindResource(PTextureHandle(handle));
dstPool->getCommands()->bindResource(PTextureHandle(handle));
vkCmdPipelineBarrier(sourceCmd, srcStage, srcStage, 0, 0, nullptr, 0, nullptr, 1, &imageBarrier);
vkCmdPipelineBarrier(destCmd, dstStage, dstStage, 0, 0, nullptr, 0, nullptr, 1, &imageBarrier);
currentOwner = newOwner;
sourcePool->submitCommands();
}
TextureBase::~TextureBase() { graphics->getDestructionManager()->queueResourceForDestruction(std::move(handle)); }
void TextureBase::executePipelineBarrier(VkAccessFlags srcAccess, VkPipelineStageFlags srcStage, VkAccessFlags dstAccess,
VkPipelineStageFlags dstStage) {
VkImageMemoryBarrier barrier = {
.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,
.pNext = nullptr,
.srcAccessMask = srcAccess,
.dstAccessMask = dstAccess,
.oldLayout = cast(layout),
.newLayout = cast(layout),
.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED,
.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED,
.image = handle->image,
.subresourceRange =
{
.aspectMask = aspect,
.baseMipLevel = 0,
.levelCount = mipLevels,
.baseArrayLayer = 0,
.layerCount = 1,
},
};
PCommand command = graphics->getQueueCommands(currentOwner)->getCommands();
vkCmdPipelineBarrier(command->getHandle(), srcStage, dstStage, 0, 0, nullptr, 0, nullptr, 1, &barrier);
command->bindResource(PTextureHandle(handle));
void TextureBase::pipelineBarrier(VkAccessFlags srcAccess, VkPipelineStageFlags srcStage, VkAccessFlags dstAccess,
VkPipelineStageFlags dstStage) {
handle->pipelineBarrier(srcAccess, srcStage, dstAccess, dstStage);
}
void TextureBase::transferOwnership(Gfx::QueueType newOwner) { handle->transferOwnership(newOwner); }
void TextureBase::changeLayout(Gfx::SeImageLayout newLayout, VkAccessFlags srcAccess, VkPipelineStageFlags srcStage,
VkAccessFlags dstAccess, VkPipelineStageFlags dstStage) {
handle->changeLayout(newLayout, srcAccess, srcStage, dstAccess, dstStage);
}
void TextureBase::download(uint32 mipLevel, uint32 arrayLayer, uint32 face, Array<uint8>& buffer) {
handle->download(mipLevel, arrayLayer, face, buffer);
}
void TextureBase::generateMipmaps() { handle->generateMipmaps(); }
Texture2D::Texture2D(PGraphics graphics, const TextureCreateInfo& createInfo, VkImage existingImage)
: Gfx::Texture2D(graphics->getFamilyMapping(), createInfo.sourceData.owner),
TextureBase(graphics, createInfo.elements > 1 ? VK_IMAGE_VIEW_TYPE_2D_ARRAY : VK_IMAGE_VIEW_TYPE_2D, createInfo,
Gfx::Texture2D::currentOwner, existingImage) {}
: Gfx::Texture2D(graphics->getFamilyMapping()),
TextureBase(graphics, createInfo.elements > 1 ? VK_IMAGE_VIEW_TYPE_2D_ARRAY : VK_IMAGE_VIEW_TYPE_2D, createInfo, existingImage) {}
Texture2D::~Texture2D() {}
@@ -435,16 +419,15 @@ void Texture2D::download(uint32 mipLevel, uint32 arrayLayer, uint32 face, Array<
void Texture2D::generateMipmaps() { TextureBase::generateMipmaps(); }
void Texture2D::executeOwnershipBarrier(Gfx::QueueType newOwner) { TextureBase::executeOwnershipBarrier(newOwner); }
void Texture2D::executeOwnershipBarrier(Gfx::QueueType newOwner) { TextureBase::transferOwnership(newOwner); }
void Texture2D::executePipelineBarrier(VkAccessFlags srcAccess, VkPipelineStageFlags srcStage, VkAccessFlags dstAccess,
VkPipelineStageFlags dstStage) {
TextureBase::executePipelineBarrier(srcAccess, srcStage, dstAccess, dstStage);
TextureBase::pipelineBarrier(srcAccess, srcStage, dstAccess, dstStage);
}
Texture3D::Texture3D(PGraphics graphics, const TextureCreateInfo& createInfo, VkImage existingImage)
: Gfx::Texture3D(graphics->getFamilyMapping(), createInfo.sourceData.owner),
TextureBase(graphics, VK_IMAGE_VIEW_TYPE_3D, createInfo, Gfx::Texture3D::currentOwner, existingImage) {}
: Gfx::Texture3D(graphics->getFamilyMapping()), TextureBase(graphics, VK_IMAGE_VIEW_TYPE_3D, createInfo, existingImage) {}
Texture3D::~Texture3D() {}
@@ -459,17 +442,16 @@ void Texture3D::download(uint32 mipLevel, uint32 arrayLayer, uint32 face, Array<
void Texture3D::generateMipmaps() { TextureBase::generateMipmaps(); }
void Texture3D::executeOwnershipBarrier(Gfx::QueueType newOwner) { TextureBase::executeOwnershipBarrier(newOwner); }
void Texture3D::executeOwnershipBarrier(Gfx::QueueType newOwner) { TextureBase::transferOwnership(newOwner); }
void Texture3D::executePipelineBarrier(VkAccessFlags srcAccess, VkPipelineStageFlags srcStage, VkAccessFlags dstAccess,
VkPipelineStageFlags dstStage) {
TextureBase::executePipelineBarrier(srcAccess, srcStage, dstAccess, dstStage);
TextureBase::pipelineBarrier(srcAccess, srcStage, dstAccess, dstStage);
}
TextureCube::TextureCube(PGraphics graphics, const TextureCreateInfo& createInfo, VkImage existingImage)
: Gfx::TextureCube(graphics->getFamilyMapping(), createInfo.sourceData.owner),
TextureBase(graphics, createInfo.elements > 1 ? VK_IMAGE_VIEW_TYPE_CUBE_ARRAY : VK_IMAGE_VIEW_TYPE_CUBE, createInfo,
Gfx::TextureCube::currentOwner, existingImage) {}
: Gfx::TextureCube(graphics->getFamilyMapping()),
TextureBase(graphics, createInfo.elements > 1 ? VK_IMAGE_VIEW_TYPE_CUBE_ARRAY : VK_IMAGE_VIEW_TYPE_CUBE, createInfo, existingImage) {}
TextureCube::~TextureCube() {}
@@ -484,9 +466,9 @@ void TextureCube::download(uint32 mipLevel, uint32 arrayLayer, uint32 face, Arra
void TextureCube::generateMipmaps() { TextureBase::generateMipmaps(); }
void TextureCube::executeOwnershipBarrier(Gfx::QueueType newOwner) { TextureBase::executeOwnershipBarrier(newOwner); }
void TextureCube::executeOwnershipBarrier(Gfx::QueueType newOwner) { TextureBase::transferOwnership(newOwner); }
void TextureCube::executePipelineBarrier(VkAccessFlags srcAccess, VkPipelineStageFlags srcStage, VkAccessFlags dstAccess,
VkPipelineStageFlags dstStage) {
TextureBase::executePipelineBarrier(srcAccess, srcStage, dstAccess, dstStage);
TextureBase::pipelineBarrier(srcAccess, srcStage, dstAccess, dstStage);
}
+64 -53
View File
@@ -1,53 +1,29 @@
#pragma once
#include "Graphics.h"
#include "Graphics/Enums.h"
#include "Graphics/Initializer.h"
#include "Graphics/Texture.h"
#include "Resources.h"
#include <vulkan/vulkan_core.h>
namespace Seele {
namespace Vulkan {
class TextureHandle : public CommandBoundResource {
public:
TextureHandle(PGraphics graphics);
TextureHandle(PGraphics graphics, VkImageViewType viewType, const TextureCreateInfo& createInfo, VkImage existingImage);
virtual ~TextureHandle();
VkImage image;
VkImageView imageView;
VmaAllocation allocation;
uint8 ownsImage;
};
DECLARE_REF(TextureHandle)
class TextureBase {
public:
TextureBase(PGraphics graphics, VkImageViewType viewType, const TextureCreateInfo& createInfo, Gfx::QueueType& owner,
VkImage existingImage = VK_NULL_HANDLE);
virtual ~TextureBase();
uint32 getWidth() const { return width; }
uint32 getHeight() const { return height; }
uint32 getDepth() const { return depth; }
PTextureHandle getHandle() const { return handle; }
VkImage getImage() const;
VkImageView getView() const;
constexpr Gfx::SeImageLayout getLayout() const { return layout; }
void setLayout(Gfx::SeImageLayout val) { layout = val; }
constexpr VkImageAspectFlags getAspect() const { return aspect; }
constexpr VkImageUsageFlags getUsage() const { return usage; }
constexpr Gfx::SeFormat getFormat() const { return format; }
constexpr Gfx::SeSampleCountFlags getNumSamples() const { return samples; }
constexpr uint32 getMipLevels() const { return mipLevels; }
constexpr bool isDepthStencil() const { return aspect & (VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT); }
void executeOwnershipBarrier(Gfx::QueueType newOwner);
void executePipelineBarrier(VkAccessFlags srcAccess, VkPipelineStageFlags srcStage, VkAccessFlags dstAccess,
void pipelineBarrier(VkAccessFlags srcAccess, VkPipelineStageFlags srcStage, VkAccessFlags dstAccess,
VkPipelineStageFlags dstStage);
void transferOwnership(Gfx::QueueType newOwner);
void changeLayout(Gfx::SeImageLayout newLayout, VkAccessFlags srcAccess, VkPipelineStageFlags srcStage, VkAccessFlags dstAccess,
VkPipelineStageFlags dstStage);
void download(uint32 mipLevel, uint32 arrayLayer, uint32 face, Array<uint8>& buffer);
void generateMipmaps();
protected:
OTextureHandle handle;
// Updates via reference
Gfx::QueueType& currentOwner;
PGraphics graphics;
VkImage image;
VkImageView imageView;
VmaAllocation allocation;
Gfx::QueueType owner;
uint32 width;
uint32 height;
uint32 depth;
@@ -57,8 +33,43 @@ class TextureBase {
uint32 samples;
Gfx::SeFormat format;
Gfx::SeImageUsageFlags usage;
VkImageAspectFlags aspect;
Gfx::SeImageLayout layout;
VkImageAspectFlags aspect;
uint8 ownsImage;
};
DECLARE_REF(TextureHandle)
class TextureBase {
public:
TextureBase(PGraphics graphics, VkImageViewType viewType, const TextureCreateInfo& createInfo,
VkImage existingImage = VK_NULL_HANDLE);
virtual ~TextureBase();
uint32 getWidth() const { return handle->width; }
uint32 getHeight() const { return handle->height; }
uint32 getDepth() const { return handle->depth; }
PTextureHandle getHandle() const { return handle; }
VkImage getImage() const { return handle->image; };
VkImageView getView() const { return handle->imageView; };
constexpr Gfx::SeImageLayout getLayout() const { return handle->layout; }
void setLayout(Gfx::SeImageLayout val) { handle->layout = val; }
constexpr VkImageAspectFlags getAspect() const { return handle->aspect; }
constexpr VkImageUsageFlags getUsage() const { return handle->usage; }
constexpr Gfx::SeFormat getFormat() const { return handle->format; }
constexpr Gfx::SeSampleCountFlags getNumSamples() const { return handle->samples; }
constexpr uint32 getMipLevels() const { return handle->mipLevels; }
constexpr bool isDepthStencil() const { return handle->aspect & (VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT); }
void pipelineBarrier(VkAccessFlags srcAccess, VkPipelineStageFlags srcStage, VkAccessFlags dstAccess,
VkPipelineStageFlags dstStage);
void transferOwnership(Gfx::QueueType newOwner);
void changeLayout(Gfx::SeImageLayout newLayout, VkAccessFlags srcAccess, VkPipelineStageFlags srcStage, VkAccessFlags dstAccess,
VkPipelineStageFlags dstStage);
void download(uint32 mipLevel, uint32 arrayLayer, uint32 face, Array<uint8>& buffer);
void generateMipmaps();
protected:
OTextureHandle handle;
// Updates via reference
PGraphics graphics;
Gfx::QueueType initialOwner;
friend class Graphics;
};
DEFINE_REF(TextureBase)
@@ -67,12 +78,12 @@ class Texture2D : public Gfx::Texture2D, public TextureBase {
public:
Texture2D(PGraphics graphics, const TextureCreateInfo& createInfo, VkImage existingImage = VK_NULL_HANDLE);
virtual ~Texture2D();
virtual uint32 getWidth() const override { return width; }
virtual uint32 getHeight() const override { return height; }
virtual uint32 getDepth() const override { return depth; }
virtual Gfx::SeFormat getFormat() const override { return format; }
virtual Gfx::SeSampleCountFlags getNumSamples() const override { return samples; }
virtual uint32 getMipLevels() const override { return mipLevels; }
virtual uint32 getWidth() const override { return handle->width; }
virtual uint32 getHeight() const override { return handle->height; }
virtual uint32 getDepth() const override { return handle->depth; }
virtual Gfx::SeFormat getFormat() const override { return handle->format; }
virtual Gfx::SeSampleCountFlags getNumSamples() const override { return handle->samples; }
virtual uint32 getMipLevels() const override { return handle->mipLevels; }
virtual void changeLayout(Gfx::SeImageLayout newLayout, Gfx::SeAccessFlags srcAccess, Gfx::SePipelineStageFlags srcStage,
Gfx::SeAccessFlags dstAccess, Gfx::SePipelineStageFlags dstStage) override;
virtual void download(uint32 mipLevel, uint32 arrayLayer, uint32 face, Array<uint8>& buffer) override;
@@ -90,12 +101,12 @@ class Texture3D : public Gfx::Texture3D, public TextureBase {
public:
Texture3D(PGraphics graphics, const TextureCreateInfo& createInfo, VkImage existingImage = VK_NULL_HANDLE);
virtual ~Texture3D();
virtual uint32 getWidth() const override { return width; }
virtual uint32 getHeight() const override { return height; }
virtual uint32 getDepth() const override { return depth; }
virtual Gfx::SeFormat getFormat() const override { return format; }
virtual Gfx::SeSampleCountFlags getNumSamples() const override { return samples; }
virtual uint32 getMipLevels() const override { return mipLevels; }
virtual uint32 getWidth() const override { return handle->width; }
virtual uint32 getHeight() const override { return handle->height; }
virtual uint32 getDepth() const override { return handle->depth; }
virtual Gfx::SeFormat getFormat() const override { return handle->format; }
virtual Gfx::SeSampleCountFlags getNumSamples() const override { return handle->samples; }
virtual uint32 getMipLevels() const override { return handle->mipLevels; }
virtual void changeLayout(Gfx::SeImageLayout newLayout, Gfx::SeAccessFlags srcAccess, Gfx::SePipelineStageFlags srcStage,
Gfx::SeAccessFlags dstAccess, Gfx::SePipelineStageFlags dstStage) override;
virtual void download(uint32 mipLevel, uint32 arrayLayer, uint32 face, Array<uint8>& buffer) override;
@@ -113,12 +124,12 @@ class TextureCube : public Gfx::TextureCube, public TextureBase {
public:
TextureCube(PGraphics graphics, const TextureCreateInfo& createInfo, VkImage existingImage = VK_NULL_HANDLE);
virtual ~TextureCube();
virtual uint32 getWidth() const override { return width; }
virtual uint32 getHeight() const override { return height; }
virtual uint32 getDepth() const override { return depth; }
virtual Gfx::SeFormat getFormat() const override { return format; }
virtual Gfx::SeSampleCountFlags getNumSamples() const override { return samples; }
virtual uint32 getMipLevels() const override { return mipLevels; }
virtual uint32 getWidth() const override { return handle->width; }
virtual uint32 getHeight() const override { return handle->height; }
virtual uint32 getDepth() const override { return handle->depth; }
virtual Gfx::SeFormat getFormat() const override { return handle->format; }
virtual Gfx::SeSampleCountFlags getNumSamples() const override { return handle->samples; }
virtual uint32 getMipLevels() const override { return handle->mipLevels; }
virtual void changeLayout(Gfx::SeImageLayout newLayout, Gfx::SeAccessFlags srcAccess, Gfx::SePipelineStageFlags srcStage,
Gfx::SeAccessFlags dstAccess, Gfx::SePipelineStageFlags dstStage) override;
virtual void download(uint32 mipLevel, uint32 arrayLayer, uint32 face, Array<uint8>& buffer) override;