diff --git a/.clangd b/.clangd new file mode 100644 index 0000000..e69de29 diff --git a/.vscode/settings.json b/.vscode/settings.json index fd5e29f..6b827b4 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -164,4 +164,5 @@ "lldb.showDisassembly": "auto", "lldb.dereferencePointers": true, "lldb.consoleMode": "commands", + "cmake.generator": "Xcode", } \ No newline at end of file diff --git a/CMakeLists.txt b/CMakeLists.txt index 0933451..c7f5cd1 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -127,7 +127,7 @@ target_compile_options(Engine PUBLIC "$<$:-DENABLE_VALIDATION>") target_compile_options(Engine PUBLIC "$<$:-DSEELE_DEBUG>") add_subdirectory(src/) -add_subdirectory(tests/) +#add_subdirectory(tests/) if(WIN32) add_custom_target(dll_copy ALL diff --git a/res/shaders/lib/Scene.slang b/res/shaders/lib/Scene.slang index 67f612d..6b24fe5 100644 --- a/res/shaders/lib/Scene.slang +++ b/res/shaders/lib/Scene.slang @@ -42,6 +42,6 @@ struct Scene StructuredBuffer primitiveIndices; StructuredBuffer vertexIndices; }; - +layout(set=2) ParameterBlock pScene; diff --git a/src/Editor/Asset/MaterialLoader.cpp b/src/Editor/Asset/MaterialLoader.cpp index 30cd3fd..fba508b 100644 --- a/src/Editor/Asset/MaterialLoader.cpp +++ b/src/Editor/Asset/MaterialLoader.cpp @@ -47,7 +47,7 @@ void MaterialLoader::import(MaterialImportArgs args, PMaterialAsset asset) json j; jsonstream >> j; std::string materialName = j["name"].get() + "Material"; - Gfx::ODescriptorLayout layout = graphics->createDescriptorLayout(materialName + "Layout"); + Gfx::ODescriptorLayout layout = graphics->createDescriptorLayout("pMaterial"); //Shader file needs to conform to the slang standard, which prohibits _ materialName.erase(std::remove(materialName.begin(), materialName.end(), '_'), materialName.end()); materialName.erase(std::remove(materialName.begin(), materialName.end(), '-'), materialName.end()); diff --git a/src/Editor/Asset/TextureLoader.cpp b/src/Editor/Asset/TextureLoader.cpp index 9e43d5f..808a378 100644 --- a/src/Editor/Asset/TextureLoader.cpp +++ b/src/Editor/Asset/TextureLoader.cpp @@ -160,4 +160,4 @@ void TextureLoader::import(TextureImportArgs args, PTextureAsset textureAsset) ////co_return; -} \ No newline at end of file +} diff --git a/src/Editor/main.cpp b/src/Editor/main.cpp index 8f35875..6509399 100644 --- a/src/Editor/main.cpp +++ b/src/Editor/main.cpp @@ -271,4 +271,4 @@ int main() { #endif } return 0; -} \ No newline at end of file +} diff --git a/src/Engine/Graphics/Descriptor.cpp b/src/Engine/Graphics/Descriptor.cpp index ce80d03..f280ec7 100644 --- a/src/Engine/Graphics/Descriptor.cpp +++ b/src/Engine/Graphics/Descriptor.cpp @@ -3,7 +3,7 @@ using namespace Seele; using namespace Seele::Gfx; -DescriptorLayout::DescriptorLayout(const std::string& name) : setIndex(0), name(name) {} +DescriptorLayout::DescriptorLayout(const std::string& name) : name(name) {} DescriptorLayout::DescriptorLayout(const DescriptorLayout& other) { descriptorBindings.resize(other.descriptorBindings.size()); @@ -62,12 +62,20 @@ PipelineLayout::PipelineLayout(PPipelineLayout baseLayout) { PipelineLayout::~PipelineLayout() {} -void PipelineLayout::addDescriptorLayout(uint32 setIndex, PDescriptorLayout layout) { - if (descriptorSetLayouts.size() <= setIndex) { - descriptorSetLayouts.resize(setIndex + 1); - } - descriptorSetLayouts[setIndex] = layout; - layout->setIndex = setIndex; +void PipelineLayout::addDescriptorLayout(PDescriptorLayout layout) { + descriptorSetLayouts[layout->getName()] = layout; } void PipelineLayout::addPushConstants(const SePushConstantRange& pushConstant) { pushConstants.add(pushConstant); } + +void PipelineLayout::addMapping(Map mapping) +{ + for(const auto& [name, index] : mapping) + { + if(parameterMapping.contains(name)) + { + assert(parameterMapping[name] == index); + } + parameterMapping[name] = index; + } +} diff --git a/src/Engine/Graphics/Descriptor.h b/src/Engine/Graphics/Descriptor.h index dc9689b..584e146 100644 --- a/src/Engine/Graphics/Descriptor.h +++ b/src/Engine/Graphics/Descriptor.h @@ -31,14 +31,12 @@ public: PDescriptorSet allocateDescriptorSet(); virtual void create() = 0; constexpr const Array& getBindings() const { return descriptorBindings; } - constexpr uint32 getSetIndex() const { return setIndex; } - constexpr void setSetIndex(uint32 _setIndex) { setIndex = _setIndex; } constexpr uint32 getHash() const { return hash; } + constexpr const std::string& getName() const { return name; } protected: Array descriptorBindings; ODescriptorPool pool; - uint32 setIndex; std::string name; uint32 hash = 0; friend class PipelineLayout; @@ -71,7 +69,7 @@ public: virtual void updateTextureArray(uint32_t binding, Array texture) = 0; bool operator<(PDescriptorSet other); - constexpr uint32 getSetIndex() const { return layout->getSetIndex(); } + constexpr PDescriptorLayout getLayout() const { return layout; } protected: PDescriptorLayout layout; @@ -84,13 +82,17 @@ public: PipelineLayout(PPipelineLayout baseLayout); virtual ~PipelineLayout(); virtual void create() = 0; - void addDescriptorLayout(uint32 setIndex, PDescriptorLayout layout); + void addDescriptorLayout(PDescriptorLayout layout); void addPushConstants(const SePushConstantRange& pushConstants); constexpr uint32 getHash() const { return layoutHash; } - + constexpr const Map& getLayouts() const { return descriptorSetLayouts; } + constexpr uint32 findParameter(const std::string& name) const { return parameterMapping[name]; } + void addMapping(Map mapping); + protected: uint32 layoutHash = 0; - Array descriptorSetLayouts; + Map descriptorSetLayouts; + Map parameterMapping; Array pushConstants; }; DEFINE_REF(PipelineLayout) diff --git a/src/Engine/Graphics/Initializer.h b/src/Engine/Graphics/Initializer.h index e1c23c6..e7cbb6a 100644 --- a/src/Engine/Graphics/Initializer.h +++ b/src/Engine/Graphics/Initializer.h @@ -115,6 +115,7 @@ struct ShaderBufferCreateInfo uint8 dynamic = 0; std::string name; }; +DECLARE_NAME_REF(Gfx, PipelineLayout) struct ShaderCreateInfo { std::string mainModule; @@ -123,6 +124,7 @@ struct ShaderCreateInfo std::string entryPoint; Array> typeParameter; Map defines; + Gfx::PPipelineLayout rootSignature; }; struct VertexInputBinding { @@ -218,7 +220,7 @@ struct LegacyPipelineCreateInfo PVertexShader vertexShader; PFragmentShader fragmentShader; PRenderPass renderPass; - OPipelineLayout pipelineLayout; + PPipelineLayout pipelineLayout; MultisampleState multisampleState; RasterizationState rasterizationState; DepthStencilState depthStencilState; @@ -235,7 +237,7 @@ struct MeshPipelineCreateInfo PMeshShader meshShader; PFragmentShader fragmentShader; PRenderPass renderPass; - OPipelineLayout pipelineLayout; + PPipelineLayout pipelineLayout; MultisampleState multisampleState; RasterizationState rasterizationState; DepthStencilState depthStencilState; @@ -248,11 +250,11 @@ struct MeshPipelineCreateInfo struct ComputePipelineCreateInfo { Gfx::PComputeShader computeShader; - Gfx::OPipelineLayout pipelineLayout; + Gfx::PPipelineLayout pipelineLayout; ComputePipelineCreateInfo(); ComputePipelineCreateInfo(ComputePipelineCreateInfo&& rhs) = default; ComputePipelineCreateInfo& operator=(ComputePipelineCreateInfo&& rhs) = default; ~ComputePipelineCreateInfo(); }; } // namespace Gfx -} // namespace Seele \ No newline at end of file +} // namespace Seele diff --git a/src/Engine/Graphics/Metal/Command.h b/src/Engine/Graphics/Metal/Command.h index c3e94f2..2b43807 100644 --- a/src/Engine/Graphics/Metal/Command.h +++ b/src/Engine/Graphics/Metal/Command.h @@ -2,6 +2,7 @@ #include "Buffer.h" #include "Graphics/Command.h" #include "Metal/MTLBlitCommandEncoder.hpp" +#include "Metal/MTLCaptureManager.hpp" #include "Metal/MTLCommandBuffer.hpp" #include "Metal/MTLComputeCommandEncoder.hpp" #include "Metal/MTLRenderCommandEncoder.hpp" @@ -16,6 +17,7 @@ DECLARE_REF(RenderCommand) DECLARE_REF(Graphics) DECLARE_REF(IndexBuffer) DECLARE_REF(GraphicsPipeline) +DECLARE_REF(ComputePipeline) class Command { public: Command(PGraphics graphics, MTL::CommandBuffer* cmdBuffer); @@ -85,6 +87,7 @@ public: virtual void dispatch(uint32 threadX, uint32 threadY, uint32 threadZ) override; private: + PComputePipeline boundPipeline; MTL::CommandBuffer* commandBuffer; MTL::ComputeCommandEncoder* encoder; std::string name; @@ -123,4 +126,4 @@ private: }; DEFINE_REF(IOCommandQueue) } // namespace Metal -} // namespace Seele \ No newline at end of file +} // namespace Seele diff --git a/src/Engine/Graphics/Metal/Command.mm b/src/Engine/Graphics/Metal/Command.mm index ffd21e6..cf9d0a4 100644 --- a/src/Engine/Graphics/Metal/Command.mm +++ b/src/Engine/Graphics/Metal/Command.mm @@ -7,6 +7,7 @@ #include "Graphics/Enums.h" #include "Graphics/Graphics.h" #include "Graphics/Resources.h" +#include "Metal/MTLCaptureManager.hpp" #include "Pipeline.h" #include "Resources.h" #include "Window.h" @@ -77,10 +78,11 @@ void RenderCommand::bindPipeline(Gfx::PGraphicsPipeline pipeline) { } void RenderCommand::bindDescriptor(Gfx::PDescriptorSet descriptorSet) { - encoder->setVertexBuffer(descriptorSet.cast()->getBuffer(), 0, descriptorSet->getSetIndex()); - encoder->setFragmentBuffer(descriptorSet.cast()->getBuffer(), 0, descriptorSet->getSetIndex()); - encoder->setMeshBuffer(descriptorSet.cast()->getBuffer(), 0, descriptorSet->getSetIndex()); - encoder->setObjectBuffer(descriptorSet.cast()->getBuffer(), 0, descriptorSet->getSetIndex()); + uint32 parameterIndex = boundPipeline->getPipelineLayout()->findParameter(descriptorSet->getLayout()->getName()); + encoder->setVertexBuffer(descriptorSet.cast()->getBuffer(), 0, parameterIndex); + encoder->setFragmentBuffer(descriptorSet.cast()->getBuffer(), 0, parameterIndex); + encoder->setMeshBuffer(descriptorSet.cast()->getBuffer(), 0, parameterIndex); + encoder->setObjectBuffer(descriptorSet.cast()->getBuffer(), 0, parameterIndex); } void RenderCommand::bindDescriptor(const Array& descriptorSets) { @@ -135,13 +137,44 @@ void ComputeCommand::end() { } void ComputeCommand::bindPipeline(Gfx::PComputePipeline pipeline) { - encoder->setComputePipelineState(pipeline.cast()->getHandle()); + boundPipeline = pipeline.cast(); + encoder->setComputePipelineState(boundPipeline->getHandle()); } void ComputeCommand::bindDescriptor(Gfx::PDescriptorSet set) { auto metalSet = set.cast(); metalSet->bind(); - encoder->setBuffer(metalSet->getBuffer(), 0, set->getSetIndex()); + uint32 parameterIndex = boundPipeline->getPipelineLayout()->findParameter(set->getLayout()->getName()); +encoder->setBuffer(metalSet->getBuffer(), 0, parameterIndex); + auto bindings =metalSet->getLayout()->getBindings(); + for(size_t i = 0; i < bindings.size(); ++i) + { + auto binding = bindings[i]; + if(binding.descriptorType == Gfx::SE_DESCRIPTOR_TYPE_SAMPLER) + { + continue; + } + MTL::ResourceUsage usage; + switch(binding.access) { + case Gfx::SE_DESCRIPTOR_ACCESS_READ_ONLY_BIT: + if(binding.descriptorType == Gfx::SE_DESCRIPTOR_TYPE_SAMPLED_IMAGE) + { + usage = MTL::ResourceUsageSample; + break; + }else + { + usage = MTL::ResourceUsageRead; + break; + } + case Gfx::SE_DESCRIPTOR_ACCESS_READ_WRITE_BIT: + usage = MTL::ResourceUsageRead | MTL::ResourceUsageWrite; + break; + case Gfx::SE_DESCRIPTOR_ACCESS_WRITE_ONLY_BIT: + usage = MTL::ResourceUsageWrite; + break; + } + encoder->useResource(metalSet->getBoundResources()[i], usage); + } } void ComputeCommand::bindDescriptor(const Array& sets) { @@ -157,7 +190,7 @@ void ComputeCommand::pushConstants(Gfx::PPipelineLayout, Gfx::SeShaderStageFlags void ComputeCommand::dispatch(uint32 threadX, uint32 threadY, uint32 threadZ) { // TODO - encoder->dispatchThreadgroups(MTL::Size(threadX, threadY, threadZ), MTL::Size(32, 32, 32)); + encoder->dispatchThreadgroups(MTL::Size(threadX, threadY, threadZ), MTL::Size(32, 32, 1)); } CommandQueue::CommandQueue(PGraphics graphics) : graphics(graphics) { diff --git a/src/Engine/Graphics/Metal/Descriptor.h b/src/Engine/Graphics/Metal/Descriptor.h index ed74601..2c9466f 100644 --- a/src/Engine/Graphics/Metal/Descriptor.h +++ b/src/Engine/Graphics/Metal/Descriptor.h @@ -48,7 +48,6 @@ public: 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 texture); - virtual bool operator<(Gfx::PDescriptorSet other); constexpr bool isCurrentlyBound() const { return bindCount > 0; } constexpr bool isCurrentlyInUse() const { return currentlyInUse; } @@ -58,12 +57,14 @@ public: constexpr void free() { currentlyInUse = false; } constexpr MTL::Buffer* getBuffer() const { return buffer; } + constexpr const Array& getBoundResources() const { return boundResources; } private: PGraphics graphics; PDescriptorPool owner; MTL::Buffer* buffer; MTL::ArgumentEncoder* encoder; + Array boundResources; uint32 bindCount; bool currentlyInUse; }; @@ -80,4 +81,4 @@ private: }; DEFINE_REF(PipelineLayout) } // namespace Metal -} // namespace Seele \ No newline at end of file +} // namespace Seele diff --git a/src/Engine/Graphics/Metal/Descriptor.mm b/src/Engine/Graphics/Metal/Descriptor.mm index 632e0c7..bc8e2f0 100644 --- a/src/Engine/Graphics/Metal/Descriptor.mm +++ b/src/Engine/Graphics/Metal/Descriptor.mm @@ -122,6 +122,7 @@ DescriptorSet::DescriptorSet(PGraphics graphics, PDescriptorPool owner) if (owner->getArguments()->count() == 0) { buffer = graphics->getDevice()->newBuffer(0, MTL::ResourceOptionCPUCacheModeDefault); } else { + boundResources.resize(owner->getArguments()->count()); encoder = graphics->getDevice()->newArgumentEncoder(owner->getArguments()); buffer = graphics->getDevice()->newBuffer(encoder->encodedLength(), MTL::ResourceOptionCPUCacheModeDefault); encoder->setArgumentBuffer(buffer, 0); @@ -135,10 +136,12 @@ void DescriptorSet::writeChanges() {} void DescriptorSet::updateBuffer(uint32_t binding, Gfx::PUniformBuffer uniformBuffer) { PUniformBuffer metalBuffer = uniformBuffer.cast(); encoder->setBuffer(metalBuffer->getHandle(), 0, binding); + boundResources[binding] = metalBuffer->getHandle(); } void DescriptorSet::updateBuffer(uint32_t binding, Gfx::PShaderBuffer uniformBuffer) { PShaderBuffer metalBuffer = uniformBuffer.cast(); encoder->setBuffer(metalBuffer->getHandle(), 0, binding); + boundResources[binding] = metalBuffer->getHandle(); } void DescriptorSet::updateSampler(uint32_t binding, Gfx::PSampler samplerState) { PSampler sampler = samplerState.cast(); @@ -147,30 +150,26 @@ void DescriptorSet::updateSampler(uint32_t binding, Gfx::PSampler samplerState) void DescriptorSet::updateTexture(uint32_t binding, Gfx::PTexture texture, Gfx::PSampler samplerState) { PTextureBase base = texture.cast(); encoder->setTexture(base->getTexture(), binding); - if (samplerState != nullptr) { - PSampler sampler = samplerState.cast(); - encoder->setSamplerState(sampler->getHandle(), binding); - } + boundResources[binding] = base->getTexture(); } void DescriptorSet::updateTextureArray(uint32_t binding, Array array) { for (auto& t : array) { PTextureBase metalTexture = t.cast(); - encoder->setTexture(metalTexture->getTexture(), binding++); + encoder->setTexture(metalTexture->getTexture(), binding); + boundResources[binding++] = metalTexture->getTexture(); } } -bool DescriptorSet::operator<(Gfx::PDescriptorSet other) { return this < other.getHandle(); } - PipelineLayout::PipelineLayout(PGraphics graphics, Gfx::PPipelineLayout baseLayout) : Gfx::PipelineLayout(baseLayout), graphics(graphics) {} PipelineLayout::~PipelineLayout() {} void PipelineLayout::create() { - for (auto& set : descriptorSetLayouts) { + for (auto& [_, set] : descriptorSetLayouts) { set->create(); uint32 setHash = set->getHash(); layoutHash = CRC::Calculate(&setHash, sizeof(uint32), CRC::CRC_32(), layoutHash); } -} \ No newline at end of file +} diff --git a/src/Engine/Graphics/Metal/Pipeline.h b/src/Engine/Graphics/Metal/Pipeline.h index 481b020..e3021ca 100644 --- a/src/Engine/Graphics/Metal/Pipeline.h +++ b/src/Engine/Graphics/Metal/Pipeline.h @@ -15,7 +15,7 @@ DECLARE_REF(PipelineLayout) DECLARE_REF(Graphics) class GraphicsPipeline : public Gfx::GraphicsPipeline { public: - GraphicsPipeline(PGraphics graphics, MTL::PrimitiveType primitive, MTL::RenderPipelineState* pipeline, Gfx::OPipelineLayout createInfo); + GraphicsPipeline(PGraphics graphics, MTL::PrimitiveType primitive, MTL::RenderPipelineState* pipeline, Gfx::PPipelineLayout createInfo); virtual ~GraphicsPipeline(); constexpr MTL::RenderPipelineState* getHandle() const { return state; } constexpr MTL::PrimitiveType getPrimitive() const { return primitiveType; } @@ -27,7 +27,7 @@ private: DEFINE_REF(GraphicsPipeline) class ComputePipeline : public Gfx::ComputePipeline { public: - ComputePipeline(PGraphics graphics, MTL::ComputePipelineState* pipeline, Gfx::OPipelineLayout); + ComputePipeline(PGraphics graphics, MTL::ComputePipelineState* pipeline, Gfx::PPipelineLayout); virtual ~ComputePipeline(); constexpr MTL::ComputePipelineState* getHandle() const { return state; } @@ -37,4 +37,4 @@ private: }; DEFINE_REF(ComputePipeline) } // namespace Metal -} // namespace Seele \ No newline at end of file +} // namespace Seele diff --git a/src/Engine/Graphics/Metal/Pipeline.mm b/src/Engine/Graphics/Metal/Pipeline.mm index 0fcaf0d..9bbbaf1 100644 --- a/src/Engine/Graphics/Metal/Pipeline.mm +++ b/src/Engine/Graphics/Metal/Pipeline.mm @@ -12,13 +12,13 @@ VertexInput::VertexInput(VertexInputStateCreateInfo createInfo) : Gfx::VertexInp VertexInput::~VertexInput() {} GraphicsPipeline::GraphicsPipeline(PGraphics graphics, MTL::PrimitiveType primitive, MTL::RenderPipelineState* pipeline, - Gfx::OPipelineLayout createInfo) - : Gfx::GraphicsPipeline(std::move(createInfo)), graphics(graphics), state(pipeline), primitiveType(primitive) {} + Gfx::PPipelineLayout layout) + : Gfx::GraphicsPipeline(layout), graphics(graphics), state(pipeline), primitiveType(primitive) {} GraphicsPipeline::~GraphicsPipeline() {} ComputePipeline::ComputePipeline(PGraphics graphics, MTL::ComputePipelineState* pipeline, - Gfx::OPipelineLayout createInfo) - : Gfx::ComputePipeline(std::move(createInfo)), graphics(graphics), state(pipeline) {} + Gfx::PPipelineLayout layout) + : Gfx::ComputePipeline(layout), graphics(graphics), state(pipeline) {} ComputePipeline::~ComputePipeline() {} diff --git a/src/Engine/Graphics/Metal/Shader.mm b/src/Engine/Graphics/Metal/Shader.mm index 10baa03..efa18da 100644 --- a/src/Engine/Graphics/Metal/Shader.mm +++ b/src/Engine/Graphics/Metal/Shader.mm @@ -6,6 +6,7 @@ #include "Graphics/slang-compile.h" #include "Metal/MTLDevice.hpp" #include "Metal/MTLLibrary.hpp" +#include "Descriptor.h" #include #include #include @@ -24,16 +25,75 @@ Shader::~Shader() { } void Shader::create(const ShaderCreateInfo& createInfo) { - Slang::ComPtr kernelBlob = generateShader(createInfo, SLANG_DXIL); - + Map test; + Slang::ComPtr kernelBlob = generateShader(createInfo, SLANG_DXIL, test); hash = CRC::Calculate(kernelBlob->getBufferPointer(), kernelBlob->getBufferSize(), CRC::CRC_32()); IRCompiler* pCompiler = IRCompilerCreate(); + IRCompilerSetMinimumGPUFamily(pCompiler, IRGPUFamilyMetal3); + IRCompilerIgnoreRootSignature(pCompiler, true); IRCompilerSetEntryPointName(pCompiler, "main"); IRObject* pDXIL = IRObjectCreateFromDXIL((const uint8*)kernelBlob->getBufferPointer(), kernelBlob->getBufferSize(), IRBytecodeOwnershipNone); - - // Compile DXIL to Metal IR: + IRVersionedRootSignatureDescriptor descriptor; + descriptor.version = IRRootSignatureVersion_1_1; + Map layouts =createInfo.rootSignature->getLayouts(); + descriptor.desc_1_1.NumParameters = layouts.size(); + descriptor.desc_1_1.NumStaticSamplers = 0; + descriptor.desc_1_1.pStaticSamplers = nullptr; + Array parameters; + // each layout has an array for its bindings + Array> ranges; + for(const auto& [name, layout] : layouts) + { + uint32 textureReg = 0; // SRV + uint32 samplerReg = 0; // Sampler + uint32 uavReg = 0; // UAV + uint32 constantReg = 0; // CBV + auto& bindingRanges = ranges.add(); + for(auto binding : layout->getBindings()) + { + IRDescriptorRangeType type; + uint32 reg = 0; + switch(binding.descriptorType) + { + case Gfx::SE_DESCRIPTOR_TYPE_SAMPLED_IMAGE: + case Gfx::SE_DESCRIPTOR_TYPE_STORAGE_BUFFER: + type = IRDescriptorRangeTypeSRV; + reg = textureReg++; + break; + case Gfx::SE_DESCRIPTOR_TYPE_UNIFORM_BUFFER: + case Gfx::SE_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER: + type = IRDescriptorRangeTypeCBV; + reg = constantReg++; + break; + case Gfx::SE_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER: + case Gfx::SE_DESCRIPTOR_TYPE_STORAGE_IMAGE: + type = IRDescriptorRangeTypeUAV; + reg = uavReg++; + break; + default: throw std::logic_error("Not implemented"); + }; + bindingRanges.add() = IRDescriptorRange1{ + .BaseShaderRegister = reg, + .NumDescriptors = binding.descriptorCount, + .RangeType = type, + .RegisterSpace = createInfo.rootSignature->findParameter(name), + }; + } + parameters.add() = IRRootParameter1{ + .ParameterType = IRRootParameterTypeDescriptorTable, + .DescriptorTable = IRRootDescriptorTable1{ .NumDescriptorRanges = (uint32)(bindingRanges.size()), bindingRanges.data() }, + .ShaderVisibility = IRShaderVisibilityAll, + }; + } + IRError* signatureError = nullptr; + descriptor.desc_1_1.NumParameters = parameters.size(); + descriptor.desc_1_1.pParameters = parameters.data(); + IRRootSignature* rootSignature = IRRootSignatureCreateFromDescriptor(&descriptor, &signatureError); + assert(rootSignature); + IRCompilerSetGlobalRootSignature(pCompiler, rootSignature); + // Compile DXIL to Metal IR: IRError* pError = nullptr; IRObject* pOutIR = IRCompilerAllocCompileAndLink(pCompiler, NULL, pDXIL, &pError); @@ -63,7 +123,13 @@ void Shader::create(const ShaderCreateInfo& createInfo) { IRMetalLibBinary* pMetallib = IRMetalLibBinaryCreate(); IRObjectGetMetalLibBinary(pOutIR, irStage, pMetallib); dispatch_data_t data = IRMetalLibGetBytecodeData(pMetallib); - + + IRShaderReflection* reflection = IRShaderReflectionCreate(); + IRObjectGetReflection(pOutIR, irStage, reflection); + std::cout << " NumRes: " << IRShaderReflectionGetResourceCount(reflection) << std::endl; + std::cout << IRShaderReflectionAllocStringAndSerialize(reflection) << std::endl; + IRShaderReflectionDestroy(reflection); + // Store the metallib to custom format or disk, or use to create a MTLLibrary. NS::Error* error; library = graphics->getDevice()->newLibrary(data, &error); @@ -78,4 +144,4 @@ void Shader::create(const ShaderCreateInfo& createInfo) { IRCompilerDestroy(pCompiler); } -uint32 Shader::getShaderHash() const { return hash; } \ No newline at end of file +uint32 Shader::getShaderHash() const { return hash; } diff --git a/src/Engine/Graphics/Metal/Texture.mm b/src/Engine/Graphics/Metal/Texture.mm index 4161446..c80a261 100644 --- a/src/Engine/Graphics/Metal/Texture.mm +++ b/src/Engine/Graphics/Metal/Texture.mm @@ -45,11 +45,11 @@ TextureBase::TextureBase(PGraphics graphics, MTL::TextureType type, descriptor->release(); } - if(createInfo.sourceData.data != nullptr) - { - MTL::Region region(0, 0, 0, width, height, depth); - texture->replaceRegion(region, 0, createInfo.sourceData.data, createInfo.sourceData.size / (depth / height)); - } +// if(createInfo.sourceData.data != nullptr) +// { +// MTL::Region region(0, 0, 0, width, height, depth); +// texture->replaceRegion(region, 0, createInfo.sourceData.data, createInfo.sourceData.size / (depth * height)); +// } } TextureBase::~TextureBase() { diff --git a/src/Engine/Graphics/Metal/Window.h b/src/Engine/Graphics/Metal/Window.h index 42c18d6..423faa2 100644 --- a/src/Engine/Graphics/Metal/Window.h +++ b/src/Engine/Graphics/Metal/Window.h @@ -51,6 +51,7 @@ private: CAMetalLayer* metalLayer; CA::MetalDrawable* drawable; OTexture2D backBuffer; + MTL::CaptureDescriptor* capture = nullptr; std::function keyCallback; std::function mouseMoveCallback; diff --git a/src/Engine/Graphics/Metal/Window.mm b/src/Engine/Graphics/Metal/Window.mm index e543b92..f05fd13 100644 --- a/src/Engine/Graphics/Metal/Window.mm +++ b/src/Engine/Graphics/Metal/Window.mm @@ -1,11 +1,15 @@ #include "Window.h" #include "Command.h" #include "Foundation/NSAutoreleasePool.hpp" +#include "Foundation/NSString.hpp" +#include "Graphics/Enums.h" #include "Graphics/Initializer.h" #include "Graphics/Metal/Enums.h" #include "Graphics/Texture.h" +#include "Metal/MTLCaptureManager.hpp" #include "Metal/MTLTexture.hpp" #include +#include #include using namespace Seele; @@ -13,6 +17,8 @@ using namespace Seele::Metal; double currentFrameDelta = 0; double Gfx::getCurrentFrameDelta() { return currentFrameDelta; } +uint32 currentFrameIndex = 0; +uint32 Gfx::getCurrentFrameIndex() { return currentFrameIndex; } void glfwKeyCallback(GLFWwindow* handle, int key, int, int action, int modifier) { if (key == -1) { @@ -88,6 +94,17 @@ Window::~Window() { glfwDestroyWindow(static_cast(windowHandle)); } void Window::pollInput() { glfwPollEvents(); } void Window::beginFrame() { + auto captureManager = MTL::CaptureManager::sharedCaptureManager(); + capture = MTL::CaptureDescriptor::alloc()->init(); + capture->setCaptureObject((__bridge id)graphics->getDevice()); + capture->setDestination(MTL::CaptureDestinationDeveloperTools); + capture->setOutputURL(NS::URL::fileURLWithPath(NS::String::string(fmt::format("frame{0}.trace", Gfx::getCurrentFrameIndex()).c_str(), NS::ASCIIStringEncoding))); + NS::Error* error; + captureManager->startCapture(capture, &error); + if(error) + { + std::cout << error->localizedDescription()->cString(NS::ASCIIStringEncoding) << std::endl; + } drawable = (__bridge CA::MetalDrawable*)[metalLayer nextDrawable]; createBackBuffer(); } @@ -95,6 +112,8 @@ void Window::beginFrame() { void Window::endFrame() { graphics->getQueue()->getCommands()->present(drawable); graphics->getQueue()->submitCommands(); + MTL::CaptureManager::sharedCaptureManager()->stopCapture(); + currentFrameIndex++; } void Window::onWindowCloseEvent() {} diff --git a/src/Engine/Graphics/Pipeline.cpp b/src/Engine/Graphics/Pipeline.cpp index 7004836..e8a0728 100644 --- a/src/Engine/Graphics/Pipeline.cpp +++ b/src/Engine/Graphics/Pipeline.cpp @@ -12,8 +12,8 @@ VertexInput::~VertexInput() { } -GraphicsPipeline::GraphicsPipeline(OPipelineLayout layout) - : layout(std::move(layout)) +GraphicsPipeline::GraphicsPipeline(PPipelineLayout layout) + : layout(layout) { } @@ -26,8 +26,8 @@ PPipelineLayout GraphicsPipeline::getPipelineLayout() const return layout; } -ComputePipeline::ComputePipeline(OPipelineLayout layout) - : layout(std::move(layout)) +ComputePipeline::ComputePipeline(PPipelineLayout layout) + : layout(layout) { } diff --git a/src/Engine/Graphics/Pipeline.h b/src/Engine/Graphics/Pipeline.h index 56f9c2a..cbd3165 100644 --- a/src/Engine/Graphics/Pipeline.h +++ b/src/Engine/Graphics/Pipeline.h @@ -18,23 +18,23 @@ private: class GraphicsPipeline { public: - GraphicsPipeline(OPipelineLayout layout); + GraphicsPipeline(PPipelineLayout layout); virtual ~GraphicsPipeline(); PPipelineLayout getPipelineLayout() const; protected: - OPipelineLayout layout; + PPipelineLayout layout; }; DEFINE_REF(GraphicsPipeline) class ComputePipeline { public: - ComputePipeline(OPipelineLayout layout); + ComputePipeline(PPipelineLayout layout); virtual ~ComputePipeline(); PPipelineLayout getPipelineLayout() const; protected: - OPipelineLayout layout; + PPipelineLayout layout; }; DEFINE_REF(ComputePipeline) } -} \ No newline at end of file +} diff --git a/src/Engine/Graphics/RenderPass/BasePass.cpp b/src/Engine/Graphics/RenderPass/BasePass.cpp index 4aad58e..f6b1310 100644 --- a/src/Engine/Graphics/RenderPass/BasePass.cpp +++ b/src/Engine/Graphics/RenderPass/BasePass.cpp @@ -19,14 +19,6 @@ BasePass::BasePass(Gfx::PGraphics graphics, PScene scene) : RenderPass(graphics, scene) , descriptorSets(6) { - if (graphics->supportMeshShading()) - { - graphics->getShaderCompiler()->registerRenderPass("BasePass", "MeshletBasePass", true, true, "BasePass", true, true, "MeshletBasePass"); - } - else - { - graphics->getShaderCompiler()->registerRenderPass("BasePass", "LegacyBasePass", true, true, "BasePass"); - } } BasePass::~BasePass() @@ -100,11 +92,6 @@ void BasePass::render() Gfx::ORenderCommand command = graphics->createRenderCommand("BaseRender"); command->setViewport(viewport); - Gfx::OPipelineLayout layout = graphics->createPipelineLayout(basePassLayout); - layout->addDescriptorLayout(INDEX_MATERIAL, materialData.material->getDescriptorLayout()); - layout->addDescriptorLayout(INDEX_VERTEX_DATA, vertexData->getVertexDataLayout()); - layout->addDescriptorLayout(INDEX_SCENE_DATA, vertexData->getInstanceDataLayout()); - layout->create(); const Gfx::ShaderCollection* collection = graphics->getShaderCompiler()->findShaders(id); assert(collection != nullptr); @@ -114,7 +101,7 @@ void BasePass::render() pipelineInfo.taskShader = collection->taskShader; pipelineInfo.meshShader = collection->meshShader; pipelineInfo.fragmentShader = collection->fragmentShader; - pipelineInfo.pipelineLayout = std::move(layout); + pipelineInfo.pipelineLayout = collection->pipelineLayout; pipelineInfo.renderPass = renderPass; pipelineInfo.depthStencilState.depthCompareOp = Gfx::SE_COMPARE_OP_LESS_OR_EQUAL; pipelineInfo.multisampleState.samples = viewport->getSamples(); @@ -127,7 +114,7 @@ void BasePass::render() Gfx::LegacyPipelineCreateInfo pipelineInfo; pipelineInfo.vertexShader = collection->vertexShader; pipelineInfo.fragmentShader = collection->fragmentShader; - pipelineInfo.pipelineLayout = std::move(layout); + pipelineInfo.pipelineLayout = collection->pipelineLayout; pipelineInfo.renderPass = renderPass; pipelineInfo.depthStencilState.depthCompareOp = Gfx::SE_COMPARE_OP_LESS_OR_EQUAL; pipelineInfo.multisampleState.samples = viewport->getSamples(); @@ -174,21 +161,30 @@ void BasePass::publishOutputs() { basePassLayout = graphics->createPipelineLayout(); - basePassLayout->addDescriptorLayout(INDEX_VIEW_PARAMS, viewParamsLayout); - basePassLayout->addDescriptorLayout(INDEX_LIGHT_ENV, scene->getLightEnvironment()->getDescriptorLayout()); + basePassLayout->addDescriptorLayout(viewParamsLayout); + basePassLayout->addDescriptorLayout(scene->getLightEnvironment()->getDescriptorLayout()); - lightCullingLayout = graphics->createDescriptorLayout("BasePassLightCulling"); + lightCullingLayout = graphics->createDescriptorLayout("pLightCullingData"); // oLightIndexList lightCullingLayout->addDescriptorBinding(0, Gfx::SE_DESCRIPTOR_TYPE_STORAGE_BUFFER); // oLightGrid lightCullingLayout->addDescriptorBinding(1, Gfx::SE_DESCRIPTOR_TYPE_STORAGE_IMAGE); lightCullingLayout->create(); - basePassLayout->addDescriptorLayout(INDEX_LIGHT_CULLING, lightCullingLayout); + basePassLayout->addDescriptorLayout(lightCullingLayout); colorAttachment = Gfx::RenderTargetAttachment(viewport, Gfx::SE_IMAGE_LAYOUT_UNDEFINED, Gfx::SE_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, Gfx::SE_ATTACHMENT_LOAD_OP_CLEAR, Gfx::SE_ATTACHMENT_STORE_OP_STORE); resources->registerRenderPassOutput("BASEPASS_COLOR", colorAttachment); + + if (graphics->supportMeshShading()) + { + graphics->getShaderCompiler()->registerRenderPass(basePassLayout, "BasePass", "MeshletBasePass", true, true, "BasePass", true, true, "MeshletBasePass"); + } + else + { + graphics->getShaderCompiler()->registerRenderPass(basePassLayout, "BasePass", "LegacyBasePass", true, true, "BasePass"); + } } void BasePass::createRenderPass() diff --git a/src/Engine/Graphics/RenderPass/DebugPass.cpp b/src/Engine/Graphics/RenderPass/DebugPass.cpp index 9fa9692..627bfbe 100644 --- a/src/Engine/Graphics/RenderPass/DebugPass.cpp +++ b/src/Engine/Graphics/RenderPass/DebugPass.cpp @@ -119,8 +119,8 @@ void DebugPass::createRenderPass() }; renderPass = graphics->createRenderPass(std::move(layout), dependency, viewport); - Gfx::OPipelineLayout pipelineLayout = graphics->createPipelineLayout(); - pipelineLayout->addDescriptorLayout(0, viewParamsLayout); + pipelineLayout = graphics->createPipelineLayout(); + pipelineLayout->addDescriptorLayout(viewParamsLayout); pipelineLayout->create(); ShaderCreateInfo createInfo = { diff --git a/src/Engine/Graphics/RenderPass/DebugPass.h b/src/Engine/Graphics/RenderPass/DebugPass.h index 3ae78fe..9cf11e8 100644 --- a/src/Engine/Graphics/RenderPass/DebugPass.h +++ b/src/Engine/Graphics/RenderPass/DebugPass.h @@ -27,6 +27,7 @@ private: Gfx::OVertexShader vertexShader; Gfx::OFragmentShader fragmentShader; Gfx::PGraphicsPipeline pipeline; + Gfx::OPipelineLayout pipelineLayout; }; DEFINE_REF(DebugPass) } // namespace Seele diff --git a/src/Engine/Graphics/RenderPass/DepthPrepass.cpp b/src/Engine/Graphics/RenderPass/DepthPrepass.cpp index d2a00c6..1ab6bba 100644 --- a/src/Engine/Graphics/RenderPass/DepthPrepass.cpp +++ b/src/Engine/Graphics/RenderPass/DepthPrepass.cpp @@ -17,14 +17,14 @@ DepthPrepass::DepthPrepass(Gfx::PGraphics graphics, PScene scene) , descriptorSets(3) { depthPrepassLayout = graphics->createPipelineLayout(); - depthPrepassLayout->addDescriptorLayout(INDEX_VIEW_PARAMS, viewParamsLayout); + depthPrepassLayout->addDescriptorLayout(viewParamsLayout); if (graphics->supportMeshShading()) { - graphics->getShaderCompiler()->registerRenderPass("DepthPass", "MeshletBasePass", false, false, "", true, true, "MeshletBasePass"); + graphics->getShaderCompiler()->registerRenderPass(depthPrepassLayout, "DepthPass", "MeshletBasePass", false, false, "", true, true, "MeshletBasePass"); } else { - graphics->getShaderCompiler()->registerRenderPass("DepthPass", "LegacyBasePass"); + graphics->getShaderCompiler()->registerRenderPass(depthPrepassLayout, "DepthPass", "LegacyBasePass"); } } @@ -68,12 +68,7 @@ void DepthPrepass::render() Gfx::ORenderCommand command = graphics->createRenderCommand("DepthRender"); command->setViewport(viewport); - Gfx::OPipelineLayout layout = graphics->createPipelineLayout(depthPrepassLayout); - //layout->addDescriptorLayout(INDEX_MATERIAL, materialData.material->getDescriptorLayout()); - layout->addDescriptorLayout(INDEX_VERTEX_DATA, vertexData->getVertexDataLayout()); - layout->addDescriptorLayout(INDEX_SCENE_DATA, vertexData->getInstanceDataLayout()); - layout->create(); - + const Gfx::ShaderCollection* collection = graphics->getShaderCompiler()->findShaders(id); assert(collection != nullptr); if(graphics->supportMeshShading()) @@ -82,7 +77,7 @@ void DepthPrepass::render() pipelineInfo.taskShader = collection->taskShader; pipelineInfo.meshShader = collection->meshShader; pipelineInfo.fragmentShader = collection->fragmentShader; - pipelineInfo.pipelineLayout = std::move(layout); + pipelineInfo.pipelineLayout = collection->pipelineLayout; pipelineInfo.renderPass = renderPass; pipelineInfo.depthStencilState.depthCompareOp = Gfx::SE_COMPARE_OP_LESS; pipelineInfo.multisampleState.samples = viewport->getSamples(); @@ -94,7 +89,7 @@ void DepthPrepass::render() Gfx::LegacyPipelineCreateInfo pipelineInfo; pipelineInfo.vertexShader = collection->vertexShader; pipelineInfo.fragmentShader = collection->fragmentShader; - pipelineInfo.pipelineLayout = std::move(layout); + pipelineInfo.pipelineLayout = collection->pipelineLayout; pipelineInfo.renderPass = renderPass; //pipelineInfo.depthStencilState.depthWriteEnable = false; pipelineInfo.depthStencilState.depthCompareOp = Gfx::SE_COMPARE_OP_LESS_OR_EQUAL; diff --git a/src/Engine/Graphics/RenderPass/LightCullingPass.cpp b/src/Engine/Graphics/RenderPass/LightCullingPass.cpp index 9fae395..5cd121c 100644 --- a/src/Engine/Graphics/RenderPass/LightCullingPass.cpp +++ b/src/Engine/Graphics/RenderPass/LightCullingPass.cpp @@ -97,7 +97,7 @@ void LightCullingPass::publishOutputs() dispatchParamsSet->updateBuffer(1, frustumBuffer); dispatchParamsSet->writeChanges(); - cullingDescriptorLayout = graphics->createDescriptorLayout("CullingLayout"); + cullingDescriptorLayout = graphics->createDescriptorLayout("pCullingParams"); //DepthTexture cullingDescriptorLayout->addDescriptorBinding(0, Gfx::SE_DESCRIPTOR_TYPE_SAMPLED_IMAGE); @@ -116,18 +116,24 @@ void LightCullingPass::publishOutputs() lightEnv = scene->getLightEnvironment(); - Gfx::OPipelineLayout cullingLayout = graphics->createPipelineLayout(); - cullingLayout->addDescriptorLayout(0, viewParamsLayout); - cullingLayout->addDescriptorLayout(1, dispatchParamsLayout); - cullingLayout->addDescriptorLayout(2, cullingDescriptorLayout); - cullingLayout->addDescriptorLayout(3, lightEnv->getDescriptorLayout()); + cullingLayout = graphics->createPipelineLayout(); + cullingLayout->addDescriptorLayout(viewParamsLayout); + cullingLayout->addDescriptorLayout(dispatchParamsLayout); + cullingLayout->addDescriptorLayout(cullingDescriptorLayout); + cullingLayout->addDescriptorLayout(lightEnv->getDescriptorLayout()); + Map mapping; + mapping["pViewParams"] = 0; + mapping["pDispatchParams"] = 1; + cullingLayout->addMapping(mapping); cullingLayout->create(); - ShaderCreateInfo createInfo; - createInfo.name = "Culling"; - createInfo.additionalModules.add("LightCulling"); - createInfo.mainModule = "LightCulling"; - createInfo.entryPoint = "cullLights"; + ShaderCreateInfo createInfo = { + .name = "Culling", + .additionalModules = {"LightCulling"}, + .mainModule = "LightCulling", + .entryPoint = "cullLights", + .rootSignature = cullingLayout, + }; cullingShader = graphics->createComputeShader(createInfo); Gfx::ComputePipelineCreateInfo pipelineInfo; @@ -202,18 +208,25 @@ void LightCullingPass::setupFrustums() dispatchParams.numThreads = numThreads; dispatchParams.numThreadGroups = numThreadGroups; - dispatchParamsLayout = graphics->createDescriptorLayout("FrustumLayout"); + dispatchParamsLayout = graphics->createDescriptorLayout("pDispatchParams"); dispatchParamsLayout->addDescriptorBinding(0, Gfx::SE_DESCRIPTOR_TYPE_UNIFORM_BUFFER); dispatchParamsLayout->addDescriptorBinding(1, Gfx::SE_DESCRIPTOR_TYPE_STORAGE_BUFFER); - Gfx::OPipelineLayout frustumLayout = graphics->createPipelineLayout(); - frustumLayout->addDescriptorLayout(0, viewParamsLayout); - frustumLayout->addDescriptorLayout(1, dispatchParamsLayout); + frustumLayout = graphics->createPipelineLayout(); + frustumLayout->addDescriptorLayout(viewParamsLayout); + frustumLayout->addDescriptorLayout(dispatchParamsLayout); + Map mapping; + mapping["pViewParams"] = 0; + mapping["pDispatchParams"] = 1; + frustumLayout->addMapping(mapping); frustumLayout->create(); - ShaderCreateInfo createInfo; - createInfo.name = "Frustum"; - createInfo.additionalModules.add("ComputeFrustums"); - createInfo.mainModule = "ComputeFrustums"; - createInfo.entryPoint = "computeFrustums"; + ShaderCreateInfo createInfo = { + .name = "Frustum", + .additionalModules = {"ComputeFrustums"}, + .mainModule = "ComputeFrustums", + .entryPoint = "computeFrustums", + .rootSignature = frustumLayout, + }; + std::cout << "Compiling frustumShader" << std::endl; frustumShader = graphics->createComputeShader(createInfo); Gfx::ComputePipelineCreateInfo pipelineInfo; @@ -256,4 +269,4 @@ void LightCullingPass::setupFrustums() graphics->executeCommands(std::move(commands)); frustumBuffer->pipelineBarrier(Gfx::SE_ACCESS_SHADER_WRITE_BIT, Gfx::SE_PIPELINE_STAGE_COMPUTE_SHADER_BIT, Gfx::SE_ACCESS_SHADER_READ_BIT, Gfx::SE_PIPELINE_STAGE_COMPUTE_SHADER_BIT); -} \ No newline at end of file +} diff --git a/src/Engine/Graphics/RenderPass/LightCullingPass.h b/src/Engine/Graphics/RenderPass/LightCullingPass.h index 3415c3c..cce2715 100644 --- a/src/Engine/Graphics/RenderPass/LightCullingPass.h +++ b/src/Engine/Graphics/RenderPass/LightCullingPass.h @@ -49,6 +49,7 @@ private: Gfx::PDescriptorSet dispatchParamsSet; Gfx::OComputeShader frustumShader; Gfx::PComputePipeline frustumPipeline; + Gfx::OPipelineLayout frustumLayout; PLightEnvironment lightEnv; Gfx::PTexture2D depthAttachment; @@ -62,6 +63,7 @@ private: Gfx::ODescriptorLayout cullingDescriptorLayout; Gfx::OComputeShader cullingShader; Gfx::PComputePipeline cullingPipeline; + Gfx::OPipelineLayout cullingLayout; }; DEFINE_REF(LightCullingPass) } // namespace Seele diff --git a/src/Engine/Graphics/RenderPass/RenderPass.cpp b/src/Engine/Graphics/RenderPass/RenderPass.cpp index aae6bd1..c22a002 100644 --- a/src/Engine/Graphics/RenderPass/RenderPass.cpp +++ b/src/Engine/Graphics/RenderPass/RenderPass.cpp @@ -7,7 +7,7 @@ RenderPass::RenderPass(Gfx::PGraphics graphics, PScene scene) , scene(scene) { - viewParamsLayout = graphics->createDescriptorLayout("ViewLayout"); + viewParamsLayout = graphics->createDescriptorLayout("pViewParams"); viewParamsLayout->addDescriptorBinding(0, Gfx::SE_DESCRIPTOR_TYPE_UNIFORM_BUFFER); UniformBufferCreateInfo uniformInitializer = { .sourceData = { @@ -57,4 +57,4 @@ void RenderPass::setViewport(Gfx::PViewport _viewport) { viewport = _viewport; publishOutputs(); -} \ No newline at end of file +} diff --git a/src/Engine/Graphics/RenderPass/SkyboxRenderPass.cpp b/src/Engine/Graphics/RenderPass/SkyboxRenderPass.cpp index 2e4cb77..b7b78e5 100644 --- a/src/Engine/Graphics/RenderPass/SkyboxRenderPass.cpp +++ b/src/Engine/Graphics/RenderPass/SkyboxRenderPass.cpp @@ -74,10 +74,10 @@ void SkyboxRenderPass::endFrame() void SkyboxRenderPass::publishOutputs() { - skyboxDataLayout = graphics->createDescriptorLayout("SkyboxDescLayout"); + skyboxDataLayout = graphics->createDescriptorLayout("pSkyboxData"); skyboxDataLayout->addDescriptorBinding(0, Gfx::SE_DESCRIPTOR_TYPE_UNIFORM_BUFFER); skyboxDataLayout->create(); - textureLayout = graphics->createDescriptorLayout(); + textureLayout = graphics->createDescriptorLayout("pSkyboxTextures"); textureLayout->addDescriptorBinding(0, Gfx::SE_DESCRIPTOR_TYPE_SAMPLED_IMAGE); textureLayout->addDescriptorBinding(1, Gfx::SE_DESCRIPTOR_TYPE_SAMPLED_IMAGE); textureLayout->addDescriptorBinding(2, Gfx::SE_DESCRIPTOR_TYPE_SAMPLER); @@ -122,10 +122,10 @@ void SkyboxRenderPass::createRenderPass() createInfo.entryPoint = "fragmentMain"; fragmentShader = graphics->createFragmentShader(createInfo); - Gfx::OPipelineLayout pipelineLayout = graphics->createPipelineLayout(); - pipelineLayout->addDescriptorLayout(0, viewParamsLayout); - pipelineLayout->addDescriptorLayout(1, skyboxDataLayout); - pipelineLayout->addDescriptorLayout(2, textureLayout); + pipelineLayout = graphics->createPipelineLayout(); + pipelineLayout->addDescriptorLayout(viewParamsLayout); + pipelineLayout->addDescriptorLayout(skyboxDataLayout); + pipelineLayout->addDescriptorLayout(textureLayout); pipelineLayout->create(); Gfx::LegacyPipelineCreateInfo gfxInfo; @@ -133,7 +133,7 @@ void SkyboxRenderPass::createRenderPass() gfxInfo.fragmentShader = fragmentShader; gfxInfo.rasterizationState.polygonMode = Gfx::SE_POLYGON_MODE_FILL; gfxInfo.topology = Gfx::SE_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST; - gfxInfo.pipelineLayout = std::move(pipelineLayout); + gfxInfo.pipelineLayout = pipelineLayout; gfxInfo.renderPass = renderPass; gfxInfo.multisampleState.samples = viewport->getSamples(); pipeline = graphics->createGraphicsPipeline(std::move(gfxInfo)); diff --git a/src/Engine/Graphics/RenderPass/SkyboxRenderPass.h b/src/Engine/Graphics/RenderPass/SkyboxRenderPass.h index 8e5bd32..8169045 100644 --- a/src/Engine/Graphics/RenderPass/SkyboxRenderPass.h +++ b/src/Engine/Graphics/RenderPass/SkyboxRenderPass.h @@ -26,6 +26,7 @@ private: Gfx::PDescriptorSet textureSet; Gfx::OVertexShader vertexShader; Gfx::OFragmentShader fragmentShader; + Gfx::OPipelineLayout pipelineLayout; Gfx::PGraphicsPipeline pipeline; Gfx::OSampler skyboxSampler; struct SkyboxData diff --git a/src/Engine/Graphics/RenderPass/TextPass.cpp b/src/Engine/Graphics/RenderPass/TextPass.cpp index c28a92d..7a1697e 100644 --- a/src/Engine/Graphics/RenderPass/TextPass.cpp +++ b/src/Engine/Graphics/RenderPass/TextPass.cpp @@ -85,7 +85,7 @@ void TextPass::render() command->bindDescriptor({generalSet, resource.textureArraySet}); //command->bindVertexBuffer({resource.vertexBuffer}); - command->pushConstants(layoutRef, Gfx::SE_SHADER_STAGE_VERTEX_BIT | Gfx::SE_SHADER_STAGE_FRAGMENT_BIT, 0, sizeof(TextData), &resource.textData); + command->pushConstants(pipelineLayout, Gfx::SE_SHADER_STAGE_VERTEX_BIT | Gfx::SE_SHADER_STAGE_FRAGMENT_BIT, 0, sizeof(TextData), &resource.textData); //command->draw(4, static_cast(resource.vertexBuffer->getNumVertices()), 0, 0); } commands.add(std::move(command)); @@ -120,12 +120,12 @@ void TextPass::createRenderPass() createInfo.name = "TextFragment"; createInfo.entryPoint = "fragmentMain"; fragmentShader = graphics->createFragmentShader(createInfo); - generalLayout = graphics->createDescriptorLayout("TextGeneral"); + generalLayout = graphics->createDescriptorLayout("pRender"); generalLayout->addDescriptorBinding(0, Gfx::SE_DESCRIPTOR_TYPE_UNIFORM_BUFFER); generalLayout->addDescriptorBinding(1, Gfx::SE_DESCRIPTOR_TYPE_SAMPLER); generalLayout->create(); - textureArrayLayout = graphics->createDescriptorLayout("TextTextureArray"); + textureArrayLayout = graphics->createDescriptorLayout("pGlyphTextures"); textureArrayLayout->addDescriptorBinding(0, Gfx::SE_DESCRIPTOR_TYPE_SAMPLED_IMAGE, Gfx::SE_IMAGE_VIEW_TYPE_2D_ARRAY, 256, Gfx::SE_DESCRIPTOR_BINDING_VARIABLE_DESCRIPTOR_COUNT_BIT); textureArrayLayout->create(); @@ -149,10 +149,9 @@ void TextPass::createRenderPass() generalSet->updateSampler(1, glyphSampler); generalSet->writeChanges(); - Gfx::OPipelineLayout pipelineLayout = graphics->createPipelineLayout(); - layoutRef = pipelineLayout; - pipelineLayout->addDescriptorLayout(0, generalLayout); - pipelineLayout->addDescriptorLayout(1, textureArrayLayout); + pipelineLayout = graphics->createPipelineLayout(); + pipelineLayout->addDescriptorLayout(generalLayout); + pipelineLayout->addDescriptorLayout(textureArrayLayout); pipelineLayout->addPushConstants({ .stageFlags = Gfx::SE_SHADER_STAGE_VERTEX_BIT | Gfx::SE_SHADER_STAGE_FRAGMENT_BIT, .offset = 0, @@ -169,7 +168,7 @@ void TextPass::createRenderPass() pipelineInfo.vertexShader = vertexShader; pipelineInfo.fragmentShader = fragmentShader; pipelineInfo.renderPass = renderPass; - pipelineInfo.pipelineLayout = std::move(pipelineLayout); + pipelineInfo.pipelineLayout = pipelineLayout; pipelineInfo.rasterizationState.cullMode = Gfx::SE_CULL_MODE_NONE; pipelineInfo.colorBlend.attachmentCount = 1; pipelineInfo.colorBlend.blendAttachments[0].blendEnable = true; diff --git a/src/Engine/Graphics/RenderPass/TextPass.h b/src/Engine/Graphics/RenderPass/TextPass.h index 16523d6..22b71b7 100644 --- a/src/Engine/Graphics/RenderPass/TextPass.h +++ b/src/Engine/Graphics/RenderPass/TextPass.h @@ -76,7 +76,7 @@ private: Gfx::OVertexShader vertexShader; Gfx::OFragmentShader fragmentShader; - Gfx::PPipelineLayout layoutRef; + Gfx::OPipelineLayout pipelineLayout; Gfx::PGraphicsPipeline pipeline; Array texts; }; diff --git a/src/Engine/Graphics/RenderPass/UIPass.cpp b/src/Engine/Graphics/RenderPass/UIPass.cpp index f268d26..f36e96a 100644 --- a/src/Engine/Graphics/RenderPass/UIPass.cpp +++ b/src/Engine/Graphics/RenderPass/UIPass.cpp @@ -106,7 +106,7 @@ void UIPass::createRenderPass() createInfo.entryPoint = "fragmentMain"; fragmentShader = graphics->createFragmentShader(createInfo); - descriptorLayout = graphics->createDescriptorLayout("UIDescriptorLayout"); + descriptorLayout = graphics->createDescriptorLayout("pParams"); descriptorLayout->addDescriptorBinding(0, Gfx::SE_DESCRIPTOR_TYPE_UNIFORM_BUFFER); descriptorLayout->addDescriptorBinding(1, Gfx::SE_DESCRIPTOR_TYPE_SAMPLER); descriptorLayout->addDescriptorBinding(2, Gfx::SE_DESCRIPTOR_TYPE_UNIFORM_BUFFER); @@ -140,7 +140,7 @@ void UIPass::createRenderPass() descriptorSet->writeChanges(); Gfx::OPipelineLayout pipelineLayout = graphics->createPipelineLayout(); - pipelineLayout->addDescriptorLayout(0, descriptorLayout); + pipelineLayout->addDescriptorLayout(descriptorLayout); pipelineLayout->create(); Gfx::RenderTargetLayout layout = Gfx::RenderTargetLayout{ diff --git a/src/Engine/Graphics/RenderPass/UIPass.h b/src/Engine/Graphics/RenderPass/UIPass.h index a6ab374..f1dd870 100644 --- a/src/Engine/Graphics/RenderPass/UIPass.h +++ b/src/Engine/Graphics/RenderPass/UIPass.h @@ -34,6 +34,7 @@ private: Gfx::OVertexShader vertexShader; Gfx::OFragmentShader fragmentShader; Gfx::PGraphicsPipeline pipeline; + Gfx::OPipelineLayout pipelineLayout; Array renderElements; Array usedTextures; diff --git a/src/Engine/Graphics/Shader.cpp b/src/Engine/Graphics/Shader.cpp index cbe72d0..4a04ba5 100644 --- a/src/Engine/Graphics/Shader.cpp +++ b/src/Engine/Graphics/Shader.cpp @@ -33,9 +33,10 @@ void ShaderCompiler::registerVertexData(VertexData* vd) compile(); } -void ShaderCompiler::registerRenderPass(std::string name, std::string mainFile, bool useMaterials, bool hasFragmentShader, std::string fragmentFile, bool useMeshShading, bool hasTaskShader, std::string taskFile) +void ShaderCompiler::registerRenderPass(Gfx::PPipelineLayout layout, std::string name, std::string mainFile, bool useMaterials, bool hasFragmentShader, std::string fragmentFile, bool useMeshShading, bool hasTaskShader, std::string taskFile) { passes[name] = PassConfig{ + .baseLayout = layout, .taskFile = taskFile, .mainFile = mainFile, .fragmentFile = fragmentFile, @@ -52,57 +53,71 @@ void ShaderCompiler::compile() { for (const auto& [name, pass] : passes) { - ShaderPermutation permutation; - if (pass.useMeshShading) - { - permutation.setMeshFile(pass.mainFile); - } - else - { - permutation.setVertexFile(pass.mainFile); - } - if (pass.hasFragmentShader) - { - permutation.setFragmentFile(pass.fragmentFile); - } - if (pass.hasTaskShader) - { - permutation.setTaskFile(pass.taskFile); - } + ShaderPermutation permutation; + if (pass.useMeshShading) + { + permutation.setMeshFile(pass.mainFile); + } + else + { + permutation.setVertexFile(pass.mainFile); + } + if (pass.hasFragmentShader) + { + permutation.setFragmentFile(pass.fragmentFile); + } + if (pass.hasTaskShader) + { + permutation.setTaskFile(pass.taskFile); + } for (const auto& [vdName, vd] : vertexData) { - permutation.setVertexData(vd->getTypeName()); + permutation.setVertexData(vd->getTypeName()); if (pass.useMaterial) { for (const auto& [matName, mat] : materials) { + OPipelineLayout layout = graphics->createPipelineLayout(pass.baseLayout); + layout->addDescriptorLayout(vd->getVertexDataLayout()); + layout->addDescriptorLayout(vd->getInstanceDataLayout()); + layout->addDescriptorLayout(mat->getDescriptorLayout()); permutation.setMaterial(mat->getName()); - createShaders(permutation); + createShaders(permutation, std::move(layout)); } } else { - createShaders(permutation); + OPipelineLayout layout = graphics->createPipelineLayout(pass.baseLayout); + layout->addDescriptorLayout(vd->getVertexDataLayout()); + layout->addDescriptorLayout(vd->getInstanceDataLayout()); + Map mapping; + mapping["pViewParams"] = 1; + mapping["pVertexData"] = 2; + mapping["pScene"] = 3; + layout->addMapping(mapping); + createShaders(permutation, std::move(layout)); } } } } -void ShaderCompiler::createShaders(ShaderPermutation permutation) +void ShaderCompiler::createShaders(ShaderPermutation permutation, Gfx::OPipelineLayout layout) { std::scoped_lock lock(shadersLock); PermutationId perm = PermutationId(permutation); if (shaders.contains(perm)) return; ShaderCollection collection; + collection.pipelineLayout = std::move(layout); ShaderCreateInfo createInfo; createInfo.name = fmt::format("Material {0}", permutation.materialName); + createInfo.rootSignature = collection.pipelineLayout; if (std::strlen(permutation.materialName) > 0) - { - createInfo.additionalModules.add(permutation.materialName); - createInfo.typeParameter.add(Pair("IMaterial", permutation.materialName)); - } + { + createInfo.additionalModules.add(permutation.materialName); + createInfo.typeParameter.add(Pair("IMaterial", permutation.materialName)); + } createInfo.typeParameter.add({ Pair("IVertexData", permutation.vertexDataName) }); createInfo.additionalModules.add(permutation.vertexDataName); createInfo.additionalModules.add(permutation.vertexMeshFile); @@ -141,4 +156,4 @@ void ShaderCompiler::createShaders(ShaderPermutation permutation) collection.fragmentShader = graphics->createFragmentShader(createInfo); } shaders[perm] = std::move(collection); -} \ No newline at end of file +} diff --git a/src/Engine/Graphics/Shader.h b/src/Engine/Graphics/Shader.h index 5644205..70e07c6 100644 --- a/src/Engine/Graphics/Shader.h +++ b/src/Engine/Graphics/Shader.h @@ -124,6 +124,7 @@ struct PermutationId }; struct ShaderCollection { + OPipelineLayout pipelineLayout; OVertexShader vertexShader; OTaskShader taskShader; OMeshShader meshShader; @@ -137,7 +138,8 @@ public: const ShaderCollection* findShaders(PermutationId id) const; void registerMaterial(PMaterial material); void registerVertexData(VertexData* vertexData); - void registerRenderPass(std::string name, + void registerRenderPass(Gfx::PPipelineLayout baseLayout, + std::string name, std::string mainFile, bool useMaterials = false, bool hasFragmentShader = false, @@ -147,13 +149,14 @@ public: std::string taskFile = ""); private: void compile(); - void createShaders(ShaderPermutation permutation); + void createShaders(ShaderPermutation permutation, OPipelineLayout layout); std::mutex shadersLock; Map shaders; Map materials; Map vertexData; struct PassConfig { + Gfx::PPipelineLayout baseLayout; std::string taskFile; std::string mainFile; std::string fragmentFile; @@ -167,4 +170,4 @@ private: }; DEFINE_REF(ShaderCompiler) } -} // namespace Seele \ No newline at end of file +} // namespace Seele diff --git a/src/Engine/Graphics/StaticMeshVertexData.cpp b/src/Engine/Graphics/StaticMeshVertexData.cpp index 2883293..4128cf2 100644 --- a/src/Engine/Graphics/StaticMeshVertexData.cpp +++ b/src/Engine/Graphics/StaticMeshVertexData.cpp @@ -116,7 +116,7 @@ void StaticMeshVertexData::deserializeMesh(MeshId id, ArchiveBuffer& buffer) void StaticMeshVertexData::init(Gfx::PGraphics _graphics) { VertexData::init(_graphics); - descriptorLayout = _graphics->createDescriptorLayout("StaticMeshDescriptorLayout"); + descriptorLayout = _graphics->createDescriptorLayout("pVertexData"); descriptorLayout->addDescriptorBinding(0, Gfx::SE_DESCRIPTOR_TYPE_STORAGE_BUFFER); descriptorLayout->addDescriptorBinding(1, Gfx::SE_DESCRIPTOR_TYPE_STORAGE_BUFFER); descriptorLayout->addDescriptorBinding(2, Gfx::SE_DESCRIPTOR_TYPE_STORAGE_BUFFER); diff --git a/src/Engine/Graphics/VertexData.cpp b/src/Engine/Graphics/VertexData.cpp index b76e39e..c8cb06a 100644 --- a/src/Engine/Graphics/VertexData.cpp +++ b/src/Engine/Graphics/VertexData.cpp @@ -264,7 +264,7 @@ void Seele::VertexData::init(Gfx::PGraphics _graphics) { graphics = _graphics; verticesAllocated = NUM_DEFAULT_ELEMENTS; - instanceDataLayout = graphics->createDescriptorLayout("VertexDataInstanceLayout"); + instanceDataLayout = graphics->createDescriptorLayout("pScene"); instanceDataLayout->addDescriptorBinding(0, Gfx::SE_DESCRIPTOR_TYPE_STORAGE_BUFFER); // meshData diff --git a/src/Engine/Graphics/slang-compile.cpp b/src/Engine/Graphics/slang-compile.cpp index 25b1876..add3bd3 100644 --- a/src/Engine/Graphics/slang-compile.cpp +++ b/src/Engine/Graphics/slang-compile.cpp @@ -8,7 +8,7 @@ #define CHECK_RESULT(x) {SlangResult r = x; if(r != 0) {throw std::runtime_error(fmt::format("Error: {0}", r));}} #define CHECK_DIAGNOSTICS() {if(diagnostics) {std::cout << (const char*)diagnostics->getBufferPointer() << std::endl; assert(false);}} -Slang::ComPtr Seele::generateShader(const ShaderCreateInfo& createInfo, SlangCompileTarget target) +Slang::ComPtr Seele::generateShader(const ShaderCreateInfo& createInfo, SlangCompileTarget target, Map& paramMapping) { thread_local Slang::ComPtr globalSession; if(!globalSession) @@ -89,5 +89,14 @@ Slang::ComPtr Seele::generateShader(const ShaderCreateInfo& create diagnostics.writeRef() ); CHECK_DIAGNOSTICS(); + slang::ProgramLayout* signature = specializedComponent->getLayout(0, diagnostics.writeRef()); + CHECK_DIAGNOSTICS(); + auto entry = signature->findEntryPointByName(createInfo.entryPoint.c_str()); + for(size_t i = 0; i < signature->getParameterCount(); ++i) + { + auto param = signature->getParameterByIndex(i); + paramMapping[param->getName()] = param->getBindingIndex(); + std::cout << param->getName() << " " << param->getBindingIndex() << " " << param->getSemanticIndex() << std::endl; + } return kernelBlob; -} \ No newline at end of file +} diff --git a/src/Engine/Graphics/slang-compile.h b/src/Engine/Graphics/slang-compile.h index fb461c5..7a9989e 100644 --- a/src/Engine/Graphics/slang-compile.h +++ b/src/Engine/Graphics/slang-compile.h @@ -4,5 +4,5 @@ #include namespace Seele { -Slang::ComPtr generateShader(const ShaderCreateInfo& createInfo, SlangCompileTarget target); -} \ No newline at end of file +Slang::ComPtr generateShader(const ShaderCreateInfo& createInfo, SlangCompileTarget target, Map& paramMapping); +} diff --git a/src/Engine/Material/Material.cpp b/src/Engine/Material/Material.cpp index 74eb317..6de6868 100644 --- a/src/Engine/Material/Material.cpp +++ b/src/Engine/Material/Material.cpp @@ -57,7 +57,7 @@ void Material::save(ArchiveBuffer& buffer) const Serialization::save(buffer, codeExpressions); Serialization::save(buffer, parameters); Serialization::save(buffer, brdf); - Serialization::save(buffer, layout->getSetIndex()); + Serialization::save(buffer, layout->getName()); const auto& bindings = layout->getBindings(); Serialization::save(buffer, bindings.size()); for (const auto& binding : bindings) @@ -81,11 +81,11 @@ void Material::load(ArchiveBuffer& buffer) Serialization::load(buffer, codeExpressions); Serialization::load(buffer, parameters); Serialization::load(buffer, brdf); - uint32 setIndex; - Serialization::load(buffer, setIndex); + std::string descriptorName; + Serialization::load(buffer, descriptorName); uint64 numBindings; Serialization::load(buffer, numBindings); - layout = graphics->createDescriptorLayout(); + layout = graphics->createDescriptorLayout(descriptorName); for (uint64 i = 0; i < numBindings; ++i) { uint32 binding; diff --git a/src/Engine/Scene/LightEnvironment.cpp b/src/Engine/Scene/LightEnvironment.cpp index 2b67b32..6065d05 100644 --- a/src/Engine/Scene/LightEnvironment.cpp +++ b/src/Engine/Scene/LightEnvironment.cpp @@ -6,7 +6,7 @@ using namespace Seele; LightEnvironment::LightEnvironment(Gfx::PGraphics graphics) : graphics(graphics) { - layout = graphics->createDescriptorLayout("LightEnvironment"); + layout = graphics->createDescriptorLayout("pLightEnv"); layout->addDescriptorBinding(0, Gfx::SE_DESCRIPTOR_TYPE_UNIFORM_BUFFER); layout->addDescriptorBinding(1, Gfx::SE_DESCRIPTOR_TYPE_STORAGE_BUFFER); layout->addDescriptorBinding(2, Gfx::SE_DESCRIPTOR_TYPE_STORAGE_BUFFER);