Descriptor sets and refactoring
This commit is contained in:
+109
-121
@@ -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
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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
|
||||
@@ -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)
|
||||
|
||||
@@ -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;
|
||||
|
||||
Reference in New Issue
Block a user