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-08-28 17:54:14 +02:00
|
|
|
#include "Foundation/NSArray.hpp"
|
2024-08-26 21:49:09 +02:00
|
|
|
#include "Foundation/NSObject.hpp"
|
2024-04-15 13:48:34 +02:00
|
|
|
#include "Graphics/Descriptor.h"
|
2024-09-16 13:00:53 +02:00
|
|
|
#include "Graphics/Enums.h"
|
2024-04-13 23:51:38 +02:00
|
|
|
#include "Graphics/Initializer.h"
|
2024-05-17 18:08:11 +02:00
|
|
|
#include "Graphics/Metal/Resources.h"
|
2024-08-28 17:54:14 +02:00
|
|
|
#include "Graphics/Metal/Shader.h"
|
2024-04-15 13:48:34 +02:00
|
|
|
#include "Metal/MTLArgument.hpp"
|
2024-08-28 17:54:14 +02:00
|
|
|
#include "Metal/MTLArgumentEncoder.hpp"
|
2024-04-15 13:48:34 +02:00
|
|
|
#include "Metal/MTLDevice.hpp"
|
|
|
|
|
#include "Metal/MTLResource.hpp"
|
2024-08-28 17:54:14 +02:00
|
|
|
#include "Metal/MTLStageInputOutputDescriptor.hpp"
|
2024-04-15 13:48:34 +02:00
|
|
|
#include "Metal/MTLTexture.hpp"
|
2024-04-13 23:51:38 +02:00
|
|
|
#include "Texture.h"
|
2024-08-26 21:49:09 +02:00
|
|
|
#include <CRC.h>
|
2024-09-16 13:00:53 +02:00
|
|
|
#include <CoreFoundation/CoreFoundation.h>
|
2024-08-28 17:54:14 +02:00
|
|
|
#include <Foundation/Foundation.h>
|
2024-04-15 13:48:34 +02:00
|
|
|
#include <iostream>
|
2024-09-16 13:00:53 +02:00
|
|
|
#include <stdexcept>
|
2024-04-12 09:27:30 +02:00
|
|
|
|
|
|
|
|
using namespace Seele;
|
|
|
|
|
using namespace Seele::Metal;
|
|
|
|
|
|
2024-08-28 17:54:14 +02:00
|
|
|
DescriptorLayout::DescriptorLayout(PGraphics graphics, const std::string& name) : Gfx::DescriptorLayout(name), graphics(graphics) {}
|
2024-04-13 23:51:38 +02:00
|
|
|
|
2025-03-04 19:38:03 +09:00
|
|
|
DescriptorLayout::~DescriptorLayout() { arguments->release(); }
|
2024-04-13 23:51:38 +02:00
|
|
|
|
|
|
|
|
void DescriptorLayout::create() {
|
2024-08-26 21:49:09 +02:00
|
|
|
pool = new DescriptorPool(graphics, this);
|
2024-08-28 17:54:14 +02:00
|
|
|
hash = CRC::Calculate(descriptorBindings.data(), sizeof(Gfx::DescriptorBinding) * descriptorBindings.size(), CRC::CRC_32());
|
|
|
|
|
MTL::ArgumentDescriptor** objects = new MTL::ArgumentDescriptor*[descriptorBindings.size()];
|
2025-02-28 16:56:51 +09:00
|
|
|
uint32 mappingCounter = 0;
|
2024-09-16 13:00:53 +02:00
|
|
|
for (uint32 i = 0; i < descriptorBindings.size(); ++i) {
|
2026-03-16 16:52:43 +01:00
|
|
|
if (descriptorBindings[i].descriptorType != Gfx::SE_DESCRIPTOR_TYPE_INLINE_UNIFORM_BLOCK) {
|
2025-02-14 00:39:53 +01:00
|
|
|
plainDescriptor = false;
|
2024-09-16 13:00:53 +02:00
|
|
|
}
|
2025-03-04 19:38:03 +09:00
|
|
|
objects[i] = MTL::ArgumentDescriptor::alloc()->init();
|
|
|
|
|
objects[i]->setIndex(mappingCounter);
|
|
|
|
|
objects[i]->setAccess(MTL::BindingAccessReadOnly);
|
|
|
|
|
objects[i]->setArrayLength(descriptorBindings[i].descriptorCount);
|
|
|
|
|
objects[i]->setDataType(MTL::DataTypeChar);
|
|
|
|
|
objects[i]->setArrayLength(descriptorBindings[i].uniformLength);
|
|
|
|
|
|
2025-02-28 16:56:51 +09:00
|
|
|
variableMapping[descriptorBindings[i].name] = DescriptorMapping{
|
|
|
|
|
.index = mappingCounter,
|
|
|
|
|
.constantSize = descriptorBindings[i].uniformLength,
|
|
|
|
|
.access = descriptorBindings[i].access,
|
|
|
|
|
};
|
|
|
|
|
mappingCounter += descriptorBindings[i].descriptorCount;
|
2024-08-28 17:54:14 +02:00
|
|
|
}
|
2025-02-28 16:56:51 +09:00
|
|
|
numResources = mappingCounter;
|
2024-08-28 17:54:14 +02:00
|
|
|
arguments = NS::Array::array((NS::Object**)objects, descriptorBindings.size());
|
2025-03-04 19:38:03 +09:00
|
|
|
delete[] objects;
|
2024-04-12 09:27:30 +02:00
|
|
|
}
|
|
|
|
|
|
2024-09-16 13:00:53 +02:00
|
|
|
MTL::ArgumentEncoder* DescriptorLayout::createEncoder() { return graphics->getDevice()->newArgumentEncoder(arguments); }
|
2024-08-28 17:54:14 +02:00
|
|
|
|
2025-08-14 18:28:13 +02:00
|
|
|
DescriptorSetHandle::DescriptorSetHandle(PGraphics graphics, PDescriptorPool owner, const std::string& name)
|
2025-09-05 07:10:27 +02:00
|
|
|
: CommandBoundResource(graphics, name), owner(owner)
|
2025-08-14 18:28:13 +02:00
|
|
|
{
|
2024-04-13 23:51:38 +02:00
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
2025-08-14 18:28:13 +02:00
|
|
|
DescriptorSetHandle::~DescriptorSetHandle() {
|
2025-03-04 19:38:03 +09:00
|
|
|
if(encoder != nullptr) {
|
|
|
|
|
encoder->release();
|
|
|
|
|
}
|
|
|
|
|
std::cout << "destroying descriptor set" << std::endl;
|
|
|
|
|
}
|
2024-04-13 23:51:38 +02:00
|
|
|
|
2025-08-14 18:28:13 +02:00
|
|
|
void DescriptorSetHandle::updateConstants(const std::string& name, uint32 offset, void* data) {
|
2025-02-28 16:56:51 +09:00
|
|
|
uint32 flattenedIndex = owner->getLayout()->variableMapping[name].index;
|
|
|
|
|
Array<uint8> contents(owner->getLayout()->variableMapping[name].constantSize);
|
|
|
|
|
std::memcpy(contents.data(), (uint8*)data + offset, contents.size());
|
2025-02-14 00:39:53 +01:00
|
|
|
uniformWrites.add(UniformWriteInfo{
|
|
|
|
|
.index = flattenedIndex,
|
2025-02-28 16:56:51 +09:00
|
|
|
.content = contents,
|
2025-02-14 00:39:53 +01:00
|
|
|
});
|
2024-04-13 23:51:38 +02:00
|
|
|
}
|
|
|
|
|
|
2025-08-14 18:28:13 +02:00
|
|
|
void DescriptorSetHandle::updateBuffer(const std::string& name, uint32 index, Gfx::PShaderBuffer uniformBuffer) {
|
2025-02-28 16:56:51 +09:00
|
|
|
uint32 flattenedIndex = owner->getLayout()->variableMapping[name].index + index;
|
2024-09-16 13:00:53 +02:00
|
|
|
PShaderBuffer buffer = uniformBuffer.cast<ShaderBuffer>();
|
2025-02-14 00:39:53 +01:00
|
|
|
bufferWrites.add(BufferWriteInfo{
|
|
|
|
|
.index = flattenedIndex,
|
2025-03-05 09:41:34 +01:00
|
|
|
.buffer = buffer->getAlloc(),
|
2025-02-28 16:56:51 +09:00
|
|
|
.access = owner->getLayout()->variableMapping[name].access,
|
2025-02-14 00:39:53 +01:00
|
|
|
});
|
2025-03-05 09:41:34 +01:00
|
|
|
boundResources.add(buffer->getAlloc());
|
2024-05-17 18:08:11 +02:00
|
|
|
}
|
|
|
|
|
|
2025-08-14 18:28:13 +02:00
|
|
|
void DescriptorSetHandle::updateBuffer(const std::string& name, uint32 index, Gfx::PVertexBuffer uniformBuffer) {
|
2025-02-28 16:56:51 +09:00
|
|
|
uint32 flattenedIndex = owner->getLayout()->variableMapping[name].index + index;
|
2024-11-01 21:04:06 +01:00
|
|
|
PVertexBuffer buffer = uniformBuffer.cast<VertexBuffer>();
|
2025-02-14 00:39:53 +01:00
|
|
|
bufferWrites.add(BufferWriteInfo{
|
|
|
|
|
.index = flattenedIndex,
|
2025-03-05 09:41:34 +01:00
|
|
|
.buffer = buffer->getAlloc(),
|
2025-02-28 16:56:51 +09:00
|
|
|
.access = owner->getLayout()->variableMapping[name].access,
|
2025-02-14 00:39:53 +01:00
|
|
|
});
|
2025-03-05 09:41:34 +01:00
|
|
|
boundResources.add(buffer->getAlloc());
|
2024-11-01 21:04:06 +01:00
|
|
|
}
|
2025-02-14 00:39:53 +01:00
|
|
|
|
2025-08-14 18:28:13 +02:00
|
|
|
void DescriptorSetHandle::updateBuffer(const std::string& name, uint32 index, Gfx::PIndexBuffer uniformBuffer) {
|
2025-02-28 16:56:51 +09:00
|
|
|
uint32 flattenedIndex = owner->getLayout()->variableMapping[name].index + index;
|
2024-09-16 13:00:53 +02:00
|
|
|
PIndexBuffer buffer = uniformBuffer.cast<IndexBuffer>();
|
2025-02-14 00:39:53 +01:00
|
|
|
bufferWrites.add(BufferWriteInfo{
|
|
|
|
|
.index = flattenedIndex,
|
2025-03-05 09:41:34 +01:00
|
|
|
.buffer = buffer->getAlloc(),
|
2025-02-28 16:56:51 +09:00
|
|
|
.access = owner->getLayout()->variableMapping[name].access,
|
2025-02-14 00:39:53 +01:00
|
|
|
});
|
2025-03-05 09:41:34 +01:00
|
|
|
boundResources.add(buffer->getAlloc());
|
2024-08-26 21:49:09 +02:00
|
|
|
}
|
|
|
|
|
|
2025-08-14 18:28:13 +02:00
|
|
|
void DescriptorSetHandle::updateBuffer(const std::string& name, uint32 index, Gfx::PUniformBuffer uniformBuffer) {
|
|
|
|
|
uint32 flattenedIndex = owner->getLayout()->variableMapping[name].index + index;
|
|
|
|
|
PIndexBuffer buffer = uniformBuffer.cast<IndexBuffer>();
|
|
|
|
|
bufferWrites.add(BufferWriteInfo{
|
|
|
|
|
.index = flattenedIndex,
|
|
|
|
|
.buffer = buffer->getAlloc(),
|
|
|
|
|
.access = owner->getLayout()->variableMapping[name].access,
|
|
|
|
|
});
|
|
|
|
|
boundResources.add(buffer->getAlloc());
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void DescriptorSetHandle::updateSampler(const std::string& name, uint32 index, Gfx::PSampler samplerState) {
|
2025-02-28 16:56:51 +09:00
|
|
|
uint32 flattenedIndex = owner->getLayout()->variableMapping[name].index + index;
|
2024-09-16 13:00:53 +02:00
|
|
|
PSampler sampler = samplerState.cast<Sampler>();
|
2025-02-14 00:39:53 +01:00
|
|
|
samplerWrites.add(SamplerWriteInfo{
|
|
|
|
|
.index = flattenedIndex,
|
2025-03-05 09:41:34 +01:00
|
|
|
.sampler = sampler,
|
2025-02-14 00:39:53 +01:00
|
|
|
});
|
2024-08-28 17:54:14 +02:00
|
|
|
}
|
2024-08-26 21:49:09 +02:00
|
|
|
|
2025-08-14 18:28:13 +02:00
|
|
|
void DescriptorSetHandle::updateTexture(const std::string& name, uint32 index, Gfx::PTextureView texture) {
|
2025-02-28 16:56:51 +09:00
|
|
|
uint32 flattenedIndex = owner->getLayout()->variableMapping[name].index + index;
|
2025-08-14 18:28:13 +02:00
|
|
|
PTextureView tex = texture.cast<TextureView>();
|
2025-02-14 00:39:53 +01:00
|
|
|
textureWrites.add(TextureWriteInfo{
|
|
|
|
|
.index = flattenedIndex,
|
2025-08-14 18:28:13 +02:00
|
|
|
.texture = tex,
|
2025-02-28 16:56:51 +09:00
|
|
|
.access = owner->getLayout()->variableMapping[name].access,
|
2025-02-14 00:39:53 +01:00
|
|
|
});
|
2025-08-14 18:28:13 +02:00
|
|
|
boundResources.add(tex);
|
2025-09-05 07:10:27 +02:00
|
|
|
boundResources.add(tex->getSource());
|
2024-11-01 21:04:06 +01:00
|
|
|
}
|
2024-08-28 17:54:14 +02:00
|
|
|
|
2025-08-14 18:28:13 +02:00
|
|
|
void DescriptorSetHandle::updateAccelerationStructure(const std::string& , uint32 , Gfx::PTopLevelAS ){}
|
|
|
|
|
|
|
|
|
|
DescriptorPool::DescriptorPool(PGraphics graphics, PDescriptorLayout layout) : graphics(graphics), layout(layout) {}
|
|
|
|
|
|
|
|
|
|
DescriptorPool::~DescriptorPool() {}
|
|
|
|
|
|
|
|
|
|
Gfx::ODescriptorSet DescriptorPool::allocateDescriptorSet() {
|
|
|
|
|
for (uint32 setIndex = 0; setIndex < allocatedSets.size(); ++setIndex) {
|
|
|
|
|
if (allocatedSets[setIndex]->isCurrentlyBound()) {
|
|
|
|
|
// Currently in use, skip
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
// Found set, stop searching
|
|
|
|
|
return new DescriptorSet(graphics, this, allocatedSets[setIndex]);
|
|
|
|
|
}
|
|
|
|
|
allocatedSets.add(new DescriptorSetHandle(graphics, this, layout->getName()));
|
|
|
|
|
return new DescriptorSet(graphics, this, allocatedSets.back());
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void DescriptorPool::reset() {}
|
|
|
|
|
|
|
|
|
|
DescriptorSet::DescriptorSet(PGraphics graphics, PDescriptorPool owner, PDescriptorSetHandle handle)
|
|
|
|
|
: Gfx::DescriptorSet(owner->getLayout()), graphics(graphics), owner(owner), setHandle(handle) {
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
DescriptorSet::~DescriptorSet() {
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void DescriptorSet::writeChanges() {}
|
|
|
|
|
|
|
|
|
|
void DescriptorSet::updateConstants(const std::string& name, uint32 offset, void* data) {
|
|
|
|
|
setHandle->updateConstants(name, offset, data);
|
|
|
|
|
}
|
|
|
|
|
void DescriptorSet::updateBuffer(const std::string& name, uint32 index, Gfx::PShaderBuffer uniformBuffer){
|
|
|
|
|
setHandle->updateBuffer(name, index, uniformBuffer);
|
|
|
|
|
}
|
|
|
|
|
void DescriptorSet::updateBuffer(const std::string& name, uint32 index, Gfx::PVertexBuffer uniformBuffer){
|
|
|
|
|
setHandle->updateBuffer(name, index, uniformBuffer);
|
|
|
|
|
}
|
|
|
|
|
void DescriptorSet::updateBuffer(const std::string& name, uint32 index, Gfx::PIndexBuffer uniformBuffer){
|
|
|
|
|
setHandle->updateBuffer(name, index, uniformBuffer);
|
|
|
|
|
}
|
|
|
|
|
void DescriptorSet::updateBuffer(const std::string& name, uint32 index, Gfx::PUniformBuffer uniformBuffer){
|
|
|
|
|
setHandle->updateBuffer(name, index, uniformBuffer);
|
|
|
|
|
}
|
|
|
|
|
void DescriptorSet::updateSampler(const std::string& name, uint32 index, Gfx::PSampler samplerState){
|
|
|
|
|
setHandle->updateSampler(name, index, samplerState);
|
|
|
|
|
}
|
|
|
|
|
void DescriptorSet::updateTexture(const std::string& name, uint32 index, Gfx::PTextureView texture){
|
|
|
|
|
setHandle->updateTexture(name, index, texture);
|
|
|
|
|
}
|
|
|
|
|
void DescriptorSet::updateAccelerationStructure(const std::string& name, uint32 index, Gfx::PTopLevelAS as){
|
|
|
|
|
setHandle->updateAccelerationStructure(name, index, as);
|
|
|
|
|
}
|
2024-08-28 17:54:14 +02:00
|
|
|
|
|
|
|
|
PipelineLayout::PipelineLayout(PGraphics graphics, const std::string& name, Gfx::PPipelineLayout baseLayout)
|
2024-04-20 21:35:43 +02:00
|
|
|
: Gfx::PipelineLayout(name, 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-08-28 17:54:14 +02:00
|
|
|
for (auto& [_, set] : descriptorSetLayouts) {
|
|
|
|
|
assert(set->getHash() != 0);
|
|
|
|
|
uint32 setHash = set->getHash();
|
|
|
|
|
layoutHash = CRC::Calculate(&setHash, sizeof(uint32), CRC::CRC_32(), layoutHash);
|
|
|
|
|
}
|
2024-04-19 18:23:36 +02:00
|
|
|
}
|