Trying to get metal backend to run

This commit is contained in:
Dynamitos
2025-04-12 17:40:14 +02:00
parent 32ad82dbd2
commit 3cee2ae9ab
24 changed files with 64 additions and 69 deletions
+9 -3
View File
@@ -133,15 +133,17 @@ void EnvironmentLoader::import(EnvironmentImportArgs args, PEnvironmentMapAsset
Gfx::SE_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL,
Gfx::SE_ATTACHMENT_LOAD_OP_DONT_CARE, Gfx::SE_ATTACHMENT_STORE_OP_STORE)},
},
{
Gfx::SubPassDependency{
{Gfx::SubPassDependency{
.srcSubpass = 0,
.dstSubpass = ~0U,
.srcStage = Gfx::SE_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,
.dstStage = Gfx::SE_PIPELINE_STAGE_FRAGMENT_SHADER_BIT,
.srcAccess = Gfx::SE_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,
.dstAccess = Gfx::SE_ACCESS_SHADER_READ_BIT,
}
}},
{
.offset = {0, 0},
.size = {SOURCE_RESOLUTION, SOURCE_RESOLUTION},
},
"EnvironmentRenderPass", {0b111111}, {0b111111});
cubeRenderPipeline = graphics->createGraphicsPipeline(Gfx::LegacyPipelineCreateInfo{
@@ -176,6 +178,10 @@ void EnvironmentLoader::import(EnvironmentImportArgs args, PEnvironmentMapAsset
Gfx::SE_ATTACHMENT_LOAD_OP_DONT_CARE, Gfx::SE_ATTACHMENT_STORE_OP_STORE)},
},
{},
{
.offset = {0, 0},
.size = {CONVOLUTED_RESOLUTION, CONVOLUTED_RESOLUTION},
},
"EnvironmentRenderPass", {0b111111}, {0b111111});
convolutionPipeline = graphics->createGraphicsPipeline(Gfx::LegacyPipelineCreateInfo{
.vertexShader = cubeRenderVertex,
+9 -2
View File
@@ -9,8 +9,8 @@
#ifdef __APPLE__
#include "Graphics/Metal/Graphics.h"
#else
#include "Graphics/Vulkan/Graphics.h"
#endif
#include "Graphics/Vulkan/Graphics.h"
#include "Graphics/StaticMeshVertexData.h"
#include "Window/InspectorView.h"
#include "Window/PlayView.h"
@@ -28,7 +28,14 @@ int main() {
std::string gameName = "MinecraftClone";
std::filesystem::path outputPath = fmt::format("../../{0}Game", gameName);
std::filesystem::path sourcePath = fmt::format("../../{0}", gameName);
std::filesystem::path binaryPath = sourcePath / "bin" / fmt::format("{0}.dll", gameName);
#ifdef WIN32
std::string libraryEnding = "dll";
#elif __APPLE__
std::string libraryEnding = "dylib";
#else
std::string libraryEnding = "so";
#endif
std::filesystem::path binaryPath = sourcePath / "bin" / fmt::format("{}.{}", gameName, libraryEnding);
std::filesystem::path cmakePath = outputPath / "cmake";
if (true) {
#ifdef __APPLE__
+1 -1
View File
@@ -55,7 +55,7 @@ class Graphics {
virtual OWindow createWindow(const WindowCreateInfo& createInfo) = 0;
virtual OViewport createViewport(PWindow owner, const ViewportCreateInfo& createInfo) = 0;
virtual ORenderPass createRenderPass(RenderTargetLayout layout, Array<SubPassDependency> dependencies,
virtual ORenderPass createRenderPass(RenderTargetLayout layout, Array<SubPassDependency> dependencies, URect renderArea,
std::string name = "", Array<uint32> viewMasks = {0}, Array<uint32> correlationMasks = {}) = 0;
virtual void beginRenderPass(PRenderPass renderPass) = 0;
virtual void endRenderPass() = 0;
+3 -7
View File
@@ -319,6 +319,7 @@ CommandQueue::CommandQueue(PGraphics graphics) : graphics(graphics) {
MTL::CommandBufferDescriptor* descriptor = MTL::CommandBufferDescriptor::alloc()->init();
descriptor->setErrorOptions(MTL::CommandBufferErrorOptionEncoderExecutionStatus);
activeCommand = new Command(graphics, queue->commandBuffer(descriptor));
activeCommand->begin();
descriptor->release();
}
@@ -353,7 +354,7 @@ void CommandQueue::executeCommands(Array<Gfx::OComputeCommand> commands) {
}
void CommandQueue::submitCommands(PEvent signalSemaphore) {
/*activeCommand->getHandle()->addCompletedHandler(MTL::CommandBufferHandler([&](MTL::CommandBuffer* cmdBuffer) {
activeCommand->getHandle()->addCompletedHandler(MTL::CommandBufferHandler([&](MTL::CommandBuffer* cmdBuffer) {
for (auto it = pendingCommands.begin(); it != pendingCommands.end(); it++) {
if ((*it)->getHandle() == cmdBuffer) {
auto& cmd = *it;
@@ -380,12 +381,7 @@ void CommandQueue::submitCommands(PEvent signalSemaphore) {
activeCommand->begin();
activeCommand->waitForEvent(prevCmdEvent);
descriptor->release();
}*/
activeCommand->end();
activeCommand->waitDeviceIdle();
activeCommand->reset();
activeCommand = new Command(graphics, queue->commandBuffer());
activeCommand->begin();
}
}
IOCommandQueue::IOCommandQueue(PGraphics graphics) : graphics(graphics) {
+1 -3
View File
@@ -70,9 +70,7 @@ class DescriptorSet : public Gfx::DescriptorSet, public CommandBoundResource {
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::PTexture2D texture) override;
virtual void updateTexture(const std::string& name, uint32 index, Gfx::PTexture3D texture) override;
virtual void updateTexture(const std::string& name, uint32 index, Gfx::PTextureCube texture) 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(); }
+1 -23
View File
@@ -152,29 +152,7 @@ void DescriptorSet::updateSampler(const std::string& name, uint32 index, Gfx::PS
});
}
void DescriptorSet::updateTexture(const std::string& name, uint32 index, Gfx::PTexture2D texture) {
uint32 flattenedIndex = owner->getLayout()->variableMapping[name].index + index;
PTextureBase tex = texture.cast<TextureBase>();
textureWrites.add(TextureWriteInfo{
.index = flattenedIndex,
.texture = tex->getHandle(),
.access = owner->getLayout()->variableMapping[name].access,
});
boundResources.add(tex->getHandle());
}
void DescriptorSet::updateTexture(const std::string& name, uint32 index, Gfx::PTexture3D texture) {
uint32 flattenedIndex = owner->getLayout()->variableMapping[name].index + index;
PTextureBase tex = texture.cast<TextureBase>();
textureWrites.add(TextureWriteInfo{
.index = flattenedIndex,
.texture = tex->getHandle(),
.access = owner->getLayout()->variableMapping[name].access,
});
boundResources.add(tex->getHandle());
}
void DescriptorSet::updateTexture(const std::string& name, uint32 index, Gfx::PTextureCube texture) {
void DescriptorSet::updateTexture(const std::string& name, uint32 index, Gfx::PTexture texture) {
uint32 flattenedIndex = owner->getLayout()->variableMapping[name].index + index;
PTextureBase tex = texture.cast<TextureBase>();
textureWrites.add(TextureWriteInfo{
+1 -2
View File
@@ -17,8 +17,7 @@ class Graphics : public Gfx::Graphics {
virtual Gfx::OWindow createWindow(const WindowCreateInfo& createInfo) override;
virtual Gfx::OViewport createViewport(Gfx::PWindow owner, const ViewportCreateInfo& createInfo) override;
virtual Gfx::ORenderPass createRenderPass(Gfx::RenderTargetLayout layout, Array<Gfx::SubPassDependency> dependencies,
Gfx::PViewport renderArea, std::string name = "") override;
virtual Gfx::ORenderPass createRenderPass(Gfx::RenderTargetLayout layout, Array<Gfx::SubPassDependency> dependencies, URect renderArea, std::string name, Array<uint32> viewMasks, Array<uint32> correlationMasks) override;
virtual void beginRenderPass(Gfx::PRenderPass renderPass) override;
virtual void endRenderPass() override;
virtual void waitDeviceIdle() override;
+1 -2
View File
@@ -38,8 +38,7 @@ 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,
Gfx::PViewport renderArea, std::string name) {
Gfx::ORenderPass Graphics::createRenderPass(Gfx::RenderTargetLayout layout, Array<Gfx::SubPassDependency> dependencies, URect renderArea, std::string name, Array<uint32> viewMask, Array<uint32> correlationMask) {
return new RenderPass(this, layout, dependencies, renderArea, name);
}
+2 -2
View File
@@ -7,7 +7,7 @@ namespace Metal {
DECLARE_REF(Graphics)
class RenderPass : public Gfx::RenderPass {
public:
RenderPass(PGraphics graphics, Gfx::RenderTargetLayout layout, Array<Gfx::SubPassDependency> dependencies, Gfx::PViewport viewport,
RenderPass(PGraphics graphics, Gfx::RenderTargetLayout layout, Array<Gfx::SubPassDependency> dependencies, URect viewport,
const std::string& name = "");
virtual ~RenderPass();
void updateRenderPass();
@@ -16,7 +16,7 @@ class RenderPass : public Gfx::RenderPass {
private:
PGraphics graphics;
Gfx::PViewport viewport;
URect renderArea;
MTL::RenderPassDescriptor* renderPass;
std::string name;
};
+4 -5
View File
@@ -8,13 +8,12 @@ using namespace Seele;
using namespace Seele::Metal;
RenderPass::RenderPass(PGraphics graphics, Gfx::RenderTargetLayout _layout, Array<Gfx::SubPassDependency> dependencies,
Gfx::PViewport viewport, const std::string& name)
: Gfx::RenderPass(std::move(_layout), dependencies), graphics(graphics), viewport(viewport), name(name) {
URect renderArea, const std::string& name)
: Gfx::RenderPass(std::move(_layout), dependencies), graphics(graphics), renderArea(renderArea), name(name) {
renderPass = MTL::RenderPassDescriptor::renderPassDescriptor();
renderPass->setRenderTargetArrayLength(1);
renderPass->setRenderTargetWidth(viewport->getWidth());
renderPass->setRenderTargetHeight(viewport->getHeight());
renderPass->setDefaultRasterSampleCount(viewport->getSamples());
renderPass->setRenderTargetWidth(renderArea.size.x);
renderPass->setRenderTargetHeight(renderArea.size.y);
for (size_t i = 0; i < layout.colorAttachments.size(); ++i) {
const auto& color = layout.colorAttachments[i];
+3 -1
View File
@@ -94,7 +94,9 @@ 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() {}
TextureBase::~TextureBase() {
graphics->getDestructionManager()->queueResourceForDestruction(std::move(handle));
}
void TextureBase::pipelineBarrier(Gfx::SeAccessFlags srcAccess, Gfx::SePipelineStageFlags srcStage, Gfx::SeAccessFlags dstAccess,
Gfx::SePipelineStageFlags dstStage) {
+1 -1
View File
@@ -472,7 +472,7 @@ void BasePass::createRenderPass() {
Gfx::SE_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT,
},
};
renderPass = graphics->createRenderPass(std::move(layout), std::move(dependency), "BasePass");
renderPass = graphics->createRenderPass(std::move(layout), std::move(dependency), viewport->getRenderArea(), "BasePass");
oLightIndexList = resources->requestBuffer("LIGHTCULLING_OLIGHTLIST");
tLightIndexList = resources->requestBuffer("LIGHTCULLING_TLIGHTLIST");
oLightGrid = resources->requestTexture("LIGHTCULLING_OLIGHTGRID");
@@ -203,5 +203,5 @@ void CachedDepthPass::createRenderPass() {
Gfx::SE_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT,
},
};
renderPass = graphics->createRenderPass(std::move(layout), std::move(dependency), "CachedDepthPass");
renderPass = graphics->createRenderPass(std::move(layout), std::move(dependency), viewport->getRenderArea(), "CachedDepthPass");
}
@@ -306,5 +306,5 @@ void DepthCullingPass::createRenderPass() {
Gfx::SE_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT,
},
};
renderPass = graphics->createRenderPass(std::move(layout), std::move(dependency), "DepthCullingPass");
renderPass = graphics->createRenderPass(std::move(layout), std::move(dependency), viewport->getRenderArea(), "DepthCullingPass");
}
@@ -216,7 +216,7 @@ void ToneMappingPass::createRenderPass() {
.dstAccess = Gfx::SE_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,
},
};
renderPass = graphics->createRenderPass(targetLayout, dependency, "ToneMappingPass");
renderPass = graphics->createRenderPass(targetLayout, dependency, viewport->getRenderArea(), "ToneMappingPass");
pipeline = graphics->createGraphicsPipeline(Gfx::LegacyPipelineCreateInfo{
.vertexShader = vert,
.fragmentShader = frag,
+1 -1
View File
@@ -170,7 +170,7 @@ void UIPass::createRenderPass() {
Gfx::SE_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT,
},
};
renderPass = graphics->createRenderPass(std::move(layout), dependency, "TextPass");
renderPass = graphics->createRenderPass(std::move(layout), dependency, viewport->getRenderArea(), "TextPass");
graphics->beginShaderCompilation(ShaderCompilationInfo{
.name = "TextVertex",
+8 -2
View File
@@ -140,11 +140,16 @@ void VertexData::createDescriptors() {
void VertexData::loadMesh(MeshId id, Array<uint32> loadedIndices, Array<Meshlet> loadedMeshlets) {
std::unique_lock l(vertexDataLock);
for (auto&& chunk : loadedMeshlets | std::views::chunk(2048)) {
uint32 numChunks = (loadedMeshlets.size() + 2047) / 2048;
for(uint32 chunkIdx = 0; chunkIdx < numChunks; ++chunkIdx)
{
uint32 meshletOffset = (uint32)meshlets.size();
AABB meshAABB;
uint32 numMeshlets = 0;
for (auto&& m : chunk) {
uint32 chunkOffset = chunkIdx * 2048;
uint32 numRemaining = loadedMeshlets.size() - chunkOffset;
for (uint32 chunk = 0; chunk < std::min(numRemaining, 2048u); chunk++) {
Meshlet& m = loadedMeshlets[chunkOffset + chunk];
numMeshlets++;
//...
meshAABB = meshAABB.combine(m.boundingBox);
@@ -169,6 +174,7 @@ void VertexData::loadMesh(MeshId id, Array<uint32> loadedIndices, Array<Meshlet>
.numMeshlets = numMeshlets,
.meshletOffset = meshletOffset,
});
}
// todo: in case of a index split for 16 bit, do something here
meshData[id][0].firstIndex = (uint32)indices.size();
+2 -1
View File
@@ -171,8 +171,9 @@ Gfx::OViewport Graphics::createViewport(Gfx::PWindow owner, const ViewportCreate
return new Viewport(owner, viewportInfo);
}
Gfx::ORenderPass Graphics::createRenderPass(Gfx::RenderTargetLayout layout, Array<Gfx::SubPassDependency> dependencies, std::string name,
Gfx::ORenderPass Graphics::createRenderPass(Gfx::RenderTargetLayout layout, Array<Gfx::SubPassDependency> dependencies, URect renderArea, std::string name,
Array<uint32> viewMasks, Array<uint32> correlationMasks) {
// todo: re-introduce render area to renderpass
return new RenderPass(this, std::move(layout), std::move(dependencies), name, std::move(viewMasks), std::move(correlationMasks));
}
void Graphics::beginRenderPass(Gfx::PRenderPass renderPass) {
+1 -1
View File
@@ -34,7 +34,7 @@ class Graphics : public Gfx::Graphics {
virtual Gfx::OWindow createWindow(const WindowCreateInfo& createInfo) override;
virtual Gfx::OViewport createViewport(Gfx::PWindow owner, const ViewportCreateInfo& createInfo) override;
virtual Gfx::ORenderPass createRenderPass(Gfx::RenderTargetLayout layout, Array<Gfx::SubPassDependency> dependencies, std::string name,
virtual Gfx::ORenderPass createRenderPass(Gfx::RenderTargetLayout layout, Array<Gfx::SubPassDependency> dependencies, URect renderArea, std::string name,
Array<uint32> viewMasks, Array<uint32> correlationMasks) override;
virtual void beginRenderPass(Gfx::PRenderPass renderPass) override;
virtual void endRenderPass() override;
+3 -1
View File
@@ -170,7 +170,9 @@ void Material::compile() {
for (const auto& expr : codeExpressions) {
codeStream << "\t\t" << expr->evaluate(varState);
}
for (const auto& [name, exp] : brdf.variables) {
//for (const auto& [name, exp] : brdf.variables) {
for(auto it = brdf.variables.begin(); it != brdf.variables.end(); ++it){
auto [name, exp] = *it;
codeStream << "\t\tresult." << name << " = " << varState[exp] << ";" << std::endl;
}
codeStream << "\t\tresult.transformNormal(input.tangentToWorld);" << std::endl;
+4 -1
View File
@@ -1,8 +1,10 @@
#include "GameInterface.h"
#include "dlfcn.h"
#include <filesystem>
using namespace Seele;
GameInterface::GameInterface(std::string soPath) : lib(NULL), soPath(soPath) {}
GameInterface::GameInterface(std::filesystem::path soPath) : lib(NULL), soPath(soPath) {}
GameInterface::~GameInterface() {}
@@ -13,6 +15,7 @@ void GameInterface::reload() {
destroyInstance(game);
dlclose(lib);
}
std::filesystem::copy(soPath.parent_path().parent_path() / "res" / "shaders", "shaders/game", std::filesystem::copy_options::overwrite_existing);
lib = dlopen(soPath.c_str(), RTLD_NOW);
createInstance = (decltype(createInstance))dlsym(lib, "createInstance");
destroyInstance = (decltype(destroyInstance))dlsym(lib, "destroyInstance");
+3 -3
View File
@@ -1,18 +1,18 @@
#pragma once
#include "Game.h"
#include "dlfcn.h"
#include <filesystem>
namespace Seele {
class GameInterface {
public:
GameInterface(std::string soPath);
GameInterface(std::filesystem::path soPath);
~GameInterface();
Game* getGame();
void reload();
private:
void* lib;
std::string soPath;
std::filesystem::path soPath;
Game* game;
Game* (*createInstance)() = nullptr;
void (*destroyInstance)(Game*) = nullptr;