From acc4064a6c5fdd8a63bbdd2b3d980c3fe326e9ca Mon Sep 17 00:00:00 2001 From: Alex Szpakowski Date: Wed, 22 Apr 2020 23:18:00 -0300 Subject: [PATCH] metal: implement stubs for missing methods --- src/modules/graphics/Graphics.h | 3 +- src/modules/graphics/metal/Graphics.mm | 152 ++++++++++++++++++------- src/modules/graphics/metal/Shader.h | 22 ++-- src/modules/graphics/metal/Texture.mm | 11 ++ src/modules/window/sdl/Window.cpp | 12 +- 5 files changed, 142 insertions(+), 58 deletions(-) diff --git a/src/modules/graphics/Graphics.h b/src/modules/graphics/Graphics.h index b5a4690d6..a76a81400 100644 --- a/src/modules/graphics/Graphics.h +++ b/src/modules/graphics/Graphics.h @@ -148,7 +148,8 @@ public: enum Renderer { - RENDERER_OPENGL = 0, + RENDERER_NONE, + RENDERER_OPENGL, RENDERER_METAL, RENDERER_MAX_ENUM }; diff --git a/src/modules/graphics/metal/Graphics.mm b/src/modules/graphics/metal/Graphics.mm index b368ac683..1abb4a6f5 100644 --- a/src/modules/graphics/metal/Graphics.mm +++ b/src/modules/graphics/metal/Graphics.mm @@ -223,46 +223,6 @@ love::graphics::Buffer *Graphics::newBuffer(size_t size, const void *data, Buffe return new Buffer(device, size, data, type, usage, mapflags); } -void Graphics::initCapabilities() -{ - int msaa = 1; - const int checkmsaa[] = {32, 16, 8, 4, 2}; - for (int samples : checkmsaa) - { - if ([device supportsTextureSampleCount:samples]) - { - msaa = samples; - break; - } - } - - capabilities.features[FEATURE_MULTI_RENDER_TARGET_FORMATS] = true; - capabilities.features[FEATURE_CLAMP_ZERO] = true; - capabilities.features[FEATURE_BLEND_MINMAX] = true; - capabilities.features[FEATURE_LIGHTEN] = true; - capabilities.features[FEATURE_FULL_NPOT] = true; - capabilities.features[FEATURE_PIXEL_SHADER_HIGHP] = true; - capabilities.features[FEATURE_SHADER_DERIVATIVES] = true; - capabilities.features[FEATURE_GLSL3] = true; - capabilities.features[FEATURE_GLSL4] = true; - capabilities.features[FEATURE_INSTANCING] = true; - static_assert(FEATURE_MAX_ENUM == 10, "Graphics::initCapabilities must be updated when adding a new graphics feature!"); - - // https://developer.apple.com/metal/Metal-Feature-Set-Tables.pdf - capabilities.limits[LIMIT_POINT_SIZE] = 511; - capabilities.limits[LIMIT_TEXTURE_SIZE] = 16384; // TODO - capabilities.limits[LIMIT_TEXTURE_LAYERS] = 2048; - capabilities.limits[LIMIT_VOLUME_TEXTURE_SIZE] = 2048; - capabilities.limits[LIMIT_CUBE_TEXTURE_SIZE] = 16384; // TODO - capabilities.limits[LIMIT_RENDER_TARGETS] = 8; // TODO - capabilities.limits[LIMIT_TEXTURE_MSAA] = msaa; - capabilities.limits[LIMIT_ANISOTROPY] = 16.0f; - static_assert(LIMIT_MAX_ENUM == 8, "Graphics::initCapabilities must be updated when adding a new system limit!"); - - for (int i = 0; i < TEXTURE_MAX_ENUM; i++) - capabilities.textureTypes[i] = true; -} - void Graphics::setViewportSize(int width, int height, int pixelwidth, int pixelheight) { this->width = width; @@ -313,14 +273,14 @@ bool Graphics::setMode(void *context, int width, int height, int pixelwidth, int if (!Shader::standardShaders[i]) { const auto &code = defaultShaderCode[i][target][gammacorrect]; - Shader::standardShaders[i] = love::graphics::Graphics::newShader(code.source[ShaderStage::STAGE_VERTEX], code.source[ShaderStage::STAGE_PIXEL]); +// Shader::standardShaders[i] = love::graphics::Graphics::newShader(code.source[ShaderStage::STAGE_VERTEX], code.source[ShaderStage::STAGE_PIXEL]); } } // A shader should always be active, but the default shader shouldn't be // returned by getShader(), so we don't do setShader(defaultShader). - if (!Shader::current) - Shader::standardShaders[Shader::STANDARD_DEFAULT]->attach(); +// if (!Shader::current) +// Shader::standardShaders[Shader::STANDARD_DEFAULT]->attach(); return true; }} @@ -917,6 +877,11 @@ void Graphics::present(void *screenshotCallbackData) } } +void Graphics::setColor(Colorf c) +{ + // TODO +} + void Graphics::setScissor(const Rect &rect) { flushBatchedDraws(); @@ -976,6 +941,26 @@ void Graphics::stopDrawToStencilBuffer() dirtyRenderState |= STATEBIT_STENCIL; } +void Graphics::setStencilTest(CompareMode compare, int value) +{ + // TODO +} + +void Graphics::setDepthMode(CompareMode compare, bool write) +{ + // TODO +} + +void Graphics::setFrontFaceWinding(vertex::Winding winding) +{ + // TODO +} + +void Graphics::setColorMask(ColorChannelMask mask) +{ + // TODO +} + void Graphics::setBlendState(const BlendState &blend) { if (!(blend == states.back().blend)) @@ -986,6 +971,37 @@ void Graphics::setBlendState(const BlendState &blend) } } +void Graphics::setPointSize(float size) +{ + // TODO +} + +void Graphics::setWireframe(bool enable) +{ + // TODO +} + +PixelFormat Graphics::getSizedFormat(PixelFormat format, bool /*rendertarget*/, bool /*readable*/, bool /*sRGB*/) const +{ + switch (format) + { + case PIXELFORMAT_NORMAL: + if (isGammaCorrect()) + return PIXELFORMAT_sRGBA8_UNORM; + else + return PIXELFORMAT_RGBA8_UNORM; + case PIXELFORMAT_HDR: + return PIXELFORMAT_RGBA16_FLOAT; + default: + return format; + } +} + +bool Graphics::isPixelFormatSupported(PixelFormat format, bool rendertarget, bool readable, bool sRGB) +{ + return true; // TODO +} + Graphics::Renderer Graphics::getRenderer() const { return RENDERER_METAL; @@ -1010,6 +1026,56 @@ Graphics::RendererInfo Graphics::getRendererInfo() const return info; } +Shader::Language Graphics::getShaderLanguageTarget() const +{ + return usesGLSLES() ? Shader::LANGUAGE_ESSL3 : Shader::LANGUAGE_GLSL3; +} + +void Graphics::initCapabilities() +{ + int msaa = 1; + const int checkmsaa[] = {32, 16, 8, 4, 2}; + for (int samples : checkmsaa) + { + if ([device supportsTextureSampleCount:samples]) + { + msaa = samples; + break; + } + } + + capabilities.features[FEATURE_MULTI_RENDER_TARGET_FORMATS] = true; + capabilities.features[FEATURE_CLAMP_ZERO] = true; + capabilities.features[FEATURE_BLEND_MINMAX] = true; + capabilities.features[FEATURE_LIGHTEN] = true; + capabilities.features[FEATURE_FULL_NPOT] = true; + capabilities.features[FEATURE_PIXEL_SHADER_HIGHP] = true; + capabilities.features[FEATURE_SHADER_DERIVATIVES] = true; + capabilities.features[FEATURE_GLSL3] = true; + capabilities.features[FEATURE_GLSL4] = true; + capabilities.features[FEATURE_INSTANCING] = true; + static_assert(FEATURE_MAX_ENUM == 10, "Graphics::initCapabilities must be updated when adding a new graphics feature!"); + + // https://developer.apple.com/metal/Metal-Feature-Set-Tables.pdf + capabilities.limits[LIMIT_POINT_SIZE] = 511; + capabilities.limits[LIMIT_TEXTURE_SIZE] = 16384; // TODO + capabilities.limits[LIMIT_TEXTURE_LAYERS] = 2048; + capabilities.limits[LIMIT_VOLUME_TEXTURE_SIZE] = 2048; + capabilities.limits[LIMIT_CUBE_TEXTURE_SIZE] = 16384; // TODO + capabilities.limits[LIMIT_RENDER_TARGETS] = 8; // TODO + capabilities.limits[LIMIT_TEXTURE_MSAA] = msaa; + capabilities.limits[LIMIT_ANISOTROPY] = 16.0f; + static_assert(LIMIT_MAX_ENUM == 8, "Graphics::initCapabilities must be updated when adding a new system limit!"); + + for (int i = 0; i < TEXTURE_MAX_ENUM; i++) + capabilities.textureTypes[i] = true; +} + +void Graphics::getAPIStats(int &shaderswitches) const +{ + shaderswitches = 0; +} + } // metal } // graphics } // love diff --git a/src/modules/graphics/metal/Shader.h b/src/modules/graphics/metal/Shader.h index 39f7eeea3..2b22d2132 100644 --- a/src/modules/graphics/metal/Shader.h +++ b/src/modules/graphics/metal/Shader.h @@ -39,16 +39,16 @@ public: virtual ~Shader(); // Implements Shader. - void attach() override; - std::string getWarnings() const override; - int getVertexAttributeIndex(const std::string &name) override; - const UniformInfo *getUniformInfo(const std::string &name) const override; - const UniformInfo *getUniformInfo(BuiltinUniform builtin) const override; - void updateUniform(const UniformInfo *info, int count) override; - void sendTextures(const UniformInfo *info, love::graphics::Texture **textures, int count) override; - bool hasUniform(const std::string &name) const override; - ptrdiff_t getHandle() const override; - void setVideoTextures(love::graphics::Texture *ytexture, love::graphics::Texture *cbtexture, love::graphics::Texture *crtexture) override; + void attach() override {} + std::string getWarnings() const override { return ""; } + int getVertexAttributeIndex(const std::string &name) override { return -1; } + const UniformInfo *getUniformInfo(const std::string &name) const override { return nullptr; } + const UniformInfo *getUniformInfo(BuiltinUniform builtin) const override { return nullptr; } + void updateUniform(const UniformInfo *info, int count) override {} + void sendTextures(const UniformInfo *info, love::graphics::Texture **textures, int count) override {} + bool hasUniform(const std::string &name) const override { return false; } + ptrdiff_t getHandle() const override { return 0; } + void setVideoTextures(love::graphics::Texture *ytexture, love::graphics::Texture *cbtexture, love::graphics::Texture *crtexture) override {} private: @@ -56,8 +56,6 @@ private: }; // Metal -extern Metal metal; - } // metal } // graphics } // love diff --git a/src/modules/graphics/metal/Texture.mm b/src/modules/graphics/metal/Texture.mm index f76f0e8ff..b4c352a01 100644 --- a/src/modules/graphics/metal/Texture.mm +++ b/src/modules/graphics/metal/Texture.mm @@ -199,6 +199,17 @@ void Texture::generateMipmaps() [encoder generateMipmapsForTexture:texture]; }} +love::image::ImageData *Texture::newImageData(love::image::Image *module, int slice, int mipmap, const Rect &rect) +{ + // TODO + return nullptr; +} + +void Texture::setSamplerState(const SamplerState &s) +{ + // TODO +} + } // metal } // graphics } // love diff --git a/src/modules/window/sdl/Window.cpp b/src/modules/window/sdl/Window.cpp index dcc0db9cf..a348a6025 100644 --- a/src/modules/window/sdl/Window.cpp +++ b/src/modules/window/sdl/Window.cpp @@ -292,6 +292,9 @@ std::vector Window::getContextAttribsList() const bool Window::createWindowAndContext(int x, int y, int w, int h, Uint32 windowflags, graphics::Graphics::Renderer renderer, int msaa, bool stencil, int depth) { bool needsglcontext = (windowflags & SDL_WINDOW_OPENGL) != 0; +#if defined(LOVE_MACOS) || defined(LOVE_IOS) + bool needsmetalview = (windowflags & SDL_WINDOW_METAL) != 0; +#endif std::string windowerror; std::string contexterror; @@ -428,7 +431,7 @@ bool Window::createWindowAndContext(int x, int y, int w, int h, Uint32 windowfla bool failed = window == nullptr; failed |= (needsglcontext && !glcontext); #if defined(LOVE_MACOS) || defined(LOVE_IOS) - + failed |= (needsmetalview && !metalView); #endif if (failed) @@ -468,7 +471,7 @@ bool Window::setWindow(int width, int height, WindowSettings *settings) if (graphics.get() && graphics->isRenderTargetActive()) throw love::Exception("love.window.setMode cannot be called while a render target is active in love.graphics."); - auto renderer = graphics->getRenderer(); + auto renderer = graphics != nullptr ? graphics->getRenderer() : graphics::Graphics::RENDERER_NONE; WindowSettings f; @@ -494,6 +497,11 @@ bool Window::setWindow(int width, int height, WindowSettings *settings) if (renderer == graphics::Graphics::RENDERER_OPENGL) sdlflags |= SDL_WINDOW_OPENGL; +#if defined(LOVE_MACOS) || defined(LOVE_IOS) + if (renderer == graphics::Graphics::RENDERER_METAL) + sdlflags |= SDL_WINDOW_METAL; +#endif + // On Android we always must have fullscreen type FULLSCREEN_TYPE_DESKTOP #ifdef LOVE_ANDROID f.fstype = FULLSCREEN_DESKTOP;