Browse Source

metal: implement stubs for missing methods

Alex Szpakowski 5 years ago
parent
commit
acc4064a6c

+ 2 - 1
src/modules/graphics/Graphics.h

@@ -148,7 +148,8 @@ public:
 
 
 	enum Renderer
 	enum Renderer
 	{
 	{
-		RENDERER_OPENGL = 0,
+		RENDERER_NONE,
+		RENDERER_OPENGL,
 		RENDERER_METAL,
 		RENDERER_METAL,
 		RENDERER_MAX_ENUM
 		RENDERER_MAX_ENUM
 	};
 	};

+ 109 - 43
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);
 	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)
 void Graphics::setViewportSize(int width, int height, int pixelwidth, int pixelheight)
 {
 {
 	this->width = width;
 	this->width = width;
@@ -313,14 +273,14 @@ bool Graphics::setMode(void *context, int width, int height, int pixelwidth, int
 		if (!Shader::standardShaders[i])
 		if (!Shader::standardShaders[i])
 		{
 		{
 			const auto &code = defaultShaderCode[i][target][gammacorrect];
 			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
 	// A shader should always be active, but the default shader shouldn't be
 	// returned by getShader(), so we don't do setShader(defaultShader).
 	// 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;
 	return true;
 }}
 }}
@@ -917,6 +877,11 @@ void Graphics::present(void *screenshotCallbackData)
 	}
 	}
 }
 }
 
 
+void Graphics::setColor(Colorf c)
+{
+	// TODO
+}
+
 void Graphics::setScissor(const Rect &rect)
 void Graphics::setScissor(const Rect &rect)
 {
 {
 	flushBatchedDraws();
 	flushBatchedDraws();
@@ -976,6 +941,26 @@ void Graphics::stopDrawToStencilBuffer()
 	dirtyRenderState |= STATEBIT_STENCIL;
 	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)
 void Graphics::setBlendState(const BlendState &blend)
 {
 {
 	if (!(blend == states.back().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
 Graphics::Renderer Graphics::getRenderer() const
 {
 {
 	return RENDERER_METAL;
 	return RENDERER_METAL;
@@ -1010,6 +1026,56 @@ Graphics::RendererInfo Graphics::getRendererInfo() const
 	return info;
 	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
 } // metal
 } // graphics
 } // graphics
 } // love
 } // love

+ 10 - 12
src/modules/graphics/metal/Shader.h

@@ -39,16 +39,16 @@ public:
 	virtual ~Shader();
 	virtual ~Shader();
 
 
 	// Implements 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:
 private:
 
 
@@ -56,8 +56,6 @@ private:
 
 
 }; // Metal
 }; // Metal
 
 
-extern Metal metal;
-
 } // metal
 } // metal
 } // graphics
 } // graphics
 } // love
 } // love

+ 11 - 0
src/modules/graphics/metal/Texture.mm

@@ -199,6 +199,17 @@ void Texture::generateMipmaps()
 	[encoder generateMipmapsForTexture:texture];
 	[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
 } // metal
 } // graphics
 } // graphics
 } // love
 } // love

+ 10 - 2
src/modules/window/sdl/Window.cpp

@@ -292,6 +292,9 @@ std::vector<Window::ContextAttribs> 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 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;
 	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 windowerror;
 	std::string contexterror;
 	std::string contexterror;
@@ -428,7 +431,7 @@ bool Window::createWindowAndContext(int x, int y, int w, int h, Uint32 windowfla
 	bool failed = window == nullptr;
 	bool failed = window == nullptr;
 	failed |= (needsglcontext && !glcontext);
 	failed |= (needsglcontext && !glcontext);
 #if defined(LOVE_MACOS) || defined(LOVE_IOS)
 #if defined(LOVE_MACOS) || defined(LOVE_IOS)
-
+	failed |= (needsmetalview && !metalView);
 #endif
 #endif
 
 
 	if (failed)
 	if (failed)
@@ -468,7 +471,7 @@ bool Window::setWindow(int width, int height, WindowSettings *settings)
 	if (graphics.get() && graphics->isRenderTargetActive())
 	if (graphics.get() && graphics->isRenderTargetActive())
 		throw love::Exception("love.window.setMode cannot be called while a render target is active in love.graphics.");
 		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;
 	WindowSettings f;
 
 
@@ -494,6 +497,11 @@ bool Window::setWindow(int width, int height, WindowSettings *settings)
 	if (renderer == graphics::Graphics::RENDERER_OPENGL)
 	if (renderer == graphics::Graphics::RENDERER_OPENGL)
 		sdlflags |= SDL_WINDOW_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
 	// On Android we always must have fullscreen type FULLSCREEN_TYPE_DESKTOP
 #ifdef LOVE_ANDROID
 #ifdef LOVE_ANDROID
 	f.fstype = FULLSCREEN_DESKTOP;
 	f.fstype = FULLSCREEN_DESKTOP;