#pragma once #include #include #include #include #include #include #include namespace mln { namespace shaders { struct AttributeInfo { constexpr AttributeInfo(std::size_t index_, gfx::AttributeDataType dataType_, std::size_t bufferIndex_, std::size_t id_) : index(index_), dataType(dataType_), bufferIndex(bufferIndex_), id(id_) {} std::size_t index; gfx::AttributeDataType dataType; std::size_t bufferIndex; std::size_t id; }; struct TextureInfo { constexpr TextureInfo(std::size_t index_, std::size_t id_) : index(index_), id(id_) {} std::size_t index; std::size_t id; }; } // namespace shaders namespace mtl { class RenderableResource; class RendererBackend; class ShaderProgram; using UniqueShaderProgram = std::unique_ptr; class ShaderProgram final : public gfx::ShaderProgramBase { public: ShaderProgram(std::string name, RendererBackend& backend, MTLFunctionPtr vertexFunction, MTLFunctionPtr fragmentFunction); ~ShaderProgram() noexcept override; static constexpr std::string_view Name{"GenericMTLShader"}; const std::string_view typeName() const noexcept override { return Name; } MTLRenderPipelineStatePtr getRenderPipelineState(const gfx::Renderable&, const MTLVertexDescriptorPtr&, const gfx::ColorMode& colorMode, const std::optional reuseHash) const; std::optional getSamplerLocation(const size_t id) const override; const gfx::VertexAttributeArray& getVertexAttributes() const override { return vertexAttributes; } const gfx::VertexAttributeArray& getInstanceAttributes() const override { return instanceAttributes; } void initVertexAttribute(const shaders::AttributeInfo&); void initInstanceAttribute(const shaders::AttributeInfo&); void initTexture(const shaders::TextureInfo&); protected: std::string shaderName; RendererBackend& backend; MTLFunctionPtr vertexFunction; MTLFunctionPtr fragmentFunction; VertexAttributeArray vertexAttributes; VertexAttributeArray instanceAttributes; std::array, shaders::maxTextureCountPerShader> textureBindings; mutable mln::unordered_map renderPipelineStateCache; }; } // namespace mtl } // namespace mln