Metal is impossible to debug, thanks apple

This commit is contained in:
Dynamitos
2024-04-14 11:35:37 +02:00
parent f5eb12a5de
commit dc2f0eac30
14 changed files with 325 additions and 138 deletions
-2
View File
@@ -3,8 +3,6 @@
#include "Graphics/Buffer.h"
#include "Graphics/Enums.h"
#include "Graphics/Initializer.h"
#include "Metal/MTLResource.hpp"
using namespace Seele;
using namespace Seele::Metal;
+5 -1
View File
@@ -1,6 +1,6 @@
#pragma once
#include "Graphics/Command.h"
#include "Metal/MTLCommandBuffer.hpp"
#include "Buffer.h"
#include "RenderPass.h"
#include "Resources.h"
@@ -10,6 +10,8 @@ DECLARE_REF(CommandQueue)
DECLARE_REF(ComputeCommand)
DECLARE_REF(RenderCommand)
DECLARE_REF(Graphics)
DECLARE_REF(IndexBuffer)
DECLARE_REF(GraphicsPipeline)
class Command
{
public:
@@ -56,6 +58,8 @@ public:
virtual void drawMesh(uint32 groupX, uint32 groupY, uint32 groupZ) override;
private:
MTL::RenderCommandEncoder* encoder;
PIndexBuffer boundIndexBuffer;
PGraphicsPipeline boundPipeline;
};
DEFINE_REF(RenderCommand)
class ComputeCommand : public Gfx::ComputeCommand
+76 -72
View File
@@ -1,30 +1,28 @@
#include "Command.h"
#include "Buffer.h"
#include "Descriptor.h"
#include "Enums.h"
#include "Graphics/Enums.h"
#include "Graphics/Graphics.h"
#include "Graphics/Metal/Resources.h"
#include "Metal/MTLCommandBuffer.hpp"
#include "Metal/MTLIOCommandQueue.hpp"
#include "Metal/MTLRenderCommandEncoder.hpp"
#include "Pipeline.h"
#include "Resources.h"
#include "Window.h"
using namespace Seele;
using namespace Seele::Metal;
Command::Command(PGraphics graphics, MTL::CommandBuffer* cmdBuffer)
: graphics(graphics), completed(new Event(graphics)),
cmdBuffer(cmdBuffer), renderEncoder(nullptr) {}
: graphics(graphics), completed(new Event(graphics)), cmdBuffer(cmdBuffer), renderEncoder(nullptr) {}
Command::~Command() { cmdBuffer->release(); }
void Command::beginRenderPass(PRenderPass renderPass) {
renderEncoder =
cmdBuffer->parallelRenderCommandEncoder(renderPass->getDescriptor());
renderEncoder = cmdBuffer->parallelRenderCommandEncoder(renderPass->getDescriptor());
}
void Command::endRenderPass() { renderEncoder->endEncoding(); }
void Command::present(MTL::Drawable *drawable) {
cmdBuffer->presentDrawable(drawable);
}
void Command::present(MTL::Drawable* drawable) { cmdBuffer->presentDrawable(drawable); }
void Command::end(PEvent signal) {
if (signal != nullptr) {
@@ -35,14 +33,14 @@ void Command::end(PEvent signal) {
}
void Command::executeCommands(Array<Gfx::ORenderCommand> commands) {
for (auto &command : commands) {
for (auto& command : commands) {
auto cmd = Gfx::PRenderCommand(command).cast<RenderCommand>();
cmd->end();
}
}
void Command::executeCommands(Array<Gfx::OComputeCommand> commands) {
for (auto &command : commands) {
for (auto& command : commands) {
auto cmd = Gfx::PComputeCommand(command).cast<ComputeCommand>();
cmd->end();
}
@@ -50,16 +48,11 @@ void Command::executeCommands(Array<Gfx::OComputeCommand> commands) {
void Command::waitDeviceIdle() { cmdBuffer->waitUntilCompleted(); }
void Command::signalEvent(PEvent event) {
cmdBuffer->encodeSignalEvent(event->getHandle(), 1);
}
void Command::signalEvent(PEvent event) { cmdBuffer->encodeSignalEvent(event->getHandle(), 1); }
void Command::waitForEvent(PEvent event) {
cmdBuffer->encodeWait(event->getHandle(), 1);
}
void Command::waitForEvent(PEvent event) { cmdBuffer->encodeWait(event->getHandle(), 1); }
RenderCommand::RenderCommand(MTL::RenderCommandEncoder *encoder)
: encoder(encoder) {}
RenderCommand::RenderCommand(MTL::RenderCommandEncoder* encoder) : encoder(encoder) {}
RenderCommand::~RenderCommand() { encoder->release(); }
@@ -78,98 +71,109 @@ void RenderCommand::setViewport(Gfx::PViewport viewport) {
}
void RenderCommand::bindPipeline(Gfx::PGraphicsPipeline pipeline) {
// encoder->setRenderPipelineState(
// pipeline.cast<GraphicsPipeline>()->getState());
boundPipeline = pipeline.cast<GraphicsPipeline>();
encoder->setRenderPipelineState(boundPipeline->getHandle());
}
void RenderCommand::bindDescriptor(Gfx::PDescriptorSet descriptorSet) {
encoder->setVertexBuffer(descriptorSet.cast<DescriptorSet>()->getBuffer(), 0, descriptorSet->getSetIndex());
encoder->setFragmentBuffer(descriptorSet.cast<DescriptorSet>()->getBuffer(), 0, descriptorSet->getSetIndex());
encoder->setMeshBuffer(descriptorSet.cast<DescriptorSet>()->getBuffer(), 0, descriptorSet->getSetIndex());
encoder->setObjectBuffer(descriptorSet.cast<DescriptorSet>()->getBuffer(), 0, descriptorSet->getSetIndex());
}
void RenderCommand::bindDescriptor(
const Array<Gfx::PDescriptorSet> &descriptorSets) {
// encoder->set ? ? ? ? ?
void RenderCommand::bindDescriptor(const Array<Gfx::PDescriptorSet>& descriptorSets) {
for (auto set : descriptorSets) {
bindDescriptor(set);
}
}
void RenderCommand::bindVertexBuffer(const Array<Gfx::PVertexBuffer> &buffers) {
// encoder->setVertexBuffers();
void RenderCommand::bindVertexBuffer(const Array<Gfx::PVertexBuffer>& buffers) {
uint32 i = 0;
for (auto buffer : buffers) {
encoder->setVertexBuffer(buffer.cast<VertexBuffer>()->getHandle(), 0, i++);
}
}
void RenderCommand::bindIndexBuffer(Gfx::PIndexBuffer indexBuffer) {
// encoder->setObjectBuffer(??, NS::UInteger offset, NS::UInteger index)
void RenderCommand::bindIndexBuffer(Gfx::PIndexBuffer gfxIndexBuffer) {
boundIndexBuffer = gfxIndexBuffer.cast<IndexBuffer>();
}
void RenderCommand::pushConstants(Gfx::PPipelineLayout layout,
Gfx::SeShaderStageFlags stage, uint32 offset,
uint32 size, const void *data) {
// ? ? ?
void RenderCommand::pushConstants(Gfx::PPipelineLayout, Gfx::SeShaderStageFlags stage, uint32 offset, uint32 size,
const void* data) {
if (stage & Gfx::SE_SHADER_STAGE_VERTEX_BIT) {
encoder->setVertexBytes((char*)data + offset, size, 0);
}
if (stage & Gfx::SE_SHADER_STAGE_FRAGMENT_BIT) {
encoder->setFragmentBytes((char*)data + offset, size, 0);
}
}
void RenderCommand::draw(uint32 vertexCount, uint32 instanceCount,
int32 firstVertex, uint32 firstInstance) {
// encoder->drawPrimitives(???, firstVertex, vertexCount, instanceCount, firstInstance);
void RenderCommand::draw(uint32 vertexCount, uint32 instanceCount, int32 firstVertex, uint32 firstInstance) {
encoder->drawPrimitives(boundPipeline->getPrimitive(), firstVertex, vertexCount, instanceCount, firstInstance);
}
void RenderCommand::drawIndexed(uint32 indexCount, uint32 instanceCount,
int32 firstIndex, uint32 vertexOffset,
void RenderCommand::drawIndexed(uint32 indexCount, uint32 instanceCount, int32 firstIndex, uint32 vertexOffset,
uint32 firstInstance) {
// encoder->drawIndexedPrimitives(???, indexCount, indexbuffer->getType(), indexBuffer->getBuffer(), firstIndex, instanceCount, vertexOffset, firstInstance);
encoder->drawIndexedPrimitives(boundPipeline->getPrimitive(), indexCount, cast(boundIndexBuffer->getIndexType()),
boundIndexBuffer->getHandle(), firstIndex, instanceCount, vertexOffset, firstInstance);
}
void RenderCommand::drawMesh(uint32 groupX, uint32 groupY, uint32 groupZ){
// encoder->drawMeshThreads(MTL::Size threadsPerGrid,
// MTL::Size threadsPerObjectThreadgroup,
// MTL::Size threadsPerMeshThreadgroup)
}
void RenderCommand::drawMesh(uint32 groupX, uint32 groupY, uint32 groupZ) {
//TODO:
encoder->drawMeshThreadgroups(MTL::Size(groupX, groupY, groupZ), MTL::Size(128, 128, 128), MTL::Size(32, 32, 32));
}
ComputeCommand::ComputeCommand(MTL::ComputeCommandEncoder *encoder)
: encoder(encoder) {}
ComputeCommand::ComputeCommand(MTL::ComputeCommandEncoder* encoder) : encoder(encoder) {}
ComputeCommand::~ComputeCommand() { encoder->release(); }
void ComputeCommand::end() { encoder->endEncoding(); }
void ComputeCommand::bindPipeline(Gfx::PComputePipeline pipeline) {
// encoder->setComputePipelineState(pipeline.cast<ComputePipeline>());
encoder->setComputePipelineState(pipeline.cast<ComputePipeline>()->getHandle());
}
void ComputeCommand::bindDescriptor(Gfx::PDescriptorSet set) {
// encoder->set ? ? ?
encoder->setBuffer(set.cast<DescriptorSet>()->getBuffer(), 0, set->getSetIndex());
}
void ComputeCommand::bindDescriptor(const Array<Gfx::PDescriptorSet> &sets) {
// encoder->set ? ? ?
void ComputeCommand::bindDescriptor(const Array<Gfx::PDescriptorSet>& sets) {
for (auto& set : sets) {
bindDescriptor(set);
}
}
void ComputeCommand::pushConstants(Gfx::PPipelineLayout layout,
Gfx::SeShaderStageFlags stage, uint32 offset,
uint32 size, const void *data) {
// ? ? ?
void ComputeCommand::pushConstants(Gfx::PPipelineLayout, Gfx::SeShaderStageFlags, uint32 offset,
uint32 size, const void* data) {
encoder->setBytes((char*)data + offset, size, 0);
}
void ComputeCommand::dispatch(uint32 threadX, uint32 threadY, uint32 threadZ) {
// encoder->dispatchThreadgroups(???);
//TODO
encoder->dispatchThreadgroups(MTL::Size(threadX, threadY, threadZ), MTL::Size(32, 32, 32));
}
CommandQueue::CommandQueue(PGraphics graphics) : graphics(graphics) {
queue = graphics->getDevice()->newCommandQueue();
activeCommand = new Command(graphics, queue->commandBuffer());
queue = graphics->getDevice()->newCommandQueue();
activeCommand = new Command(graphics, queue->commandBuffer());
}
CommandQueue::~CommandQueue() { queue->release(); }
ORenderCommand CommandQueue::getRenderCommand(const std::string &name) {
return new RenderCommand(activeCommand->createRenderEncoder());
ORenderCommand CommandQueue::getRenderCommand(const std::string& name) {
return new RenderCommand(activeCommand->createRenderEncoder());
}
OComputeCommand CommandQueue::getComputeCommand(const std::string &name) {
return new ComputeCommand(activeCommand->createComputeEncoder());
OComputeCommand CommandQueue::getComputeCommand(const std::string& name) {
return new ComputeCommand(activeCommand->createComputeEncoder());
}
void CommandQueue::submitCommands(PEvent signalSemaphore) {
activeCommand->end(signalSemaphore);
PEvent prevCmdEvent = activeCommand->getCompletedEvent();
activeCommand = new Command(graphics, queue->commandBuffer());
activeCommand->waitForEvent(prevCmdEvent);
activeCommand->end(signalSemaphore);
PEvent prevCmdEvent = activeCommand->getCompletedEvent();
activeCommand = new Command(graphics, queue->commandBuffer());
activeCommand->waitForEvent(prevCmdEvent);
}
IOCommandQueue::IOCommandQueue(PGraphics graphics) : graphics(graphics) {
@@ -177,16 +181,16 @@ IOCommandQueue::IOCommandQueue(PGraphics graphics) : graphics(graphics) {
desc->setType(MTL::IOCommandQueueTypeConcurrent);
desc->setPriority(MTL::IOPriorityNormal);
queue = graphics->getDevice()->newIOCommandQueue(desc, nullptr);
//activeCommand = new Command(graphics, queue->commandBuffer());
// activeCommand = new Command(graphics, queue->commandBuffer());
desc->release();
}
IOCommandQueue::~IOCommandQueue() { queue->release(); }
void IOCommandQueue::submitCommands(PEvent signalSemaphore) {
//TODO: scratch buffer
activeCommand->end(signalSemaphore);
PEvent prevCmdEvent = activeCommand->getCompletedEvent();
//activeCommand = new Command(graphics, queue->commandBuffer());
activeCommand->waitForEvent(prevCmdEvent);
// TODO: scratch buffer
activeCommand->end(signalSemaphore);
PEvent prevCmdEvent = activeCommand->getCompletedEvent();
// activeCommand = new Command(graphics, queue->commandBuffer());
activeCommand->waitForEvent(prevCmdEvent);
}
+3 -2
View File
@@ -1,9 +1,8 @@
#pragma once
#include "Foundation/NSArray.hpp"
#include "Graphics/Descriptor.h"
#include "Graphics/Initializer.h"
#include "Metal/MTLArgumentEncoder.hpp"
#include "MinimalEngine.h"
#include "Buffer.h"
namespace Seele {
namespace Metal {
@@ -58,6 +57,8 @@ public:
constexpr void allocate() { currentlyInUse = true; }
constexpr void free() { currentlyInUse = false; }
constexpr MTL::Buffer* getBuffer() const { return buffer; }
private:
PGraphics graphics;
PDescriptorPool owner;
+1
View File
@@ -47,6 +47,7 @@ void DescriptorLayout::create() {
descriptors.add(desc);
}
arguments = NS::Array::array(descriptors.data(), descriptors.size());
pool = new DescriptorPool(graphics, this);
}
DescriptorPool::DescriptorPool(PGraphics graphics, PDescriptorLayout layout) : graphics(graphics), layout(layout) {}
+5 -2
View File
@@ -1,7 +1,6 @@
#pragma once
#include "Graphics/Enums.h"
#include "Metal/MTLDepthStencil.hpp"
#include "Metal/MTLSampler.hpp"
#include "Metal/MTLStageInputOutputDescriptor.hpp"
#include "Resources.h"
namespace Seele
@@ -26,5 +25,9 @@ MTL::SamplerMipFilter cast(Gfx::SeSamplerMipmapMode filter);
Gfx::SeSamplerMipmapMode cast(MTL::SamplerMipFilter filter);
MTL::SamplerAddressMode cast(Gfx::SeSamplerAddressMode mode);
Gfx::SeSamplerAddressMode cast(MTL::SamplerAddressMode mode);
MTL::PrimitiveTopologyClass cast(Gfx::SePrimitiveTopology topology);
Gfx::SePrimitiveTopology cast(MTL::PrimitiveTopologyClass topology);
MTL::IndexType cast(Gfx::SeIndexType indexType);
Gfx::SeIndexType cast(MTL::IndexType indexType);
}
}
+48 -3
View File
@@ -1,8 +1,6 @@
#include "Enums.h"
#include "Graphics/Enums.h"
#include "Metal/MTLArgument.hpp"
#include "Metal/MTLDepthStencil.hpp"
#include "Metal/MTLSampler.hpp"
#include "Metal/MTLStageInputOutputDescriptor.hpp"
#include <stdexcept>
using namespace Seele;
@@ -768,3 +766,50 @@ Gfx::SeSamplerAddressMode Seele::Metal::cast(MTL::SamplerAddressMode mode) {
return Gfx::SE_SAMPLER_ADDRESS_MODE_CLAMP_TO_BORDER;
}
}
MTL::PrimitiveTopologyClass Seele::Metal::cast(Gfx::SePrimitiveTopology topology) {
switch (topology) {
case Gfx::SE_PRIMITIVE_TOPOLOGY_POINT_LIST:
return MTL::PrimitiveTopologyClassPoint;
case Gfx::SE_PRIMITIVE_TOPOLOGY_LINE_LIST:
return MTL::PrimitiveTopologyClassLine;
case Gfx::SE_PRIMITIVE_TOPOLOGY_LINE_STRIP:
return MTL::PrimitiveTopologyClassLine;
case Gfx::SE_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST:
return MTL::PrimitiveTopologyClassTriangle;
case Gfx::SE_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP:
return MTL::PrimitiveTopologyClassTriangle;
case Gfx::SE_PRIMITIVE_TOPOLOGY_TRIANGLE_FAN:
return MTL::PrimitiveTopologyClassTriangle;
case Gfx::SE_PRIMITIVE_TOPOLOGY_LINE_LIST_WITH_ADJACENCY:
return MTL::PrimitiveTopologyClassLine;
case Gfx::SE_PRIMITIVE_TOPOLOGY_LINE_STRIP_WITH_ADJACENCY:
return MTL::PrimitiveTopologyClassLine;
case Gfx::SE_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST_WITH_ADJACENCY:
return MTL::PrimitiveTopologyClassTriangle;
case Gfx::SE_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP_WITH_ADJACENCY:
return MTL::PrimitiveTopologyClassTriangle;
case Gfx::SE_PRIMITIVE_TOPOLOGY_PATCH_LIST:
return MTL::PrimitiveTopologyClassUnspecified;
}
}
MTL::IndexType Seele::Metal::cast(Gfx::SeIndexType indexType) {
switch (indexType) {
case Gfx::SE_INDEX_TYPE_UINT16:
return MTL::IndexTypeUInt16;
case Gfx::SE_INDEX_TYPE_UINT32:
return MTL::IndexTypeUInt32;
default:
throw std::logic_error("Not implemented");
}
}
Gfx::SeIndexType Seele::Metal::cast(MTL::IndexType indexType) {
switch (indexType) {
case MTL::IndexTypeUInt16:
return Gfx::SE_INDEX_TYPE_UINT16;
case MTL::IndexTypeUInt32:
return Gfx::SE_INDEX_TYPE_UINT32;
}
}
+2
View File
@@ -8,6 +8,7 @@ namespace Metal
{
DECLARE_REF(CommandQueue)
DECLARE_REF(IOCommandQueue)
DECLARE_REF(PipelineCache)
class Graphics : public Gfx::Graphics
{
public:
@@ -61,6 +62,7 @@ protected:
MTL::Device* device;
OCommandQueue queue;
OIOCommandQueue ioQueue;
OPipelineCache cache;
};
DEFINE_REF(Graphics)
} // namespace Metal
+19 -8
View File
@@ -1,7 +1,12 @@
#include "Graphics.h"
#include "Graphics/Initializer.h"
#include "Graphics/Metal/Descriptor.h"
#include "Graphics/Metal/Pipeline.h"
#include "Graphics/Metal/PipelineCache.h"
#include "Graphics/Metal/Resources.h"
#include "Shader.h"
#include "RenderPass.h"
#include "Resources.h"
#include "Command.h"
#include "Window.h"
#include "Buffer.h"
@@ -24,6 +29,7 @@ void Graphics::init(GraphicsInitializer)
device = MTL::CreateSystemDefaultDevice();
queue = new CommandQueue(this);
ioQueue = new IOCommandQueue(this);
cache = new PipelineCache(this, "pipelines.metal");
}
Gfx::OWindow Graphics::createWindow(const WindowCreateInfo &createInfo)
@@ -118,12 +124,14 @@ Gfx::OVertexShader Graphics::createVertexShader(const ShaderCreateInfo& createIn
result->create(createInfo);
return result;
}
Gfx::OFragmentShader Graphics::createFragmentShader(const ShaderCreateInfo& createInfo)
{
OFragmentShader result = new FragmentShader(this);
result->create(createInfo);
return result;
}
Gfx::OComputeShader Graphics::createComputeShader(const ShaderCreateInfo& createInfo)
{
OComputeShader result = new ComputeShader(this);
@@ -137,6 +145,7 @@ Gfx::OMeshShader Graphics::createMeshShader(const ShaderCreateInfo& createInfo)
result->create(createInfo);
return result;
}
Gfx::OTaskShader Graphics::createTaskShader(const ShaderCreateInfo& createInfo)
{
OTaskShader result = new TaskShader(this);
@@ -146,39 +155,41 @@ Gfx::OTaskShader Graphics::createTaskShader(const ShaderCreateInfo& createInfo)
Gfx::PGraphicsPipeline Graphics::createGraphicsPipeline(Gfx::LegacyPipelineCreateInfo createInfo)
{
return cache->createPipeline(std::move(createInfo));
}
Gfx::PGraphicsPipeline Graphics::createGraphicsPipeline(Gfx::MeshPipelineCreateInfo createInfo)
{
return cache->createPipeline(std::move(createInfo));
}
Gfx::PComputePipeline Graphics::createComputePipeline(Gfx::ComputePipelineCreateInfo createInfo)
{
return cache->createPipeline(std::move(createInfo));
}
Gfx::OSampler Graphics::createSampler(const SamplerCreateInfo& createInfo)
{
return new Sampler(this, createInfo);
}
Gfx::ODescriptorLayout Graphics::createDescriptorLayout(const std::string& name)
{
return new DescriptorLayout(this, name);
}
Gfx::OPipelineLayout Graphics::createPipelineLayout(Gfx::PPipelineLayout baseLayout)
{
return new PipelineLayout(this, baseLayout);
}
Gfx::OVertexInput Graphics::createVertexInput(VertexInputStateCreateInfo createInfo)
{
return new VertexInput(createInfo);
}
void Graphics::resolveTexture(Gfx::PTexture source, Gfx::PTexture destination)
{
}
+15 -12
View File
@@ -1,37 +1,40 @@
#pragma once
#include "Graphics/Initializer.h"
#include "Graphics/Pipeline.h"
#include "Resources.h"
#include "MinimalEngine.h"
#include "Resources.h"
namespace Seele {
namespace Metal {
class VertexInput : public Gfx::VertexInput
{
class VertexInput : public Gfx::VertexInput {
public:
VertexInput(VertexInputStateCreateInfo createInfo);
virtual ~VertexInput();
};
DECLARE_REF(PipelineLayout)
DECLARE_REF(Graphics)
class GraphicsPipeline : public Gfx::GraphicsPipeline
{
class GraphicsPipeline : public Gfx::GraphicsPipeline {
public:
GraphicsPipeline(PGraphics graphics, Gfx::LegacyPipelineCreateInfo createInfo);
GraphicsPipeline(PGraphics graphics, Gfx::MeshPipelineCreateInfo createInfo);
GraphicsPipeline(PGraphics graphics, MTL::PrimitiveType primitive, MTL::RenderPipelineState* pipeline, Gfx::OPipelineLayout createInfo);
virtual ~GraphicsPipeline();
constexpr MTL::RenderPipelineState* getHandle() const { return state; }
constexpr MTL::PrimitiveType getPrimitive() const { return primitiveType; }
private:
PGraphics graphics;
MTL::RenderPipelineState* state;
MTL::PrimitiveType primitiveType;
};
DEFINE_REF(GraphicsPipeline)
class ComputePipeline : public Gfx::ComputePipeline
{
class ComputePipeline : public Gfx::ComputePipeline {
public:
ComputePipeline(PGraphics graphics, Gfx::ComputePipelineCreateInfo createInfo);
ComputePipeline(PGraphics graphics, MTL::ComputePipelineState* pipeline, Gfx::OPipelineLayout);
virtual ~ComputePipeline();
constexpr MTL::ComputePipelineState* getHandle() const { return state; }
private:
PGraphics graphics;
MTL::ComputePipelineState* state;
};
DEFINE_REF(ComputePipeline)
}
}
} // namespace Metal
} // namespace Seele
+15 -8
View File
@@ -1,17 +1,24 @@
#include "Pipeline.h"
#include "Graphics/Initializer.h"
#include "Graphics/Metal/Graphics.h"
#include "Graphics/Pipeline.h"
#include "Graphics/Resources.h"
#include "Metal/MTLRenderPipeline.hpp"
using namespace Seele;
using namespace Seele::Metal;
VertexInput::VertexInput(VertexInputStateCreateInfo createInfo)
: Gfx::VertexInput(createInfo)
{
}
VertexInput::VertexInput(VertexInputStateCreateInfo createInfo) : Gfx::VertexInput(createInfo) {}
VertexInput::~VertexInput()
{
}
VertexInput::~VertexInput() {}
GraphicsPipeline::GraphicsPipeline(PGraphics graphics, MTL::PrimitiveType primitive, MTL::RenderPipelineState* pipeline,
Gfx::OPipelineLayout createInfo)
: Gfx::GraphicsPipeline(std::move(createInfo)), graphics(graphics), state(pipeline), primitiveType(primitive) {}
GraphicsPipeline::~GraphicsPipeline() {}
ComputePipeline::ComputePipeline(PGraphics graphics, MTL::ComputePipelineState* pipeline,
Gfx::OPipelineLayout createInfo)
: Gfx::ComputePipeline(std::move(createInfo)), graphics(graphics), state(pipeline) {}
ComputePipeline::~ComputePipeline() {}
+1 -1
View File
@@ -15,7 +15,7 @@ public:
private:
PGraphics graphics;
Map<uint32, OGraphicsPipeline> graphicsPipelines;
Map<uint32, OComputePipeline> computePipeline;
Map<uint32, OComputePipeline> computePipelines;
std::string cacheFile;
};
DEFINE_REF(PipelineCache)
+120 -10
View File
@@ -1,11 +1,18 @@
#include "PipelineCache.h"
#include "Descriptor.h"
#include "Enums.h"
#include "Foundation/NSError.hpp"
#include "Graphics.h"
#include "Shader.h"
#include "Graphics/Descriptor.h"
#include "Graphics/Enums.h"
#include "Graphics/Metal/Pipeline.h"
#include "Metal/MTLComputePipeline.hpp"
#include "Metal/MTLDevice.hpp"
#include "Metal/MTLRenderCommandEncoder.hpp"
#include "Metal/MTLRenderPipeline.hpp"
#include "Metal/MTLVertexDescriptor.hpp"
#include "Shader.h"
#include "Texture.h"
using namespace Seele;
using namespace Seele::Metal;
@@ -16,15 +23,12 @@ PipelineCache::~PipelineCache() {}
PGraphicsPipeline PipelineCache::createPipeline(Gfx::LegacyPipelineCreateInfo createInfo) {
PPipelineLayout layout = Gfx::PPipelineLayout(createInfo.pipelineLayout).cast<PipelineLayout>();
uint32 hash = layout->getHash();
MTL::RenderPipelineDescriptor* pipelineDescriptor = MTL::RenderPipelineDescriptor::alloc()->init();
MTL::VertexDescriptor* vertexDescriptor = MTL::VertexDescriptor::alloc()->init();
MTL::VertexAttributeDescriptorArray* attributes = vertexDescriptor->attributes();
const auto& vertexInfo = createInfo.vertexInput->getInfo();
for (size_t attr = 0; attr < vertexInfo.attributes.size(); ++attr) {
MTL::VertexAttributeDescriptor* attribute = MTL::VertexAttributeDescriptor::alloc()->init();
attribute->setBufferIndex(vertexInfo.attributes[attr].binding);
@@ -40,7 +44,6 @@ PGraphicsPipeline PipelineCache::createPipeline(Gfx::LegacyPipelineCreateInfo cr
}
MTL::VertexBufferLayoutDescriptorArray* bufferLayout = vertexDescriptor->layouts();
for (size_t binding = 0; binding < vertexInfo.bindings.size(); ++binding) {
MTL::VertexBufferLayoutDescriptor* buffer = MTL::VertexBufferLayoutDescriptor::alloc()->init();
buffer->setStride(vertexInfo.bindings[binding].stride);
@@ -55,16 +58,123 @@ PGraphicsPipeline PipelineCache::createPipeline(Gfx::LegacyPipelineCreateInfo cr
}
bufferLayout->setObject(buffer, binding);
}
pipelineDescriptor->setVertexDescriptor(vertexDescriptor);
pipelineDescriptor->setVertexFunction(createInfo.vertexShader.cast<VertexShader>()->getFunction());
if (createInfo.fragmentShader != nullptr) {
pipelineDescriptor->setFragmentFunction(createInfo.fragmentShader.cast<FragmentShader>()->getFunction());
}
pipelineDescriptor->setInputPrimitiveTopology(cast(createInfo.topology));
if (createInfo.renderPass->getLayout().depthAttachment.getTexture() != nullptr) {
pipelineDescriptor->setDepthAttachmentPixelFormat(
cast(createInfo.renderPass->getLayout().depthAttachment.getTexture().cast<Texture2D>()->getFormat()));
}
pipelineDescriptor->setAlphaToCoverageEnabled(createInfo.multisampleState.alphaCoverageEnable);
pipelineDescriptor->setAlphaToOneEnabled(createInfo.multisampleState.alphaToOneEnable);
pipelineDescriptor->setRasterSampleCount(createInfo.multisampleState.samples);
pipelineDescriptor->setRasterizationEnabled(!createInfo.rasterizationState.rasterizerDiscardEnable);
uint32 hash = pipelineDescriptor->hash();
if (graphicsPipelines.contains(hash)) {
return graphicsPipelines[hash];
}
MTL::PrimitiveType type = MTL::PrimitiveTypeTriangle;
switch (createInfo.topology) {
case Gfx::SE_PRIMITIVE_TOPOLOGY_POINT_LIST:
type = MTL::PrimitiveTypePoint;
break;
case Gfx::SE_PRIMITIVE_TOPOLOGY_LINE_LIST:
type = MTL::PrimitiveTypeLine;
break;
case Gfx::SE_PRIMITIVE_TOPOLOGY_LINE_STRIP:
type = MTL::PrimitiveTypeLineStrip;
break;
case Gfx::SE_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST:
type = MTL::PrimitiveTypeTriangle;
break;
case Gfx::SE_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP:
type = MTL::PrimitiveTypeTriangleStrip;
break;
case Gfx::SE_PRIMITIVE_TOPOLOGY_TRIANGLE_FAN:
type = MTL::PrimitiveTypeTriangle;
break;
case Gfx::SE_PRIMITIVE_TOPOLOGY_LINE_LIST_WITH_ADJACENCY:
type = MTL::PrimitiveTypeLine;
break;
case Gfx::SE_PRIMITIVE_TOPOLOGY_LINE_STRIP_WITH_ADJACENCY:
type = MTL::PrimitiveTypeLineStrip;
break;
case Gfx::SE_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST_WITH_ADJACENCY:
type = MTL::PrimitiveTypeTriangle;
break;
case Gfx::SE_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP_WITH_ADJACENCY:
type = MTL::PrimitiveTypeTriangleStrip;
break;
case Gfx::SE_PRIMITIVE_TOPOLOGY_PATCH_LIST:
type = MTL::PrimitiveTypeTriangle;
break;
}
NS::Error* error;
graphicsPipelines[hash] =
new GraphicsPipeline(graphics, type, graphics->getDevice()->newRenderPipelineState(pipelineDescriptor, &error),
std::move(createInfo.pipelineLayout));
assert(!error);
vertexDescriptor->release();
pipelineDescriptor->release();
return graphicsPipelines[hash];
}
PGraphicsPipeline PipelineCache::createPipeline(Gfx::MeshPipelineCreateInfo createInfo) {}
PGraphicsPipeline PipelineCache::createPipeline(Gfx::MeshPipelineCreateInfo createInfo) {
MTL::MeshRenderPipelineDescriptor* pipelineDescriptor = MTL::MeshRenderPipelineDescriptor::alloc()->init();
PComputePipeline PipelineCache::createPipeline(Gfx::ComputePipelineCreateInfo createInfo) {}
pipelineDescriptor->setMeshFunction(createInfo.meshShader.cast<VertexShader>()->getFunction());
if (createInfo.taskShader != nullptr) {
pipelineDescriptor->setObjectFunction(createInfo.taskShader.cast<TaskShader>()->getFunction());
}
if (createInfo.fragmentShader != nullptr) {
pipelineDescriptor->setFragmentFunction(createInfo.fragmentShader.cast<FragmentShader>()->getFunction());
}
if (createInfo.renderPass->getLayout().depthAttachment.getTexture() != nullptr) {
pipelineDescriptor->setDepthAttachmentPixelFormat(
cast(createInfo.renderPass->getLayout().depthAttachment.getTexture().cast<Texture2D>()->getFormat()));
}
pipelineDescriptor->setAlphaToCoverageEnabled(createInfo.multisampleState.alphaCoverageEnable);
pipelineDescriptor->setAlphaToOneEnabled(createInfo.multisampleState.alphaToOneEnable);
pipelineDescriptor->setRasterSampleCount(createInfo.multisampleState.samples);
pipelineDescriptor->setRasterizationEnabled(!createInfo.rasterizationState.rasterizerDiscardEnable);
uint32 hash = pipelineDescriptor->hash();
if (graphicsPipelines.contains(hash)) {
return graphicsPipelines[hash];
}
graphics->getDevice()->newRenderPipelineState(
pipelineDescriptor, MTL::PipelineOptionNone,
[&](MTL::RenderPipelineState* state, MTL::RenderPipelineReflection*, NS::Error* error) {
assert(!error);
graphicsPipelines[hash] =
new GraphicsPipeline(graphics, MTL::PrimitiveTypeLine, state, std::move(createInfo.pipelineLayout));
});
pipelineDescriptor->release();
return graphicsPipelines[hash];
}
PComputePipeline PipelineCache::createPipeline(Gfx::ComputePipelineCreateInfo createInfo) {
PComputeShader shader = createInfo.computeShader.cast<ComputeShader>();
uint32 hash = shader->getShaderHash();
if (computePipelines.contains(hash)) {
return computePipelines[hash];
}
NS::Error* error;
computePipelines[hash] =
new ComputePipeline(graphics, graphics->getDevice()->newComputePipelineState(shader->getFunction(), &error),
std::move(createInfo.pipelineLayout));
assert(!error);
return computePipelines[hash];
}
+15 -17
View File
@@ -14,8 +14,8 @@
using namespace Seele;
using namespace Seele::Metal;
Shader::Shader(PGraphics graphics, Gfx::SeShaderStageFlags stage)
: stage(stage), graphics(graphics) {}
Shader::Shader(PGraphics graphics, Gfx::SeShaderStageFlags stage) : stage(stage), graphics(graphics) {}
Shader::~Shader() {
if (function) {
function->release();
@@ -23,29 +23,27 @@ Shader::~Shader() {
}
}
void Shader::create(const ShaderCreateInfo &createInfo) {
Slang::ComPtr<slang::IBlob> kernelBlob =
generateShader(createInfo, SLANG_SPIRV);
spirv_cross::CompilerMSL comp((const uint32 *)kernelBlob->getBufferPointer(),
kernelBlob->getBufferSize() / 4);
void Shader::create(const ShaderCreateInfo& createInfo) {
Slang::ComPtr<slang::IBlob> kernelBlob = generateShader(createInfo, SLANG_SPIRV);
hash = CRC::Calculate(kernelBlob->getBufferPointer(), kernelBlob->getBufferSize(), CRC::CRC_32());
spirv_cross::CompilerMSL comp((const uint32*)kernelBlob->getBufferPointer(), kernelBlob->getBufferSize() / 4);
auto options = comp.get_msl_options();
options.argument_buffers = true;
options.argument_buffers_tier =
spirv_cross::CompilerMSL::Options::ArgumentBuffersTier::Tier2;
options.argument_buffers_tier = spirv_cross::CompilerMSL::Options::ArgumentBuffersTier::Tier2;
options.set_msl_version(3);
comp.set_msl_options(options);
std::string metalCode = comp.compile();
NS::Error *error = nullptr;
MTL::CompileOptions *mtlOptions = MTL::CompileOptions::alloc()->init();
NS::Error* error = nullptr;
MTL::CompileOptions* mtlOptions = MTL::CompileOptions::alloc()->init();
library = graphics->getDevice()->newLibrary(
NS::String::string(metalCode.c_str(), NS::ASCIIStringEncoding),
mtlOptions, &error);
library = graphics->getDevice()->newLibrary(NS::String::string(metalCode.c_str(), NS::ASCIIStringEncoding),
mtlOptions, &error);
if (error) {
std::cout << error->debugDescription() << std::endl;
assert(false);
}
function =
library->newFunction(NS::String::string("main", NS::ASCIIStringEncoding));
function = library->newFunction(NS::String::string("main", NS::ASCIIStringEncoding));
mtlOptions->release();
}
}
uint32 Shader::getShaderHash() const { return hash; }