Implementing graphics layer changes in metal
This commit is contained in:
Vendored
+1
-1
Submodule external/vcpkg updated: f9a99aa79c...0bf1354d67
@@ -227,7 +227,7 @@ void AssetRegistry::initialize(const std::filesystem::path& _rootFolder, Gfx::PG
|
||||
this->assetRoot = new AssetFolder("");
|
||||
if (!std::filesystem::exists(rootFolder))
|
||||
{
|
||||
std::filesystem::create_directories(rootFolder);
|
||||
//std::filesystem::create_directories(rootFolder);
|
||||
}
|
||||
else if (!std::filesystem::is_directory(rootFolder))
|
||||
{
|
||||
|
||||
@@ -128,16 +128,17 @@ void RenderCommand::bindPipeline(Gfx::PRayTracingPipeline pipeline) {}
|
||||
|
||||
void RenderCommand::bindDescriptor(Gfx::PDescriptorSet descriptorSet) {
|
||||
auto metalSet = descriptorSet.cast<DescriptorSet>();
|
||||
metalSet->bind();
|
||||
boundResources.add(metalSet);
|
||||
auto setHandle = metalSet->setHandle;
|
||||
setHandle->bind();
|
||||
boundResources.add(setHandle);
|
||||
uint32 descriptorIndex = boundPipeline->getPipelineLayout()->findParameter(metalSet->getLayout()->getName());
|
||||
|
||||
auto createEncoder = [&metalSet, descriptorIndex](MTL::Function* function, const Array<uint32>& usedSets) {
|
||||
if(metalSet->encoder == nullptr) {
|
||||
auto createEncoder = [metalSet, &setHandle, descriptorIndex](MTL::Function* function, const Array<uint32>& usedSets) {
|
||||
if(setHandle->encoder == nullptr) {
|
||||
if (metalSet->isPlainDescriptor()) {
|
||||
metalSet->encoder = metalSet->createEncoder();
|
||||
setHandle->encoder = metalSet->createEncoder();
|
||||
} else if (function != nullptr && usedSets.contains(descriptorIndex)) {
|
||||
metalSet->encoder = function->newArgumentEncoder(descriptorIndex);
|
||||
setHandle->encoder = function->newArgumentEncoder(descriptorIndex);
|
||||
}
|
||||
}
|
||||
};
|
||||
@@ -145,39 +146,39 @@ void RenderCommand::bindDescriptor(Gfx::PDescriptorSet descriptorSet) {
|
||||
createEncoder(boundPipeline->meshFunction, boundPipeline->meshSets);
|
||||
createEncoder(boundPipeline->vertexFunction, boundPipeline->vertexSets);
|
||||
createEncoder(boundPipeline->fragmentFunction, boundPipeline->fragmentSets);
|
||||
if(metalSet->argumentBuffer == nullptr) {
|
||||
metalSet->argumentBuffer = new BufferAllocation(metalSet->graphics, "ArgumentBuffer", metalSet->encoder->encodedLength());
|
||||
metalSet->encoder->setArgumentBuffer(metalSet->argumentBuffer->buffer, 0);
|
||||
if(setHandle->argumentBuffer == nullptr) {
|
||||
setHandle->argumentBuffer = new BufferAllocation(setHandle->graphics, "ArgumentBuffer", setHandle->encoder->encodedLength());
|
||||
setHandle->encoder->setArgumentBuffer(setHandle->argumentBuffer->buffer, 0);
|
||||
}
|
||||
metalSet->argumentBuffer->bind();
|
||||
boundResources.add(PBufferAllocation(metalSet->argumentBuffer));
|
||||
for (const auto& write : metalSet->uniformWrites) {
|
||||
write.apply(metalSet->encoder);
|
||||
setHandle->argumentBuffer->bind();
|
||||
boundResources.add(PBufferAllocation(setHandle->argumentBuffer));
|
||||
for (const auto& write : setHandle->uniformWrites) {
|
||||
write.apply(setHandle->encoder);
|
||||
}
|
||||
for (const auto& write : metalSet->bufferWrites) {
|
||||
write.apply(metalSet->encoder);
|
||||
for (const auto& write : setHandle->bufferWrites) {
|
||||
write.apply(setHandle->encoder);
|
||||
encoder->useResource(write.buffer->buffer, write.access);
|
||||
}
|
||||
for (const auto& write : metalSet->samplerWrites) {
|
||||
write.apply(metalSet->encoder);
|
||||
for (const auto& write : setHandle->samplerWrites) {
|
||||
write.apply(setHandle->encoder);
|
||||
}
|
||||
for (const auto& write : metalSet->textureWrites) {
|
||||
write.apply(metalSet->encoder);
|
||||
encoder->useResource(write.texture->texture, write.access);
|
||||
for (const auto& write : setHandle->textureWrites) {
|
||||
write.apply(setHandle->encoder);
|
||||
encoder->useResource(write.texture->getHandle(), write.access);
|
||||
}
|
||||
for (const auto& write : metalSet->accelerationWrites) {
|
||||
write.apply(metalSet->encoder);
|
||||
for (const auto& write : setHandle->accelerationWrites) {
|
||||
write.apply(setHandle->encoder);
|
||||
encoder->useResource(write.accelerationStructure, write.access);
|
||||
}
|
||||
for(auto& res : metalSet->boundResources) {
|
||||
for(auto& res : setHandle->boundResources) {
|
||||
res->bind();
|
||||
boundResources.add(res);
|
||||
}
|
||||
encoder->useResource(metalSet->argumentBuffer->buffer, MTL::ResourceUsageRead);
|
||||
encoder->setObjectBuffer(metalSet->argumentBuffer->buffer, 0, descriptorIndex);
|
||||
encoder->setMeshBuffer(metalSet->argumentBuffer->buffer, 0, descriptorIndex);
|
||||
encoder->setVertexBuffer(metalSet->argumentBuffer->buffer, 0, descriptorIndex);
|
||||
encoder->setFragmentBuffer(metalSet->argumentBuffer->buffer, 0, descriptorIndex);
|
||||
encoder->useResource(setHandle->argumentBuffer->buffer, MTL::ResourceUsageRead);
|
||||
encoder->setObjectBuffer(setHandle->argumentBuffer->buffer, 0, descriptorIndex);
|
||||
encoder->setMeshBuffer(setHandle->argumentBuffer->buffer, 0, descriptorIndex);
|
||||
encoder->setVertexBuffer(setHandle->argumentBuffer->buffer, 0, descriptorIndex);
|
||||
encoder->setFragmentBuffer(setHandle->argumentBuffer->buffer, 0, descriptorIndex);
|
||||
}
|
||||
|
||||
void RenderCommand::bindDescriptor(const Array<Gfx::PDescriptorSet>& descriptorSets) {
|
||||
@@ -252,46 +253,53 @@ void ComputeCommand::bindPipeline(Gfx::PComputePipeline pipeline) {
|
||||
encoder->setComputePipelineState(boundPipeline->getHandle());
|
||||
}
|
||||
|
||||
void ComputeCommand::bindDescriptor(Gfx::PDescriptorSet set) {
|
||||
auto metalSet = set.cast<DescriptorSet>();
|
||||
metalSet->bind();
|
||||
boundResources.add(metalSet);
|
||||
void ComputeCommand::bindDescriptor(Gfx::PDescriptorSet descriptorSet) {
|
||||
auto metalSet = descriptorSet.cast<DescriptorSet>();
|
||||
auto setHandle = metalSet->setHandle;
|
||||
setHandle->bind();
|
||||
boundResources.add(setHandle);
|
||||
uint32 descriptorIndex = boundPipeline->getPipelineLayout()->findParameter(metalSet->getLayout()->getName());
|
||||
if(metalSet->encoder == nullptr) {
|
||||
|
||||
auto createEncoder = [metalSet, &setHandle, descriptorIndex](MTL::Function* function) {
|
||||
if(setHandle->encoder == nullptr) {
|
||||
if (metalSet->isPlainDescriptor()) {
|
||||
metalSet->encoder = metalSet->createEncoder();
|
||||
} else {
|
||||
metalSet->encoder = boundPipeline->computeFunction->newArgumentEncoder(descriptorIndex);
|
||||
setHandle->encoder = metalSet->createEncoder();
|
||||
} else if (function != nullptr) {
|
||||
setHandle->encoder = function->newArgumentEncoder(descriptorIndex);
|
||||
}
|
||||
metalSet->argumentBuffer = new BufferAllocation(metalSet->graphics, "ArgumentBuffer", metalSet->encoder->encodedLength());
|
||||
metalSet->encoder->setArgumentBuffer(metalSet->argumentBuffer->buffer, 0);
|
||||
}
|
||||
metalSet->argumentBuffer->bind();
|
||||
boundResources.add(PBufferAllocation(metalSet->argumentBuffer));
|
||||
for (const auto& write : metalSet->uniformWrites) {
|
||||
write.apply(metalSet->encoder);
|
||||
};
|
||||
createEncoder(boundPipeline->computeFunction);
|
||||
if(setHandle->argumentBuffer == nullptr) {
|
||||
setHandle->argumentBuffer = new BufferAllocation(setHandle->graphics, "ArgumentBuffer", setHandle->encoder->encodedLength());
|
||||
setHandle->encoder->setArgumentBuffer(setHandle->argumentBuffer->buffer, 0);
|
||||
}
|
||||
for (const auto& write : metalSet->bufferWrites) {
|
||||
write.apply(metalSet->encoder);
|
||||
setHandle->argumentBuffer->bind();
|
||||
boundResources.add(PBufferAllocation(setHandle->argumentBuffer));
|
||||
for (const auto& write : setHandle->uniformWrites) {
|
||||
write.apply(setHandle->encoder);
|
||||
}
|
||||
for (const auto& write : setHandle->bufferWrites) {
|
||||
write.apply(setHandle->encoder);
|
||||
encoder->useResource(write.buffer->buffer, write.access);
|
||||
}
|
||||
for (const auto& write : metalSet->samplerWrites) {
|
||||
write.apply(metalSet->encoder);
|
||||
for (const auto& write : setHandle->samplerWrites) {
|
||||
write.apply(setHandle->encoder);
|
||||
}
|
||||
for (const auto& write : metalSet->textureWrites) {
|
||||
write.apply(metalSet->encoder);
|
||||
encoder->useResource(write.texture->texture, write.access);
|
||||
for (const auto& write : setHandle->textureWrites) {
|
||||
write.apply(setHandle->encoder);
|
||||
encoder->useResource(write.texture->getHandle(), write.access);
|
||||
}
|
||||
for (const auto& write : metalSet->accelerationWrites) {
|
||||
write.apply(metalSet->encoder);
|
||||
for (const auto& write : setHandle->accelerationWrites) {
|
||||
write.apply(setHandle->encoder);
|
||||
encoder->useResource(write.accelerationStructure, write.access);
|
||||
}
|
||||
for(auto& res : metalSet->boundResources) {
|
||||
for(auto& res : setHandle->boundResources) {
|
||||
res->bind();
|
||||
boundResources.add(res);
|
||||
}
|
||||
encoder->useResource(metalSet->argumentBuffer->buffer, MTL::ResourceUsageRead);
|
||||
encoder->setBuffer(metalSet->argumentBuffer->buffer, 0, descriptorIndex);
|
||||
encoder->useResource(setHandle->argumentBuffer->buffer, MTL::ResourceUsageRead);
|
||||
encoder->setBuffer(setHandle->argumentBuffer->buffer, 0, descriptorIndex);
|
||||
}
|
||||
|
||||
void ComputeCommand::bindDescriptor(const Array<Gfx::PDescriptorSet>& sets) {
|
||||
|
||||
@@ -40,49 +40,29 @@ class DescriptorLayout : public Gfx::DescriptorLayout {
|
||||
// descriptor sets containing only uniform data are not actually argument buffers, so they need to be
|
||||
// handled separately
|
||||
bool plainDescriptor = true;
|
||||
friend class DescriptorSet;
|
||||
friend class DescriptorSetHandle;
|
||||
};
|
||||
DEFINE_REF(DescriptorLayout)
|
||||
|
||||
DECLARE_REF(DescriptorSet)
|
||||
class DescriptorPool : public Gfx::DescriptorPool {
|
||||
DECLARE_REF(DescriptorPool)
|
||||
class DescriptorSetHandle : public CommandBoundResource {
|
||||
public:
|
||||
DescriptorPool(PGraphics graphics, PDescriptorLayout layout);
|
||||
virtual ~DescriptorPool();
|
||||
virtual Gfx::PDescriptorSet allocateDescriptorSet() override;
|
||||
virtual void reset() override;
|
||||
constexpr PDescriptorLayout getLayout() const { return layout; }
|
||||
DescriptorSetHandle(PGraphics grapics, PDescriptorPool owner, const std::string& name);
|
||||
virtual ~DescriptorSetHandle();
|
||||
void updateConstants(const std::string& name, uint32 offset, void* data);
|
||||
void updateBuffer(const std::string& name, uint32 index, Gfx::PShaderBuffer uniformBuffer);
|
||||
void updateBuffer(const std::string& name, uint32 index, Gfx::PVertexBuffer uniformBuffer);
|
||||
void updateBuffer(const std::string& name, uint32 index, Gfx::PIndexBuffer uniformBuffer);
|
||||
void updateBuffer(const std::string& name, uint32 index, Gfx::PUniformBuffer uniformBuffer);
|
||||
void updateSampler(const std::string& name, uint32 index, Gfx::PSampler samplerState);
|
||||
void updateTexture(const std::string& name, uint32 index, Gfx::PTextureView texture);
|
||||
void updateAccelerationStructure(const std::string& name, uint32 index, Gfx::PTopLevelAS as);
|
||||
|
||||
private:
|
||||
PGraphics graphics;
|
||||
PDescriptorLayout layout;
|
||||
Array<ODescriptorSet> allocatedSets;
|
||||
};
|
||||
DEFINE_REF(DescriptorPool)
|
||||
class DescriptorSet : public Gfx::DescriptorSet, public CommandBoundResource {
|
||||
public:
|
||||
DescriptorSet(PGraphics graphics, PDescriptorPool owner);
|
||||
virtual ~DescriptorSet();
|
||||
virtual void reset();
|
||||
virtual void writeChanges() override;
|
||||
virtual void updateConstants(const std::string& name, uint32 offset, void* data) override;
|
||||
virtual void updateBuffer(const std::string& name, uint32 index, Gfx::PShaderBuffer uniformBuffer) override;
|
||||
virtual void updateBuffer(const std::string& name, uint32 index, Gfx::PVertexBuffer uniformBuffer) override;
|
||||
virtual void updateBuffer(const std::string& name, uint32 index, Gfx::PIndexBuffer uniformBuffer) override;
|
||||
virtual void updateSampler(const std::string& name, uint32 index, Gfx::PSampler samplerState) override;
|
||||
virtual void updateTexture(const std::string& name, uint32 index, Gfx::PTexture texture) override;
|
||||
virtual void updateAccelerationStructure(const std::string& name, uint32 index, Gfx::PTopLevelAS as) override;
|
||||
|
||||
constexpr bool isPlainDescriptor() const { return owner->getLayout()->isPlainDescriptor(); }
|
||||
constexpr MTL::ArgumentEncoder* createEncoder() const { return owner->getLayout()->createEncoder(); }
|
||||
|
||||
private:
|
||||
PGraphics graphics;
|
||||
PDescriptorPool owner;
|
||||
OBufferAllocation argumentBuffer = nullptr;
|
||||
MTL::ArgumentEncoder* encoder = nullptr;
|
||||
Array<PCommandBoundResource> boundResources;
|
||||
|
||||
struct UniformWriteInfo
|
||||
{
|
||||
uint32 index;
|
||||
@@ -102,8 +82,8 @@ class DescriptorSet : public Gfx::DescriptorSet, public CommandBoundResource {
|
||||
{
|
||||
uint32 index;
|
||||
MTL::ResourceUsage access;
|
||||
PTextureHandle texture;
|
||||
void apply(MTL::ArgumentEncoder* encoder) const { encoder->setTexture(texture->texture, index); }
|
||||
PTextureView texture;
|
||||
void apply(MTL::ArgumentEncoder* encoder) const { encoder->setTexture(texture->getHandle(), index); }
|
||||
};
|
||||
Array<TextureWriteInfo> textureWrites;
|
||||
struct SamplerWriteInfo
|
||||
@@ -122,6 +102,46 @@ class DescriptorSet : public Gfx::DescriptorSet, public CommandBoundResource {
|
||||
};
|
||||
Array<AccelerationStructureWriteInfo> accelerationWrites;
|
||||
|
||||
};
|
||||
DEFINE_REF(DescriptorSetHandle)
|
||||
|
||||
DECLARE_REF(DescriptorSet)
|
||||
class DescriptorPool : public Gfx::DescriptorPool {
|
||||
public:
|
||||
DescriptorPool(PGraphics graphics, PDescriptorLayout layout);
|
||||
virtual ~DescriptorPool();
|
||||
virtual Gfx::ODescriptorSet allocateDescriptorSet() override;
|
||||
virtual void reset() override;
|
||||
constexpr PDescriptorLayout getLayout() const { return layout; }
|
||||
|
||||
private:
|
||||
PGraphics graphics;
|
||||
PDescriptorLayout layout;
|
||||
Array<ODescriptorSetHandle> allocatedSets;
|
||||
};
|
||||
DEFINE_REF(DescriptorPool)
|
||||
|
||||
class DescriptorSet : public Gfx::DescriptorSet {
|
||||
public:
|
||||
DescriptorSet(PGraphics graphics, PDescriptorPool owner, PDescriptorSetHandle handle);
|
||||
virtual ~DescriptorSet();
|
||||
virtual void writeChanges() override;
|
||||
virtual void updateConstants(const std::string& name, uint32 offset, void* data) override;
|
||||
virtual void updateBuffer(const std::string& name, uint32 index, Gfx::PShaderBuffer uniformBuffer) override;
|
||||
virtual void updateBuffer(const std::string& name, uint32 index, Gfx::PVertexBuffer uniformBuffer) override;
|
||||
virtual void updateBuffer(const std::string& name, uint32 index, Gfx::PIndexBuffer uniformBuffer) override;
|
||||
virtual void updateBuffer(const std::string& name, uint32 index, Gfx::PUniformBuffer uniformBuffer) override;
|
||||
virtual void updateSampler(const std::string& name, uint32 index, Gfx::PSampler samplerState) override;
|
||||
virtual void updateTexture(const std::string& name, uint32 index, Gfx::PTextureView texture) override;
|
||||
virtual void updateAccelerationStructure(const std::string& name, uint32 index, Gfx::PTopLevelAS as) override;
|
||||
|
||||
constexpr bool isPlainDescriptor() const { return owner->getLayout()->isPlainDescriptor(); }
|
||||
constexpr MTL::ArgumentEncoder* createEncoder() const { return owner->getLayout()->createEncoder(); }
|
||||
|
||||
private:
|
||||
PGraphics graphics;
|
||||
PDescriptorPool owner;
|
||||
PDescriptorSetHandle setHandle;
|
||||
friend class RenderCommand;
|
||||
friend class ComputeCommand;
|
||||
};
|
||||
|
||||
@@ -58,49 +58,20 @@ void DescriptorLayout::create() {
|
||||
|
||||
MTL::ArgumentEncoder* DescriptorLayout::createEncoder() { return graphics->getDevice()->newArgumentEncoder(arguments); }
|
||||
|
||||
DescriptorPool::DescriptorPool(PGraphics graphics, PDescriptorLayout layout) : graphics(graphics), layout(layout) {}
|
||||
DescriptorSetHandle::DescriptorSetHandle(PGraphics graphics, PDescriptorPool owner, const std::string& name)
|
||||
: CommandBoundResource(graphics), owner(owner)
|
||||
{
|
||||
|
||||
DescriptorPool::~DescriptorPool() {}
|
||||
|
||||
Gfx::PDescriptorSet DescriptorPool::allocateDescriptorSet() {
|
||||
for (uint32 setIndex = 0; setIndex < allocatedSets.size(); ++setIndex) {
|
||||
if (allocatedSets[setIndex]->isCurrentlyBound()) {
|
||||
// Currently in use, skip
|
||||
continue;
|
||||
}
|
||||
// Found set, stop searching
|
||||
allocatedSets[setIndex]->reset();
|
||||
return PDescriptorSet(allocatedSets[setIndex]);
|
||||
}
|
||||
allocatedSets.add(new DescriptorSet(graphics, this));
|
||||
return PDescriptorSet(allocatedSets.back());
|
||||
}
|
||||
|
||||
void DescriptorPool::reset() {}
|
||||
|
||||
DescriptorSet::DescriptorSet(PGraphics graphics, PDescriptorPool owner)
|
||||
: Gfx::DescriptorSet(owner->getLayout()), CommandBoundResource(graphics), graphics(graphics), owner(owner) {
|
||||
}
|
||||
|
||||
DescriptorSet::~DescriptorSet() {
|
||||
DescriptorSetHandle::~DescriptorSetHandle() {
|
||||
if(encoder != nullptr) {
|
||||
encoder->release();
|
||||
}
|
||||
std::cout << "destroying descriptor set" << std::endl;
|
||||
}
|
||||
|
||||
void DescriptorSet::reset() {
|
||||
boundResources.clear();
|
||||
uniformWrites.clear();
|
||||
bufferWrites.clear();
|
||||
textureWrites.clear();
|
||||
samplerWrites.clear();
|
||||
accelerationWrites.clear();
|
||||
}
|
||||
|
||||
void DescriptorSet::writeChanges() {}
|
||||
|
||||
void DescriptorSet::updateConstants(const std::string& name, uint32 offset, void* data) {
|
||||
void DescriptorSetHandle::updateConstants(const std::string& name, uint32 offset, void* data) {
|
||||
uint32 flattenedIndex = owner->getLayout()->variableMapping[name].index;
|
||||
Array<uint8> contents(owner->getLayout()->variableMapping[name].constantSize);
|
||||
std::memcpy(contents.data(), (uint8*)data + offset, contents.size());
|
||||
@@ -110,7 +81,7 @@ void DescriptorSet::updateConstants(const std::string& name, uint32 offset, void
|
||||
});
|
||||
}
|
||||
|
||||
void DescriptorSet::updateBuffer(const std::string& name, uint32 index, Gfx::PShaderBuffer uniformBuffer) {
|
||||
void DescriptorSetHandle::updateBuffer(const std::string& name, uint32 index, Gfx::PShaderBuffer uniformBuffer) {
|
||||
uint32 flattenedIndex = owner->getLayout()->variableMapping[name].index + index;
|
||||
PShaderBuffer buffer = uniformBuffer.cast<ShaderBuffer>();
|
||||
bufferWrites.add(BufferWriteInfo{
|
||||
@@ -121,7 +92,7 @@ void DescriptorSet::updateBuffer(const std::string& name, uint32 index, Gfx::PSh
|
||||
boundResources.add(buffer->getAlloc());
|
||||
}
|
||||
|
||||
void DescriptorSet::updateBuffer(const std::string& name, uint32 index, Gfx::PVertexBuffer uniformBuffer) {
|
||||
void DescriptorSetHandle::updateBuffer(const std::string& name, uint32 index, Gfx::PVertexBuffer uniformBuffer) {
|
||||
uint32 flattenedIndex = owner->getLayout()->variableMapping[name].index + index;
|
||||
PVertexBuffer buffer = uniformBuffer.cast<VertexBuffer>();
|
||||
bufferWrites.add(BufferWriteInfo{
|
||||
@@ -132,7 +103,7 @@ void DescriptorSet::updateBuffer(const std::string& name, uint32 index, Gfx::PVe
|
||||
boundResources.add(buffer->getAlloc());
|
||||
}
|
||||
|
||||
void DescriptorSet::updateBuffer(const std::string& name, uint32 index, Gfx::PIndexBuffer uniformBuffer) {
|
||||
void DescriptorSetHandle::updateBuffer(const std::string& name, uint32 index, Gfx::PIndexBuffer uniformBuffer) {
|
||||
uint32 flattenedIndex = owner->getLayout()->variableMapping[name].index + index;
|
||||
PIndexBuffer buffer = uniformBuffer.cast<IndexBuffer>();
|
||||
bufferWrites.add(BufferWriteInfo{
|
||||
@@ -143,7 +114,18 @@ void DescriptorSet::updateBuffer(const std::string& name, uint32 index, Gfx::PIn
|
||||
boundResources.add(buffer->getAlloc());
|
||||
}
|
||||
|
||||
void DescriptorSet::updateSampler(const std::string& name, uint32 index, Gfx::PSampler samplerState) {
|
||||
void DescriptorSetHandle::updateBuffer(const std::string& name, uint32 index, Gfx::PUniformBuffer uniformBuffer) {
|
||||
uint32 flattenedIndex = owner->getLayout()->variableMapping[name].index + index;
|
||||
PIndexBuffer buffer = uniformBuffer.cast<IndexBuffer>();
|
||||
bufferWrites.add(BufferWriteInfo{
|
||||
.index = flattenedIndex,
|
||||
.buffer = buffer->getAlloc(),
|
||||
.access = owner->getLayout()->variableMapping[name].access,
|
||||
});
|
||||
boundResources.add(buffer->getAlloc());
|
||||
}
|
||||
|
||||
void DescriptorSetHandle::updateSampler(const std::string& name, uint32 index, Gfx::PSampler samplerState) {
|
||||
uint32 flattenedIndex = owner->getLayout()->variableMapping[name].index + index;
|
||||
PSampler sampler = samplerState.cast<Sampler>();
|
||||
samplerWrites.add(SamplerWriteInfo{
|
||||
@@ -152,18 +134,71 @@ void DescriptorSet::updateSampler(const std::string& name, uint32 index, Gfx::PS
|
||||
});
|
||||
}
|
||||
|
||||
void DescriptorSet::updateTexture(const std::string& name, uint32 index, Gfx::PTexture texture) {
|
||||
void DescriptorSetHandle::updateTexture(const std::string& name, uint32 index, Gfx::PTextureView texture) {
|
||||
uint32 flattenedIndex = owner->getLayout()->variableMapping[name].index + index;
|
||||
PTextureBase tex = texture.cast<TextureBase>();
|
||||
PTextureView tex = texture.cast<TextureView>();
|
||||
textureWrites.add(TextureWriteInfo{
|
||||
.index = flattenedIndex,
|
||||
.texture = tex->getHandle(),
|
||||
.texture = tex,
|
||||
.access = owner->getLayout()->variableMapping[name].access,
|
||||
});
|
||||
boundResources.add(tex->getHandle());
|
||||
boundResources.add(tex);
|
||||
}
|
||||
|
||||
void DescriptorSet::updateAccelerationStructure(const std::string& name, uint32 index, Gfx::PTopLevelAS as) { assert(false && "TODO"); }
|
||||
void DescriptorSetHandle::updateAccelerationStructure(const std::string& , uint32 , Gfx::PTopLevelAS ){}
|
||||
|
||||
DescriptorPool::DescriptorPool(PGraphics graphics, PDescriptorLayout layout) : graphics(graphics), layout(layout) {}
|
||||
|
||||
DescriptorPool::~DescriptorPool() {}
|
||||
|
||||
Gfx::ODescriptorSet DescriptorPool::allocateDescriptorSet() {
|
||||
for (uint32 setIndex = 0; setIndex < allocatedSets.size(); ++setIndex) {
|
||||
if (allocatedSets[setIndex]->isCurrentlyBound()) {
|
||||
// Currently in use, skip
|
||||
continue;
|
||||
}
|
||||
// Found set, stop searching
|
||||
return new DescriptorSet(graphics, this, allocatedSets[setIndex]);
|
||||
}
|
||||
allocatedSets.add(new DescriptorSetHandle(graphics, this, layout->getName()));
|
||||
return new DescriptorSet(graphics, this, allocatedSets.back());
|
||||
}
|
||||
|
||||
void DescriptorPool::reset() {}
|
||||
|
||||
DescriptorSet::DescriptorSet(PGraphics graphics, PDescriptorPool owner, PDescriptorSetHandle handle)
|
||||
: Gfx::DescriptorSet(owner->getLayout()), graphics(graphics), owner(owner), setHandle(handle) {
|
||||
}
|
||||
|
||||
DescriptorSet::~DescriptorSet() {
|
||||
}
|
||||
|
||||
void DescriptorSet::writeChanges() {}
|
||||
|
||||
void DescriptorSet::updateConstants(const std::string& name, uint32 offset, void* data) {
|
||||
setHandle->updateConstants(name, offset, data);
|
||||
}
|
||||
void DescriptorSet::updateBuffer(const std::string& name, uint32 index, Gfx::PShaderBuffer uniformBuffer){
|
||||
setHandle->updateBuffer(name, index, uniformBuffer);
|
||||
}
|
||||
void DescriptorSet::updateBuffer(const std::string& name, uint32 index, Gfx::PVertexBuffer uniformBuffer){
|
||||
setHandle->updateBuffer(name, index, uniformBuffer);
|
||||
}
|
||||
void DescriptorSet::updateBuffer(const std::string& name, uint32 index, Gfx::PIndexBuffer uniformBuffer){
|
||||
setHandle->updateBuffer(name, index, uniformBuffer);
|
||||
}
|
||||
void DescriptorSet::updateBuffer(const std::string& name, uint32 index, Gfx::PUniformBuffer uniformBuffer){
|
||||
setHandle->updateBuffer(name, index, uniformBuffer);
|
||||
}
|
||||
void DescriptorSet::updateSampler(const std::string& name, uint32 index, Gfx::PSampler samplerState){
|
||||
setHandle->updateSampler(name, index, samplerState);
|
||||
}
|
||||
void DescriptorSet::updateTexture(const std::string& name, uint32 index, Gfx::PTextureView texture){
|
||||
setHandle->updateTexture(name, index, texture);
|
||||
}
|
||||
void DescriptorSet::updateAccelerationStructure(const std::string& name, uint32 index, Gfx::PTopLevelAS as){
|
||||
setHandle->updateAccelerationStructure(name, index, as);
|
||||
}
|
||||
|
||||
PipelineLayout::PipelineLayout(PGraphics graphics, const std::string& name, Gfx::PPipelineLayout baseLayout)
|
||||
: Gfx::PipelineLayout(name, baseLayout), graphics(graphics) {}
|
||||
|
||||
@@ -28,6 +28,7 @@ class Graphics : public Gfx::Graphics {
|
||||
virtual void executeCommands(Array<Gfx::OComputeCommand> commands) override;
|
||||
|
||||
virtual Gfx::OTexture2D createTexture2D(const TextureCreateInfo& createInfo) override;
|
||||
virtual Gfx::OTexture2DArray createTexture2DArray(const TextureCreateInfo& createInfo) override;
|
||||
virtual Gfx::OTexture3D createTexture3D(const TextureCreateInfo& createInfo) override;
|
||||
virtual Gfx::OTextureCube createTextureCube(const TextureCreateInfo& createInfo) override;
|
||||
virtual Gfx::OUniformBuffer createUniformBuffer(const UniformBufferCreateInfo& bulkData) override;
|
||||
|
||||
@@ -38,7 +38,8 @@ Gfx::OViewport Graphics::createViewport(Gfx::PWindow owner, const ViewportCreate
|
||||
return new Viewport(owner, createInfo);
|
||||
}
|
||||
|
||||
Gfx::ORenderPass Graphics::createRenderPass(Gfx::RenderTargetLayout layout, Array<Gfx::SubPassDependency> dependencies, URect renderArea, std::string name, Array<uint32> viewMask, Array<uint32> correlationMask) {
|
||||
Gfx::ORenderPass Graphics::createRenderPass(Gfx::RenderTargetLayout layout, Array<Gfx::SubPassDependency> dependencies, URect renderArea,
|
||||
std::string name, Array<uint32>, Array<uint32>) {
|
||||
return new RenderPass(this, layout, dependencies, renderArea, name);
|
||||
}
|
||||
|
||||
@@ -46,9 +47,7 @@ void Graphics::beginRenderPass(Gfx::PRenderPass renderPass) { queue->getCommands
|
||||
|
||||
void Graphics::endRenderPass() { queue->getCommands()->endRenderPass(); }
|
||||
|
||||
void Graphics::waitDeviceIdle() {
|
||||
queue->submitCommands();
|
||||
}
|
||||
void Graphics::waitDeviceIdle() { queue->submitCommands(); }
|
||||
|
||||
void Graphics::executeCommands(Gfx::ORenderCommand commands) {
|
||||
Array<Gfx::ORenderCommand> command;
|
||||
@@ -68,6 +67,8 @@ void Graphics::executeCommands(Array<Gfx::OComputeCommand> commands) { queue->ex
|
||||
|
||||
Gfx::OTexture2D Graphics::createTexture2D(const TextureCreateInfo& createInfo) { return new Texture2D(this, createInfo); }
|
||||
|
||||
Gfx::OTexture2DArray Graphics::createTexture2DArray(const TextureCreateInfo& createInfo) { return new Texture2DArray(this, createInfo); }
|
||||
|
||||
Gfx::OTexture3D Graphics::createTexture3D(const TextureCreateInfo& createInfo) { return new Texture3D(this, createInfo); }
|
||||
|
||||
Gfx::OTextureCube Graphics::createTextureCube(const TextureCreateInfo& createInfo) { return new TextureCube(this, createInfo); }
|
||||
@@ -155,23 +156,18 @@ void Graphics::beginDebugRegion(const std::string& name) {
|
||||
queue->getCommands()->getHandle()->pushDebugGroup(NS::String::string(name.c_str(), NS::ASCIIStringEncoding));
|
||||
}
|
||||
|
||||
void Graphics::endDebugRegion() {
|
||||
queue->getCommands()->getHandle()->popDebugGroup();
|
||||
}
|
||||
void Graphics::endDebugRegion() { queue->getCommands()->getHandle()->popDebugGroup(); }
|
||||
|
||||
void Graphics::resolveTexture(Gfx::PTexture, Gfx::PTexture) {}
|
||||
|
||||
void Graphics::copyTexture(Gfx::PTexture, Gfx::PTexture) {}
|
||||
void Graphics::copyTexture(Gfx::PTexture, Gfx::PTexture) { assert(false); }
|
||||
|
||||
void Graphics::copyBuffer(Gfx::PShaderBuffer src, Gfx::PShaderBuffer dst)
|
||||
{
|
||||
// TODO blit commands
|
||||
}
|
||||
void Graphics::copyBuffer(Gfx::PShaderBuffer, Gfx::PShaderBuffer) { assert(false); }
|
||||
|
||||
// Ray Tracing
|
||||
Gfx::OBottomLevelAS Graphics::createBottomLevelAccelerationStructure(const Gfx::BottomLevelASCreateInfo& createInfo) { return nullptr; }
|
||||
Gfx::OBottomLevelAS Graphics::createBottomLevelAccelerationStructure(const Gfx::BottomLevelASCreateInfo&) { return nullptr; }
|
||||
|
||||
Gfx::OTopLevelAS Graphics::createTopLevelAccelerationStructure(const Gfx::TopLevelASCreateInfo& createInfo) { return nullptr; }
|
||||
Gfx::OTopLevelAS Graphics::createTopLevelAccelerationStructure(const Gfx::TopLevelASCreateInfo&) { return nullptr; }
|
||||
|
||||
void Graphics::buildBottomLevelAccelerationStructures(Array<Gfx::PBottomLevelAS>) {}
|
||||
|
||||
|
||||
@@ -88,11 +88,11 @@ PGraphicsPipeline PipelineCache::createPipeline(Gfx::LegacyPipelineCreateInfo cr
|
||||
}
|
||||
|
||||
MTL::DepthStencilDescriptor* depthDescriptor = MTL::DepthStencilDescriptor::alloc()->init();
|
||||
if (createInfo.renderPass->getLayout().depthAttachment.getTexture() != nullptr) {
|
||||
if (createInfo.renderPass->getLayout().depthAttachment.getTextureView() != nullptr) {
|
||||
depthDescriptor->setDepthWriteEnabled(createInfo.depthStencilState.depthWriteEnable);
|
||||
depthDescriptor->setDepthCompareFunction(cast(createInfo.depthStencilState.depthCompareOp));
|
||||
pipelineDescriptor->setDepthAttachmentPixelFormat(
|
||||
cast(createInfo.renderPass->getLayout().depthAttachment.getTexture().cast<Texture2D>()->getFormat()));
|
||||
cast(createInfo.renderPass->getLayout().depthAttachment.getTextureView()->getFormat()));
|
||||
}
|
||||
pipelineDescriptor->setAlphaToCoverageEnabled(createInfo.multisampleState.alphaCoverageEnable);
|
||||
pipelineDescriptor->setAlphaToOneEnabled(createInfo.multisampleState.alphaToOneEnable);
|
||||
@@ -196,11 +196,11 @@ PGraphicsPipeline PipelineCache::createPipeline(Gfx::MeshPipelineCreateInfo crea
|
||||
pipelineDescriptor->colorAttachments()->setObject(desc, c);
|
||||
}
|
||||
MTL::DepthStencilDescriptor* depthDescriptor = MTL::DepthStencilDescriptor::alloc()->init();
|
||||
if (createInfo.renderPass->getLayout().depthAttachment.getTexture() != nullptr) {
|
||||
if (createInfo.renderPass->getLayout().depthAttachment.getTextureView() != nullptr) {
|
||||
depthDescriptor->setDepthWriteEnabled(createInfo.depthStencilState.depthWriteEnable);
|
||||
depthDescriptor->setDepthCompareFunction(cast(createInfo.depthStencilState.depthCompareOp));
|
||||
pipelineDescriptor->setDepthAttachmentPixelFormat(
|
||||
cast(createInfo.renderPass->getLayout().depthAttachment.getTexture().cast<Texture2D>()->getFormat()));
|
||||
cast(createInfo.renderPass->getLayout().depthAttachment.getTextureView()->getFormat()));
|
||||
}
|
||||
pipelineDescriptor->setAlphaToCoverageEnabled(createInfo.multisampleState.alphaCoverageEnable);
|
||||
pipelineDescriptor->setAlphaToOneEnabled(createInfo.multisampleState.alphaToOneEnable);
|
||||
@@ -209,9 +209,9 @@ PGraphicsPipeline PipelineCache::createPipeline(Gfx::MeshPipelineCreateInfo crea
|
||||
|
||||
MTL::DepthStencilState* depthState = graphics->getDevice()->newDepthStencilState(depthDescriptor);
|
||||
depthDescriptor->release();
|
||||
if (createInfo.renderPass->getLayout().depthAttachment.getTexture() != nullptr) {
|
||||
if (createInfo.renderPass->getLayout().depthAttachment.getTextureView() != nullptr) {
|
||||
pipelineDescriptor->setDepthAttachmentPixelFormat(
|
||||
cast(createInfo.renderPass->getLayout().depthAttachment.getTexture().cast<Texture2D>()->getFormat()));
|
||||
cast(createInfo.renderPass->getLayout().depthAttachment.getTextureView()->getFormat()));
|
||||
}
|
||||
pipelineDescriptor->setAlphaToCoverageEnabled(createInfo.multisampleState.alphaCoverageEnable);
|
||||
pipelineDescriptor->setAlphaToOneEnabled(createInfo.multisampleState.alphaToOneEnable);
|
||||
|
||||
@@ -33,13 +33,13 @@ RenderPass::RenderPass(PGraphics graphics, Gfx::RenderTargetLayout _layout, Arra
|
||||
}
|
||||
}
|
||||
}
|
||||
if (layout.depthAttachment.getTexture() != nullptr) {
|
||||
if (layout.depthAttachment.getTextureView() != nullptr) {
|
||||
auto depth = renderPass->depthAttachment();
|
||||
depth->setClearDepth(layout.depthAttachment.clear.depthStencil.depth);
|
||||
depth->setLoadAction(cast(layout.depthAttachment.getLoadOp()));
|
||||
depth->setStoreAction(cast(layout.depthAttachment.getStoreOp()));
|
||||
|
||||
if (layout.depthResolveAttachment.getTexture() != nullptr) {
|
||||
if (layout.depthResolveAttachment.getTextureView() != nullptr) {
|
||||
// store multisampled attachment as well
|
||||
if(layout.depthAttachment.getStoreOp() == Gfx::SE_ATTACHMENT_STORE_OP_STORE) {
|
||||
depth->setStoreAction(MTL::StoreActionStoreAndMultisampleResolve);
|
||||
@@ -56,17 +56,17 @@ void RenderPass::updateRenderPass() {
|
||||
for (size_t i = 0; i < layout.colorAttachments.size(); ++i) {
|
||||
const auto& color = layout.colorAttachments[i];
|
||||
auto desc = renderPass->colorAttachments()->object(i);
|
||||
desc->setTexture(color.getTexture().cast<TextureBase>()->getImage());
|
||||
desc->setTexture(color.getTextureView().cast<TextureBase>()->getImage());
|
||||
if (!layout.resolveAttachments.empty()) {
|
||||
const auto& resolve = layout.resolveAttachments[i];
|
||||
desc->setResolveTexture(resolve.getTexture().cast<TextureBase>()->getImage());
|
||||
desc->setResolveTexture(resolve.getTextureView().cast<TextureBase>()->getImage());
|
||||
}
|
||||
}
|
||||
if (layout.depthAttachment.getTexture() != nullptr) {
|
||||
if (layout.depthAttachment.getTextureView() != nullptr) {
|
||||
auto depth = renderPass->depthAttachment();
|
||||
depth->setTexture(layout.depthAttachment.getTexture().cast<TextureBase>()->getImage());
|
||||
if (layout.depthResolveAttachment.getTexture() != nullptr) {
|
||||
depth->setResolveTexture(layout.depthResolveAttachment.getTexture().cast<TextureBase>()->getImage());
|
||||
depth->setTexture(layout.depthAttachment.getTextureView().cast<TextureBase>()->getImage());
|
||||
if (layout.depthResolveAttachment.getTextureView() != nullptr) {
|
||||
depth->setResolveTexture(layout.depthResolveAttachment.getTextureView().cast<TextureBase>()->getImage());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -7,6 +7,37 @@
|
||||
|
||||
namespace Seele {
|
||||
namespace Metal {
|
||||
DECLARE_REF(TextureHandle)
|
||||
class TextureView : public Gfx::TextureView, public CommandBoundResource {
|
||||
public:
|
||||
TextureView(PGraphics graphics, PTextureHandle source, uint32 width, uint32 height, uint32 numLayers, uint32 numMipLevels, MTL::Texture* view);
|
||||
virtual ~TextureView();
|
||||
virtual Gfx::SeFormat getFormat() const override;
|
||||
virtual uint32 getWidth() const override;
|
||||
virtual uint32 getHeight() const override;
|
||||
virtual uint32 getDepth() const override;
|
||||
virtual uint32 getNumLayers() const override;
|
||||
virtual Gfx::SeSampleCountFlags getNumSamples() const override;
|
||||
virtual uint32 getMipLevels() const override;
|
||||
virtual void pipelineBarrier(Gfx::SeAccessFlags srcAccess, Gfx::SePipelineStageFlags srcStage, Gfx::SeAccessFlags dstAccess,
|
||||
Gfx::SePipelineStageFlags dstStage) override;
|
||||
virtual void changeLayout(Gfx::SeImageLayout newLayout, Gfx::SeAccessFlags srcAccess, Gfx::SePipelineStageFlags srcStage,
|
||||
Gfx::SeAccessFlags dstAccess, Gfx::SePipelineStageFlags dstStage) override;
|
||||
|
||||
MTL::Texture* getHandle() const { return view; }
|
||||
PTextureHandle getSource() const { return source;}
|
||||
|
||||
private:
|
||||
uint32 width;
|
||||
uint32 height;
|
||||
uint32 numLayers;
|
||||
uint32 numMipLevels;
|
||||
PTextureHandle source;
|
||||
MTL::Texture* view;
|
||||
friend class TextureBase;
|
||||
};
|
||||
DEFINE_REF(TextureView)
|
||||
|
||||
class TextureHandle : public CommandBoundResource {
|
||||
public:
|
||||
TextureHandle(PGraphics graphics, MTL::TextureType type, const TextureCreateInfo& createInfo, MTL::Texture* existingImage);
|
||||
@@ -18,8 +49,10 @@ class TextureHandle : public CommandBoundResource{
|
||||
Gfx::SeAccessFlags dstAccess, Gfx::SePipelineStageFlags dstStage);
|
||||
void download(uint32 mipLevel, uint32 arrayLayer, uint32 face, Array<uint8>& buffer);
|
||||
void generateMipmaps();
|
||||
Gfx::OTextureView createTextureView(uint32 baseMipLevel, uint32 levelCount, uint32 baseArrayLayer, uint32 layerCount);
|
||||
|
||||
MTL::Texture* texture;
|
||||
OTextureView textureView;
|
||||
MTL::TextureType type;
|
||||
uint32 width;
|
||||
uint32 height;
|
||||
@@ -87,6 +120,8 @@ class Texture2D : public Gfx::Texture2D, public TextureBase {
|
||||
Gfx::SeAccessFlags dstAccess, Gfx::SePipelineStageFlags dstStage) override;
|
||||
virtual void download(uint32 mipLevel, uint32 arrayLayer, uint32 face, Array<uint8>& buffer) override;
|
||||
virtual void generateMipmaps() override;
|
||||
virtual Gfx::PTextureView getDefaultView() const override;
|
||||
virtual Gfx::OTextureView createTextureView(uint32 baseMipLevel, uint32 levelCount, uint32 baseArrayLayer, uint32 layerCount) override;
|
||||
|
||||
protected:
|
||||
// Inherited via QueueOwnedResource
|
||||
@@ -95,7 +130,31 @@ class Texture2D : public Gfx::Texture2D, public TextureBase {
|
||||
Gfx::SePipelineStageFlags dstStage) override;
|
||||
};
|
||||
DEFINE_REF(Texture2D)
|
||||
class Texture2DArray : public Gfx::Texture2DArray, public TextureBase {
|
||||
public:
|
||||
Texture2DArray(PGraphics graphics, const TextureCreateInfo& createInfo, MTL::Texture* existingImage = nullptr);
|
||||
virtual ~Texture2DArray();
|
||||
virtual uint32 getWidth() const override { return handle->width; }
|
||||
virtual uint32 getHeight() const override { return handle->height; }
|
||||
virtual uint32 getDepth() const override { return handle->depth; }
|
||||
virtual uint32 getNumLayers() const override { return handle->arrayCount; }
|
||||
virtual Gfx::SeFormat getFormat() const override { return handle->format; }
|
||||
virtual Gfx::SeSampleCountFlags getNumSamples() const override { return handle->samples; }
|
||||
virtual uint32 getMipLevels() const override { return handle->mipLevels; }
|
||||
virtual void changeLayout(Gfx::SeImageLayout newLayout, Gfx::SeAccessFlags srcAccess, Gfx::SePipelineStageFlags srcStage,
|
||||
Gfx::SeAccessFlags dstAccess, Gfx::SePipelineStageFlags dstStage) override;
|
||||
virtual void download(uint32 mipLevel, uint32 arrayLayer, uint32 face, Array<uint8>& buffer) override;
|
||||
virtual void generateMipmaps() override;
|
||||
virtual Gfx::PTextureView getDefaultView() const override;
|
||||
virtual Gfx::OTextureView createTextureView(uint32 baseMipLevel, uint32 levelCount, uint32 baseArrayLayer, uint32 layerCount) override;
|
||||
|
||||
protected:
|
||||
// Inherited via QueueOwnedResource
|
||||
virtual void executeOwnershipBarrier(Gfx::QueueType newOwner) override;
|
||||
virtual void executePipelineBarrier(Gfx::SeAccessFlags srcAccess, Gfx::SePipelineStageFlags srcStage, Gfx::SeAccessFlags dstAccess,
|
||||
Gfx::SePipelineStageFlags dstStage) override;
|
||||
};
|
||||
DEFINE_REF(Texture2DArray)
|
||||
class Texture3D : public Gfx::Texture3D, public TextureBase {
|
||||
public:
|
||||
Texture3D(PGraphics graphics, const TextureCreateInfo& createInfo);
|
||||
@@ -111,6 +170,8 @@ class Texture3D : public Gfx::Texture3D, public TextureBase {
|
||||
Gfx::SeAccessFlags dstAccess, Gfx::SePipelineStageFlags dstStage) override;
|
||||
virtual void download(uint32 mipLevel, uint32 arrayLayer, uint32 face, Array<uint8>& buffer) override;
|
||||
virtual void generateMipmaps() override;
|
||||
virtual Gfx::PTextureView getDefaultView() const override;
|
||||
virtual Gfx::OTextureView createTextureView(uint32 baseMipLevel, uint32 levelCount, uint32 baseArrayLayer, uint32 layerCount) override;
|
||||
|
||||
protected:
|
||||
// Inherited via QueueOwnedResource
|
||||
@@ -135,6 +196,8 @@ class TextureCube : public Gfx::TextureCube, public TextureBase {
|
||||
Gfx::SeAccessFlags dstAccess, Gfx::SePipelineStageFlags dstStage) override;
|
||||
virtual void download(uint32 mipLevel, uint32 arrayLayer, uint32 face, Array<uint8>& buffer) override;
|
||||
virtual void generateMipmaps() override;
|
||||
virtual Gfx::PTextureView getDefaultView() const override;
|
||||
virtual Gfx::OTextureView createTextureView(uint32 baseMipLevel, uint32 levelCount, uint32 baseArrayLayer, uint32 layerCount) override;
|
||||
|
||||
protected:
|
||||
// Inherited via QueueOwnedResource
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
#include "Texture.h"
|
||||
#include "Command.h"
|
||||
#include "Enums.h"
|
||||
#include "Graphics/Enums.h"
|
||||
#include "Graphics/Initializer.h"
|
||||
#include "Graphics/Metal/Buffer.h"
|
||||
#include "Graphics/Metal/Graphics.h"
|
||||
#include "Command.h"
|
||||
#include "Graphics/Metal/Resources.h"
|
||||
#include "Metal/MTLTexture.hpp"
|
||||
#include "Metal/MTLTypes.hpp"
|
||||
@@ -12,9 +12,47 @@
|
||||
using namespace Seele;
|
||||
using namespace Seele::Metal;
|
||||
|
||||
TextureView::TextureView(PGraphics graphics, PTextureHandle source, uint32 width, uint32 height, uint32 numLayers, uint32 numMipLevels, MTL::Texture* view)
|
||||
: CommandBoundResource(graphics), width(width), height(height), numLayers(numLayers), numMipLevels(numMipLevels), source(source), view(view) {}
|
||||
|
||||
TextureView::~TextureView() {}
|
||||
|
||||
Gfx::SeFormat TextureView::getFormat() const { return source->format; }
|
||||
|
||||
uint32 TextureView::getWidth() const { return width; }
|
||||
|
||||
uint32 TextureView::getHeight() const { return height; }
|
||||
|
||||
uint32 TextureView::getDepth() const { return source->depth; }
|
||||
|
||||
uint32 TextureView::getNumLayers() const { return numLayers; }
|
||||
|
||||
Gfx::SeSampleCountFlags TextureView::getNumSamples() const { return source->samples; }
|
||||
|
||||
uint32 TextureView::getMipLevels() const { return numMipLevels; }
|
||||
|
||||
void TextureView::pipelineBarrier(Gfx::SeAccessFlags srcAccess, Gfx::SePipelineStageFlags srcStage, Gfx::SeAccessFlags dstAccess,
|
||||
Gfx::SePipelineStageFlags dstStage) {
|
||||
return source->pipelineBarrier(srcAccess, srcStage, dstAccess, dstStage);
|
||||
}
|
||||
|
||||
void TextureView::changeLayout(Gfx::SeImageLayout newLayout, Gfx::SeAccessFlags srcAccess, Gfx::SePipelineStageFlags srcStage,
|
||||
Gfx::SeAccessFlags dstAccess, Gfx::SePipelineStageFlags dstStage) {
|
||||
return source->changeLayout(newLayout, srcAccess, srcStage, dstAccess, dstStage);
|
||||
}
|
||||
|
||||
Gfx::OTextureView TextureHandle::createTextureView(uint32 baseMipLevel, uint32 viewLevelCount, uint32 baseArrayLayer,
|
||||
uint32 viewLayerCount) {
|
||||
MTL::Texture* viewTexture =
|
||||
texture->newTextureView(cast(format), type, NS::Range(baseMipLevel, viewLevelCount), NS::Range(baseArrayLayer, viewLayerCount));
|
||||
uint32 viewWidth = width * std::pow(0.5, baseMipLevel);
|
||||
uint32 viewHeight = height * std::pow(0.5, baseMipLevel);
|
||||
return new TextureView(graphics, this, viewWidth, viewHeight, viewLayerCount, viewLevelCount, viewTexture);
|
||||
}
|
||||
|
||||
TextureHandle::TextureHandle(PGraphics graphics, MTL::TextureType type, const TextureCreateInfo& createInfo, MTL::Texture* existingImage)
|
||||
: CommandBoundResource(graphics), texture(existingImage), type(type), width(createInfo.width), height(createInfo.height), depth(createInfo.depth),
|
||||
arrayCount(createInfo.elements), mipLevels(1), samples(createInfo.samples), format(createInfo.format),
|
||||
: CommandBoundResource(graphics), texture(existingImage), type(type), width(createInfo.width), height(createInfo.height),
|
||||
depth(createInfo.depth), arrayCount(createInfo.elements), mipLevels(1), samples(createInfo.samples), format(createInfo.format),
|
||||
usage(createInfo.usage), layout(Gfx::SE_IMAGE_LAYOUT_UNDEFINED), ownsImage(existingImage == nullptr) {
|
||||
if (createInfo.useMip) {
|
||||
mipLevels = static_cast<uint32_t>(std::floor(std::log2(std::max(width, height)))) + 1;
|
||||
@@ -50,9 +88,9 @@ TextureHandle::TextureHandle(PGraphics graphics, MTL::TextureType type, const Te
|
||||
|
||||
descriptor->release();
|
||||
}
|
||||
if(createInfo.sourceData.data != nullptr)
|
||||
{
|
||||
OBufferAllocation stagingBuffer = new BufferAllocation(graphics, "TextureStaging", createInfo.sourceData.size, MTL::ResourceStorageModeShared);
|
||||
if (createInfo.sourceData.data != nullptr) {
|
||||
OBufferAllocation stagingBuffer =
|
||||
new BufferAllocation(graphics, "TextureStaging", createInfo.sourceData.size, MTL::ResourceStorageModeShared);
|
||||
std::memcpy(stagingBuffer->map(), createInfo.sourceData.data, createInfo.sourceData.size);
|
||||
MTL::BlitCommandEncoder* blitEnc = graphics->getQueue()->getCommands()->getBlitEncoder();
|
||||
uint32 sliceSize = createInfo.sourceData.size / arrayCount;
|
||||
@@ -63,7 +101,8 @@ TextureHandle::TextureHandle(PGraphics graphics, MTL::TextureType type, const Te
|
||||
}
|
||||
uint32 offset = 0;
|
||||
for (uint32 slice = 0; slice < numSlices; ++slice) {
|
||||
blitEnc->copyFromBuffer(stagingBuffer->buffer, offset, sliceSize / createInfo.height, arrayCount == 1 ? 0 : sliceSize, MTL::Size(createInfo.width, createInfo.height, createInfo.depth), texture, slice, 0, MTL::Origin());
|
||||
blitEnc->copyFromBuffer(stagingBuffer->buffer, offset, sliceSize / createInfo.height, arrayCount == 1 ? 0 : sliceSize,
|
||||
MTL::Size(createInfo.width, createInfo.height, createInfo.depth), texture, slice, 0, MTL::Origin());
|
||||
offset += sliceSize;
|
||||
}
|
||||
if (mipLevels > 1) {
|
||||
@@ -72,6 +111,7 @@ TextureHandle::TextureHandle(PGraphics graphics, MTL::TextureType type, const Te
|
||||
graphics->getQueue()->getCommands()->bindResource(PBufferAllocation(stagingBuffer));
|
||||
graphics->getDestructionManager()->queueResourceForDestruction(std::move(stagingBuffer));
|
||||
}
|
||||
textureView = new TextureView(graphics, this, width, height, arrayCount, mipLevels, texture);
|
||||
}
|
||||
|
||||
TextureHandle::~TextureHandle() {
|
||||
@@ -85,7 +125,7 @@ void TextureHandle::pipelineBarrier(Gfx::SeAccessFlags, Gfx::SePipelineStageFlag
|
||||
void TextureHandle::changeLayout(Gfx::SeImageLayout, Gfx::SeAccessFlags, Gfx::SePipelineStageFlags, Gfx::SeAccessFlags,
|
||||
Gfx::SePipelineStageFlags) {}
|
||||
|
||||
void TextureHandle::transferOwnership(Gfx::QueueType newOwner) {}
|
||||
void TextureHandle::transferOwnership(Gfx::QueueType) {}
|
||||
|
||||
void TextureHandle::download(uint32, uint32, uint32, Array<uint8>&) {}
|
||||
|
||||
@@ -94,9 +134,7 @@ void TextureHandle::generateMipmaps() {}
|
||||
TextureBase::TextureBase(PGraphics graphics, MTL::TextureType viewType, const TextureCreateInfo& createInfo, MTL::Texture* existingImage)
|
||||
: handle(new TextureHandle(graphics, viewType, createInfo, existingImage)), graphics(graphics) {}
|
||||
|
||||
TextureBase::~TextureBase() {
|
||||
graphics->getDestructionManager()->queueResourceForDestruction(std::move(handle));
|
||||
}
|
||||
TextureBase::~TextureBase() { graphics->getDestructionManager()->queueResourceForDestruction(std::move(handle)); }
|
||||
|
||||
void TextureBase::pipelineBarrier(Gfx::SeAccessFlags srcAccess, Gfx::SePipelineStageFlags srcStage, Gfx::SeAccessFlags dstAccess,
|
||||
Gfx::SePipelineStageFlags dstStage) {
|
||||
@@ -132,6 +170,12 @@ void Texture2D::download(uint32 mipLevel, uint32 arrayLayer, uint32 face, Array<
|
||||
|
||||
void Texture2D::generateMipmaps() { TextureBase::generateMipmaps(); }
|
||||
|
||||
Gfx::PTextureView Texture2D::getDefaultView() const { return PTextureView(handle->textureView); }
|
||||
|
||||
Gfx::OTextureView Texture2D::createTextureView(uint32 baseMipLevel, uint32 levelCount, uint32 baseArrayLayer, uint32 layerCount) {
|
||||
return handle->createTextureView(baseMipLevel, levelCount, baseArrayLayer, layerCount);
|
||||
}
|
||||
|
||||
void Texture2D::executeOwnershipBarrier(Gfx::QueueType newOwner) { TextureBase::transferOwnership(newOwner); }
|
||||
|
||||
void Texture2D::executePipelineBarrier(Gfx::SeAccessFlags srcAccess, Gfx::SePipelineStageFlags srcStage, Gfx::SeAccessFlags dstAccess,
|
||||
@@ -139,6 +183,39 @@ void Texture2D::executePipelineBarrier(Gfx::SeAccessFlags srcAccess, Gfx::SePipe
|
||||
TextureBase::pipelineBarrier(srcAccess, srcStage, dstAccess, dstStage);
|
||||
}
|
||||
|
||||
Texture2DArray::Texture2DArray(PGraphics graphics, const TextureCreateInfo& createInfo, MTL::Texture* existingImage)
|
||||
: Gfx::Texture2DArray(graphics->getFamilyMapping()),
|
||||
TextureBase(graphics,
|
||||
createInfo.elements > 1 ? (createInfo.samples > 1 ? MTL::TextureType2DMultisampleArray : MTL::TextureType2DArray)
|
||||
: (createInfo.samples > 1 ? MTL::TextureType2DMultisample : MTL::TextureType2D),
|
||||
createInfo, existingImage) {}
|
||||
|
||||
Texture2DArray::~Texture2DArray() {}
|
||||
|
||||
void Texture2DArray::changeLayout(Gfx::SeImageLayout newLayout, Gfx::SeAccessFlags srcAccess, Gfx::SePipelineStageFlags srcStage,
|
||||
Gfx::SeAccessFlags dstAccess, Gfx::SePipelineStageFlags dstStage) {
|
||||
TextureBase::changeLayout(newLayout, srcAccess, srcStage, dstAccess, dstStage);
|
||||
}
|
||||
|
||||
void Texture2DArray::download(uint32 mipLevel, uint32 arrayLayer, uint32 face, Array<uint8>& buffer) {
|
||||
TextureBase::download(mipLevel, arrayLayer, face, buffer);
|
||||
}
|
||||
|
||||
void Texture2DArray::generateMipmaps() { TextureBase::generateMipmaps(); }
|
||||
|
||||
Gfx::PTextureView Texture2DArray::getDefaultView() const { return PTextureView(handle->textureView); }
|
||||
|
||||
Gfx::OTextureView Texture2DArray::createTextureView(uint32 baseMipLevel, uint32 levelCount, uint32 baseArrayLayer, uint32 layerCount) {
|
||||
return handle->createTextureView(baseMipLevel, levelCount, baseArrayLayer, layerCount);
|
||||
}
|
||||
|
||||
void Texture2DArray::executeOwnershipBarrier(Gfx::QueueType newOwner) { TextureBase::transferOwnership(newOwner); }
|
||||
|
||||
void Texture2DArray::executePipelineBarrier(Gfx::SeAccessFlags srcAccess, Gfx::SePipelineStageFlags srcStage, Gfx::SeAccessFlags dstAccess,
|
||||
Gfx::SePipelineStageFlags dstStage) {
|
||||
TextureBase::pipelineBarrier(srcAccess, srcStage, dstAccess, dstStage);
|
||||
}
|
||||
|
||||
Texture3D::Texture3D(PGraphics graphics, const TextureCreateInfo& createInfo)
|
||||
: Gfx::Texture3D(graphics->getFamilyMapping()), TextureBase(graphics, MTL::TextureType3D, createInfo) {}
|
||||
|
||||
@@ -155,6 +232,12 @@ void Texture3D::download(uint32 mipLevel, uint32 arrayLayer, uint32 face, Array<
|
||||
|
||||
void Texture3D::generateMipmaps() { TextureBase::generateMipmaps(); }
|
||||
|
||||
Gfx::PTextureView Texture3D::getDefaultView() const { return PTextureView(handle->textureView); }
|
||||
|
||||
Gfx::OTextureView Texture3D::createTextureView(uint32 baseMipLevel, uint32 levelCount, uint32 baseArrayLayer, uint32 layerCount) {
|
||||
return handle->createTextureView(baseMipLevel, levelCount, baseArrayLayer, layerCount);
|
||||
}
|
||||
|
||||
void Texture3D::executeOwnershipBarrier(Gfx::QueueType newOwner) { TextureBase::transferOwnership(newOwner); }
|
||||
|
||||
void Texture3D::executePipelineBarrier(Gfx::SeAccessFlags srcAccess, Gfx::SePipelineStageFlags srcStage, Gfx::SeAccessFlags dstAccess,
|
||||
@@ -179,6 +262,12 @@ void TextureCube::download(uint32 mipLevel, uint32 arrayLayer, uint32 face, Arra
|
||||
|
||||
void TextureCube::generateMipmaps() { TextureBase::generateMipmaps(); }
|
||||
|
||||
Gfx::PTextureView TextureCube::getDefaultView() const { return PTextureView(handle->textureView); }
|
||||
|
||||
Gfx::OTextureView TextureCube::createTextureView(uint32 baseMipLevel, uint32 levelCount, uint32 baseArrayLayer, uint32 layerCount) {
|
||||
return handle->createTextureView(baseMipLevel, levelCount, baseArrayLayer, layerCount);
|
||||
}
|
||||
|
||||
void TextureCube::executeOwnershipBarrier(Gfx::QueueType newOwner) { TextureBase::transferOwnership(newOwner); }
|
||||
|
||||
void TextureCube::executePipelineBarrier(Gfx::SeAccessFlags srcAccess, Gfx::SePipelineStageFlags srcStage, Gfx::SeAccessFlags dstAccess,
|
||||
|
||||
@@ -152,7 +152,7 @@ void Seele::beginCompilation(const ShaderCompilationInfo& info, SlangCompileTarg
|
||||
layout->addMapping("pResources", 4);
|
||||
layout->addMapping("pRayTracingParams", 5);
|
||||
}
|
||||
layout->addMapping("pVertexData", 1);
|
||||
//layout->addMapping("pVertexData", 1);
|
||||
// layout->addMapping("pWaterMaterial", 1);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user