Files
Seele/src/Engine/Graphics/Metal/Descriptor.mm
T

180 lines
6.5 KiB
Plaintext
Raw Normal View History

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-19 22:44:00 +02:00
if (owner->getArguments()->count() > 0) {
boundResources.resize(owner->getArguments()->count());
encoder = graphics->getDevice()->newArgumentEncoder(owner->getArguments());
buffer = graphics->getDevice()->newBuffer(encoder->encodedLength(), MTL::ResourceOptionCPUCacheModeDefault);
encoder->setArgumentBuffer(buffer, 0);
} else
{
buffer = graphics->getDevice()->newBuffer(8, MTL::ResourceOptionCPUCacheModeDefault);
2024-04-15 13:48:34 +02:00
}
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>();
2024-04-19 22:44:00 +02:00
if(layout->getBindings()[binding].access == Gfx::SE_DESCRIPTOR_ACCESS_READ_ONLY_BIT)
{
encoder->setTexture(base->getTexture(), binding);
}else{
encoder->setBuffer(base->getTexture()->buffer(), 0, 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
}