Metal is impossible to debug, thanks apple
This commit is contained in:
@@ -3,8 +3,6 @@
|
|||||||
#include "Graphics/Buffer.h"
|
#include "Graphics/Buffer.h"
|
||||||
#include "Graphics/Enums.h"
|
#include "Graphics/Enums.h"
|
||||||
#include "Graphics/Initializer.h"
|
#include "Graphics/Initializer.h"
|
||||||
#include "Metal/MTLResource.hpp"
|
|
||||||
|
|
||||||
using namespace Seele;
|
using namespace Seele;
|
||||||
using namespace Seele::Metal;
|
using namespace Seele::Metal;
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
#include "Graphics/Command.h"
|
#include "Graphics/Command.h"
|
||||||
#include "Metal/MTLCommandBuffer.hpp"
|
#include "Buffer.h"
|
||||||
#include "RenderPass.h"
|
#include "RenderPass.h"
|
||||||
#include "Resources.h"
|
#include "Resources.h"
|
||||||
|
|
||||||
@@ -10,6 +10,8 @@ DECLARE_REF(CommandQueue)
|
|||||||
DECLARE_REF(ComputeCommand)
|
DECLARE_REF(ComputeCommand)
|
||||||
DECLARE_REF(RenderCommand)
|
DECLARE_REF(RenderCommand)
|
||||||
DECLARE_REF(Graphics)
|
DECLARE_REF(Graphics)
|
||||||
|
DECLARE_REF(IndexBuffer)
|
||||||
|
DECLARE_REF(GraphicsPipeline)
|
||||||
class Command
|
class Command
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
@@ -56,6 +58,8 @@ public:
|
|||||||
virtual void drawMesh(uint32 groupX, uint32 groupY, uint32 groupZ) override;
|
virtual void drawMesh(uint32 groupX, uint32 groupY, uint32 groupZ) override;
|
||||||
private:
|
private:
|
||||||
MTL::RenderCommandEncoder* encoder;
|
MTL::RenderCommandEncoder* encoder;
|
||||||
|
PIndexBuffer boundIndexBuffer;
|
||||||
|
PGraphicsPipeline boundPipeline;
|
||||||
};
|
};
|
||||||
DEFINE_REF(RenderCommand)
|
DEFINE_REF(RenderCommand)
|
||||||
class ComputeCommand : public Gfx::ComputeCommand
|
class ComputeCommand : public Gfx::ComputeCommand
|
||||||
|
|||||||
@@ -1,30 +1,28 @@
|
|||||||
#include "Command.h"
|
#include "Command.h"
|
||||||
|
#include "Buffer.h"
|
||||||
|
#include "Descriptor.h"
|
||||||
|
#include "Enums.h"
|
||||||
|
#include "Graphics/Enums.h"
|
||||||
#include "Graphics/Graphics.h"
|
#include "Graphics/Graphics.h"
|
||||||
#include "Graphics/Metal/Resources.h"
|
#include "Pipeline.h"
|
||||||
#include "Metal/MTLCommandBuffer.hpp"
|
#include "Resources.h"
|
||||||
#include "Metal/MTLIOCommandQueue.hpp"
|
|
||||||
#include "Metal/MTLRenderCommandEncoder.hpp"
|
|
||||||
#include "Window.h"
|
#include "Window.h"
|
||||||
|
|
||||||
using namespace Seele;
|
using namespace Seele;
|
||||||
using namespace Seele::Metal;
|
using namespace Seele::Metal;
|
||||||
|
|
||||||
Command::Command(PGraphics graphics, MTL::CommandBuffer* cmdBuffer)
|
Command::Command(PGraphics graphics, MTL::CommandBuffer* cmdBuffer)
|
||||||
: graphics(graphics), completed(new Event(graphics)),
|
: graphics(graphics), completed(new Event(graphics)), cmdBuffer(cmdBuffer), renderEncoder(nullptr) {}
|
||||||
cmdBuffer(cmdBuffer), renderEncoder(nullptr) {}
|
|
||||||
|
|
||||||
Command::~Command() { cmdBuffer->release(); }
|
Command::~Command() { cmdBuffer->release(); }
|
||||||
|
|
||||||
void Command::beginRenderPass(PRenderPass renderPass) {
|
void Command::beginRenderPass(PRenderPass renderPass) {
|
||||||
renderEncoder =
|
renderEncoder = cmdBuffer->parallelRenderCommandEncoder(renderPass->getDescriptor());
|
||||||
cmdBuffer->parallelRenderCommandEncoder(renderPass->getDescriptor());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Command::endRenderPass() { renderEncoder->endEncoding(); }
|
void Command::endRenderPass() { renderEncoder->endEncoding(); }
|
||||||
|
|
||||||
void Command::present(MTL::Drawable *drawable) {
|
void Command::present(MTL::Drawable* drawable) { cmdBuffer->presentDrawable(drawable); }
|
||||||
cmdBuffer->presentDrawable(drawable);
|
|
||||||
}
|
|
||||||
|
|
||||||
void Command::end(PEvent signal) {
|
void Command::end(PEvent signal) {
|
||||||
if (signal != nullptr) {
|
if (signal != nullptr) {
|
||||||
@@ -35,14 +33,14 @@ void Command::end(PEvent signal) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void Command::executeCommands(Array<Gfx::ORenderCommand> commands) {
|
void Command::executeCommands(Array<Gfx::ORenderCommand> commands) {
|
||||||
for (auto &command : commands) {
|
for (auto& command : commands) {
|
||||||
auto cmd = Gfx::PRenderCommand(command).cast<RenderCommand>();
|
auto cmd = Gfx::PRenderCommand(command).cast<RenderCommand>();
|
||||||
cmd->end();
|
cmd->end();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Command::executeCommands(Array<Gfx::OComputeCommand> commands) {
|
void Command::executeCommands(Array<Gfx::OComputeCommand> commands) {
|
||||||
for (auto &command : commands) {
|
for (auto& command : commands) {
|
||||||
auto cmd = Gfx::PComputeCommand(command).cast<ComputeCommand>();
|
auto cmd = Gfx::PComputeCommand(command).cast<ComputeCommand>();
|
||||||
cmd->end();
|
cmd->end();
|
||||||
}
|
}
|
||||||
@@ -50,16 +48,11 @@ void Command::executeCommands(Array<Gfx::OComputeCommand> commands) {
|
|||||||
|
|
||||||
void Command::waitDeviceIdle() { cmdBuffer->waitUntilCompleted(); }
|
void Command::waitDeviceIdle() { cmdBuffer->waitUntilCompleted(); }
|
||||||
|
|
||||||
void Command::signalEvent(PEvent event) {
|
void Command::signalEvent(PEvent event) { cmdBuffer->encodeSignalEvent(event->getHandle(), 1); }
|
||||||
cmdBuffer->encodeSignalEvent(event->getHandle(), 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
void Command::waitForEvent(PEvent event) {
|
void Command::waitForEvent(PEvent event) { cmdBuffer->encodeWait(event->getHandle(), 1); }
|
||||||
cmdBuffer->encodeWait(event->getHandle(), 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
RenderCommand::RenderCommand(MTL::RenderCommandEncoder *encoder)
|
RenderCommand::RenderCommand(MTL::RenderCommandEncoder* encoder) : encoder(encoder) {}
|
||||||
: encoder(encoder) {}
|
|
||||||
|
|
||||||
RenderCommand::~RenderCommand() { encoder->release(); }
|
RenderCommand::~RenderCommand() { encoder->release(); }
|
||||||
|
|
||||||
@@ -78,76 +71,87 @@ void RenderCommand::setViewport(Gfx::PViewport viewport) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void RenderCommand::bindPipeline(Gfx::PGraphicsPipeline pipeline) {
|
void RenderCommand::bindPipeline(Gfx::PGraphicsPipeline pipeline) {
|
||||||
// encoder->setRenderPipelineState(
|
boundPipeline = pipeline.cast<GraphicsPipeline>();
|
||||||
// pipeline.cast<GraphicsPipeline>()->getState());
|
encoder->setRenderPipelineState(boundPipeline->getHandle());
|
||||||
}
|
}
|
||||||
|
|
||||||
void RenderCommand::bindDescriptor(Gfx::PDescriptorSet descriptorSet) {
|
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(
|
void RenderCommand::bindDescriptor(const Array<Gfx::PDescriptorSet>& descriptorSets) {
|
||||||
const Array<Gfx::PDescriptorSet> &descriptorSets) {
|
for (auto set : descriptorSets) {
|
||||||
// encoder->set ? ? ? ? ?
|
bindDescriptor(set);
|
||||||
}
|
|
||||||
|
|
||||||
void RenderCommand::bindVertexBuffer(const Array<Gfx::PVertexBuffer> &buffers) {
|
|
||||||
// encoder->setVertexBuffers();
|
|
||||||
}
|
|
||||||
|
|
||||||
void RenderCommand::bindIndexBuffer(Gfx::PIndexBuffer indexBuffer) {
|
|
||||||
// encoder->setObjectBuffer(??, NS::UInteger offset, NS::UInteger index)
|
|
||||||
}
|
|
||||||
|
|
||||||
void RenderCommand::pushConstants(Gfx::PPipelineLayout layout,
|
|
||||||
Gfx::SeShaderStageFlags stage, uint32 offset,
|
|
||||||
uint32 size, const void *data) {
|
|
||||||
// ? ? ?
|
|
||||||
}
|
|
||||||
|
|
||||||
void RenderCommand::draw(uint32 vertexCount, uint32 instanceCount,
|
|
||||||
int32 firstVertex, uint32 firstInstance) {
|
|
||||||
// encoder->drawPrimitives(???, firstVertex, vertexCount, instanceCount, firstInstance);
|
|
||||||
}
|
|
||||||
|
|
||||||
void RenderCommand::drawIndexed(uint32 indexCount, uint32 instanceCount,
|
|
||||||
int32 firstIndex, uint32 vertexOffset,
|
|
||||||
uint32 firstInstance) {
|
|
||||||
// encoder->drawIndexedPrimitives(???, indexCount, indexbuffer->getType(), indexBuffer->getBuffer(), firstIndex, instanceCount, vertexOffset, firstInstance);
|
|
||||||
}
|
|
||||||
|
|
||||||
void RenderCommand::drawMesh(uint32 groupX, uint32 groupY, uint32 groupZ){
|
|
||||||
// encoder->drawMeshThreads(MTL::Size threadsPerGrid,
|
|
||||||
// MTL::Size threadsPerObjectThreadgroup,
|
|
||||||
// MTL::Size threadsPerMeshThreadgroup)
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
ComputeCommand::ComputeCommand(MTL::ComputeCommandEncoder *encoder)
|
void RenderCommand::bindVertexBuffer(const Array<Gfx::PVertexBuffer>& buffers) {
|
||||||
: encoder(encoder) {}
|
uint32 i = 0;
|
||||||
|
for (auto buffer : buffers) {
|
||||||
|
encoder->setVertexBuffer(buffer.cast<VertexBuffer>()->getHandle(), 0, i++);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void RenderCommand::bindIndexBuffer(Gfx::PIndexBuffer gfxIndexBuffer) {
|
||||||
|
boundIndexBuffer = gfxIndexBuffer.cast<IndexBuffer>();
|
||||||
|
}
|
||||||
|
|
||||||
|
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(boundPipeline->getPrimitive(), firstVertex, vertexCount, instanceCount, firstInstance);
|
||||||
|
}
|
||||||
|
|
||||||
|
void RenderCommand::drawIndexed(uint32 indexCount, uint32 instanceCount, int32 firstIndex, uint32 vertexOffset,
|
||||||
|
uint32 firstInstance) {
|
||||||
|
encoder->drawIndexedPrimitives(boundPipeline->getPrimitive(), indexCount, cast(boundIndexBuffer->getIndexType()),
|
||||||
|
boundIndexBuffer->getHandle(), firstIndex, instanceCount, vertexOffset, firstInstance);
|
||||||
|
}
|
||||||
|
|
||||||
|
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() { encoder->release(); }
|
ComputeCommand::~ComputeCommand() { encoder->release(); }
|
||||||
|
|
||||||
void ComputeCommand::end() { encoder->endEncoding(); }
|
void ComputeCommand::end() { encoder->endEncoding(); }
|
||||||
|
|
||||||
void ComputeCommand::bindPipeline(Gfx::PComputePipeline pipeline) {
|
void ComputeCommand::bindPipeline(Gfx::PComputePipeline pipeline) {
|
||||||
// encoder->setComputePipelineState(pipeline.cast<ComputePipeline>());
|
encoder->setComputePipelineState(pipeline.cast<ComputePipeline>()->getHandle());
|
||||||
}
|
}
|
||||||
|
|
||||||
void ComputeCommand::bindDescriptor(Gfx::PDescriptorSet set) {
|
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) {
|
void ComputeCommand::bindDescriptor(const Array<Gfx::PDescriptorSet>& sets) {
|
||||||
// encoder->set ? ? ?
|
for (auto& set : sets) {
|
||||||
|
bindDescriptor(set);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void ComputeCommand::pushConstants(Gfx::PPipelineLayout layout,
|
void ComputeCommand::pushConstants(Gfx::PPipelineLayout, Gfx::SeShaderStageFlags, uint32 offset,
|
||||||
Gfx::SeShaderStageFlags stage, uint32 offset,
|
uint32 size, const void* data) {
|
||||||
uint32 size, const void *data) {
|
encoder->setBytes((char*)data + offset, size, 0);
|
||||||
// ? ? ?
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void ComputeCommand::dispatch(uint32 threadX, uint32 threadY, uint32 threadZ) {
|
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) {
|
CommandQueue::CommandQueue(PGraphics graphics) : graphics(graphics) {
|
||||||
@@ -157,11 +161,11 @@ CommandQueue::CommandQueue(PGraphics graphics) : graphics(graphics) {
|
|||||||
|
|
||||||
CommandQueue::~CommandQueue() { queue->release(); }
|
CommandQueue::~CommandQueue() { queue->release(); }
|
||||||
|
|
||||||
ORenderCommand CommandQueue::getRenderCommand(const std::string &name) {
|
ORenderCommand CommandQueue::getRenderCommand(const std::string& name) {
|
||||||
return new RenderCommand(activeCommand->createRenderEncoder());
|
return new RenderCommand(activeCommand->createRenderEncoder());
|
||||||
}
|
}
|
||||||
|
|
||||||
OComputeCommand CommandQueue::getComputeCommand(const std::string &name) {
|
OComputeCommand CommandQueue::getComputeCommand(const std::string& name) {
|
||||||
return new ComputeCommand(activeCommand->createComputeEncoder());
|
return new ComputeCommand(activeCommand->createComputeEncoder());
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -177,16 +181,16 @@ IOCommandQueue::IOCommandQueue(PGraphics graphics) : graphics(graphics) {
|
|||||||
desc->setType(MTL::IOCommandQueueTypeConcurrent);
|
desc->setType(MTL::IOCommandQueueTypeConcurrent);
|
||||||
desc->setPriority(MTL::IOPriorityNormal);
|
desc->setPriority(MTL::IOPriorityNormal);
|
||||||
queue = graphics->getDevice()->newIOCommandQueue(desc, nullptr);
|
queue = graphics->getDevice()->newIOCommandQueue(desc, nullptr);
|
||||||
//activeCommand = new Command(graphics, queue->commandBuffer());
|
// activeCommand = new Command(graphics, queue->commandBuffer());
|
||||||
desc->release();
|
desc->release();
|
||||||
}
|
}
|
||||||
|
|
||||||
IOCommandQueue::~IOCommandQueue() { queue->release(); }
|
IOCommandQueue::~IOCommandQueue() { queue->release(); }
|
||||||
|
|
||||||
void IOCommandQueue::submitCommands(PEvent signalSemaphore) {
|
void IOCommandQueue::submitCommands(PEvent signalSemaphore) {
|
||||||
//TODO: scratch buffer
|
// TODO: scratch buffer
|
||||||
activeCommand->end(signalSemaphore);
|
activeCommand->end(signalSemaphore);
|
||||||
PEvent prevCmdEvent = activeCommand->getCompletedEvent();
|
PEvent prevCmdEvent = activeCommand->getCompletedEvent();
|
||||||
//activeCommand = new Command(graphics, queue->commandBuffer());
|
// activeCommand = new Command(graphics, queue->commandBuffer());
|
||||||
activeCommand->waitForEvent(prevCmdEvent);
|
activeCommand->waitForEvent(prevCmdEvent);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,9 +1,8 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
#include "Foundation/NSArray.hpp"
|
|
||||||
#include "Graphics/Descriptor.h"
|
#include "Graphics/Descriptor.h"
|
||||||
#include "Graphics/Initializer.h"
|
#include "Graphics/Initializer.h"
|
||||||
#include "Metal/MTLArgumentEncoder.hpp"
|
|
||||||
#include "MinimalEngine.h"
|
#include "MinimalEngine.h"
|
||||||
|
#include "Buffer.h"
|
||||||
|
|
||||||
namespace Seele {
|
namespace Seele {
|
||||||
namespace Metal {
|
namespace Metal {
|
||||||
@@ -58,6 +57,8 @@ public:
|
|||||||
constexpr void allocate() { currentlyInUse = true; }
|
constexpr void allocate() { currentlyInUse = true; }
|
||||||
constexpr void free() { currentlyInUse = false; }
|
constexpr void free() { currentlyInUse = false; }
|
||||||
|
|
||||||
|
constexpr MTL::Buffer* getBuffer() const { return buffer; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
PGraphics graphics;
|
PGraphics graphics;
|
||||||
PDescriptorPool owner;
|
PDescriptorPool owner;
|
||||||
|
|||||||
@@ -47,6 +47,7 @@ void DescriptorLayout::create() {
|
|||||||
descriptors.add(desc);
|
descriptors.add(desc);
|
||||||
}
|
}
|
||||||
arguments = NS::Array::array(descriptors.data(), descriptors.size());
|
arguments = NS::Array::array(descriptors.data(), descriptors.size());
|
||||||
|
pool = new DescriptorPool(graphics, this);
|
||||||
}
|
}
|
||||||
|
|
||||||
DescriptorPool::DescriptorPool(PGraphics graphics, PDescriptorLayout layout) : graphics(graphics), layout(layout) {}
|
DescriptorPool::DescriptorPool(PGraphics graphics, PDescriptorLayout layout) : graphics(graphics), layout(layout) {}
|
||||||
|
|||||||
@@ -1,7 +1,6 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
#include "Graphics/Enums.h"
|
#include "Graphics/Enums.h"
|
||||||
#include "Metal/MTLDepthStencil.hpp"
|
#include "Metal/MTLStageInputOutputDescriptor.hpp"
|
||||||
#include "Metal/MTLSampler.hpp"
|
|
||||||
#include "Resources.h"
|
#include "Resources.h"
|
||||||
|
|
||||||
namespace Seele
|
namespace Seele
|
||||||
@@ -26,5 +25,9 @@ MTL::SamplerMipFilter cast(Gfx::SeSamplerMipmapMode filter);
|
|||||||
Gfx::SeSamplerMipmapMode cast(MTL::SamplerMipFilter filter);
|
Gfx::SeSamplerMipmapMode cast(MTL::SamplerMipFilter filter);
|
||||||
MTL::SamplerAddressMode cast(Gfx::SeSamplerAddressMode mode);
|
MTL::SamplerAddressMode cast(Gfx::SeSamplerAddressMode mode);
|
||||||
Gfx::SeSamplerAddressMode cast(MTL::SamplerAddressMode 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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1,8 +1,6 @@
|
|||||||
#include "Enums.h"
|
#include "Enums.h"
|
||||||
#include "Graphics/Enums.h"
|
#include "Graphics/Enums.h"
|
||||||
#include "Metal/MTLArgument.hpp"
|
#include "Metal/MTLStageInputOutputDescriptor.hpp"
|
||||||
#include "Metal/MTLDepthStencil.hpp"
|
|
||||||
#include "Metal/MTLSampler.hpp"
|
|
||||||
#include <stdexcept>
|
#include <stdexcept>
|
||||||
|
|
||||||
using namespace Seele;
|
using namespace Seele;
|
||||||
@@ -768,3 +766,50 @@ Gfx::SeSamplerAddressMode Seele::Metal::cast(MTL::SamplerAddressMode mode) {
|
|||||||
return Gfx::SE_SAMPLER_ADDRESS_MODE_CLAMP_TO_BORDER;
|
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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -8,6 +8,7 @@ namespace Metal
|
|||||||
{
|
{
|
||||||
DECLARE_REF(CommandQueue)
|
DECLARE_REF(CommandQueue)
|
||||||
DECLARE_REF(IOCommandQueue)
|
DECLARE_REF(IOCommandQueue)
|
||||||
|
DECLARE_REF(PipelineCache)
|
||||||
class Graphics : public Gfx::Graphics
|
class Graphics : public Gfx::Graphics
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
@@ -61,6 +62,7 @@ protected:
|
|||||||
MTL::Device* device;
|
MTL::Device* device;
|
||||||
OCommandQueue queue;
|
OCommandQueue queue;
|
||||||
OIOCommandQueue ioQueue;
|
OIOCommandQueue ioQueue;
|
||||||
|
OPipelineCache cache;
|
||||||
};
|
};
|
||||||
DEFINE_REF(Graphics)
|
DEFINE_REF(Graphics)
|
||||||
} // namespace Metal
|
} // namespace Metal
|
||||||
|
|||||||
@@ -1,7 +1,12 @@
|
|||||||
#include "Graphics.h"
|
#include "Graphics.h"
|
||||||
#include "Graphics/Initializer.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 "Shader.h"
|
||||||
#include "RenderPass.h"
|
#include "RenderPass.h"
|
||||||
|
#include "Resources.h"
|
||||||
#include "Command.h"
|
#include "Command.h"
|
||||||
#include "Window.h"
|
#include "Window.h"
|
||||||
#include "Buffer.h"
|
#include "Buffer.h"
|
||||||
@@ -24,6 +29,7 @@ void Graphics::init(GraphicsInitializer)
|
|||||||
device = MTL::CreateSystemDefaultDevice();
|
device = MTL::CreateSystemDefaultDevice();
|
||||||
queue = new CommandQueue(this);
|
queue = new CommandQueue(this);
|
||||||
ioQueue = new IOCommandQueue(this);
|
ioQueue = new IOCommandQueue(this);
|
||||||
|
cache = new PipelineCache(this, "pipelines.metal");
|
||||||
}
|
}
|
||||||
|
|
||||||
Gfx::OWindow Graphics::createWindow(const WindowCreateInfo &createInfo)
|
Gfx::OWindow Graphics::createWindow(const WindowCreateInfo &createInfo)
|
||||||
@@ -118,12 +124,14 @@ Gfx::OVertexShader Graphics::createVertexShader(const ShaderCreateInfo& createIn
|
|||||||
result->create(createInfo);
|
result->create(createInfo);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
Gfx::OFragmentShader Graphics::createFragmentShader(const ShaderCreateInfo& createInfo)
|
Gfx::OFragmentShader Graphics::createFragmentShader(const ShaderCreateInfo& createInfo)
|
||||||
{
|
{
|
||||||
OFragmentShader result = new FragmentShader(this);
|
OFragmentShader result = new FragmentShader(this);
|
||||||
result->create(createInfo);
|
result->create(createInfo);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
Gfx::OComputeShader Graphics::createComputeShader(const ShaderCreateInfo& createInfo)
|
Gfx::OComputeShader Graphics::createComputeShader(const ShaderCreateInfo& createInfo)
|
||||||
{
|
{
|
||||||
OComputeShader result = new ComputeShader(this);
|
OComputeShader result = new ComputeShader(this);
|
||||||
@@ -137,6 +145,7 @@ Gfx::OMeshShader Graphics::createMeshShader(const ShaderCreateInfo& createInfo)
|
|||||||
result->create(createInfo);
|
result->create(createInfo);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
Gfx::OTaskShader Graphics::createTaskShader(const ShaderCreateInfo& createInfo)
|
Gfx::OTaskShader Graphics::createTaskShader(const ShaderCreateInfo& createInfo)
|
||||||
{
|
{
|
||||||
OTaskShader result = new TaskShader(this);
|
OTaskShader result = new TaskShader(this);
|
||||||
@@ -146,39 +155,41 @@ Gfx::OTaskShader Graphics::createTaskShader(const ShaderCreateInfo& createInfo)
|
|||||||
|
|
||||||
Gfx::PGraphicsPipeline Graphics::createGraphicsPipeline(Gfx::LegacyPipelineCreateInfo createInfo)
|
Gfx::PGraphicsPipeline Graphics::createGraphicsPipeline(Gfx::LegacyPipelineCreateInfo createInfo)
|
||||||
{
|
{
|
||||||
|
return cache->createPipeline(std::move(createInfo));
|
||||||
}
|
}
|
||||||
|
|
||||||
Gfx::PGraphicsPipeline Graphics::createGraphicsPipeline(Gfx::MeshPipelineCreateInfo createInfo)
|
Gfx::PGraphicsPipeline Graphics::createGraphicsPipeline(Gfx::MeshPipelineCreateInfo createInfo)
|
||||||
{
|
{
|
||||||
|
return cache->createPipeline(std::move(createInfo));
|
||||||
}
|
}
|
||||||
|
|
||||||
Gfx::PComputePipeline Graphics::createComputePipeline(Gfx::ComputePipelineCreateInfo createInfo)
|
Gfx::PComputePipeline Graphics::createComputePipeline(Gfx::ComputePipelineCreateInfo createInfo)
|
||||||
{
|
{
|
||||||
|
return cache->createPipeline(std::move(createInfo));
|
||||||
}
|
}
|
||||||
|
|
||||||
Gfx::OSampler Graphics::createSampler(const SamplerCreateInfo& createInfo)
|
Gfx::OSampler Graphics::createSampler(const SamplerCreateInfo& createInfo)
|
||||||
{
|
{
|
||||||
|
return new Sampler(this, createInfo);
|
||||||
}
|
}
|
||||||
|
|
||||||
Gfx::ODescriptorLayout Graphics::createDescriptorLayout(const std::string& name)
|
Gfx::ODescriptorLayout Graphics::createDescriptorLayout(const std::string& name)
|
||||||
{
|
{
|
||||||
|
return new DescriptorLayout(this, name);
|
||||||
}
|
}
|
||||||
|
|
||||||
Gfx::OPipelineLayout Graphics::createPipelineLayout(Gfx::PPipelineLayout baseLayout)
|
Gfx::OPipelineLayout Graphics::createPipelineLayout(Gfx::PPipelineLayout baseLayout)
|
||||||
{
|
{
|
||||||
|
return new PipelineLayout(this, baseLayout);
|
||||||
}
|
}
|
||||||
|
|
||||||
Gfx::OVertexInput Graphics::createVertexInput(VertexInputStateCreateInfo createInfo)
|
Gfx::OVertexInput Graphics::createVertexInput(VertexInputStateCreateInfo createInfo)
|
||||||
{
|
{
|
||||||
|
return new VertexInput(createInfo);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Graphics::resolveTexture(Gfx::PTexture source, Gfx::PTexture destination)
|
void Graphics::resolveTexture(Gfx::PTexture source, Gfx::PTexture destination)
|
||||||
{
|
{
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -1,37 +1,40 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
#include "Graphics/Initializer.h"
|
#include "Graphics/Initializer.h"
|
||||||
#include "Graphics/Pipeline.h"
|
#include "Graphics/Pipeline.h"
|
||||||
#include "Resources.h"
|
|
||||||
#include "MinimalEngine.h"
|
#include "MinimalEngine.h"
|
||||||
|
#include "Resources.h"
|
||||||
|
|
||||||
namespace Seele {
|
namespace Seele {
|
||||||
namespace Metal {
|
namespace Metal {
|
||||||
class VertexInput : public Gfx::VertexInput
|
class VertexInput : public Gfx::VertexInput {
|
||||||
{
|
|
||||||
public:
|
public:
|
||||||
VertexInput(VertexInputStateCreateInfo createInfo);
|
VertexInput(VertexInputStateCreateInfo createInfo);
|
||||||
virtual ~VertexInput();
|
virtual ~VertexInput();
|
||||||
};
|
};
|
||||||
DECLARE_REF(PipelineLayout)
|
DECLARE_REF(PipelineLayout)
|
||||||
DECLARE_REF(Graphics)
|
DECLARE_REF(Graphics)
|
||||||
class GraphicsPipeline : public Gfx::GraphicsPipeline
|
class GraphicsPipeline : public Gfx::GraphicsPipeline {
|
||||||
{
|
|
||||||
public:
|
public:
|
||||||
GraphicsPipeline(PGraphics graphics, Gfx::LegacyPipelineCreateInfo createInfo);
|
GraphicsPipeline(PGraphics graphics, MTL::PrimitiveType primitive, MTL::RenderPipelineState* pipeline, Gfx::OPipelineLayout createInfo);
|
||||||
GraphicsPipeline(PGraphics graphics, Gfx::MeshPipelineCreateInfo createInfo);
|
|
||||||
virtual ~GraphicsPipeline();
|
virtual ~GraphicsPipeline();
|
||||||
|
constexpr MTL::RenderPipelineState* getHandle() const { return state; }
|
||||||
|
constexpr MTL::PrimitiveType getPrimitive() const { return primitiveType; }
|
||||||
private:
|
private:
|
||||||
|
PGraphics graphics;
|
||||||
MTL::RenderPipelineState* state;
|
MTL::RenderPipelineState* state;
|
||||||
|
MTL::PrimitiveType primitiveType;
|
||||||
};
|
};
|
||||||
DEFINE_REF(GraphicsPipeline)
|
DEFINE_REF(GraphicsPipeline)
|
||||||
class ComputePipeline : public Gfx::ComputePipeline
|
class ComputePipeline : public Gfx::ComputePipeline {
|
||||||
{
|
|
||||||
public:
|
public:
|
||||||
ComputePipeline(PGraphics graphics, Gfx::ComputePipelineCreateInfo createInfo);
|
ComputePipeline(PGraphics graphics, MTL::ComputePipelineState* pipeline, Gfx::OPipelineLayout);
|
||||||
virtual ~ComputePipeline();
|
virtual ~ComputePipeline();
|
||||||
|
constexpr MTL::ComputePipelineState* getHandle() const { return state; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
PGraphics graphics;
|
||||||
MTL::ComputePipelineState* state;
|
MTL::ComputePipelineState* state;
|
||||||
};
|
};
|
||||||
DEFINE_REF(ComputePipeline)
|
DEFINE_REF(ComputePipeline)
|
||||||
}
|
} // namespace Metal
|
||||||
}
|
} // namespace Seele
|
||||||
@@ -1,17 +1,24 @@
|
|||||||
#include "Pipeline.h"
|
#include "Pipeline.h"
|
||||||
#include "Graphics/Initializer.h"
|
#include "Graphics/Initializer.h"
|
||||||
#include "Graphics/Metal/Graphics.h"
|
#include "Graphics/Metal/Graphics.h"
|
||||||
|
#include "Graphics/Pipeline.h"
|
||||||
#include "Graphics/Resources.h"
|
#include "Graphics/Resources.h"
|
||||||
#include "Metal/MTLRenderPipeline.hpp"
|
|
||||||
|
|
||||||
using namespace Seele;
|
using namespace Seele;
|
||||||
using namespace Seele::Metal;
|
using namespace Seele::Metal;
|
||||||
|
|
||||||
VertexInput::VertexInput(VertexInputStateCreateInfo createInfo)
|
VertexInput::VertexInput(VertexInputStateCreateInfo createInfo) : Gfx::VertexInput(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() {}
|
||||||
|
|||||||
@@ -15,7 +15,7 @@ public:
|
|||||||
private:
|
private:
|
||||||
PGraphics graphics;
|
PGraphics graphics;
|
||||||
Map<uint32, OGraphicsPipeline> graphicsPipelines;
|
Map<uint32, OGraphicsPipeline> graphicsPipelines;
|
||||||
Map<uint32, OComputePipeline> computePipeline;
|
Map<uint32, OComputePipeline> computePipelines;
|
||||||
std::string cacheFile;
|
std::string cacheFile;
|
||||||
};
|
};
|
||||||
DEFINE_REF(PipelineCache)
|
DEFINE_REF(PipelineCache)
|
||||||
|
|||||||
@@ -1,11 +1,18 @@
|
|||||||
#include "PipelineCache.h"
|
#include "PipelineCache.h"
|
||||||
#include "Descriptor.h"
|
#include "Descriptor.h"
|
||||||
|
#include "Enums.h"
|
||||||
|
#include "Foundation/NSError.hpp"
|
||||||
#include "Graphics.h"
|
#include "Graphics.h"
|
||||||
#include "Shader.h"
|
|
||||||
#include "Graphics/Descriptor.h"
|
#include "Graphics/Descriptor.h"
|
||||||
#include "Graphics/Enums.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/MTLRenderPipeline.hpp"
|
||||||
#include "Metal/MTLVertexDescriptor.hpp"
|
#include "Metal/MTLVertexDescriptor.hpp"
|
||||||
|
#include "Shader.h"
|
||||||
|
#include "Texture.h"
|
||||||
|
|
||||||
using namespace Seele;
|
using namespace Seele;
|
||||||
using namespace Seele::Metal;
|
using namespace Seele::Metal;
|
||||||
@@ -16,15 +23,12 @@ PipelineCache::~PipelineCache() {}
|
|||||||
|
|
||||||
PGraphicsPipeline PipelineCache::createPipeline(Gfx::LegacyPipelineCreateInfo createInfo) {
|
PGraphicsPipeline PipelineCache::createPipeline(Gfx::LegacyPipelineCreateInfo createInfo) {
|
||||||
PPipelineLayout layout = Gfx::PPipelineLayout(createInfo.pipelineLayout).cast<PipelineLayout>();
|
PPipelineLayout layout = Gfx::PPipelineLayout(createInfo.pipelineLayout).cast<PipelineLayout>();
|
||||||
uint32 hash = layout->getHash();
|
|
||||||
MTL::RenderPipelineDescriptor* pipelineDescriptor = MTL::RenderPipelineDescriptor::alloc()->init();
|
MTL::RenderPipelineDescriptor* pipelineDescriptor = MTL::RenderPipelineDescriptor::alloc()->init();
|
||||||
|
|
||||||
MTL::VertexDescriptor* vertexDescriptor = MTL::VertexDescriptor::alloc()->init();
|
MTL::VertexDescriptor* vertexDescriptor = MTL::VertexDescriptor::alloc()->init();
|
||||||
|
|
||||||
MTL::VertexAttributeDescriptorArray* attributes = vertexDescriptor->attributes();
|
MTL::VertexAttributeDescriptorArray* attributes = vertexDescriptor->attributes();
|
||||||
|
|
||||||
const auto& vertexInfo = createInfo.vertexInput->getInfo();
|
const auto& vertexInfo = createInfo.vertexInput->getInfo();
|
||||||
|
|
||||||
for (size_t attr = 0; attr < vertexInfo.attributes.size(); ++attr) {
|
for (size_t attr = 0; attr < vertexInfo.attributes.size(); ++attr) {
|
||||||
MTL::VertexAttributeDescriptor* attribute = MTL::VertexAttributeDescriptor::alloc()->init();
|
MTL::VertexAttributeDescriptor* attribute = MTL::VertexAttributeDescriptor::alloc()->init();
|
||||||
attribute->setBufferIndex(vertexInfo.attributes[attr].binding);
|
attribute->setBufferIndex(vertexInfo.attributes[attr].binding);
|
||||||
@@ -40,7 +44,6 @@ PGraphicsPipeline PipelineCache::createPipeline(Gfx::LegacyPipelineCreateInfo cr
|
|||||||
}
|
}
|
||||||
|
|
||||||
MTL::VertexBufferLayoutDescriptorArray* bufferLayout = vertexDescriptor->layouts();
|
MTL::VertexBufferLayoutDescriptorArray* bufferLayout = vertexDescriptor->layouts();
|
||||||
|
|
||||||
for (size_t binding = 0; binding < vertexInfo.bindings.size(); ++binding) {
|
for (size_t binding = 0; binding < vertexInfo.bindings.size(); ++binding) {
|
||||||
MTL::VertexBufferLayoutDescriptor* buffer = MTL::VertexBufferLayoutDescriptor::alloc()->init();
|
MTL::VertexBufferLayoutDescriptor* buffer = MTL::VertexBufferLayoutDescriptor::alloc()->init();
|
||||||
buffer->setStride(vertexInfo.bindings[binding].stride);
|
buffer->setStride(vertexInfo.bindings[binding].stride);
|
||||||
@@ -55,16 +58,123 @@ PGraphicsPipeline PipelineCache::createPipeline(Gfx::LegacyPipelineCreateInfo cr
|
|||||||
}
|
}
|
||||||
bufferLayout->setObject(buffer, binding);
|
bufferLayout->setObject(buffer, binding);
|
||||||
}
|
}
|
||||||
|
|
||||||
pipelineDescriptor->setVertexDescriptor(vertexDescriptor);
|
pipelineDescriptor->setVertexDescriptor(vertexDescriptor);
|
||||||
|
|
||||||
pipelineDescriptor->setVertexFunction(createInfo.vertexShader.cast<VertexShader>()->getFunction());
|
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();
|
vertexDescriptor->release();
|
||||||
pipelineDescriptor->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];
|
||||||
|
}
|
||||||
|
|||||||
@@ -14,8 +14,8 @@
|
|||||||
using namespace Seele;
|
using namespace Seele;
|
||||||
using namespace Seele::Metal;
|
using namespace Seele::Metal;
|
||||||
|
|
||||||
Shader::Shader(PGraphics graphics, Gfx::SeShaderStageFlags stage)
|
Shader::Shader(PGraphics graphics, Gfx::SeShaderStageFlags stage) : stage(stage), graphics(graphics) {}
|
||||||
: stage(stage), graphics(graphics) {}
|
|
||||||
Shader::~Shader() {
|
Shader::~Shader() {
|
||||||
if (function) {
|
if (function) {
|
||||||
function->release();
|
function->release();
|
||||||
@@ -23,29 +23,27 @@ Shader::~Shader() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Shader::create(const ShaderCreateInfo &createInfo) {
|
void Shader::create(const ShaderCreateInfo& createInfo) {
|
||||||
Slang::ComPtr<slang::IBlob> kernelBlob =
|
Slang::ComPtr<slang::IBlob> kernelBlob = generateShader(createInfo, SLANG_SPIRV);
|
||||||
generateShader(createInfo, SLANG_SPIRV);
|
hash = CRC::Calculate(kernelBlob->getBufferPointer(), kernelBlob->getBufferSize(), CRC::CRC_32());
|
||||||
spirv_cross::CompilerMSL comp((const uint32 *)kernelBlob->getBufferPointer(),
|
spirv_cross::CompilerMSL comp((const uint32*)kernelBlob->getBufferPointer(), kernelBlob->getBufferSize() / 4);
|
||||||
kernelBlob->getBufferSize() / 4);
|
|
||||||
auto options = comp.get_msl_options();
|
auto options = comp.get_msl_options();
|
||||||
options.argument_buffers = true;
|
options.argument_buffers = true;
|
||||||
options.argument_buffers_tier =
|
options.argument_buffers_tier = spirv_cross::CompilerMSL::Options::ArgumentBuffersTier::Tier2;
|
||||||
spirv_cross::CompilerMSL::Options::ArgumentBuffersTier::Tier2;
|
|
||||||
options.set_msl_version(3);
|
options.set_msl_version(3);
|
||||||
comp.set_msl_options(options);
|
comp.set_msl_options(options);
|
||||||
std::string metalCode = comp.compile();
|
std::string metalCode = comp.compile();
|
||||||
NS::Error *error = nullptr;
|
NS::Error* error = nullptr;
|
||||||
MTL::CompileOptions *mtlOptions = MTL::CompileOptions::alloc()->init();
|
MTL::CompileOptions* mtlOptions = MTL::CompileOptions::alloc()->init();
|
||||||
|
|
||||||
library = graphics->getDevice()->newLibrary(
|
library = graphics->getDevice()->newLibrary(NS::String::string(metalCode.c_str(), NS::ASCIIStringEncoding),
|
||||||
NS::String::string(metalCode.c_str(), NS::ASCIIStringEncoding),
|
|
||||||
mtlOptions, &error);
|
mtlOptions, &error);
|
||||||
if (error) {
|
if (error) {
|
||||||
std::cout << error->debugDescription() << std::endl;
|
std::cout << error->debugDescription() << std::endl;
|
||||||
assert(false);
|
assert(false);
|
||||||
}
|
}
|
||||||
function =
|
function = library->newFunction(NS::String::string("main", NS::ASCIIStringEncoding));
|
||||||
library->newFunction(NS::String::string("main", NS::ASCIIStringEncoding));
|
|
||||||
mtlOptions->release();
|
mtlOptions->release();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
uint32 Shader::getShaderHash() const { return hash; }
|
||||||
Reference in New Issue
Block a user