Descriptor sets and refactoring

This commit is contained in:
Dynamitos
2024-04-13 23:51:38 +02:00
parent efb2c0e169
commit f5eb12a5de
31 changed files with 1688 additions and 1365 deletions
+109 -121
View File
@@ -1,146 +1,134 @@
#pragma once
#include "Graphics/Buffer.h"
#include "Graphics.h"
#include "Graphics/Buffer.h"
namespace Seele
{
namespace Vulkan
{
class Buffer
{
namespace Seele {
namespace Vulkan {
class Buffer {
public:
Buffer(PGraphics graphics,
uint64 size,
VkBufferUsageFlags usage,
Gfx::QueueType& queueType,
bool dynamic,
std::string name);
virtual ~Buffer();
VkBuffer getHandle() const
{
return buffers[currentBuffer].buffer;
}
uint64 getSize() const
{
return size;
}
void advanceBuffer()
{
currentBuffer = (currentBuffer + 1) % numBuffers;
}
void *map(bool writeOnly = true);
void *mapRegion(uint64 regionOffset, uint64 regionSize, bool writeOnly = true);
void unmap();
Buffer(PGraphics graphics, uint64 size, VkBufferUsageFlags usage,
Gfx::QueueType &queueType, bool dynamic, std::string name);
virtual ~Buffer();
VkBuffer getHandle() const { return buffers[currentBuffer].buffer; }
uint64 getSize() const { return size; }
void *map(bool writeOnly = true);
void *mapRegion(uint64 regionOffset, uint64 regionSize,
bool writeOnly = true);
void unmap();
protected:
struct BufferAllocation
{
VkBuffer buffer;
VmaAllocation allocation;
VmaAllocationInfo info;
VkMemoryPropertyFlags properties;
};
PGraphics graphics;
uint32 currentBuffer;
uint64 size;
Gfx::QueueType& owner;
BufferAllocation buffers[Gfx::numFramesBuffered];
uint32 numBuffers;
std::string name;
struct BufferAllocation {
VkBuffer buffer;
VmaAllocation allocation;
VmaAllocationInfo info;
VkMemoryPropertyFlags properties;
};
PGraphics graphics;
uint32 currentBuffer;
uint64 size;
Gfx::QueueType &owner;
Array<BufferAllocation> buffers;
uint32 numBuffers;
std::string name;
void executeOwnershipBarrier(Gfx::QueueType newOwner);
void executePipelineBarrier(VkAccessFlags srcAccess, VkPipelineStageFlags srcStage,
VkAccessFlags dstAccess, VkPipelineStageFlags dstStage);
virtual void requestOwnershipTransfer(Gfx::QueueType newOwner) = 0;
void executeOwnershipBarrier(Gfx::QueueType newOwner);
void executePipelineBarrier(VkAccessFlags srcAccess,
VkPipelineStageFlags srcStage,
VkAccessFlags dstAccess,
VkPipelineStageFlags dstStage);
virtual VkAccessFlags getSourceAccessMask() = 0;
virtual VkAccessFlags getDestAccessMask() = 0;
virtual void requestOwnershipTransfer(Gfx::QueueType newOwner) = 0;
virtual VkAccessFlags getSourceAccessMask() = 0;
virtual VkAccessFlags getDestAccessMask() = 0;
};
DEFINE_REF(Buffer)
class UniformBuffer : public Gfx::UniformBuffer, public Buffer
{
class VertexBuffer : public Gfx::VertexBuffer, public Buffer {
public:
UniformBuffer(PGraphics graphics, const UniformBufferCreateInfo &sourceData);
virtual ~UniformBuffer();
virtual bool updateContents(const DataSource &sourceData) override;
virtual void beginFrame() override;
VertexBuffer(PGraphics graphics, const VertexBufferCreateInfo &sourceData);
virtual ~VertexBuffer();
virtual void updateRegion(DataSource update) override;
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(VkAccessFlags srcAccess, VkPipelineStageFlags srcStage,
VkAccessFlags dstAccess, VkPipelineStageFlags dstStage) override;
// 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,
Gfx::SePipelineStageFlags dstStage) override;
};
DEFINE_REF(VertexBuffer)
class IndexBuffer : public Gfx::IndexBuffer, public Buffer {
public:
IndexBuffer(PGraphics graphics, const IndexBufferCreateInfo &sourceData);
virtual ~IndexBuffer();
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,
Gfx::SePipelineStageFlags dstStage) override;
};
DEFINE_REF(IndexBuffer)
class UniformBuffer : public Gfx::UniformBuffer, public Buffer {
public:
UniformBuffer(PGraphics graphics, const UniformBufferCreateInfo &sourceData);
virtual ~UniformBuffer();
virtual bool updateContents(const DataSource &sourceData) 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,
Gfx::SePipelineStageFlags dstStage) override;
private:
};
DEFINE_REF(UniformBuffer)
class ShaderBuffer : public Gfx::ShaderBuffer, public Buffer
{
class ShaderBuffer : public Gfx::ShaderBuffer, public Buffer {
public:
ShaderBuffer(PGraphics graphics, const ShaderBufferCreateInfo &sourceData);
virtual ~ShaderBuffer();
virtual bool updateContents(const DataSource &sourceData) override;
virtual void beginFrame() override;
ShaderBuffer(PGraphics graphics, const ShaderBufferCreateInfo &sourceData);
virtual ~ShaderBuffer();
virtual bool updateContents(const DataSource &sourceData) 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(VkAccessFlags srcAccess, VkPipelineStageFlags srcStage,
VkAccessFlags dstAccess, VkPipelineStageFlags dstStage) override;
// 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,
Gfx::SePipelineStageFlags dstStage) override;
private:
};
DEFINE_REF(ShaderBuffer)
class VertexBuffer : public Gfx::VertexBuffer, public Buffer
{
public:
VertexBuffer(PGraphics graphics, const VertexBufferCreateInfo &sourceData);
virtual ~VertexBuffer();
virtual void updateRegion(DataSource update) override;
virtual void download(Array<uint8>& buffer) override;
virtual void beginFrame() 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(VkAccessFlags srcAccess, VkPipelineStageFlags srcStage,
VkAccessFlags dstAccess, VkPipelineStageFlags dstStage) override;
};
DEFINE_REF(VertexBuffer)
class IndexBuffer : public Gfx::IndexBuffer, public Buffer
{
public:
IndexBuffer(PGraphics graphics, const IndexBufferCreateInfo &sourceData);
virtual ~IndexBuffer();
virtual void download(Array<uint8>& buffer) override;
virtual void beginFrame() 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(VkAccessFlags srcAccess, VkPipelineStageFlags srcStage,
VkAccessFlags dstAccess, VkPipelineStageFlags dstStage) override;
};
DEFINE_REF(IndexBuffer)
}
}
} // namespace Vulkan
} // namespace Seele
+312 -378
View File
@@ -1,433 +1,367 @@
#include "Descriptor.h"
#include "Graphics.h"
#include "Texture.h"
#include "Buffer.h"
#include "Command.h"
#include "Graphics.h"
#include "Texture.h"
using namespace Seele;
using namespace Seele::Vulkan;
DescriptorLayout::DescriptorLayout(PGraphics graphics, const std::string& name)
: Gfx::DescriptorLayout(name)
, graphics(graphics)
, layoutHandle(VK_NULL_HANDLE)
{
}
DescriptorLayout::~DescriptorLayout()
{
if (layoutHandle != VK_NULL_HANDLE)
{
vkDestroyDescriptorSetLayout(graphics->getDevice(), layoutHandle, nullptr);
}
: Gfx::DescriptorLayout(name), graphics(graphics), layoutHandle(VK_NULL_HANDLE) {}
DescriptorLayout::~DescriptorLayout() {
if (layoutHandle != VK_NULL_HANDLE) {
vkDestroyDescriptorSetLayout(graphics->getDevice(), layoutHandle, nullptr);
}
}
void DescriptorLayout::create()
{
if (layoutHandle != VK_NULL_HANDLE)
{
return;
}
bindings.resize(descriptorBindings.size());
Array<VkDescriptorBindingFlags> bindingFlags(descriptorBindings.size());
for (size_t i = 0; i < descriptorBindings.size(); ++i)
{
const Gfx::DescriptorBinding &gfxBinding = descriptorBindings[i];
bindings[i] = {
.binding = gfxBinding.binding,
.descriptorType = cast(gfxBinding.descriptorType),
.descriptorCount = gfxBinding.descriptorCount,
.stageFlags = gfxBinding.shaderStages,
.pImmutableSamplers = nullptr,
};
bindingFlags[i] = gfxBinding.bindingFlags;
}
VkDescriptorSetLayoutBindingFlagsCreateInfo bindingFlagsInfo = {
.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_BINDING_FLAGS_CREATE_INFO,
.pNext = nullptr,
.bindingCount = static_cast<uint32>(bindingFlags.size()),
.pBindingFlags = bindingFlags.data(),
void DescriptorLayout::create() {
if (layoutHandle != VK_NULL_HANDLE) {
return;
}
bindings.resize(descriptorBindings.size());
Array<VkDescriptorBindingFlags> bindingFlags(descriptorBindings.size());
for (size_t i = 0; i < descriptorBindings.size(); ++i) {
const Gfx::DescriptorBinding& gfxBinding = descriptorBindings[i];
bindings[i] = {
.binding = gfxBinding.binding,
.descriptorType = cast(gfxBinding.descriptorType),
.descriptorCount = gfxBinding.descriptorCount,
.stageFlags = gfxBinding.shaderStages,
.pImmutableSamplers = nullptr,
};
VkDescriptorSetLayoutCreateInfo createInfo = {
.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO,
.pNext = &bindingFlagsInfo,
.flags = 0,
.bindingCount = (uint32)bindings.size(),
.pBindings = bindings.data(),
};
VK_CHECK(vkCreateDescriptorSetLayout(graphics->getDevice(), &createInfo, nullptr, &layoutHandle));
bindingFlags[i] = gfxBinding.bindingFlags;
}
VkDescriptorSetLayoutBindingFlagsCreateInfo bindingFlagsInfo = {
.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_BINDING_FLAGS_CREATE_INFO,
.pNext = nullptr,
.bindingCount = static_cast<uint32>(bindingFlags.size()),
.pBindingFlags = bindingFlags.data(),
};
VkDescriptorSetLayoutCreateInfo createInfo = {
.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO,
.pNext = &bindingFlagsInfo,
.flags = 0,
.bindingCount = (uint32)bindings.size(),
.pBindings = bindings.data(),
};
VK_CHECK(vkCreateDescriptorSetLayout(graphics->getDevice(), &createInfo, nullptr, &layoutHandle));
pool = new DescriptorPool(graphics, *this);
pool = new DescriptorPool(graphics, this);
hash = CRC::Calculate(bindings.data(), sizeof(VkDescriptorSetLayoutBinding) * bindings.size(), CRC::CRC_32());
hash = CRC::Calculate(bindings.data(), sizeof(VkDescriptorSetLayoutBinding) * bindings.size(), CRC::CRC_32());
}
PipelineLayout::~PipelineLayout()
{
}
DescriptorPool::DescriptorPool(PGraphics graphics, PDescriptorLayout layout) : graphics(graphics), layout(layout) {
for (uint32 i = 0; i < cachedHandles.size(); ++i) {
cachedHandles[i] = nullptr;
}
Map<uint32, VkPipelineLayout> cachedLayouts;
void PipelineLayout::create()
{
vulkanDescriptorLayouts.resize(descriptorSetLayouts.size());
for (size_t i = 0; i < descriptorSetLayouts.size(); ++i)
{
// There could be unused descriptor set indices
if(descriptorSetLayouts[i] == nullptr)
{
vulkanDescriptorLayouts[i] = VK_NULL_HANDLE;
continue;
}
PDescriptorLayout layout = descriptorSetLayouts[i].cast<DescriptorLayout>();
layout->create();
vulkanDescriptorLayouts[i] = layout->getHandle();
uint32 perTypeSizes[VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT]; // TODO: FIX ENUM
std::memset(perTypeSizes, 0, sizeof(perTypeSizes));
for (uint32 i = 0; i < layout->getBindings().size(); ++i) {
auto& binding = layout->getBindings()[i];
int typeIndex = binding.descriptorType;
perTypeSizes[typeIndex] += 256;
}
Array<VkDescriptorPoolSize> poolSizes;
for (uint32 i = 0; i < VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT; ++i) {
if (perTypeSizes[i] > 0) {
VkDescriptorPoolSize size;
size.descriptorCount = perTypeSizes[i];
size.type = (VkDescriptorType)i;
poolSizes.add(size);
}
Array<VkPushConstantRange> vkPushConstants(pushConstants.size());
for (size_t i = 0; i < pushConstants.size(); i++)
{
vkPushConstants[i].offset = pushConstants[i].offset;
vkPushConstants[i].size = pushConstants[i].size;
vkPushConstants[i].stageFlags = (VkShaderStageFlagBits)pushConstants[i].stageFlags;
}
VkPipelineLayoutCreateInfo createInfo = {
.sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO,
.pNext = nullptr,
.flags = 0,
.setLayoutCount = (uint32)vulkanDescriptorLayouts.size(),
.pSetLayouts = vulkanDescriptorLayouts.data(),
.pushConstantRangeCount = (uint32)vkPushConstants.size(),
.pPushConstantRanges = vkPushConstants.data(),
};
layoutHash = CRC::Calculate(createInfo.pPushConstantRanges, sizeof(VkPushConstantRange) * createInfo.pushConstantRangeCount, CRC::CRC_32());
layoutHash = CRC::Calculate(createInfo.pSetLayouts, sizeof(VkDescriptorSetLayout) * createInfo.setLayoutCount, CRC::CRC_32(), layoutHash);
if (cachedLayouts.contains(layoutHash))
{
layoutHandle = cachedLayouts[layoutHash];
return;
}
VK_CHECK(vkCreatePipelineLayout(graphics->getDevice(), &createInfo, nullptr, &layoutHandle));
cachedLayouts[layoutHash] = layoutHandle;
}
VkDescriptorPoolCreateInfo createInfo = {
.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO,
.pNext = nullptr,
.flags = 0,
.maxSets = maxSets * Gfx::numFramesBuffered,
.poolSizeCount = (uint32)poolSizes.size(),
.pPoolSizes = poolSizes.data(),
};
VK_CHECK(vkCreateDescriptorPool(graphics->getDevice(), &createInfo, nullptr, &poolHandle));
}
void PipelineLayout::reset()
{
vkDestroyPipelineLayout(graphics->getDevice(), layoutHandle, nullptr);
descriptorSetLayouts.clear();
pushConstants.clear();
DescriptorPool::~DescriptorPool() {
graphics->getDestructionManager()->queueDescriptorPool(graphics->getGraphicsCommands()->getCommands(), poolHandle);
if (nextAlloc) {
delete nextAlloc;
}
}
DescriptorSet::~DescriptorSet()
{
}
void DescriptorSet::updateBuffer(uint32_t binding, Gfx::PUniformBuffer uniformBuffer)
{
PUniformBuffer vulkanBuffer = uniformBuffer.cast<UniformBuffer>();
UniformBuffer* cachedBuffer = reinterpret_cast<UniformBuffer*>(cachedData[binding]);
if(vulkanBuffer->isDataEquals(cachedBuffer))
{
//std::cout << "uniform data equal, skip" << std::endl;
return;
Gfx::PDescriptorSet DescriptorPool::allocateDescriptorSet() {
VkDescriptorSetLayout layoutHandle = layout->getHandle();
VkDescriptorSetVariableDescriptorCountAllocateInfo setCounts = {
.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_VARIABLE_DESCRIPTOR_COUNT_ALLOCATE_INFO,
.pNext = nullptr,
.descriptorSetCount = 1,
};
VkDescriptorSetAllocateInfo allocInfo = {
.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO,
.pNext = nullptr,
.descriptorPool = poolHandle,
.descriptorSetCount = 1,
.pSetLayouts = &layoutHandle,
};
uint32 counts = 0;
for (const auto& binding : layout->bindings) {
if (binding.descriptorCount > 0) {
counts = binding.descriptorCount;
}
bufferInfos.add(VkDescriptorBufferInfo{
.buffer = vulkanBuffer->getHandle(),
.offset = 0,
.range = vulkanBuffer->getSize(),
});
}
if (layout->bindings.size() > 0) {
setCounts.pDescriptorCounts = &counts;
allocInfo.pNext = &setCounts;
}
for (uint32 setIndex = 0; setIndex < cachedHandles.size(); ++setIndex) {
if (cachedHandles[setIndex] == nullptr) {
cachedHandles[setIndex] = new DescriptorSet(graphics, this);
}
if (cachedHandles[setIndex]->isCurrentlyBound() || cachedHandles[setIndex]->isCurrentlyInUse()) {
// Currently in use, skip
continue;
}
if (cachedHandles[setIndex]->getHandle() == VK_NULL_HANDLE) {
// If it hasnt been initialized, allocate it
VK_CHECK(vkAllocateDescriptorSets(graphics->getDevice(), &allocInfo, &cachedHandles[setIndex]->setHandle));
}
cachedHandles[setIndex]->allocate();
writeDescriptors.add(VkWriteDescriptorSet{
.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET,
.pNext = nullptr,
.dstSet = setHandle,
.dstBinding = binding,
.dstArrayElement = 0,
.descriptorCount = 1,
.descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,
.pBufferInfo = &bufferInfos.back(),
});
PDescriptorSet vulkanSet = cachedHandles[setIndex];
vulkanSet->cachedData.resize(layout->bindings.size());
// Not really pretty, but this way the set knows which ones are valid
std::memset(vulkanSet->cachedData.data(), 0, sizeof(void*) * vulkanSet->cachedData.size());
cachedData[binding] = vulkanBuffer.getHandle();
// Found set, stop searching
return vulkanSet;
}
if (nextAlloc == nullptr) {
nextAlloc = new DescriptorPool(graphics, layout);
}
// std::cout << "Out of descriptors, forwarding" << std::endl;
return nextAlloc->allocateDescriptorSet();
// throw std::logic_error("Out of descriptor sets");
}
void DescriptorSet::updateBuffer(uint32_t binding, Gfx::PShaderBuffer shaderBuffer)
{
PShaderBuffer vulkanBuffer = shaderBuffer.cast<ShaderBuffer>();
ShaderBuffer* cachedBuffer = reinterpret_cast<ShaderBuffer*>(cachedData[binding]);
if(vulkanBuffer.getHandle() == cachedBuffer)
{
return;
void DescriptorPool::reset() {
for (uint32 i = 0; i < cachedHandles.size(); ++i) {
if (cachedHandles[i] == nullptr) {
return;
}
bufferInfos.add(VkDescriptorBufferInfo{
.buffer = vulkanBuffer->getHandle(),
.offset = 0,
.range = vulkanBuffer->getSize(),
});
writeDescriptors.add(VkWriteDescriptorSet{
.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET,
.pNext = nullptr,
.dstSet = setHandle,
.dstBinding = binding,
.dstArrayElement = 0,
.descriptorCount = 1,
.descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER,
.pBufferInfo = &bufferInfos.back(),
});
cachedData[binding] = vulkanBuffer.getHandle();
cachedHandles[i]->free();
}
if (nextAlloc != nullptr) {
nextAlloc->reset();
}
}
void DescriptorSet::updateSampler(uint32_t binding, Gfx::PSampler samplerState)
{
PSampler vulkanSampler = samplerState.cast<Sampler>();
Sampler* cachedSampler = reinterpret_cast<Sampler*>(cachedData[binding]);
if(vulkanSampler.getHandle() == cachedSampler)
{
return;
}
DescriptorSet::DescriptorSet(PGraphics graphics, PDescriptorPool owner)
: Gfx::DescriptorSet(owner->getLayout()), setHandle(VK_NULL_HANDLE), graphics(graphics), owner(owner), bindCount(0),
currentlyInUse(false) {}
DescriptorSet::~DescriptorSet() {}
void DescriptorSet::updateBuffer(uint32_t binding, Gfx::PUniformBuffer uniformBuffer) {
PUniformBuffer vulkanBuffer = uniformBuffer.cast<UniformBuffer>();
UniformBuffer* cachedBuffer = reinterpret_cast<UniformBuffer*>(cachedData[binding]);
if (vulkanBuffer->isDataEquals(cachedBuffer)) {
// std::cout << "uniform data equal, skip" << std::endl;
return;
}
bufferInfos.add(VkDescriptorBufferInfo{
.buffer = vulkanBuffer->getHandle(),
.offset = 0,
.range = vulkanBuffer->getSize(),
});
writeDescriptors.add(VkWriteDescriptorSet{
.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET,
.pNext = nullptr,
.dstSet = setHandle,
.dstBinding = binding,
.dstArrayElement = 0,
.descriptorCount = 1,
.descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,
.pBufferInfo = &bufferInfos.back(),
});
cachedData[binding] = vulkanBuffer.getHandle();
}
void DescriptorSet::updateBuffer(uint32_t binding, Gfx::PShaderBuffer shaderBuffer) {
PShaderBuffer vulkanBuffer = shaderBuffer.cast<ShaderBuffer>();
ShaderBuffer* cachedBuffer = reinterpret_cast<ShaderBuffer*>(cachedData[binding]);
if (vulkanBuffer.getHandle() == cachedBuffer) {
return;
}
bufferInfos.add(VkDescriptorBufferInfo{
.buffer = vulkanBuffer->getHandle(),
.offset = 0,
.range = vulkanBuffer->getSize(),
});
writeDescriptors.add(VkWriteDescriptorSet{
.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET,
.pNext = nullptr,
.dstSet = setHandle,
.dstBinding = binding,
.dstArrayElement = 0,
.descriptorCount = 1,
.descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER,
.pBufferInfo = &bufferInfos.back(),
});
cachedData[binding] = vulkanBuffer.getHandle();
}
void DescriptorSet::updateSampler(uint32_t binding, Gfx::PSampler samplerState) {
PSampler vulkanSampler = samplerState.cast<Sampler>();
Sampler* cachedSampler = reinterpret_cast<Sampler*>(cachedData[binding]);
if (vulkanSampler.getHandle() == cachedSampler) {
return;
}
imageInfos.add(VkDescriptorImageInfo{
.sampler = vulkanSampler->sampler,
.imageView = VK_NULL_HANDLE,
.imageLayout = VK_IMAGE_LAYOUT_UNDEFINED,
});
writeDescriptors.add(VkWriteDescriptorSet{
.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET,
.pNext = nullptr,
.dstSet = setHandle,
.dstBinding = binding,
.dstArrayElement = 0,
.descriptorCount = 1,
.descriptorType = VK_DESCRIPTOR_TYPE_SAMPLER,
.pImageInfo = &imageInfos.back(),
});
cachedData[binding] = vulkanSampler.getHandle();
}
void DescriptorSet::updateTexture(uint32_t binding, Gfx::PTexture texture, Gfx::PSampler samplerState) {
TextureBase* vulkanTexture = texture.cast<TextureBase>().getHandle();
TextureBase* cachedTexture = reinterpret_cast<TextureBase*>(cachedData[binding]);
if (vulkanTexture == cachedTexture) {
return;
}
// It is assumed that the image is in the correct layout
imageInfos.add(VkDescriptorImageInfo{
.sampler = samplerState != nullptr ? samplerState.cast<Sampler>()->sampler : VK_NULL_HANDLE,
.imageView = vulkanTexture->getView(),
.imageLayout = cast(vulkanTexture->getLayout()),
});
VkDescriptorType descriptorType = VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE;
if (samplerState != nullptr) {
descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER;
} else if (vulkanTexture->getUsage() & VK_IMAGE_USAGE_STORAGE_BIT) {
descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_IMAGE;
}
writeDescriptors.add(VkWriteDescriptorSet{
.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET,
.pNext = nullptr,
.dstSet = setHandle,
.dstBinding = binding,
.dstArrayElement = 0,
.descriptorCount = 1,
.descriptorType = descriptorType,
.pImageInfo = &imageInfos.back(),
});
cachedData[binding] = vulkanTexture;
}
void DescriptorSet::updateTextureArray(uint32_t binding, Array<Gfx::PTexture> textures) {
// maybe make this a parameter?
uint32 arrayElement = 0;
for (auto& gfxTexture : textures) {
TextureBase* vulkanTexture = gfxTexture.cast<TextureBase>().getHandle();
imageInfos.add(VkDescriptorImageInfo{
.sampler = vulkanSampler->sampler,
.imageView = VK_NULL_HANDLE,
.imageLayout = VK_IMAGE_LAYOUT_UNDEFINED,
});
writeDescriptors.add(VkWriteDescriptorSet{
.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET,
.pNext = nullptr,
.dstSet = setHandle,
.dstBinding = binding,
.dstArrayElement = 0,
.descriptorCount = 1,
.descriptorType = VK_DESCRIPTOR_TYPE_SAMPLER,
.pImageInfo = &imageInfos.back(),
});
cachedData[binding] = vulkanSampler.getHandle();
}
void DescriptorSet::updateTexture(uint32_t binding, Gfx::PTexture texture, Gfx::PSampler samplerState)
{
TextureBase* vulkanTexture = texture.cast<TextureBase>().getHandle();
TextureBase* cachedTexture = reinterpret_cast<TextureBase*>(cachedData[binding]);
if(vulkanTexture == cachedTexture)
{
return;
}
//It is assumed that the image is in the correct layout
imageInfos.add(VkDescriptorImageInfo{
.sampler = samplerState != nullptr ? samplerState.cast<Sampler>()->sampler : VK_NULL_HANDLE,
.sampler = VK_NULL_HANDLE,
.imageView = vulkanTexture->getView(),
.imageLayout = cast(vulkanTexture->getLayout()),
});
VkDescriptorType descriptorType = VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE;
if(samplerState != nullptr)
{
descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER;
}
else if (vulkanTexture->getUsage() & VK_IMAGE_USAGE_STORAGE_BIT)
{
descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_IMAGE;
if (vulkanTexture->getUsage() & VK_IMAGE_USAGE_STORAGE_BIT) {
descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_IMAGE;
}
writeDescriptors.add(VkWriteDescriptorSet{
.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET,
.pNext = nullptr,
.dstSet = setHandle,
.dstBinding = binding,
.dstArrayElement = 0,
.dstArrayElement = arrayElement++,
.descriptorCount = 1,
.descriptorType = descriptorType,
.pImageInfo = &imageInfos.back(),
});
cachedData[binding] = vulkanTexture;
}
void DescriptorSet::updateTextureArray(uint32_t binding, Array<Gfx::PTexture> textures)
{
// maybe make this a parameter?
uint32 arrayElement = 0;
for(auto& gfxTexture : textures)
{
TextureBase* vulkanTexture = gfxTexture.cast<TextureBase>().getHandle();
imageInfos.add(VkDescriptorImageInfo{
.sampler = VK_NULL_HANDLE,
.imageView = vulkanTexture->getView(),
.imageLayout = cast(vulkanTexture->getLayout()),
});
VkDescriptorType descriptorType = VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE;
if (vulkanTexture->getUsage() & VK_IMAGE_USAGE_STORAGE_BIT)
{
descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_IMAGE;
}
writeDescriptors.add(VkWriteDescriptorSet{
.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET,
.pNext = nullptr,
.dstSet = setHandle,
.dstBinding = binding,
.dstArrayElement = arrayElement++,
.descriptorCount = 1,
.descriptorType = descriptorType,
.pImageInfo = &imageInfos.back(),
});
}
});
}
}
bool DescriptorSet::operator<(Gfx::PDescriptorSet other)
{
PDescriptorSet otherSet = other.cast<DescriptorSet>();
return this < otherSet.getHandle();
void DescriptorSet::writeChanges() {
if (writeDescriptors.size() > 0) {
if (isCurrentlyBound()) {
std::cout << "Descriptor currently bound, allocate a new one instead" << std::endl;
assert(!isCurrentlyBound());
}
vkUpdateDescriptorSets(graphics->getDevice(), (uint32)writeDescriptors.size(), writeDescriptors.data(), 0, nullptr);
writeDescriptors.clear();
imageInfos.clear();
bufferInfos.clear();
}
}
uint32 DescriptorSet::getSetIndex() const
{
return owner->getLayout().getSetIndex();
}
PipelineLayout::PipelineLayout(PGraphics graphics, Gfx::PPipelineLayout baseLayout)
: Gfx::PipelineLayout(baseLayout), graphics(graphics), layoutHandle(VK_NULL_HANDLE) {}
void DescriptorSet::writeChanges()
{
if (writeDescriptors.size() > 0)
{
if(isCurrentlyBound())
{
std::cout << "Descriptor currently bound, allocate a new one instead" << std::endl;
assert(!isCurrentlyBound());
}
vkUpdateDescriptorSets(graphics->getDevice(), (uint32)writeDescriptors.size(), writeDescriptors.data(), 0, nullptr);
writeDescriptors.clear();
imageInfos.clear();
bufferInfos.clear();
}
}
PipelineLayout::~PipelineLayout() {}
DescriptorPool::DescriptorPool(PGraphics graphics, DescriptorLayout &layout)
: graphics(graphics)
, layout(layout)
{
for(uint32 i = 0; i < cachedHandles.size(); ++i)
{
cachedHandles[i] = nullptr;
}
Map<uint32, VkPipelineLayout> cachedLayouts;
uint32 perTypeSizes[VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT]; // TODO: FIX ENUM
std::memset(perTypeSizes, 0, sizeof(perTypeSizes));
for (uint32 i = 0; i < layout.getBindings().size(); ++i)
{
auto &binding = layout.getBindings()[i];
int typeIndex = binding.descriptorType;
perTypeSizes[typeIndex] += 256;
void PipelineLayout::create() {
vulkanDescriptorLayouts.resize(descriptorSetLayouts.size());
for (size_t i = 0; i < descriptorSetLayouts.size(); ++i) {
// There could be unused descriptor set indices
if (descriptorSetLayouts[i] == nullptr) {
vulkanDescriptorLayouts[i] = VK_NULL_HANDLE;
continue;
}
Array<VkDescriptorPoolSize> poolSizes;
for (uint32 i = 0; i < VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT; ++i)
{
if (perTypeSizes[i] > 0)
{
VkDescriptorPoolSize size;
size.descriptorCount = perTypeSizes[i];
size.type = (VkDescriptorType)i;
poolSizes.add(size);
}
}
VkDescriptorPoolCreateInfo createInfo = {
.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO,
.pNext = nullptr,
.flags = 0,
.maxSets = maxSets * Gfx::numFramesBuffered,
.poolSizeCount = (uint32)poolSizes.size(),
.pPoolSizes = poolSizes.data(),
};
VK_CHECK(vkCreateDescriptorPool(graphics->getDevice(), &createInfo, nullptr, &poolHandle));
}
PDescriptorLayout layout = descriptorSetLayouts[i].cast<DescriptorLayout>();
layout->create();
vulkanDescriptorLayouts[i] = layout->getHandle();
}
DescriptorPool::~DescriptorPool()
{
graphics->getDestructionManager()->queueDescriptorPool(graphics->getGraphicsCommands()->getCommands(), poolHandle);
if(nextAlloc)
{
delete nextAlloc;
}
}
Array<VkPushConstantRange> vkPushConstants(pushConstants.size());
for (size_t i = 0; i < pushConstants.size(); i++) {
vkPushConstants[i].offset = pushConstants[i].offset;
vkPushConstants[i].size = pushConstants[i].size;
vkPushConstants[i].stageFlags = (VkShaderStageFlagBits)pushConstants[i].stageFlags;
}
Gfx::PDescriptorSet DescriptorPool::allocateDescriptorSet()
{
VkDescriptorSetLayout layoutHandle = layout.getHandle();
VkDescriptorSetVariableDescriptorCountAllocateInfo setCounts = {
.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_VARIABLE_DESCRIPTOR_COUNT_ALLOCATE_INFO,
.pNext = nullptr,
.descriptorSetCount = 1,
};
VkDescriptorSetAllocateInfo allocInfo = {
.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO,
.pNext = nullptr,
.descriptorPool = poolHandle,
.descriptorSetCount = 1,
.pSetLayouts = &layoutHandle,
};
uint32 counts = 0;
for(const auto& binding : layout.bindings)
{
if(binding.descriptorCount > 0)
{
counts = binding.descriptorCount;
}
}
if (layout.bindings.size() > 0)
{
setCounts.pDescriptorCounts = &counts;
allocInfo.pNext = &setCounts;
}
for(uint32 setIndex = 0; setIndex < cachedHandles.size(); ++setIndex)
{
if(cachedHandles[setIndex] == nullptr)
{
cachedHandles[setIndex] = new DescriptorSet(graphics, this);
}
if(cachedHandles[setIndex]->isCurrentlyBound() || cachedHandles[setIndex]->isCurrentlyInUse())
{
// Currently in use, skip
continue;
}
if(cachedHandles[setIndex]->getHandle() == VK_NULL_HANDLE)
{
//If it hasnt been initialized, allocate it
VK_CHECK(vkAllocateDescriptorSets(graphics->getDevice(), &allocInfo, &cachedHandles[setIndex]->setHandle));
}
cachedHandles[setIndex]->allocate();
PDescriptorSet vulkanSet = cachedHandles[setIndex];
vulkanSet->cachedData.resize(layout.bindings.size());
// Not really pretty, but this way the set knows which ones are valid
std::memset(vulkanSet->cachedData.data(), 0, sizeof(void*) * vulkanSet->cachedData.size());
//Found set, stop searching
return vulkanSet;
}
if(nextAlloc == nullptr)
{
nextAlloc = new DescriptorPool(graphics, layout);
}
//std::cout << "Out of descriptors, forwarding" << std::endl;
return nextAlloc->allocateDescriptorSet();
//throw std::logic_error("Out of descriptor sets");
}
VkPipelineLayoutCreateInfo createInfo = {
.sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO,
.pNext = nullptr,
.flags = 0,
.setLayoutCount = (uint32)vulkanDescriptorLayouts.size(),
.pSetLayouts = vulkanDescriptorLayouts.data(),
.pushConstantRangeCount = (uint32)vkPushConstants.size(),
.pPushConstantRanges = vkPushConstants.data(),
};
void DescriptorPool::reset()
{
for(uint32 i = 0; i < cachedHandles.size(); ++i)
{
if(cachedHandles[i] == nullptr)
{
return;
}
cachedHandles[i]->free();
}
if(nextAlloc != nullptr)
{
nextAlloc->reset();
}
layoutHash = CRC::Calculate(createInfo.pPushConstantRanges,
sizeof(VkPushConstantRange) * createInfo.pushConstantRangeCount, CRC::CRC_32());
layoutHash = CRC::Calculate(createInfo.pSetLayouts, sizeof(VkDescriptorSetLayout) * createInfo.setLayoutCount,
CRC::CRC_32(), layoutHash);
if (cachedLayouts.contains(layoutHash)) {
layoutHandle = cachedLayouts[layoutHash];
return;
}
VK_CHECK(vkCreatePipelineLayout(graphics->getDevice(), &createInfo, nullptr, &layoutHandle));
cachedLayouts[layoutHash] = layoutHandle;
}
+73 -123
View File
@@ -1,150 +1,100 @@
#pragma once
#include "Containers/List.h"
#include "Enums.h"
#include "Graphics/Descriptor.h"
#include "Containers/List.h"
#include "Resources.h"
namespace Seele
{
namespace Vulkan
{
namespace Seele {
namespace Vulkan {
DECLARE_REF(Graphics)
class DescriptorLayout : public Gfx::DescriptorLayout
{
class DescriptorLayout : public Gfx::DescriptorLayout {
public:
DescriptorLayout(PGraphics graphics, const std::string& name);
virtual ~DescriptorLayout();
virtual void create() override;
constexpr VkDescriptorSetLayout getHandle() const
{
return layoutHandle;
}
DescriptorLayout(PGraphics graphics, const std::string& name);
virtual ~DescriptorLayout();
virtual void create() override;
constexpr VkDescriptorSetLayout getHandle() const { return layoutHandle; }
private:
uint32 hash;
PGraphics graphics;
Array<VkDescriptorSetLayoutBinding> bindings;
VkDescriptorSetLayout layoutHandle;
friend class DescriptorPool;
PGraphics graphics;
Array<VkDescriptorSetLayoutBinding> bindings;
VkDescriptorSetLayout layoutHandle;
friend class DescriptorPool;
};
DEFINE_REF(DescriptorLayout)
class PipelineLayout : public Gfx::PipelineLayout
{
DECLARE_REF(DescriptorSet)
class DescriptorPool : public Gfx::DescriptorPool {
public:
PipelineLayout(PGraphics graphics, Gfx::PPipelineLayout baseLayout)
: Gfx::PipelineLayout(baseLayout)
, graphics(graphics)
, layoutHandle(VK_NULL_HANDLE)
{}
virtual ~PipelineLayout();
virtual void create();
virtual void reset();
constexpr VkPipelineLayout getHandle() const
{
return layoutHandle;
}
DescriptorPool(PGraphics graphics, PDescriptorLayout layout);
virtual ~DescriptorPool();
virtual Gfx::PDescriptorSet allocateDescriptorSet() override;
virtual void reset() override;
constexpr VkDescriptorPool getHandle() const { return poolHandle; }
constexpr PDescriptorLayout getLayout() const { return layout; }
private:
Array<VkDescriptorSetLayout> vulkanDescriptorLayouts;
PGraphics graphics;
VkPipelineLayout layoutHandle;
PGraphics graphics;
PDescriptorLayout layout;
const static int maxSets = 64;
StaticArray<ODescriptorSet, maxSets> cachedHandles;
VkDescriptorPool poolHandle;
DescriptorPool* nextAlloc = nullptr;
};
DEFINE_REF(PipelineLayout)
DEFINE_REF(DescriptorPool)
class DescriptorSet : public Gfx::DescriptorSet
{
class DescriptorSet : public Gfx::DescriptorSet {
public:
DescriptorSet(PGraphics graphics, PDescriptorPool owner)
: setHandle(VK_NULL_HANDLE)
, graphics(graphics)
, owner(owner)
, bindCount(0)
, currentlyInUse(false)
{
}
virtual ~DescriptorSet();
virtual void writeChanges();
virtual void updateBuffer(uint32_t binding, Gfx::PUniformBuffer uniformBuffer);
virtual void updateBuffer(uint32_t binding, Gfx::PShaderBuffer uniformBuffer);
virtual void updateSampler(uint32_t binding, Gfx::PSampler samplerState);
virtual void updateTexture(uint32_t binding, Gfx::PTexture texture, Gfx::PSampler sampler = nullptr);
virtual void updateTextureArray(uint32_t binding, Array<Gfx::PTexture> texture);
virtual bool operator<(Gfx::PDescriptorSet other);
constexpr bool isCurrentlyBound() const
{
return bindCount > 0;
}
constexpr bool isCurrentlyInUse() const
{
return currentlyInUse;
}
constexpr void bind()
{
bindCount++;
}
constexpr void unbind()
{
bindCount--;
}
constexpr void allocate()
{
currentlyInUse = true;
}
constexpr void free()
{
currentlyInUse = false;
}
constexpr VkDescriptorSet getHandle() const
{
return setHandle;
}
virtual uint32 getSetIndex() const;
DescriptorSet(PGraphics graphics, PDescriptorPool owner);
virtual ~DescriptorSet();
virtual void writeChanges() override;
virtual void updateBuffer(uint32_t binding, Gfx::PUniformBuffer uniformBuffer) override;
virtual void updateBuffer(uint32_t binding, Gfx::PShaderBuffer uniformBuffer) override;
virtual void updateSampler(uint32_t binding, Gfx::PSampler samplerState) override;
virtual void updateTexture(uint32_t binding, Gfx::PTexture texture, Gfx::PSampler sampler = nullptr) override;
virtual void updateTextureArray(uint32_t binding, Array<Gfx::PTexture> texture) override;
constexpr bool isCurrentlyBound() const { return bindCount > 0; }
constexpr bool isCurrentlyInUse() const { return currentlyInUse; }
constexpr void bind() { bindCount++; }
constexpr void unbind() { bindCount--; }
constexpr void allocate() { currentlyInUse = true; }
constexpr void free() { currentlyInUse = false; }
constexpr VkDescriptorSet getHandle() const { return setHandle; }
private:
List<VkDescriptorImageInfo> imageInfos;
List<VkDescriptorBufferInfo> bufferInfos;
Array<VkWriteDescriptorSet> writeDescriptors;
// contains the previously bound resources at every binding
// 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;
VkDescriptorSet setHandle;
PGraphics graphics;
PDescriptorPool owner;
uint32 bindCount;
bool currentlyInUse;
friend class DescriptorPool;
friend class Command;
friend class RenderCommand;
friend class ComputeCommand;
List<VkDescriptorImageInfo> imageInfos;
List<VkDescriptorBufferInfo> bufferInfos;
Array<VkWriteDescriptorSet> writeDescriptors;
// contains the previously bound resources at every binding
// 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;
VkDescriptorSet setHandle;
PGraphics graphics;
PDescriptorPool owner;
uint32 bindCount;
bool currentlyInUse;
friend class DescriptorPool;
friend class Command;
friend class RenderCommand;
friend class ComputeCommand;
};
DEFINE_REF(DescriptorSet)
class DescriptorPool : public Gfx::DescriptorPool
{
class PipelineLayout : public Gfx::PipelineLayout {
public:
DescriptorPool(PGraphics graphics, DescriptorLayout &layout);
virtual ~DescriptorPool();
virtual Gfx::PDescriptorSet allocateDescriptorSet() override;
virtual void reset() override;
constexpr VkDescriptorPool getHandle() const
{
return poolHandle;
}
constexpr DescriptorLayout& getLayout() const
{
return layout;
}
PipelineLayout(PGraphics graphics, Gfx::PPipelineLayout baseLayout);
virtual ~PipelineLayout();
virtual void create();
constexpr VkPipelineLayout getHandle() const { return layoutHandle; }
private:
PGraphics graphics;
DescriptorLayout &layout;
const static int maxSets = 64;
StaticArray<ODescriptorSet, maxSets> cachedHandles;
VkDescriptorPool poolHandle;
DescriptorPool* nextAlloc = nullptr;
Array<VkDescriptorSetLayout> vulkanDescriptorLayouts;
PGraphics graphics;
VkPipelineLayout layoutHandle;
};
DEFINE_REF(DescriptorPool)
DEFINE_REF(PipelineLayout)
} // namespace Vulkan
} // namespace Seele
+43 -44
View File
@@ -1,4 +1,5 @@
#include "Enums.h"
#include <stdexcept>
using namespace Seele;
using namespace Seele::Vulkan;
@@ -76,9 +77,8 @@ Seele::Gfx::SeDescriptorType Seele::Vulkan::cast(const VkDescriptorType &descrip
return SE_DESCRIPTOR_TYPE_ACCELERATION_STRUCTURE_NV;
#endif
default:
break;
throw std::logic_error("Not implemented");
}
return SE_DESCRIPTOR_TYPE_MAX_ENUM;
}
VkShaderStageFlagBits Seele::Vulkan::cast(const Seele::Gfx::SeShaderStageFlagBits &stage)
@@ -120,10 +120,9 @@ VkShaderStageFlagBits Seele::Vulkan::cast(const Seele::Gfx::SeShaderStageFlagBit
case SE_SHADER_STAGE_MESH_BIT_NV:
return VK_SHADER_STAGE_MESH_BIT_NV;
#endif
default:
break;
default: throw std::logic_error("Not implemented");
}
return VK_SHADER_STAGE_ALL;
}
Seele::Gfx::SeShaderStageFlagBits Seele::Vulkan::cast(const VkShaderStageFlagBits &stage)
@@ -164,10 +163,10 @@ Seele::Gfx::SeShaderStageFlagBits Seele::Vulkan::cast(const VkShaderStageFlagBit
case VK_SHADER_STAGE_MESH_BIT_NV:
return SE_SHADER_STAGE_MESH_BIT_NV;
#endif
default:
break;
default: throw std::logic_error("Not implemented");
}
return SE_SHADER_STAGE_ALL;
}
VkFormat Seele::Vulkan::cast(const Seele::Gfx::SeFormat &format)
@@ -1090,8 +1089,8 @@ Seele::Gfx::SeFormat Seele::Vulkan::cast(const VkFormat &format)
return SE_FORMAT_PVRTC2_2BPP_SRGB_BLOCK_IMG;
case VK_FORMAT_PVRTC2_4BPP_SRGB_BLOCK_IMG:
return SE_FORMAT_PVRTC2_4BPP_SRGB_BLOCK_IMG;
default:
return SE_FORMAT_MAX_ENUM;
default: throw std::logic_error("Not implemented");
}
}
@@ -1129,8 +1128,8 @@ VkImageLayout Seele::Vulkan::cast(const Gfx::SeImageLayout &imageLayout)
return VK_IMAGE_LAYOUT_SHADING_RATE_OPTIMAL_NV;
case SE_IMAGE_LAYOUT_FRAGMENT_DENSITY_MAP_OPTIMAL_EXT:
return VK_IMAGE_LAYOUT_FRAGMENT_DENSITY_MAP_OPTIMAL_EXT;
default:
return VK_IMAGE_LAYOUT_MAX_ENUM;
default: throw std::logic_error("Not implemented");
}
}
Gfx::SeImageLayout Seele::Vulkan::cast(const VkImageLayout &imageLayout)
@@ -1167,8 +1166,8 @@ Gfx::SeImageLayout Seele::Vulkan::cast(const VkImageLayout &imageLayout)
return SE_IMAGE_LAYOUT_SHADING_RATE_OPTIMAL_NV;
case VK_IMAGE_LAYOUT_FRAGMENT_DENSITY_MAP_OPTIMAL_EXT:
return SE_IMAGE_LAYOUT_FRAGMENT_DENSITY_MAP_OPTIMAL_EXT;
default:
return SE_IMAGE_LAYOUT_MAX_ENUM;
default: throw std::logic_error("Not implemented");
}
}
VkAttachmentStoreOp Seele::Vulkan::cast(const Gfx::SeAttachmentStoreOp &storeOp)
@@ -1179,8 +1178,8 @@ VkAttachmentStoreOp Seele::Vulkan::cast(const Gfx::SeAttachmentStoreOp &storeOp)
return VK_ATTACHMENT_STORE_OP_STORE;
case SE_ATTACHMENT_STORE_OP_DONT_CARE:
return VK_ATTACHMENT_STORE_OP_DONT_CARE;
default:
return VK_ATTACHMENT_STORE_OP_MAX_ENUM;
default: throw std::logic_error("Not implemented");
}
}
Gfx::SeAttachmentStoreOp Seele::Vulkan::cast(const VkAttachmentStoreOp &storeOp)
@@ -1191,8 +1190,8 @@ Gfx::SeAttachmentStoreOp Seele::Vulkan::cast(const VkAttachmentStoreOp &storeOp)
return SE_ATTACHMENT_STORE_OP_STORE;
case VK_ATTACHMENT_STORE_OP_DONT_CARE:
return SE_ATTACHMENT_STORE_OP_DONT_CARE;
default:
return SE_ATTACHMENT_STORE_OP_MAX_ENUM;
default: throw std::logic_error("Not implemented");
}
}
VkAttachmentLoadOp Seele::Vulkan::cast(const Gfx::SeAttachmentLoadOp &loadOp)
@@ -1205,8 +1204,8 @@ VkAttachmentLoadOp Seele::Vulkan::cast(const Gfx::SeAttachmentLoadOp &loadOp)
return VK_ATTACHMENT_LOAD_OP_CLEAR;
case SE_ATTACHMENT_LOAD_OP_DONT_CARE:
return VK_ATTACHMENT_LOAD_OP_DONT_CARE;
default:
return VK_ATTACHMENT_LOAD_OP_MAX_ENUM;
default: throw std::logic_error("Not implemented");
}
}
Gfx::SeAttachmentLoadOp Seele::Vulkan::cast(const VkAttachmentLoadOp &loadOp)
@@ -1219,8 +1218,8 @@ Gfx::SeAttachmentLoadOp Seele::Vulkan::cast(const VkAttachmentLoadOp &loadOp)
return SE_ATTACHMENT_LOAD_OP_CLEAR;
case VK_ATTACHMENT_LOAD_OP_DONT_CARE:
return SE_ATTACHMENT_LOAD_OP_DONT_CARE;
default:
return SE_ATTACHMENT_LOAD_OP_MAX_ENUM;
default: throw std::logic_error("Not implemented");
}
}
@@ -1244,8 +1243,8 @@ Gfx::SeIndexType Seele::Vulkan::cast(const VkIndexType &indexType)
return Gfx::SE_INDEX_TYPE_UINT16;
case VK_INDEX_TYPE_UINT32:
return Gfx::SE_INDEX_TYPE_UINT32;
default:
return Gfx::SE_INDEX_TYPE_MAX_ENUM;
default: throw std::logic_error("Not implemented");
}
}
@@ -1305,8 +1304,8 @@ Gfx::SePrimitiveTopology Seele::Vulkan::cast(const VkPrimitiveTopology &topology
return SE_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP_WITH_ADJACENCY;
case VK_PRIMITIVE_TOPOLOGY_PATCH_LIST:
return SE_PRIMITIVE_TOPOLOGY_PATCH_LIST;
default:
return SE_PRIMITIVE_TOPOLOGY_MAX_ENUM;
default: throw std::logic_error("Not implemented");
}
}
@@ -1334,8 +1333,8 @@ Gfx::SePolygonMode Seele::Vulkan::cast(const VkPolygonMode &mode)
return SE_POLYGON_MODE_LINE;
case VK_POLYGON_MODE_POINT:
return SE_POLYGON_MODE_POINT;
default:
return SE_POLYGON_MODE_MAX_ENUM;
default: throw std::logic_error("Not implemented");
}
}
VkCompareOp Seele::Vulkan::cast(const Gfx::SeCompareOp &op)
@@ -1358,8 +1357,8 @@ VkCompareOp Seele::Vulkan::cast(const Gfx::SeCompareOp &op)
return VK_COMPARE_OP_GREATER_OR_EQUAL;
case SE_COMPARE_OP_ALWAYS:
return VK_COMPARE_OP_ALWAYS;
default:
return VK_COMPARE_OP_MAX_ENUM;
default: throw std::logic_error("Not implemented");
}
}
Gfx::SeCompareOp Seele::Vulkan::cast(const VkCompareOp &op)
@@ -1382,8 +1381,8 @@ Gfx::SeCompareOp Seele::Vulkan::cast(const VkCompareOp &op)
return SE_COMPARE_OP_GREATER_OR_EQUAL;
case VK_COMPARE_OP_ALWAYS:
return SE_COMPARE_OP_ALWAYS;
default:
return SE_COMPARE_OP_MAX_ENUM;
default: throw std::logic_error("Not implemented");
}
}
@@ -1455,8 +1454,8 @@ Gfx::SeSamplerAddressMode Seele::Vulkan::cast(const VkSamplerAddressMode &mode)
return SE_SAMPLER_ADDRESS_MODE_CLAMP_TO_BORDER;
case VK_SAMPLER_ADDRESS_MODE_MIRROR_CLAMP_TO_EDGE:
return SE_SAMPLER_ADDRESS_MODE_MIRROR_CLAMP_TO_EDGE;
default:
return SE_SAMPLER_ADDRESS_MODE_MAX_ENUM;
default: throw std::logic_error("Not implemented");
}
}
VkBorderColor Seele::Vulkan::cast(const Gfx::SeBorderColor &color)
@@ -1495,8 +1494,8 @@ Gfx::SeBorderColor Seele::Vulkan::cast(const VkBorderColor &color)
return SE_BORDER_COLOR_FLOAT_OPAQUE_WHITE;
case VK_BORDER_COLOR_INT_OPAQUE_WHITE:
return SE_BORDER_COLOR_INT_OPAQUE_WHITE;
default:
return SE_BORDER_COLOR_MAX_ENUM;
default: throw std::logic_error("Not implemented");
}
}
@@ -1510,8 +1509,8 @@ VkFilter Seele::Vulkan::cast(const Gfx::SeFilter &filter)
return VK_FILTER_LINEAR;
case SE_FILTER_CUBIC_IMG:
return VK_FILTER_CUBIC_IMG;
default:
return VK_FILTER_MAX_ENUM;
default: throw std::logic_error("Not implemented");
}
}
Gfx::SeFilter Seele::Vulkan::cast(const VkFilter &filter)
@@ -1524,8 +1523,8 @@ Gfx::SeFilter Seele::Vulkan::cast(const VkFilter &filter)
return SE_FILTER_LINEAR;
case VK_FILTER_CUBIC_IMG:
return SE_FILTER_CUBIC_IMG;
default:
return SE_FILTER_MAX_ENUM;
default: throw std::logic_error("Not implemented");
}
}
@@ -1537,8 +1536,8 @@ VkSamplerMipmapMode Seele::Vulkan::cast(const Gfx::SeSamplerMipmapMode &filter)
return VK_SAMPLER_MIPMAP_MODE_NEAREST;
case SE_SAMPLER_MIPMAP_MODE_LINEAR:
return VK_SAMPLER_MIPMAP_MODE_LINEAR;
default:
return VK_SAMPLER_MIPMAP_MODE_MAX_ENUM;
default: throw std::logic_error("Not implemented");
}
}
Gfx::SeSamplerMipmapMode Seele::Vulkan::cast(const VkSamplerMipmapMode &filter)
@@ -1549,8 +1548,8 @@ Gfx::SeSamplerMipmapMode Seele::Vulkan::cast(const VkSamplerMipmapMode &filter)
return SE_SAMPLER_MIPMAP_MODE_NEAREST;
case VK_SAMPLER_MIPMAP_MODE_LINEAR:
return SE_SAMPLER_MIPMAP_MODE_LINEAR;
default:
return SE_SAMPLER_MIPMAP_MODE_MAX_ENUM;
default: throw std::logic_error("Not implemented");
}
}
VkAccessFlagBits Seele::Vulkan::cast(const Gfx::SeAccessFlagBits &flags)
+1 -1
View File
@@ -14,7 +14,7 @@ public:
PGraphicsPipeline createPipeline(Gfx::MeshPipelineCreateInfo createInfo);
PComputePipeline createPipeline(Gfx::ComputePipelineCreateInfo createInfo);
private:
std::map<uint32, OGraphicsPipeline> graphicsPipelines;
Map<uint32, OGraphicsPipeline> graphicsPipelines;
Map<uint32, OComputePipeline> computePipelines;
std::mutex cacheLock;
VkPipelineCache cache;