Adding transparency support

This commit is contained in:
Dynamitos
2024-06-20 21:57:26 +02:00
parent 2dc9d57c71
commit bd63b14260
27 changed files with 578 additions and 282 deletions
+12 -9
View File
@@ -10,8 +10,8 @@ using namespace Seele::Vulkan;
BufferAllocation::BufferAllocation(PGraphics graphics, const std::string& name, VkBufferCreateInfo bufferInfo,
VmaAllocationCreateInfo allocInfo, Gfx::QueueType owner, uint64 alignment)
: CommandBoundResource(graphics), size(bufferInfo.size), owner(owner) {
VK_CHECK(vmaCreateBufferWithAlignment(graphics->getAllocator(), &bufferInfo, &allocInfo, alignment, &buffer, &allocation, nullptr));
: CommandBoundResource(graphics), size(bufferInfo.size), name(name), owner(owner) {
VK_CHECK(vmaCreateBufferWithAlignment(graphics->getAllocator(), &bufferInfo, &allocInfo, alignment, &buffer, &allocation, &info));
vmaGetAllocationMemoryProperties(graphics->getAllocator(), allocation, &properties);
VkDebugUtilsObjectNameInfoEXT nameInfo = {
.sType = VK_STRUCTURE_TYPE_DEBUG_UTILS_OBJECT_NAME_INFO_EXT,
@@ -167,10 +167,10 @@ void BufferAllocation::readContents(uint64 regionOffset, uint64 regionSize, void
}
Buffer::Buffer(PGraphics graphics, uint64 size, VkBufferUsageFlags usage, Gfx::QueueType queueType, bool dynamic, std::string name,
uint32 clearValue)
bool createCleared, uint32 clearValue)
: graphics(graphics), currentBuffer(0), initialOwner(queueType),
usage(usage | VK_BUFFER_USAGE_SHADER_DEVICE_ADDRESS_BIT | VK_BUFFER_USAGE_TRANSFER_SRC_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT),
dynamic(dynamic), name(name), clearValue(clearValue) {
dynamic(dynamic), createCleared(createCleared), name(name), clearValue(clearValue) {
if (size > 0) {
buffers.add(nullptr);
createBuffer(size, 0);
@@ -235,10 +235,13 @@ void Buffer::createBuffer(uint64 size, uint32 destIndex) {
.usage = VMA_MEMORY_USAGE_AUTO_PREFER_DEVICE,
};
buffers[destIndex] = new BufferAllocation(graphics, name, info, allocInfo, initialOwner);
PCommand command = graphics->getQueueCommands(initialOwner)->getCommands();
vkCmdFillBuffer(command->getHandle(), buffers[destIndex]->buffer, 0, VK_WHOLE_SIZE, clearValue);
pipelineBarrier(VK_ACCESS_TRANSFER_WRITE_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT,
VK_ACCESS_MEMORY_READ_BIT | VK_ACCESS_MEMORY_WRITE_BIT, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT);
if (createCleared)
{
PCommand command = graphics->getQueueCommands(initialOwner)->getCommands();
vkCmdFillBuffer(command->getHandle(), buffers[destIndex]->buffer, 0, VK_WHOLE_SIZE, clearValue);
pipelineBarrier(VK_ACCESS_TRANSFER_WRITE_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT,
VK_ACCESS_MEMORY_READ_BIT | VK_ACCESS_MEMORY_WRITE_BIT, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT);
}
}
}
@@ -321,7 +324,7 @@ ShaderBuffer::ShaderBuffer(PGraphics graphics, const ShaderBufferCreateInfo& cre
(createInfo.vertexBuffer ? VK_BUFFER_USAGE_ACCELERATION_STRUCTURE_BUILD_INPUT_READ_ONLY_BIT_KHR |
VK_BUFFER_USAGE_SHADER_DEVICE_ADDRESS_BIT
: 0),
createInfo.sourceData.owner, createInfo.dynamic, createInfo.name) {
createInfo.sourceData.owner, createInfo.dynamic, createInfo.name, createInfo.createCleared, createInfo.clearValue) {
if (createInfo.sourceData.size > 0 && createInfo.sourceData.data != nullptr) {
getAlloc()->updateContents(createInfo.sourceData.offset, createInfo.sourceData.size, createInfo.sourceData.data);
}
+4 -1
View File
@@ -22,13 +22,15 @@ class BufferAllocation : public CommandBoundResource {
VmaAllocationInfo info = VmaAllocationInfo();
VkMemoryPropertyFlags properties = 0;
uint64 size = 0;
std::string name;
VkDeviceAddress deviceAddress;
Gfx::QueueType owner;
};
DEFINE_REF(BufferAllocation);
class Buffer {
public:
Buffer(PGraphics graphics, uint64 size, VkBufferUsageFlags usage, Gfx::QueueType initialOwner, bool dynamic, std::string name, uint32 clearValue = 0);
Buffer(PGraphics graphics, uint64 size, VkBufferUsageFlags usage, Gfx::QueueType initialOwner, bool dynamic, std::string name,
bool createCleared = false, uint32 clearValue = 0);
virtual ~Buffer();
VkBuffer getHandle() const { return buffers[currentBuffer]->buffer; }
VkDeviceAddress getDeviceAddress() const { return buffers[currentBuffer]->deviceAddress; }
@@ -44,6 +46,7 @@ class Buffer {
Array<OBufferAllocation> buffers;
VkBufferUsageFlags usage;
bool dynamic;
bool createCleared;
std::string name;
uint32 clearValue;
void rotateBuffer(uint64 size, bool preserveContents = false);
+22 -12
View File
@@ -7,7 +7,6 @@
#include "RenderPass.h"
#include "Window.h"
using namespace Seele;
using namespace Seele::Vulkan;
@@ -151,8 +150,7 @@ void Command::waitForCommand(uint32 timeout) {
checkFence();
}
void Command::setPipelineStatisticsFlags(VkQueryPipelineStatisticFlags flags)
{ statisticsFlags = flags; }
void Command::setPipelineStatisticsFlags(VkQueryPipelineStatisticFlags flags) { statisticsFlags = flags; }
void Command::bindResource(PCommandBoundResource resource) {
resource->bind();
@@ -239,8 +237,10 @@ void RenderCommand::bindDescriptor(Gfx::PDescriptorSet descriptorSet, Array<uint
descriptor->bind();
boundResources.add(descriptor.getHandle());
for (auto binding : descriptor->boundResources) {
binding->bind();
boundResources.add(binding);
for (auto res : binding) {
res->bind();
boundResources.add(res);
}
}
VkDescriptorSet setHandle = descriptor->getHandle();
@@ -260,8 +260,13 @@ void RenderCommand::bindDescriptor(const Array<Gfx::PDescriptorSet>& descriptorS
boundResources.add(descriptorSet.getHandle());
for (auto binding : descriptorSet->boundResources) {
binding->bind();
boundResources.add(binding);
for (auto res : binding) {
// partially bound descriptors can include nulls
if (res != nullptr) {
res->bind();
boundResources.add(res);
}
}
}
sets[pipeline->getPipelineLayout()->findParameter(descriptorSet->getName())] = descriptorSet->getHandle();
}
@@ -316,7 +321,7 @@ void RenderCommand::drawMeshIndirect(Gfx::PShaderBuffer buffer, uint64 offset, u
vkCmdDrawMeshTasksIndirectEXT(handle, buffer.cast<ShaderBuffer>()->getHandle(), offset, drawCount, stride);
}
void RenderCommand::traceRays() { }
void RenderCommand::traceRays() {}
ComputeCommand::ComputeCommand(PGraphics graphics, VkCommandPool cmdPool) : graphics(graphics), owner(cmdPool) {
VkCommandBufferAllocateInfo allocInfo = {
@@ -378,8 +383,10 @@ void ComputeCommand::bindDescriptor(Gfx::PDescriptorSet descriptorSet, Array<uin
boundResources.add(descriptor.getHandle());
for (auto binding : descriptor->boundResources) {
binding->bind();
boundResources.add(binding);
for (auto res : binding) {
res->bind();
boundResources.add(res);
}
}
VkDescriptorSet setHandle = descriptor->getHandle();
@@ -398,9 +405,12 @@ void ComputeCommand::bindDescriptor(const Array<Gfx::PDescriptorSet>& descriptor
boundResources.add(descriptorSet.getHandle());
// std::cout << "Binding descriptor " << descriptorSet->getHandle() << " to cmd " << handle << std::endl;
for (auto binding : descriptorSet->boundResources) {
binding->bind();
boundResources.add(binding);
for (auto res : binding) {
res->bind();
boundResources.add(res);
}
}
sets[pipeline->getPipelineLayout()->findParameter(descriptorSet->getName())] = descriptorSet->getHandle();
}
+52 -19
View File
@@ -168,13 +168,17 @@ DescriptorSet::DescriptorSet(PGraphics graphics, PDescriptorPool owner)
: Gfx::DescriptorSet(owner->getLayout()), CommandBoundResource(graphics), setHandle(VK_NULL_HANDLE), graphics(graphics), owner(owner),
bindCount(0), currentlyInUse(false) {
boundResources.resize(owner->getLayout()->getBindings().size());
for (uint32 i = 0; i < boundResources.size(); ++i)
{
boundResources[i].resize(owner->getLayout()->getBindings()[i].descriptorCount);
}
}
DescriptorSet::~DescriptorSet() {}
void DescriptorSet::updateBuffer(uint32_t binding, Gfx::PUniformBuffer uniformBuffer) {
PUniformBuffer vulkanBuffer = uniformBuffer.cast<UniformBuffer>();
if (boundResources[binding] == vulkanBuffer->getAlloc()) {
if (boundResources[binding][0] == vulkanBuffer->getAlloc()) {
return;
}
@@ -195,12 +199,12 @@ void DescriptorSet::updateBuffer(uint32_t binding, Gfx::PUniformBuffer uniformBu
.pBufferInfo = &bufferInfos.back(),
});
boundResources[binding] = vulkanBuffer->getAlloc();
boundResources[binding][0] = vulkanBuffer->getAlloc();
}
void DescriptorSet::updateBuffer(uint32_t binding, Gfx::PShaderBuffer shaderBuffer) {
PShaderBuffer vulkanBuffer = shaderBuffer.cast<ShaderBuffer>();
if (boundResources[binding] == vulkanBuffer->getAlloc()) {
if (boundResources[binding][0] == vulkanBuffer->getAlloc()) {
return;
}
@@ -220,12 +224,12 @@ void DescriptorSet::updateBuffer(uint32_t binding, Gfx::PShaderBuffer shaderBuff
.pBufferInfo = &bufferInfos.back(),
});
boundResources[binding] = vulkanBuffer->getAlloc();
boundResources[binding][0] = vulkanBuffer->getAlloc();
}
void DescriptorSet::updateBuffer(uint32_t binding, uint32 index, Gfx::PShaderBuffer shaderBuffer) {
PShaderBuffer vulkanBuffer = shaderBuffer.cast<ShaderBuffer>();
if (boundResources[binding] == vulkanBuffer->getAlloc()) {
if (boundResources[binding][index] == vulkanBuffer->getAlloc()) {
return;
}
@@ -246,12 +250,12 @@ void DescriptorSet::updateBuffer(uint32_t binding, uint32 index, Gfx::PShaderBuf
.pBufferInfo = &bufferInfos.back(),
});
boundResources[binding] = vulkanBuffer->getAlloc();
boundResources[binding][index] = vulkanBuffer->getAlloc();
}
void DescriptorSet::updateSampler(uint32_t binding, Gfx::PSampler samplerState) {
PSampler vulkanSampler = samplerState.cast<Sampler>();
if (boundResources[binding] == vulkanSampler->getHandle()) {
if (boundResources[binding][0] == vulkanSampler->getHandle()) {
return;
}
@@ -272,13 +276,13 @@ void DescriptorSet::updateSampler(uint32_t binding, Gfx::PSampler samplerState)
.pImageInfo = &imageInfos.back(),
});
boundResources[binding] = vulkanSampler->getHandle();
boundResources[binding][0] = vulkanSampler->getHandle();
}
void DescriptorSet::updateSampler(uint32_t binding, uint32 dstArrayIndex, Gfx::PSampler samplerState)
{
PSampler vulkanSampler = samplerState.cast<Sampler>();
if (boundResources[binding] == vulkanSampler->getHandle()) {
if (boundResources[binding][dstArrayIndex] == vulkanSampler->getHandle()) {
return;
}
@@ -299,13 +303,13 @@ void DescriptorSet::updateSampler(uint32_t binding, uint32 dstArrayIndex, Gfx::P
.pImageInfo = &imageInfos.back(),
});
boundResources[binding] = vulkanSampler->getHandle();
boundResources[binding][dstArrayIndex] = vulkanSampler->getHandle();
}
void DescriptorSet::updateTexture(uint32_t binding, Gfx::PTexture texture, Gfx::PSampler samplerState) {
TextureBase* vulkanTexture = texture.cast<TextureBase>().getHandle();
if (boundResources[binding] == vulkanTexture->getHandle()) {
if (boundResources[binding][0] == vulkanTexture->getHandle()) {
return;
}
@@ -332,13 +336,13 @@ void DescriptorSet::updateTexture(uint32_t binding, Gfx::PTexture texture, Gfx::
.pImageInfo = &imageInfos.back(),
});
boundResources[binding] = vulkanTexture->getHandle();
boundResources[binding][0] = vulkanTexture->getHandle();
}
void DescriptorSet::updateTexture(uint32 binding, uint32 dstArrayIndex, Gfx::PTexture texture)
{
TextureBase* vulkanTexture = texture.cast<TextureBase>().getHandle();
if (boundResources[binding] == vulkanTexture->getHandle()) {
if (boundResources[binding][dstArrayIndex] == vulkanTexture->getHandle()) {
return;
}
@@ -359,17 +363,16 @@ void DescriptorSet::updateTexture(uint32 binding, uint32 dstArrayIndex, Gfx::PTe
.pImageInfo = &imageInfos.back(),
});
boundResources[binding] = vulkanTexture->getHandle();
boundResources[binding][dstArrayIndex] = vulkanTexture->getHandle();
}
void DescriptorSet::updateTextureArray(uint32_t binding, Array<Gfx::PTexture> textures) {
void DescriptorSet::updateTextureArray(uint32_t binding, Array<Gfx::PTexture2D> textures) {
// maybe make this a parameter?
uint32 arrayElement = 0;
boundResources.resize(binding + textures.size());
for (auto& gfxTexture : textures) {
TextureBase* vulkanTexture = gfxTexture.cast<TextureBase>().getHandle();
if (boundResources[binding + arrayElement] == vulkanTexture->getHandle()) {
if (boundResources[binding][arrayElement] == vulkanTexture->getHandle()) {
continue;
}
imageInfos.add(VkDescriptorImageInfo{
@@ -382,7 +385,7 @@ void DescriptorSet::updateTextureArray(uint32_t binding, Array<Gfx::PTexture> te
if (vulkanTexture->getUsage() & VK_IMAGE_USAGE_STORAGE_BIT) {
descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_IMAGE;
}
boundResources[binding + arrayElement] = vulkanTexture->getHandle();
boundResources[binding][arrayElement] = vulkanTexture->getHandle();
writeDescriptors.add(VkWriteDescriptorSet{
.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET,
.pNext = nullptr,
@@ -393,10 +396,40 @@ void DescriptorSet::updateTextureArray(uint32_t binding, Array<Gfx::PTexture> te
.descriptorType = descriptorType,
.pImageInfo = &imageInfos.back(),
});
vulkanTexture->getHandle()->bind();
}
}
void DescriptorSet::updateSamplerArray(uint32_t binding, Array<Gfx::PSampler> samplers) {
// maybe make this a parameter?
uint32 arrayElement = 0;
for (auto& gfxSampler : samplers) {
PSampler vulkanSampler = gfxSampler.cast<Sampler>();
if (boundResources[binding][arrayElement] == vulkanSampler->getHandle()) {
continue;
}
imageInfos.add(VkDescriptorImageInfo{
.sampler = vulkanSampler->getHandle()->sampler,
.imageView = VK_NULL_HANDLE,
.imageLayout = VK_IMAGE_LAYOUT_UNDEFINED,
});
VkDescriptorType descriptorType = VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE;
boundResources[binding][arrayElement] = vulkanSampler->getHandle();
writeDescriptors.add(VkWriteDescriptorSet{
.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET,
.pNext = nullptr,
.dstSet = setHandle,
.dstBinding = binding,
.dstArrayElement = arrayElement++,
.descriptorCount = 1,
.descriptorType = VK_DESCRIPTOR_TYPE_SAMPLER,
.pImageInfo = &imageInfos.back(),
});
}
}
void DescriptorSet::writeChanges() {
if (writeDescriptors.size() > 0) {
if (isCurrentlyBound()) {
+3 -2
View File
@@ -55,7 +55,8 @@ class DescriptorSet : public Gfx::DescriptorSet, public CommandBoundResource {
virtual void updateSampler(uint32_t binding, uint32 dstArrayIndex, Gfx::PSampler samplerState) override;
virtual void updateTexture(uint32_t binding, Gfx::PTexture texture, Gfx::PSampler sampler = nullptr) override;
virtual void updateTexture(uint32 binding, uint32 dstArrayIndex, Gfx::PTexture texture) override;
virtual void updateTextureArray(uint32_t binding, Array<Gfx::PTexture> texture) override;
virtual void updateTextureArray(uint32_t binding, Array<Gfx::PTexture2D> texture) override;
virtual void updateSamplerArray(uint32_t binding, Array<Gfx::PSampler> samplers) override;
constexpr bool isCurrentlyInUse() const { return currentlyInUse; }
constexpr void allocate() { currentlyInUse = true; }
@@ -70,7 +71,7 @@ class DescriptorSet : public Gfx::DescriptorSet, public CommandBoundResource {
// since the layout is fixed, trying to bind a texture to a buffer
// would not work anyways, so casts should be safe
// Array<void*> cachedData;
Array<PCommandBoundResource> boundResources;
Array<Array<PCommandBoundResource>> boundResources;
VkDescriptorSet setHandle;
PGraphics graphics;
PDescriptorPool owner;
+6 -1
View File
@@ -51,13 +51,18 @@ void QueryPool::end() {
// sizeof(uint64) * currentQuery, resultsStride + sizeof(uint64),
// VK_QUERY_RESULT_64_BIT | VK_QUERY_RESULT_WITH_AVAILABILITY_BIT);
graphics->getGraphicsCommands()->submitCommands();
std::unique_lock l(queryMutex);
currentQuery = (currentQuery + 1) % numQueries;
queryCV.notify_all();
}
void QueryPool::getQueryResults(Array<uint64>& results) {
//uint64 numInts = resultsStride / sizeof(uint64);
while (currentQuery == pendingQuery)
;
{
std::unique_lock l(queryMutex);
queryCV.wait(l);
}
results.resize(resultsStride/ sizeof(uint64));
vkGetQueryPoolResults(graphics->getDevice(), handle, pendingQuery, 1, resultsStride, results.data(), resultsStride,
VK_QUERY_RESULT_WAIT_BIT | VK_QUERY_RESULT_64_BIT);
+2
View File
@@ -24,6 +24,8 @@ class QueryPool {
uint32 currentQuery = 0;
uint32 numQueries;
uint32 resultsStride;
std::mutex queryMutex;
std::condition_variable queryCV;
};
class OcclusionQuery : public Gfx::OcclusionQuery, public QueryPool {
public:
+5 -2
View File
@@ -4,7 +4,6 @@
#include "Graphics.h"
#include "Window.h"
using namespace Seele;
using namespace Seele::Vulkan;
@@ -76,7 +75,11 @@ DestructionManager::DestructionManager(PGraphics graphics) : graphics(graphics)
DestructionManager::~DestructionManager() {}
void DestructionManager::queueResourceForDestruction(OCommandBoundResource resource) { resources.add(std::move(resource)); }
void DestructionManager::queueResourceForDestruction(OCommandBoundResource resource) {
if (resource->isCurrentlyBound()) {
resources.add(std::move(resource));
}
}
void DestructionManager::notifyCommandComplete() {
for (size_t i = 0; i < resources.size(); ++i) {