2024-04-12 09:27:30 +02:00
|
|
|
#include "Descriptor.h"
|
2024-04-13 23:51:38 +02:00
|
|
|
#include "Buffer.h"
|
|
|
|
|
#include "Enums.h"
|
2024-04-15 13:48:34 +02:00
|
|
|
#include "Graphics/Descriptor.h"
|
2024-04-13 23:51:38 +02:00
|
|
|
#include "Graphics/Initializer.h"
|
2024-04-15 13:48:34 +02:00
|
|
|
#include "Metal/MTLArgument.hpp"
|
|
|
|
|
#include "Metal/MTLDevice.hpp"
|
|
|
|
|
#include "Metal/MTLResource.hpp"
|
|
|
|
|
#include "Metal/MTLTexture.hpp"
|
2024-04-13 23:51:38 +02:00
|
|
|
#include "Texture.h"
|
2024-04-15 13:48:34 +02:00
|
|
|
#include <Foundation/Foundation.h>
|
|
|
|
|
#include <iostream>
|
2024-04-12 09:27:30 +02:00
|
|
|
|
|
|
|
|
using namespace Seele;
|
|
|
|
|
using namespace Seele::Metal;
|
|
|
|
|
|
2024-04-13 23:51:38 +02:00
|
|
|
DescriptorLayout::DescriptorLayout(PGraphics graphics, const std::string& name)
|
2024-04-15 13:48:34 +02:00
|
|
|
: Gfx::DescriptorLayout(name), graphics(graphics), arguments(nullptr) {}
|
2024-04-13 23:51:38 +02:00
|
|
|
|
|
|
|
|
DescriptorLayout::~DescriptorLayout() {}
|
|
|
|
|
|
|
|
|
|
void DescriptorLayout::create() {
|
2024-04-15 13:48:34 +02:00
|
|
|
if (arguments != nullptr) {
|
|
|
|
|
return;
|
|
|
|
|
}
|
2024-04-13 23:51:38 +02:00
|
|
|
Array<NS::Object*> descriptors;
|
|
|
|
|
for (size_t i = 0; i < descriptorBindings.size(); ++i) {
|
|
|
|
|
const auto& binding = descriptorBindings[i];
|
|
|
|
|
auto desc = MTL::ArgumentDescriptor::alloc()->init();
|
|
|
|
|
desc->setAccess(cast(binding.access));
|
|
|
|
|
desc->setArrayLength(binding.descriptorCount);
|
|
|
|
|
MTL::DataType dataType;
|
|
|
|
|
switch (binding.descriptorType) {
|
|
|
|
|
case Gfx::SE_DESCRIPTOR_TYPE_SAMPLER:
|
|
|
|
|
case Gfx::SE_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER:
|
|
|
|
|
case Gfx::SE_DESCRIPTOR_TYPE_SAMPLED_IMAGE:
|
|
|
|
|
case Gfx::SE_DESCRIPTOR_TYPE_STORAGE_IMAGE:
|
|
|
|
|
case Gfx::SE_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER:
|
|
|
|
|
case Gfx::SE_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER:
|
|
|
|
|
case Gfx::SE_DESCRIPTOR_TYPE_INPUT_ATTACHMENT:
|
|
|
|
|
dataType = MTL::DataTypeTexture;
|
|
|
|
|
break;
|
|
|
|
|
case Gfx::SE_DESCRIPTOR_TYPE_UNIFORM_BUFFER:
|
|
|
|
|
case Gfx::SE_DESCRIPTOR_TYPE_STORAGE_BUFFER:
|
|
|
|
|
case Gfx::SE_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC:
|
|
|
|
|
case Gfx::SE_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC:
|
|
|
|
|
case Gfx::SE_DESCRIPTOR_TYPE_INLINE_UNIFORM_BLOCK_EXT:
|
2024-04-15 13:48:34 +02:00
|
|
|
dataType = MTL::DataTypePointer;
|
2024-04-13 23:51:38 +02:00
|
|
|
break;
|
|
|
|
|
case Gfx::SE_DESCRIPTOR_TYPE_ACCELERATION_STRUCTURE_NV:
|
|
|
|
|
dataType = MTL::DataTypePrimitiveAccelerationStructure;
|
|
|
|
|
break;
|
|
|
|
|
default:
|
|
|
|
|
throw std::logic_error("Nooo");
|
|
|
|
|
}
|
|
|
|
|
desc->setDataType(dataType);
|
2024-04-15 13:48:34 +02:00
|
|
|
desc->setIndex(i);
|
|
|
|
|
if (dataType == MTL::DataTypeTexture) {
|
|
|
|
|
switch (binding.textureType) {
|
|
|
|
|
case Gfx::SE_IMAGE_VIEW_TYPE_1D:
|
|
|
|
|
desc->setTextureType(MTL::TextureType1D);
|
|
|
|
|
break;
|
|
|
|
|
case Gfx::SE_IMAGE_VIEW_TYPE_2D:
|
|
|
|
|
desc->setTextureType(MTL::TextureType2D);
|
|
|
|
|
break;
|
|
|
|
|
case Gfx::SE_IMAGE_VIEW_TYPE_3D:
|
|
|
|
|
desc->setTextureType(MTL::TextureType3D);
|
|
|
|
|
break;
|
|
|
|
|
case Gfx::SE_IMAGE_VIEW_TYPE_CUBE:
|
|
|
|
|
desc->setTextureType(MTL::TextureTypeCube);
|
|
|
|
|
break;
|
|
|
|
|
case Gfx::SE_IMAGE_VIEW_TYPE_1D_ARRAY:
|
|
|
|
|
desc->setTextureType(MTL::TextureType1DArray);
|
|
|
|
|
break;
|
|
|
|
|
case Gfx::SE_IMAGE_VIEW_TYPE_2D_ARRAY:
|
|
|
|
|
desc->setTextureType(MTL::TextureType2DArray);
|
|
|
|
|
break;
|
|
|
|
|
case Gfx::SE_IMAGE_VIEW_TYPE_CUBE_ARRAY:
|
|
|
|
|
desc->setTextureType(MTL::TextureTypeCubeArray);
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
2024-04-13 23:51:38 +02:00
|
|
|
descriptors.add(desc);
|
|
|
|
|
}
|
|
|
|
|
arguments = NS::Array::array(descriptors.data(), descriptors.size());
|
2024-04-14 11:35:37 +02:00
|
|
|
pool = new DescriptorPool(graphics, this);
|
2024-04-15 13:48:34 +02:00
|
|
|
hash = CRC::Calculate(descriptorBindings.data(), sizeof(Gfx::DescriptorBinding) * descriptorBindings.size(),
|
|
|
|
|
CRC::CRC_32());
|
2024-04-12 09:27:30 +02:00
|
|
|
}
|
|
|
|
|
|
2024-04-13 23:51:38 +02:00
|
|
|
DescriptorPool::DescriptorPool(PGraphics graphics, PDescriptorLayout layout) : graphics(graphics), layout(layout) {}
|
|
|
|
|
|
|
|
|
|
DescriptorPool::~DescriptorPool() {}
|
|
|
|
|
|
|
|
|
|
Gfx::PDescriptorSet DescriptorPool::allocateDescriptorSet() {
|
|
|
|
|
for (uint32 setIndex = 0; setIndex < allocatedSets.size(); ++setIndex) {
|
|
|
|
|
if (allocatedSets[setIndex]->isCurrentlyBound() || allocatedSets[setIndex]->isCurrentlyInUse()) {
|
|
|
|
|
// Currently in use, skip
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
allocatedSets[setIndex]->allocate();
|
|
|
|
|
|
|
|
|
|
// Found set, stop searching
|
|
|
|
|
return PDescriptorSet(allocatedSets[setIndex]);
|
|
|
|
|
}
|
|
|
|
|
allocatedSets.add(new DescriptorSet(graphics, this));
|
2024-04-15 13:48:34 +02:00
|
|
|
allocatedSets.back()->allocate();
|
2024-04-13 23:51:38 +02:00
|
|
|
return PDescriptorSet(allocatedSets.back());
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void DescriptorPool::reset() {
|
|
|
|
|
for (auto& set : allocatedSets) {
|
|
|
|
|
set->free();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
DescriptorSet::DescriptorSet(PGraphics graphics, PDescriptorPool owner)
|
|
|
|
|
: Gfx::DescriptorSet(owner->getLayout()), graphics(graphics), owner(owner), bindCount(0), currentlyInUse(false) {
|
2024-04-15 13:48:34 +02:00
|
|
|
// auto desc = (MTL::ArgumentDescriptor*)owner->getArguments()->object(0);
|
|
|
|
|
// std::cout << desc->access() << " " << desc->arrayLength() << " " << desc->index() << " " << desc->textureType() <<
|
|
|
|
|
// " " << desc->dataType() << std::endl;
|
|
|
|
|
if (owner->getArguments()->count() == 0) {
|
|
|
|
|
buffer = graphics->getDevice()->newBuffer(0, MTL::ResourceOptionCPUCacheModeDefault);
|
|
|
|
|
} else {
|
2024-04-19 18:23:36 +02:00
|
|
|
boundResources.resize(owner->getArguments()->count());
|
2024-04-15 13:48:34 +02:00
|
|
|
encoder = graphics->getDevice()->newArgumentEncoder(owner->getArguments());
|
|
|
|
|
buffer = graphics->getDevice()->newBuffer(encoder->encodedLength(), MTL::ResourceOptionCPUCacheModeDefault);
|
|
|
|
|
encoder->setArgumentBuffer(buffer, 0);
|
|
|
|
|
}
|
2024-04-13 23:51:38 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
DescriptorSet::~DescriptorSet() {}
|
|
|
|
|
|
|
|
|
|
void DescriptorSet::writeChanges() {}
|
|
|
|
|
|
|
|
|
|
void DescriptorSet::updateBuffer(uint32_t binding, Gfx::PUniformBuffer uniformBuffer) {
|
|
|
|
|
PUniformBuffer metalBuffer = uniformBuffer.cast<UniformBuffer>();
|
|
|
|
|
encoder->setBuffer(metalBuffer->getHandle(), 0, binding);
|
2024-04-19 18:23:36 +02:00
|
|
|
boundResources[binding] = metalBuffer->getHandle();
|
2024-04-13 23:51:38 +02:00
|
|
|
}
|
|
|
|
|
void DescriptorSet::updateBuffer(uint32_t binding, Gfx::PShaderBuffer uniformBuffer) {
|
|
|
|
|
PShaderBuffer metalBuffer = uniformBuffer.cast<ShaderBuffer>();
|
|
|
|
|
encoder->setBuffer(metalBuffer->getHandle(), 0, binding);
|
2024-04-19 18:23:36 +02:00
|
|
|
boundResources[binding] = metalBuffer->getHandle();
|
2024-04-13 23:51:38 +02:00
|
|
|
}
|
|
|
|
|
void DescriptorSet::updateSampler(uint32_t binding, Gfx::PSampler samplerState) {
|
|
|
|
|
PSampler sampler = samplerState.cast<Sampler>();
|
|
|
|
|
encoder->setSamplerState(sampler->getHandle(), binding);
|
|
|
|
|
}
|
|
|
|
|
void DescriptorSet::updateTexture(uint32_t binding, Gfx::PTexture texture, Gfx::PSampler samplerState) {
|
|
|
|
|
PTextureBase base = texture.cast<TextureBase>();
|
|
|
|
|
encoder->setTexture(base->getTexture(), binding);
|
2024-04-19 18:23:36 +02:00
|
|
|
boundResources[binding] = base->getTexture();
|
2024-04-13 23:51:38 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void DescriptorSet::updateTextureArray(uint32_t binding, Array<Gfx::PTexture> array) {
|
|
|
|
|
for (auto& t : array) {
|
|
|
|
|
PTextureBase metalTexture = t.cast<TextureBase>();
|
2024-04-19 18:23:36 +02:00
|
|
|
encoder->setTexture(metalTexture->getTexture(), binding);
|
|
|
|
|
boundResources[binding++] = metalTexture->getTexture();
|
2024-04-13 23:51:38 +02:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
PipelineLayout::PipelineLayout(PGraphics graphics, Gfx::PPipelineLayout baseLayout)
|
2024-04-15 13:48:34 +02:00
|
|
|
: Gfx::PipelineLayout(baseLayout), graphics(graphics) {}
|
2024-04-13 23:51:38 +02:00
|
|
|
|
2024-04-15 13:48:34 +02:00
|
|
|
PipelineLayout::~PipelineLayout() {}
|
2024-04-13 23:51:38 +02:00
|
|
|
|
2024-04-15 13:48:34 +02:00
|
|
|
void PipelineLayout::create() {
|
2024-04-19 18:23:36 +02:00
|
|
|
for (auto& [_, set] : descriptorSetLayouts) {
|
2024-04-15 13:48:34 +02:00
|
|
|
set->create();
|
2024-04-13 23:51:38 +02:00
|
|
|
uint32 setHash = set->getHash();
|
|
|
|
|
layoutHash = CRC::Calculate(&setHash, sizeof(uint32), CRC::CRC_32(), layoutHash);
|
|
|
|
|
}
|
2024-04-19 18:23:36 +02:00
|
|
|
}
|