Fixing some mac stuff
This commit is contained in:
@@ -2,18 +2,29 @@
|
||||
#include "Graphics/Buffer.h"
|
||||
#include "Graphics/Enums.h"
|
||||
#include "Graphics/Initializer.h"
|
||||
#include "Metal/MTLTypes.hpp"
|
||||
#include "MinimalEngine.h"
|
||||
#include "Resources.h"
|
||||
|
||||
namespace Seele {
|
||||
namespace Metal {
|
||||
DECLARE_REF(Graphics)
|
||||
class BufferAllocation : public CommandBoundResource
|
||||
{
|
||||
public:
|
||||
BufferAllocation(PGraphics graphics);
|
||||
virtual ~BufferAllocation();
|
||||
MTL::Buffer* buffer = nullptr;
|
||||
uint64 size = 0;
|
||||
};
|
||||
DECLARE_REF(BufferAllocation)
|
||||
class Buffer {
|
||||
public:
|
||||
Buffer(PGraphics graphics, uint64 size, void *data, bool dynamic, const std::string& name);
|
||||
virtual ~Buffer();
|
||||
MTL::Buffer *getHandle() const { return buffers[currentBuffer]; }
|
||||
uint64 getSize() const { return size; }
|
||||
void advanceBuffer() { currentBuffer = (currentBuffer + 1) % numBuffers; }
|
||||
MTL::Buffer *getHandle() const { return buffers[currentBuffer]->buffer; }
|
||||
PBufferAllocation getAlloc() const { return buffers[currentBuffer]; }
|
||||
uint64 getSize() const { return buffers[currentBuffer]->size; }
|
||||
void *map(bool writeOnly = true);
|
||||
void *mapRegion(uint64 regionOffset, uint64 regionSize, bool writeOnly);
|
||||
void unmap();
|
||||
@@ -21,11 +32,14 @@ public:
|
||||
protected:
|
||||
PGraphics graphics;
|
||||
uint32 currentBuffer = 0;
|
||||
uint64 size;
|
||||
MTL::Buffer *buffers[Gfx::numFramesBuffered];
|
||||
uint32 numBuffers;
|
||||
Array<OBufferAllocation> buffers;
|
||||
bool dynamic;
|
||||
std::string name;
|
||||
void rotateBuffer(uint64 size);
|
||||
void createBuffer(uint64 size, void* data);
|
||||
};
|
||||
DEFINE_REF(Buffer)
|
||||
|
||||
class VertexBuffer : public Gfx::VertexBuffer, public Buffer {
|
||||
public:
|
||||
VertexBuffer(PGraphics graphics, const VertexBufferCreateInfo &createInfo);
|
||||
@@ -72,8 +86,10 @@ class ShaderBuffer : public Gfx::ShaderBuffer, public Buffer {
|
||||
public:
|
||||
ShaderBuffer(PGraphics graphics, const ShaderBufferCreateInfo &createInfo);
|
||||
virtual ~ShaderBuffer();
|
||||
|
||||
virtual bool updateContents(const DataSource &sourceData) override;
|
||||
virtual void rotateBuffer(uint64 size) override;
|
||||
virtual void updateContents(const ShaderBufferCreateInfo &sourceData) override;
|
||||
virtual void *mapRegion(uint64 offset, uint64 size, bool writeOnly) override;
|
||||
virtual void unmap() override;
|
||||
|
||||
protected:
|
||||
// Inherited via QueueOwnedResource
|
||||
|
||||
@@ -3,30 +3,35 @@
|
||||
#include "Graphics/Buffer.h"
|
||||
#include "Graphics/Enums.h"
|
||||
#include "Graphics/Initializer.h"
|
||||
#include "Graphics/Metal/Resources.h"
|
||||
#include "Metal/MTLResource.hpp"
|
||||
#include <iostream>
|
||||
|
||||
using namespace Seele;
|
||||
using namespace Seele::Metal;
|
||||
|
||||
Buffer::Buffer(PGraphics graphics, uint64 size, void* data, bool dynamic, const std::string& name) : graphics(graphics), size(size) {
|
||||
if (dynamic) {
|
||||
numBuffers = Gfx::numFramesBuffered;
|
||||
} else {
|
||||
numBuffers = 1;
|
||||
}
|
||||
for (size_t i = 0; i < numBuffers; ++i) {
|
||||
if (data != nullptr) {
|
||||
buffers[i] = graphics->getDevice()->newBuffer(data, size, MTL::StorageModeShared);
|
||||
} else {
|
||||
buffers[i] = graphics->getDevice()->newBuffer(size, MTL::StorageModeShared);
|
||||
}
|
||||
buffers[i]->setLabel(NS::String::string(name.c_str(), NS::ASCIIStringEncoding));
|
||||
BufferAllocation::BufferAllocation(PGraphics graphics)
|
||||
: CommandBoundResource(graphics)
|
||||
{}
|
||||
|
||||
BufferAllocation::~BufferAllocation()
|
||||
{
|
||||
if(buffer != nullptr)
|
||||
{
|
||||
buffer->release();
|
||||
}
|
||||
}
|
||||
|
||||
Buffer::Buffer(PGraphics graphics, uint64 size, void* data, bool dynamic, const std::string& name)
|
||||
: graphics(graphics)
|
||||
, dynamic(dynamic)
|
||||
, name(name) {
|
||||
createBuffer(size, data);
|
||||
}
|
||||
|
||||
Buffer::~Buffer() {
|
||||
for (size_t i = 0; i < numBuffers; ++i) {
|
||||
buffers[i]->release();
|
||||
for (size_t i = 0; i < buffers.size(); ++i) {
|
||||
//TODO
|
||||
}
|
||||
}
|
||||
|
||||
@@ -36,6 +41,39 @@ void* Buffer::mapRegion(uint64 regionOffset, uint64, bool) { return (char*)getHa
|
||||
|
||||
void Buffer::unmap() {}
|
||||
|
||||
void Buffer::rotateBuffer(uint64 size)
|
||||
{
|
||||
size = std::max(getSize(), size);
|
||||
for(size_t i = 0; i < buffers.size(); ++i)
|
||||
{
|
||||
if(buffers[i]->isCurrentlyBound())
|
||||
{
|
||||
continue;
|
||||
}
|
||||
if(buffers[i]->size < size)
|
||||
{
|
||||
buffers[i]->buffer->release();
|
||||
buffers[i]->buffer = graphics->getDevice()->newBuffer(size, MTL::StorageModeShared);
|
||||
buffers[i]->size = size;
|
||||
}
|
||||
currentBuffer = i;
|
||||
return;
|
||||
}
|
||||
createBuffer(size, nullptr);
|
||||
currentBuffer = buffers.size() - 1;
|
||||
}
|
||||
|
||||
void Buffer::createBuffer(uint64 size, void* data)
|
||||
{
|
||||
buffers.add(new BufferAllocation(graphics));
|
||||
if (data != nullptr) {
|
||||
buffers.back()->buffer = graphics->getDevice()->newBuffer(data, size, MTL::StorageModeShared);
|
||||
} else {
|
||||
buffers.back()->buffer = graphics->getDevice()->newBuffer(size, MTL::StorageModeShared);
|
||||
}
|
||||
buffers.back()->buffer->setLabel(NS::String::string(name.c_str(), NS::ASCIIStringEncoding));
|
||||
}
|
||||
|
||||
VertexBuffer::VertexBuffer(PGraphics graphics, const VertexBufferCreateInfo& createInfo)
|
||||
: Gfx::VertexBuffer(graphics->getFamilyMapping(), createInfo.numVertices, createInfo.vertexSize,
|
||||
createInfo.sourceData.owner),
|
||||
@@ -50,8 +88,8 @@ void VertexBuffer::updateRegion(DataSource update) {
|
||||
|
||||
void VertexBuffer::download(Array<uint8>& buffer) {
|
||||
void* data = getHandle()->contents();
|
||||
buffer.resize(size);
|
||||
std::memcpy(buffer.data(), data, size);
|
||||
buffer.resize(getSize());
|
||||
std::memcpy(buffer.data(), data, getSize());
|
||||
}
|
||||
|
||||
void VertexBuffer::executeOwnershipBarrier(Gfx::QueueType newOwner) { currentOwner = newOwner; }
|
||||
@@ -70,8 +108,8 @@ IndexBuffer::~IndexBuffer() {}
|
||||
|
||||
void IndexBuffer::download(Array<uint8>& buffer) {
|
||||
void* data = getHandle()->contents();
|
||||
buffer.resize(size);
|
||||
std::memcpy(buffer.data(), data, size);
|
||||
buffer.resize(getSize());
|
||||
std::memcpy(buffer.data(), data, getSize());
|
||||
}
|
||||
void IndexBuffer::executeOwnershipBarrier(Gfx::QueueType newOwner) { currentOwner = newOwner; }
|
||||
|
||||
@@ -101,10 +139,29 @@ ShaderBuffer::ShaderBuffer(PGraphics graphics, const ShaderBufferCreateInfo& cre
|
||||
|
||||
ShaderBuffer::~ShaderBuffer() {}
|
||||
|
||||
bool ShaderBuffer::updateContents(const DataSource& sourceData) {
|
||||
void* data = getHandle()->contents();
|
||||
std::memcpy((char*)data + sourceData.offset, sourceData.data, sourceData.size);
|
||||
return true;
|
||||
void ShaderBuffer::rotateBuffer(uint64 size) {
|
||||
Metal::Buffer::rotateBuffer(size);
|
||||
}
|
||||
|
||||
void ShaderBuffer::updateContents(const ShaderBufferCreateInfo& createInfo) {
|
||||
Gfx::ShaderBuffer::updateContents(createInfo);
|
||||
if(createInfo.sourceData.data == nullptr)
|
||||
{
|
||||
return;
|
||||
}
|
||||
void* data = map();
|
||||
std::memcpy((char*)data + createInfo.sourceData.offset, createInfo.sourceData.data, createInfo.sourceData.size);
|
||||
unmap();
|
||||
}
|
||||
|
||||
void* ShaderBuffer::mapRegion(uint64 offset, uint64 size, bool writeOnly)
|
||||
{
|
||||
return Metal::Buffer::mapRegion(offset, size, writeOnly);
|
||||
}
|
||||
|
||||
void ShaderBuffer::unmap()
|
||||
{
|
||||
Metal::Buffer::unmap();
|
||||
}
|
||||
|
||||
void ShaderBuffer::executeOwnershipBarrier(Gfx::QueueType newOwner) { currentOwner = newOwner; }
|
||||
|
||||
@@ -56,16 +56,17 @@ public:
|
||||
void end();
|
||||
virtual void setViewport(Gfx::PViewport viewport) override;
|
||||
virtual void bindPipeline(Gfx::PGraphicsPipeline pipeline) override;
|
||||
virtual void bindDescriptor(Gfx::PDescriptorSet descriptorSet) override;
|
||||
virtual void bindDescriptor(const Array<Gfx::PDescriptorSet>& descriptorSets) override;
|
||||
virtual void bindDescriptor(Gfx::PDescriptorSet descriptorSet, Array<uint32> dynamicOffsets) override;
|
||||
virtual void bindDescriptor(const Array<Gfx::PDescriptorSet>& descriptorSets, Array<uint32> dynamicOffsets) override;
|
||||
virtual void bindVertexBuffer(const Array<Gfx::PVertexBuffer>& buffers) override;
|
||||
virtual void bindIndexBuffer(Gfx::PIndexBuffer indexBuffer) override;
|
||||
virtual void pushConstants(Gfx::PPipelineLayout layout, Gfx::SeShaderStageFlags stage, uint32 offset, uint32 size,
|
||||
virtual void pushConstants(Gfx::SeShaderStageFlags stage, uint32 offset, uint32 size,
|
||||
const void* data) override;
|
||||
virtual void draw(uint32 vertexCount, uint32 instanceCount, int32 firstVertex, uint32 firstInstance) override;
|
||||
virtual void drawIndexed(uint32 indexCount, uint32 instanceCount, int32 firstIndex, uint32 vertexOffset,
|
||||
uint32 firstInstance) override;
|
||||
virtual void drawMesh(uint32 groupX, uint32 groupY, uint32 groupZ) override;
|
||||
virtual void drawMeshIndirect(Gfx::PShaderBuffer buffer, uint64 offset, uint32 drawCount, uint32 stride) override;
|
||||
|
||||
private:
|
||||
PGraphicsPipeline boundPipeline;
|
||||
@@ -81,9 +82,9 @@ public:
|
||||
virtual ~ComputeCommand();
|
||||
void end();
|
||||
virtual void bindPipeline(Gfx::PComputePipeline pipeline) override;
|
||||
virtual void bindDescriptor(Gfx::PDescriptorSet set) override;
|
||||
virtual void bindDescriptor(const Array<Gfx::PDescriptorSet>& sets) override;
|
||||
virtual void pushConstants(Gfx::PPipelineLayout layout, Gfx::SeShaderStageFlags stage, uint32 offset, uint32 size,
|
||||
virtual void bindDescriptor(Gfx::PDescriptorSet set, Array<uint32> dynamicOffsets) override;
|
||||
virtual void bindDescriptor(const Array<Gfx::PDescriptorSet>& sets, Array<uint32> dynamicOffsets) override;
|
||||
virtual void pushConstants(Gfx::SeShaderStageFlags stage, uint32 offset, uint32 size,
|
||||
const void* data) override;
|
||||
virtual void dispatch(uint32 threadX, uint32 threadY, uint32 threadZ) override;
|
||||
|
||||
|
||||
@@ -84,7 +84,7 @@ void RenderCommand::bindPipeline(Gfx::PGraphicsPipeline pipeline) {
|
||||
NS::String::string(boundPipeline->getPipelineLayout()->getName().c_str(), NS::ASCIIStringEncoding));
|
||||
}
|
||||
|
||||
void RenderCommand::bindDescriptor(Gfx::PDescriptorSet descriptorSet) {
|
||||
void RenderCommand::bindDescriptor(Gfx::PDescriptorSet descriptorSet, Array<uint32> offsets) {
|
||||
auto metalSet = descriptorSet.cast<DescriptorSet>();
|
||||
uint32 parameterIndex = boundPipeline->getPipelineLayout()->findParameter(descriptorSet->getLayout()->getName());
|
||||
uint64* topLevelTable = (uint64*)argumentBuffer->contents();
|
||||
@@ -117,9 +117,9 @@ void RenderCommand::bindDescriptor(Gfx::PDescriptorSet descriptorSet) {
|
||||
}
|
||||
}
|
||||
|
||||
void RenderCommand::bindDescriptor(const Array<Gfx::PDescriptorSet>& descriptorSets) {
|
||||
void RenderCommand::bindDescriptor(const Array<Gfx::PDescriptorSet>& descriptorSets, Array<uint32> offsets) {
|
||||
for (auto set : descriptorSets) {
|
||||
bindDescriptor(set);
|
||||
bindDescriptor(set, offsets);
|
||||
}
|
||||
}
|
||||
void RenderCommand::bindVertexBuffer(const Array<Gfx::PVertexBuffer>& buffers) {
|
||||
@@ -133,7 +133,7 @@ void RenderCommand::bindIndexBuffer(Gfx::PIndexBuffer gfxIndexBuffer) {
|
||||
boundIndexBuffer = gfxIndexBuffer.cast<IndexBuffer>();
|
||||
}
|
||||
|
||||
void RenderCommand::pushConstants(Gfx::PPipelineLayout, Gfx::SeShaderStageFlags stage, uint32 offset, uint32 size,
|
||||
void RenderCommand::pushConstants(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);
|
||||
@@ -162,6 +162,10 @@ void RenderCommand::drawMesh(uint32 groupX, uint32 groupY, uint32 groupZ) {
|
||||
encoder->drawMeshThreadgroups(MTL::Size(groupX, groupY, groupZ), MTL::Size(128, 1, 1), MTL::Size(32, 1, 1));
|
||||
}
|
||||
|
||||
void RenderCommand::drawMeshIndirect(Gfx::PShaderBuffer buffer, uint64 offset, uint32 drawCount, uint32 stride) {
|
||||
//encoder->drawMeshThreadgroups()
|
||||
}
|
||||
|
||||
ComputeCommand::ComputeCommand(MTL::CommandBuffer* cmdBuffer, const std::string& name)
|
||||
: commandBuffer(cmdBuffer), encoder(cmdBuffer->computeCommandEncoder()), name(name) {}
|
||||
|
||||
@@ -181,7 +185,7 @@ void ComputeCommand::bindPipeline(Gfx::PComputePipeline pipeline) {
|
||||
NS::String::string(pipeline->getPipelineLayout()->getName().c_str(), NS::ASCIIStringEncoding));
|
||||
}
|
||||
|
||||
void ComputeCommand::bindDescriptor(Gfx::PDescriptorSet set) {
|
||||
void ComputeCommand::bindDescriptor(Gfx::PDescriptorSet set, Array<uint32> offsets) {
|
||||
auto metalSet = set.cast<DescriptorSet>();
|
||||
metalSet->bind();
|
||||
uint32 parameterIndex = boundPipeline->getPipelineLayout()->findParameter(set->getLayout()->getName());
|
||||
@@ -215,13 +219,13 @@ void ComputeCommand::bindDescriptor(Gfx::PDescriptorSet set) {
|
||||
}
|
||||
}
|
||||
|
||||
void ComputeCommand::bindDescriptor(const Array<Gfx::PDescriptorSet>& sets) {
|
||||
void ComputeCommand::bindDescriptor(const Array<Gfx::PDescriptorSet>& sets, Array<uint32> offsets) {
|
||||
for (auto& set : sets) {
|
||||
bindDescriptor(set);
|
||||
bindDescriptor(set, offsets);
|
||||
}
|
||||
}
|
||||
|
||||
void ComputeCommand::pushConstants(Gfx::PPipelineLayout, Gfx::SeShaderStageFlags, uint32 offset, uint32 size,
|
||||
void ComputeCommand::pushConstants(Gfx::SeShaderStageFlags, uint32 offset, uint32 size,
|
||||
const void* data) {
|
||||
encoder->setBytes((char*)data + offset, size, 0);
|
||||
}
|
||||
|
||||
@@ -1,15 +1,16 @@
|
||||
#pragma once
|
||||
#include "Buffer.h"
|
||||
#include "Graphics/Descriptor.h"
|
||||
#include "Graphics/Initializer.h"
|
||||
#include "Graphics/Metal/Resources.h"
|
||||
#include "MinimalEngine.h"
|
||||
#include "Buffer.h"
|
||||
|
||||
namespace Seele {
|
||||
namespace Metal {
|
||||
DECLARE_REF(Graphics)
|
||||
class DescriptorLayout : public Gfx::DescriptorLayout {
|
||||
public:
|
||||
DescriptorLayout(PGraphics graphics, const std::string& name);
|
||||
DescriptorLayout(PGraphics graphics, const std::string &name);
|
||||
virtual ~DescriptorLayout();
|
||||
virtual void create() override;
|
||||
|
||||
@@ -34,44 +35,47 @@ private:
|
||||
};
|
||||
DEFINE_REF(DescriptorPool)
|
||||
|
||||
class DescriptorSet : public Gfx::DescriptorSet {
|
||||
class DescriptorSet : public Gfx::DescriptorSet, public CommandBoundResource {
|
||||
public:
|
||||
DescriptorSet(PGraphics graphics, PDescriptorPool owner);
|
||||
virtual ~DescriptorSet();
|
||||
virtual void writeChanges();
|
||||
virtual void updateBuffer(uint32_t binding, Gfx::PUniformBuffer uniformBuffer);
|
||||
virtual void updateBuffer(uint32_t binding, Gfx::PShaderBuffer uniformBuffer);
|
||||
virtual void updateSampler(uint32_t binding, Gfx::PSampler samplerState);
|
||||
virtual void updateTexture(uint32_t binding, Gfx::PTexture texture, Gfx::PSampler sampler = nullptr);
|
||||
virtual void updateTextureArray(uint32_t binding, Array<Gfx::PTexture> texture);
|
||||
virtual void writeChanges() override;
|
||||
virtual void updateBuffer(uint32_t binding,
|
||||
Gfx::PUniformBuffer uniformBuffer) override;
|
||||
virtual void updateBuffer(uint32_t binding, Gfx::PShaderBuffer uniformBuffer) override;
|
||||
virtual void updateBuffer(uint32_t binding, uint32 index, Gfx::PShaderBuffer uniformBuffer) override;
|
||||
virtual void updateSampler(uint32_t binding, Gfx::PSampler samplerState) override;
|
||||
virtual void updateTexture(uint32_t binding, Gfx::PTexture texture,
|
||||
Gfx::PSampler sampler = nullptr) override;
|
||||
virtual void updateTextureArray(uint32_t binding,
|
||||
Array<Gfx::PTexture> texture) override;
|
||||
|
||||
constexpr bool isCurrentlyBound() const { return bindCount > 0; }
|
||||
constexpr bool isCurrentlyInUse() const { return currentlyInUse; }
|
||||
constexpr void bind() { bindCount++; }
|
||||
constexpr void unbind() { bindCount--; }
|
||||
constexpr void allocate() { currentlyInUse = true; }
|
||||
constexpr void free() { currentlyInUse = false; }
|
||||
|
||||
constexpr MTL::Buffer* getBuffer() const { return buffer; }
|
||||
constexpr const Array<MTL::Resource*>& getBoundResources() const { return boundResources; }
|
||||
constexpr MTL::Buffer *getBuffer() const { return buffer; }
|
||||
constexpr const Array<MTL::Resource *> &getBoundResources() const {
|
||||
return boundResources;
|
||||
}
|
||||
|
||||
private:
|
||||
PGraphics graphics;
|
||||
PDescriptorPool owner;
|
||||
MTL::Buffer* buffer = nullptr;
|
||||
uint64* argumentBuffer = nullptr;
|
||||
Array<MTL::Resource*> boundResources;
|
||||
uint32 bindCount;
|
||||
MTL::Buffer *buffer = nullptr;
|
||||
uint64 *argumentBuffer = nullptr;
|
||||
Array<MTL::Resource *> boundResources;
|
||||
bool currentlyInUse;
|
||||
};
|
||||
DEFINE_REF(DescriptorSet)
|
||||
|
||||
class PipelineLayout : public Gfx::PipelineLayout {
|
||||
public:
|
||||
PipelineLayout(PGraphics graphics, const std::string& name, Gfx::PPipelineLayout baseLayout);
|
||||
PipelineLayout(PGraphics graphics, const std::string &name,
|
||||
Gfx::PPipelineLayout baseLayout);
|
||||
virtual ~PipelineLayout();
|
||||
virtual void create() override;
|
||||
|
||||
|
||||
private:
|
||||
PGraphics graphics;
|
||||
};
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
#include "Enums.h"
|
||||
#include "Graphics/Descriptor.h"
|
||||
#include "Graphics/Initializer.h"
|
||||
#include "Graphics/Metal/Resources.h"
|
||||
#include "Metal/MTLArgument.hpp"
|
||||
#include "Metal/MTLDevice.hpp"
|
||||
#include "Metal/MTLResource.hpp"
|
||||
@@ -14,24 +15,28 @@
|
||||
using namespace Seele;
|
||||
using namespace Seele::Metal;
|
||||
|
||||
DescriptorLayout::DescriptorLayout(PGraphics graphics, const std::string& name)
|
||||
DescriptorLayout::DescriptorLayout(PGraphics graphics, const std::string &name)
|
||||
: Gfx::DescriptorLayout(name), graphics(graphics) {}
|
||||
|
||||
DescriptorLayout::~DescriptorLayout() {}
|
||||
|
||||
void DescriptorLayout::create() {
|
||||
pool = new DescriptorPool(graphics, this);
|
||||
hash = CRC::Calculate(descriptorBindings.data(), sizeof(Gfx::DescriptorBinding) * descriptorBindings.size(),
|
||||
CRC::CRC_32());
|
||||
hash =
|
||||
CRC::Calculate(descriptorBindings.data(),
|
||||
sizeof(Gfx::DescriptorBinding) * descriptorBindings.size(),
|
||||
CRC::CRC_32());
|
||||
}
|
||||
|
||||
DescriptorPool::DescriptorPool(PGraphics graphics, PDescriptorLayout layout) : graphics(graphics), layout(layout) {}
|
||||
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()) {
|
||||
if (allocatedSets[setIndex]->isCurrentlyBound() ||
|
||||
allocatedSets[setIndex]->isCurrentlyInUse()) {
|
||||
// Currently in use, skip
|
||||
continue;
|
||||
}
|
||||
@@ -46,80 +51,104 @@ Gfx::PDescriptorSet DescriptorPool::allocateDescriptorSet() {
|
||||
}
|
||||
|
||||
void DescriptorPool::reset() {
|
||||
for (auto& set : allocatedSets) {
|
||||
for (auto &set : allocatedSets) {
|
||||
set->free();
|
||||
}
|
||||
}
|
||||
|
||||
DescriptorSet::DescriptorSet(PGraphics graphics, PDescriptorPool owner)
|
||||
: Gfx::DescriptorSet(owner->getLayout()), graphics(graphics), owner(owner), bindCount(0), currentlyInUse(false) {
|
||||
: Gfx::DescriptorSet(owner->getLayout()), CommandBoundResource(graphics),
|
||||
graphics(graphics), owner(owner), currentlyInUse(false) {
|
||||
boundResources.resize(owner->getLayout()->getBindings().size());
|
||||
buffer = graphics->getDevice()->newBuffer(std::max<size_t>(8, sizeof(uint64_t) * 3 * owner->getLayout()->getBindings().size()), MTL::ResourceStorageModeShared);
|
||||
argumentBuffer = (uint64*)buffer->contents();
|
||||
buffer->setLabel(NS::String::string(owner->getLayout()->getName().c_str(), NS::ASCIIStringEncoding));
|
||||
buffer = graphics->getDevice()->newBuffer(
|
||||
std::max<size_t>(8, sizeof(uint64_t) * 3 *
|
||||
owner->getLayout()->getBindings().size()),
|
||||
MTL::ResourceStorageModeShared);
|
||||
argumentBuffer = (uint64 *)buffer->contents();
|
||||
buffer->setLabel(NS::String::string(owner->getLayout()->getName().c_str(),
|
||||
NS::ASCIIStringEncoding));
|
||||
}
|
||||
|
||||
DescriptorSet::~DescriptorSet() {buffer->release();}
|
||||
DescriptorSet::~DescriptorSet() { buffer->release(); }
|
||||
|
||||
void DescriptorSet::writeChanges() {}
|
||||
|
||||
void DescriptorSet::updateBuffer(uint32_t binding, Gfx::PUniformBuffer uniformBuffer) {
|
||||
void DescriptorSet::updateBuffer(uint32_t binding,
|
||||
Gfx::PUniformBuffer uniformBuffer) {
|
||||
PUniformBuffer metalBuffer = uniformBuffer.cast<UniformBuffer>();
|
||||
uint64 offset = binding * 3;
|
||||
argumentBuffer[offset + 0] = metalBuffer->getHandle()->gpuAddress();
|
||||
argumentBuffer[offset + 1] = 0;
|
||||
argumentBuffer[offset + 2] = (uint32)metalBuffer->getSize(); // TODO: buffer texture view, typed??
|
||||
boundResources[binding] = metalBuffer->getHandle();
|
||||
uint64 offset = binding * 3;
|
||||
argumentBuffer[offset + 0] = metalBuffer->getHandle()->gpuAddress();
|
||||
argumentBuffer[offset + 1] = 0;
|
||||
argumentBuffer[offset + 2] =
|
||||
(uint32)metalBuffer->getSize(); // TODO: buffer texture view, typed??
|
||||
boundResources[binding] = metalBuffer->getHandle();
|
||||
}
|
||||
void DescriptorSet::updateBuffer(uint32_t binding, Gfx::PShaderBuffer uniformBuffer) {
|
||||
void DescriptorSet::updateBuffer(uint32_t binding,
|
||||
Gfx::PShaderBuffer uniformBuffer) {
|
||||
PShaderBuffer metalBuffer = uniformBuffer.cast<ShaderBuffer>();
|
||||
uint64 offset = binding * 3;
|
||||
argumentBuffer[offset + 0] = metalBuffer->getHandle()->gpuAddress();
|
||||
argumentBuffer[offset + 1] = 0;
|
||||
argumentBuffer[offset + 2] = (uint32)metalBuffer->getSize(); // TODO: buffer texture view, typed??
|
||||
boundResources[binding] = metalBuffer->getHandle();
|
||||
}
|
||||
void DescriptorSet::updateSampler(uint32_t binding, Gfx::PSampler samplerState) {
|
||||
PSampler sampler = samplerState.cast<Sampler>();
|
||||
MTL::ResourceID resourceId =sampler->getHandle()->gpuResourceID();
|
||||
uint64 offset = binding * 3;
|
||||
argumentBuffer[offset + 0] = 0;
|
||||
argumentBuffer[offset + 1] = *(uint64*)&resourceId;
|
||||
argumentBuffer[offset + 2] = 0; // LOD bias
|
||||
}
|
||||
void DescriptorSet::updateTexture(uint32_t binding, Gfx::PTexture texture, Gfx::PSampler samplerState) {
|
||||
PTextureBase base = texture.cast<TextureBase>();
|
||||
if(layout->getBindings()[binding].access == Gfx::SE_DESCRIPTOR_ACCESS_READ_ONLY_BIT)
|
||||
{
|
||||
MTL::ResourceID resourceId =base->getTexture()->gpuResourceID();
|
||||
uint64 offset = binding * 3;
|
||||
argumentBuffer[offset + 0] = 0;
|
||||
argumentBuffer[offset + 1] = *(uint64*)&resourceId;
|
||||
argumentBuffer[offset + 2] = 0; // min LOD clamp
|
||||
}else{
|
||||
uint64 offset = binding * 3;
|
||||
argumentBuffer[offset + 0] = base->getTexture()->buffer()->gpuAddress();
|
||||
argumentBuffer[offset + 1] = 0;
|
||||
argumentBuffer[offset + 2] = (uint32)base->getTexture()->buffer()->length(); // TODO: buffer texture view, typed??
|
||||
}
|
||||
boundResources[binding] = base->getTexture();
|
||||
uint64 offset = binding * 3;
|
||||
argumentBuffer[offset + 0] = metalBuffer->getHandle()->gpuAddress();
|
||||
argumentBuffer[offset + 1] = 0;
|
||||
argumentBuffer[offset + 2] =
|
||||
(uint32)metalBuffer->getSize(); // TODO: buffer texture view, typed??
|
||||
boundResources[binding] = metalBuffer->getHandle();
|
||||
}
|
||||
|
||||
void DescriptorSet::updateTextureArray(uint32_t binding, Array<Gfx::PTexture> array) {
|
||||
for (auto& t : array) {
|
||||
updateTexture(binding++, t);
|
||||
void DescriptorSet::updateBuffer(uint32_t binding, uint32 index, Gfx::PShaderBuffer uniformBuffer)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
|
||||
void DescriptorSet::updateSampler(uint32_t binding,
|
||||
Gfx::PSampler samplerState) {
|
||||
PSampler sampler = samplerState.cast<Sampler>();
|
||||
MTL::ResourceID resourceId = sampler->getHandle()->gpuResourceID();
|
||||
uint64 offset = binding * 3;
|
||||
argumentBuffer[offset + 0] = 0;
|
||||
argumentBuffer[offset + 1] = *(uint64 *)&resourceId;
|
||||
argumentBuffer[offset + 2] = 0; // LOD bias
|
||||
}
|
||||
void DescriptorSet::updateTexture(uint32_t binding, Gfx::PTexture texture,
|
||||
Gfx::PSampler samplerState) {
|
||||
PTextureBase base = texture.cast<TextureBase>();
|
||||
if (layout->getBindings()[binding].access ==
|
||||
Gfx::SE_DESCRIPTOR_ACCESS_READ_ONLY_BIT) {
|
||||
MTL::ResourceID resourceId = base->getTexture()->gpuResourceID();
|
||||
uint64 offset = binding * 3;
|
||||
argumentBuffer[offset + 0] = 0;
|
||||
argumentBuffer[offset + 1] = *(uint64 *)&resourceId;
|
||||
argumentBuffer[offset + 2] = 0; // min LOD clamp
|
||||
} else {
|
||||
uint64 offset = binding * 3;
|
||||
argumentBuffer[offset + 0] = base->getTexture()->buffer()->gpuAddress();
|
||||
argumentBuffer[offset + 1] = 0;
|
||||
argumentBuffer[offset + 2] =
|
||||
(uint32)base->getTexture()
|
||||
->buffer()
|
||||
->length(); // TODO: buffer texture view, typed??
|
||||
}
|
||||
boundResources[binding] = base->getTexture();
|
||||
}
|
||||
|
||||
void DescriptorSet::updateTextureArray(uint32_t binding,
|
||||
Array<Gfx::PTexture> array) {
|
||||
for (auto &t : array) {
|
||||
updateTexture(binding++, t);
|
||||
}
|
||||
}
|
||||
|
||||
PipelineLayout::PipelineLayout(PGraphics graphics, const std::string& name, Gfx::PPipelineLayout baseLayout)
|
||||
PipelineLayout::PipelineLayout(PGraphics graphics, const std::string &name,
|
||||
Gfx::PPipelineLayout baseLayout)
|
||||
: Gfx::PipelineLayout(name, baseLayout), graphics(graphics) {}
|
||||
|
||||
PipelineLayout::~PipelineLayout() {}
|
||||
|
||||
void PipelineLayout::create() {
|
||||
for (auto& [_, set] : descriptorSetLayouts) {
|
||||
assert(set->getHash() != 0);
|
||||
for (auto &[_, set] : descriptorSetLayouts) {
|
||||
assert(set->getHash() != 0);
|
||||
uint32 setHash = set->getHash();
|
||||
layoutHash = CRC::Calculate(&setHash, sizeof(uint32), CRC::CRC_32(), layoutHash);
|
||||
layoutHash =
|
||||
CRC::Calculate(&setHash, sizeof(uint32), CRC::CRC_32(), layoutHash);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -31,7 +31,7 @@ void Graphics::init(GraphicsInitializer)
|
||||
queue = new CommandQueue(this);
|
||||
ioQueue = new IOCommandQueue(this);
|
||||
cache = new PipelineCache(this, "pipelines.metal");
|
||||
meshShadingEnabled = true;
|
||||
meshShadingEnabled = false;
|
||||
}
|
||||
|
||||
Gfx::OWindow Graphics::createWindow(const WindowCreateInfo &createInfo)
|
||||
|
||||
@@ -10,6 +10,27 @@
|
||||
namespace Seele {
|
||||
namespace Metal {
|
||||
DECLARE_REF(Graphics);
|
||||
class CommandBoundResource
|
||||
{
|
||||
public:
|
||||
CommandBoundResource(PGraphics graphics)
|
||||
: graphics(graphics)
|
||||
{
|
||||
}
|
||||
virtual ~CommandBoundResource()
|
||||
{
|
||||
if (isCurrentlyBound())
|
||||
abort();
|
||||
}
|
||||
constexpr bool isCurrentlyBound() const { return bindCount > 0; }
|
||||
constexpr void bind() { bindCount++; }
|
||||
constexpr void unbind() { bindCount--; }
|
||||
protected:
|
||||
PGraphics graphics;
|
||||
uint64 bindCount = 0;
|
||||
};
|
||||
DEFINE_REF(CommandBoundResource)
|
||||
|
||||
class Fence {
|
||||
public:
|
||||
Fence(PGraphics graphics);
|
||||
|
||||
@@ -14,7 +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) {
|
||||
@@ -23,20 +24,27 @@ Shader::~Shader() {
|
||||
}
|
||||
}
|
||||
|
||||
void Shader::create(const ShaderCreateInfo& createInfo) {
|
||||
void Shader::create(const ShaderCreateInfo &createInfo) {
|
||||
std::cout << "Compiling " << createInfo.name << std::endl;
|
||||
Map<std::string, uint32> paramMapping;
|
||||
Slang::ComPtr<slang::IBlob> kernelBlob = generateShader(createInfo, SLANG_METAL, paramMapping);
|
||||
std::cout << (char*)kernelBlob->getBufferPointer() << std::endl;
|
||||
hash = CRC::Calculate(kernelBlob->getBufferPointer(), kernelBlob->getBufferSize(), CRC::CRC_32());
|
||||
dispatch_data_t dispatchData = dispatch_data_create(kernelBlob->getBufferPointer(), kernelBlob->getBufferSize(), dispatch_get_main_queue(), NULL);
|
||||
NS::Error* error;
|
||||
library = graphics->getDevice()->newLibrary(dispatchData, &error);
|
||||
if(error)
|
||||
{
|
||||
std::cout << error->localizedDescription()->cString(NS::ASCIIStringEncoding) << std::endl;
|
||||
}
|
||||
function = library->newFunction(NS::String::string("main", NS::ASCIIStringEncoding));
|
||||
Slang::ComPtr<slang::IBlob> kernelBlob =
|
||||
generateShader(createInfo, SLANG_METAL, paramMapping);
|
||||
std::cout << (char*)kernelBlob->getBufferPointer() << std::endl;
|
||||
hash = CRC::Calculate(kernelBlob->getBufferPointer(),
|
||||
kernelBlob->getBufferSize(), CRC::CRC_32());
|
||||
NS::Error *error;
|
||||
MTL::CompileOptions *options = MTL::CompileOptions::alloc()->init();
|
||||
library = graphics->getDevice()->newLibrary(
|
||||
NS::String::string((char *)kernelBlob->getBufferPointer(),
|
||||
NS::ASCIIStringEncoding),
|
||||
options, &error);
|
||||
options->release();
|
||||
if (error) {
|
||||
std::cout << error->localizedDescription()->cString(NS::ASCIIStringEncoding)
|
||||
<< std::endl;
|
||||
}
|
||||
function =
|
||||
library->newFunction(NS::String::string(createInfo.entryPoint.c_str(), NS::ASCIIStringEncoding));
|
||||
if (!function) {
|
||||
assert(false);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user