Browse Source

Fix compilation

Alex Szpakowski 3 years ago
parent
commit
7a910484c3

+ 2 - 14
src/modules/graphics/Shader.cpp

@@ -933,6 +933,8 @@ bool Shader::validateInternal(StrongRef<ShaderStage> stages[], std::string &err,
 bool Shader::validateTexture(const UniformInfo *info, Texture *tex, bool internalUpdate)
 {
 	const SamplerState &sampler = tex->getSamplerState();
+	bool isstoragetex = info->baseType == UNIFORM_STORAGETEXTURE;
+
 	if (!tex->isReadable())
 	{
 		if (internalUpdate)
@@ -993,20 +995,6 @@ bool Shader::validateTexture(const UniformInfo *info, Texture *tex, bool interna
 	return true;
 }
 
-static bool isTexelBaseTypeCompatible(DataBaseType a, DataBaseType b)
-{
-	if (a == DATA_BASETYPE_FLOAT || a == DATA_BASETYPE_UNORM || a == DATA_BASETYPE_SNORM)
-		return b == DATA_BASETYPE_FLOAT || b == DATA_BASETYPE_UNORM || b == DATA_BASETYPE_SNORM;
-
-	if (a == DATA_BASETYPE_INT && b == DATA_BASETYPE_INT)
-		return true;
-
-	if (a == DATA_BASETYPE_UINT && b == DATA_BASETYPE_UINT)
-		return true;
-
-	return false;
-}
-
 bool Shader::validateBuffer(const UniformInfo *info, Buffer *buffer, bool internalUpdate)
 {
 	uint32 requiredtypeflags = 0;

+ 10 - 8
src/modules/graphics/metal/Graphics.h

@@ -47,13 +47,13 @@ public:
 
 	struct RenderEncoderBindings
 	{
-		void *textures[32][ShaderStage::STAGE_MAX_ENUM];
-		void *samplers[32][ShaderStage::STAGE_MAX_ENUM];
+		void *textures[32][SHADERSTAGE_MAX_ENUM];
+		void *samplers[32][SHADERSTAGE_MAX_ENUM];
 		struct
 		{
 			void *buffer;
 			size_t offset;
-		} buffers[32][ShaderStage::STAGE_MAX_ENUM];
+		} buffers[32][SHADERSTAGE_MAX_ENUM];
 	};
 
 	Graphics();
@@ -71,12 +71,14 @@ public:
 
 	void setActive(bool active) override;
 
+	bool dispatch(int x, int y, int z) override;
+
 	void draw(const DrawCommand &cmd) override;
 	void draw(const DrawIndexedCommand &cmd) override;
 	void drawQuads(int start, int count, const VertexAttributes &attributes, const BufferBindings &buffers, love::graphics::Texture *texture) override;
 
-	void clear(OptionalColorf color, OptionalInt stencil, OptionalDouble depth) override;
-	void clear(const std::vector<OptionalColorf> &colors, OptionalInt stencil, OptionalDouble depth) override;
+	void clear(OptionalColorD color, OptionalInt stencil, OptionalDouble depth) override;
+	void clear(const std::vector<OptionalColorD> &colors, OptionalInt stencil, OptionalDouble depth) override;
 
 	void discard(const std::vector<bool> &colorbuffers, bool depthstencil) override;
 
@@ -108,7 +110,7 @@ public:
 	void setWireframe(bool enable) override;
 	
 	PixelFormat getSizedFormat(PixelFormat format, bool rendertarget, bool readable) const override;
-	bool isPixelFormatSupported(PixelFormat format, bool rendertarget, bool readable, bool sRGB = false) override;
+	bool isPixelFormatSupported(PixelFormat format, PixelFormatUsageFlags usage, bool sRGB = false) override;
 	Renderer getRenderer() const override;
 	bool usesGLSLES() const override;
 	RendererInfo getRendererInfo() const override;
@@ -186,8 +188,8 @@ private:
 		MTLStoreAction stencil;
 	};
 
-	love::graphics::ShaderStage *newShaderStageInternal(ShaderStage::StageType stage, const std::string &cachekey, const std::string &source, bool gles) override;
-	love::graphics::Shader *newShaderInternal(love::graphics::ShaderStage *vertex, love::graphics::ShaderStage *pixel) override;
+	love::graphics::ShaderStage *newShaderStageInternal(ShaderStageType stage, const std::string &cachekey, const std::string &source, bool gles) override;
+	love::graphics::Shader *newShaderInternal(StrongRef<love::graphics::ShaderStage> stages[SHADERSTAGE_MAX_ENUM]) override;
 	love::graphics::StreamBuffer *newStreamBuffer(BufferUsage usage, size_t size) override;
 	void setRenderTargetsInternal(const RenderTargets &rts, int w, int h, int pixelw, int pixelh, bool hasSRGBcanvas) override;
 	void initCapabilities() override;

+ 60 - 52
src/modules/graphics/metal/Graphics.mm

@@ -145,7 +145,7 @@ static inline id<MTLBuffer> getMTLBuffer(love::graphics::Resource *res)
 	return res ? (__bridge id<MTLBuffer>)(void *) res->getHandle() : nil;
 }
 
-static inline void setBuffer(id<MTLRenderCommandEncoder> encoder, Graphics::RenderEncoderBindings &bindings, ShaderStage::StageType stage, int index, id<MTLBuffer> buffer, size_t offset)
+static inline void setBuffer(id<MTLRenderCommandEncoder> encoder, Graphics::RenderEncoderBindings &bindings, ShaderStageType stage, int index, id<MTLBuffer> buffer, size_t offset)
 {
 	void *b = (__bridge void *)buffer;
 	auto &binding = bindings.buffers[index][stage];
@@ -153,45 +153,45 @@ static inline void setBuffer(id<MTLRenderCommandEncoder> encoder, Graphics::Rend
 	{
 		binding.buffer = b;
 		binding.offset = offset;
-		if (stage == ShaderStage::STAGE_VERTEX)
+		if (stage == SHADERSTAGE_VERTEX)
 			[encoder setVertexBuffer:buffer offset:offset atIndex:index];
-		else if (stage == ShaderStage::STAGE_PIXEL)
+		else if (stage == SHADERSTAGE_PIXEL)
 			[encoder setFragmentBuffer:buffer offset:offset atIndex:index];
 	}
 	else if (binding.offset != offset)
 	{
 		binding.offset = offset;
-		if (stage == ShaderStage::STAGE_VERTEX)
+		if (stage == SHADERSTAGE_VERTEX)
 			[encoder setVertexBufferOffset:offset atIndex:index];
-		else if (stage == ShaderStage::STAGE_PIXEL)
+		else if (stage == SHADERSTAGE_PIXEL)
 			[encoder setFragmentBufferOffset:offset atIndex:index];
 	}
 }
 
-static inline void setTexture(id<MTLRenderCommandEncoder> encoder, Graphics::RenderEncoderBindings &bindings, ShaderStage::StageType stage, int index, id<MTLTexture> texture)
+static inline void setTexture(id<MTLRenderCommandEncoder> encoder, Graphics::RenderEncoderBindings &bindings, ShaderStageType stage, int index, id<MTLTexture> texture)
 {
 	void *t = (__bridge void *)texture;
 	auto &binding = bindings.textures[index][stage];
 	if (binding != t)
 	{
 		binding = t;
-		if (stage == ShaderStage::STAGE_VERTEX)
+		if (stage == SHADERSTAGE_VERTEX)
 			[encoder setVertexTexture:texture atIndex:index];
-		else if (stage == ShaderStage::STAGE_PIXEL)
+		else if (stage == SHADERSTAGE_PIXEL)
 			[encoder setFragmentTexture:texture atIndex:index];
 	}
 }
 
-static inline void setSampler(id<MTLRenderCommandEncoder> encoder, Graphics::RenderEncoderBindings &bindings, ShaderStage::StageType stage, int index, id<MTLSamplerState> sampler)
+static inline void setSampler(id<MTLRenderCommandEncoder> encoder, Graphics::RenderEncoderBindings &bindings, ShaderStageType stage, int index, id<MTLSamplerState> sampler)
 {
 	void *s = (__bridge void *)sampler;
 	auto &binding = bindings.samplers[index][stage];
 	if (binding != s)
 	{
 		binding = s;
-		if (stage == ShaderStage::STAGE_VERTEX)
+		if (stage == SHADERSTAGE_VERTEX)
 			[encoder setVertexSamplerState:sampler atIndex:index];
-		else if (stage == ShaderStage::STAGE_PIXEL)
+		else if (stage == SHADERSTAGE_PIXEL)
 			[encoder setFragmentSamplerState:sampler atIndex:index];
 	}
 }
@@ -297,8 +297,8 @@ Graphics::Graphics()
 		if (!Shader::standardShaders[i])
 		{
 			std::vector<std::string> stages;
-			stages.push_back(Shader::getDefaultCode(stype, ShaderStage::STAGE_VERTEX));
-			stages.push_back(Shader::getDefaultCode(stype, ShaderStage::STAGE_PIXEL));
+			stages.push_back(Shader::getDefaultCode(stype, SHADERSTAGE_VERTEX));
+			stages.push_back(Shader::getDefaultCode(stype, SHADERSTAGE_PIXEL));
 			Shader::standardShaders[i] = newShader(stages);
 		}
 	}
@@ -361,14 +361,14 @@ love::graphics::Texture *Graphics::newTexture(const Texture::Settings &settings,
 	return new Texture(this, device, settings, data);
 }
 
-love::graphics::ShaderStage *Graphics::newShaderStageInternal(ShaderStage::StageType stage, const std::string &cachekey, const std::string &source, bool gles)
+love::graphics::ShaderStage *Graphics::newShaderStageInternal(ShaderStageType stage, const std::string &cachekey, const std::string &source, bool gles)
 {
 	return new ShaderStage(this, stage, source, gles, cachekey);
 }
 
-love::graphics::Shader *Graphics::newShaderInternal(love::graphics::ShaderStage *vertex, love::graphics::ShaderStage *pixel)
+love::graphics::Shader *Graphics::newShaderInternal(StrongRef<love::graphics::ShaderStage> stages[SHADERSTAGE_MAX_ENUM])
 {
-	return new Shader(device, vertex, pixel);
+	return new Shader(device, stages);
 }
 
 love::graphics::Buffer *Graphics::newBuffer(const Buffer::Settings &settings, const std::vector<Buffer::DataDeclaration> &format, const void *data, size_t size, size_t arraylength)
@@ -573,7 +573,7 @@ id<MTLRenderCommandEncoder> Graphics::useRenderEncoder()
 		renderBindings = {};
 
 		id<MTLBuffer> defaultbuffer = getMTLBuffer(defaultAttributesBuffer);
-		setBuffer(renderEncoder, renderBindings, ShaderStage::STAGE_VERTEX, DEFAULT_VERTEX_BUFFER_BINDING, defaultbuffer, 0);
+		setBuffer(renderEncoder, renderBindings, SHADERSTAGE_VERTEX, DEFAULT_VERTEX_BUFFER_BINDING, defaultbuffer, 0);
 
 		dirtyRenderState = STATEBIT_ALL;
 	}
@@ -925,8 +925,8 @@ void Graphics::applyShaderUniforms(id<MTLRenderCommandEncoder> renderEncoder, lo
 	int uniformindex = Shader::getUniformBufferBinding();
 
 	auto &bindings = renderBindings;
-	setBuffer(renderEncoder, bindings, ShaderStage::STAGE_VERTEX, uniformindex, buffer, uniformBufferOffset);
-	setBuffer(renderEncoder, bindings, ShaderStage::STAGE_PIXEL, uniformindex, buffer, uniformBufferOffset);
+	setBuffer(renderEncoder, bindings, SHADERSTAGE_VERTEX, uniformindex, buffer, uniformBufferOffset);
+	setBuffer(renderEncoder, bindings, SHADERSTAGE_PIXEL, uniformindex, buffer, uniformBufferOffset);
 
 	uniformBufferOffset += alignUp(size, alignment);
 
@@ -939,40 +939,40 @@ void Graphics::applyShaderUniforms(id<MTLRenderCommandEncoder> renderEncoder, lo
 		{
 			if (maintex == nullptr)
 			{
-				auto textype = shader->getMainTextureType();
-				if (textype != TEXTURE_MAX_ENUM)
-					maintex = defaultTextures[textype];
+				auto texinfo = shader->getMainTextureInfo();
+				if (texinfo != nullptr && texinfo->textureType != TEXTURE_MAX_ENUM)
+					maintex = defaultTextures[texinfo->textureType];
 			}
 
 			texture = getMTLTexture(maintex);
 			sampler = getMTLSampler(maintex);
 		}
 
-		uint8 texindex = b.textureStages[ShaderStage::STAGE_VERTEX];
-		uint8 sampindex = b.samplerStages[ShaderStage::STAGE_VERTEX];
+		uint8 texindex = b.textureStages[SHADERSTAGE_VERTEX];
+		uint8 sampindex = b.samplerStages[SHADERSTAGE_VERTEX];
 
 		if (texindex != LOVE_UINT8_MAX)
-			setTexture(renderEncoder, bindings, ShaderStage::STAGE_VERTEX, texindex, texture);
+			setTexture(renderEncoder, bindings, SHADERSTAGE_VERTEX, texindex, texture);
 		if (sampindex != LOVE_UINT8_MAX)
-			setSampler(renderEncoder, bindings, ShaderStage::STAGE_VERTEX, sampindex, sampler);
+			setSampler(renderEncoder, bindings, SHADERSTAGE_VERTEX, sampindex, sampler);
 
-		texindex = b.textureStages[ShaderStage::STAGE_PIXEL];
-		sampindex = b.samplerStages[ShaderStage::STAGE_PIXEL];
+		texindex = b.textureStages[SHADERSTAGE_PIXEL];
+		sampindex = b.samplerStages[SHADERSTAGE_PIXEL];
 
 		if (texindex != LOVE_UINT8_MAX)
-			setTexture(renderEncoder, bindings, ShaderStage::STAGE_PIXEL, texindex, texture);
+			setTexture(renderEncoder, bindings, SHADERSTAGE_PIXEL, texindex, texture);
 		if (sampindex != LOVE_UINT8_MAX)
-			setSampler(renderEncoder, bindings, ShaderStage::STAGE_PIXEL, sampindex, sampler);
+			setSampler(renderEncoder, bindings, SHADERSTAGE_PIXEL, sampindex, sampler);
 	}
 
 	for (const Shader::BufferBinding &b : s->getBufferBindings())
 	{
-		uint8 index = b.stages[ShaderStage::STAGE_VERTEX];
+		uint8 index = b.stages[SHADERSTAGE_VERTEX];
 		if (index != LOVE_UINT8_MAX)
-			setBuffer(renderEncoder, bindings, ShaderStage::STAGE_VERTEX, index, b.buffer, 0);
-		index = b.stages[ShaderStage::STAGE_PIXEL];
+			setBuffer(renderEncoder, bindings, SHADERSTAGE_VERTEX, index, b.buffer, 0);
+		index = b.stages[SHADERSTAGE_PIXEL];
 		if (index != LOVE_UINT8_MAX)
-			setBuffer(renderEncoder, bindings, ShaderStage::STAGE_PIXEL, index, b.buffer, 0);
+			setBuffer(renderEncoder, bindings, SHADERSTAGE_PIXEL, index, b.buffer, 0);
 	}
 }
 
@@ -988,7 +988,7 @@ static void setVertexBuffers(id<MTLRenderCommandEncoder> encoder, const BufferBi
 		{
 			auto b = buffers->info[i];
 			id<MTLBuffer> buffer = getMTLBuffer(b.buffer);
-			setBuffer(encoder, bindings, ShaderStage::STAGE_VERTEX, i + VERTEX_BUFFER_BINDING_START, buffer, b.offset);
+			setBuffer(encoder, bindings, SHADERSTAGE_VERTEX, i + VERTEX_BUFFER_BINDING_START, buffer, b.offset);
 		}
 
 		i++;
@@ -1077,6 +1077,12 @@ void Graphics::drawQuads(int start, int count, const VertexAttributes &attribute
 	}
 }}
 
+bool Graphics::dispatch(int x, int y, int z)
+{
+	// TODO
+	return false;
+}
+
 void Graphics::setRenderTargetsInternal(const RenderTargets &rts, int w, int h, int /*pixelw*/, int /*pixelh*/, bool /*hasSRGBtexture*/)
 { @autoreleasepool {
 	endPass();
@@ -1145,7 +1151,7 @@ void Graphics::endPass()
 	}
 }
 
-void Graphics::clear(OptionalColorf c, OptionalInt stencil, OptionalDouble depth)
+void Graphics::clear(OptionalColorD c, OptionalInt stencil, OptionalDouble depth)
 { @autoreleasepool {
 	if (c.hasValue || stencil.hasValue || depth.hasValue)
 	{
@@ -1161,8 +1167,9 @@ void Graphics::clear(OptionalColorf c, OptionalInt stencil, OptionalDouble depth
 
 	if (c.hasValue)
 	{
-		gammaCorrectColor(c.value);
-		auto color = MTLClearColorMake(c.value.r, c.value.g, c.value.b, c.value.a);
+		Colorf cf((float)c.value.r, (float)c.value.g, (float)c.value.b, (float)c.value.a);
+		gammaCorrectColor(cf);
+		auto color = MTLClearColorMake(cf.r, cf.g, cf.b, cf.a);
 		for (int i = 0; i < MAX_COLOR_RENDER_TARGETS; i++)
 		{
 			passDesc.colorAttachments[i].clearColor = color;
@@ -1183,7 +1190,7 @@ void Graphics::clear(OptionalColorf c, OptionalInt stencil, OptionalDouble depth
 	}
 }}
 
-void Graphics::clear(const std::vector<OptionalColorf> &colors, OptionalInt stencil, OptionalDouble depth)
+void Graphics::clear(const std::vector<OptionalColorD> &colors, OptionalInt stencil, OptionalDouble depth)
 { @autoreleasepool {
 	if (colors.size() == 0 && !stencil.hasValue && !depth.hasValue)
 		return;
@@ -1193,7 +1200,7 @@ void Graphics::clear(const std::vector<OptionalColorf> &colors, OptionalInt sten
 
 	if (ncolors <= 1 && ncolorcanvases <= 1)
 	{
-		clear(ncolors > 0 ? colors[0] : OptionalColorf(), stencil, depth);
+		clear(ncolors > 0 ? colors[0] : OptionalColorD(), stencil, depth);
 		return;
 	}
 
@@ -1211,10 +1218,11 @@ void Graphics::clear(const std::vector<OptionalColorf> &colors, OptionalInt sten
 		if (!colors[i].hasValue)
 			continue;
 
-		Colorf c = colors[i].value;
-		gammaCorrectColor(c);
+		const ColorD &cd = colors[i].value;
+		Colorf cf((float)cd.r, (float)cd.g, (float)cd.b, (float)cd.a);
+		gammaCorrectColor(cf);
 
-		passDesc.colorAttachments[i].clearColor = MTLClearColorMake(c.r, c.g, c.b, c.a);
+		passDesc.colorAttachments[i].clearColor = MTLClearColorMake(cf.r, cf.g, cf.b, cf.a);
 		passDesc.colorAttachments[i].loadAction = MTLLoadActionClear;
 	}
 
@@ -1539,19 +1547,16 @@ PixelFormat Graphics::getSizedFormat(PixelFormat format, bool /*rendertarget*/,
 	}
 }
 
-bool Graphics::isPixelFormatSupported(PixelFormat format, bool rendertarget, bool readable, bool sRGB)
+bool Graphics::isPixelFormatSupported(PixelFormat format, PixelFormatUsageFlags usage, bool sRGB)
 {
+	bool rendertarget = (usage & PIXELFORMATUSAGEFLAGS_RENDERTARGET) != 0;
+	bool readable = (usage & PIXELFORMATUSAGEFLAGS_SAMPLE) != 0;
+
 	format = getSizedFormat(format, rendertarget, readable);
 
 	if (sRGB)
 		format = getSRGBPixelFormat(format);
 
-	uint32 requiredflags = 0;
-	if (rendertarget)
-		requiredflags |= PIXELFORMATUSAGEFLAGS_RENDERTARGET;
-	if (readable)
-		requiredflags |= PIXELFORMATUSAGEFLAGS_SAMPLE;
-
 	const uint32 sample = PIXELFORMATUSAGEFLAGS_SAMPLE;
 	const uint32 rt = PIXELFORMATUSAGEFLAGS_RENDERTARGET;
 	const uint32 blend = PIXELFORMATUSAGEFLAGS_BLEND;
@@ -1750,7 +1755,7 @@ bool Graphics::isPixelFormatSupported(PixelFormat format, bool rendertarget, boo
 			break;
 	}
 
-	return (requiredflags & flags) == requiredflags;
+	return (usage & flags) == usage;
 }
 
 Graphics::Renderer Graphics::getRenderer() const
@@ -1855,13 +1860,16 @@ void Graphics::initCapabilities()
 	}
 	capabilities.limits[LIMIT_TEXEL_BUFFER_SIZE] = 128 * 1024 * 1024;
 	capabilities.limits[LIMIT_SHADER_STORAGE_BUFFER_SIZE] = 128 * 1024 * 1024; // TODO;
+	capabilities.limits[LIMIT_THREADGROUPS_X] = LOVE_INT32_MAX; // TODO: is there a real limit?
+	capabilities.limits[LIMIT_THREADGROUPS_Y] = LOVE_INT32_MAX;
+	capabilities.limits[LIMIT_THREADGROUPS_Z] = LOVE_INT32_MAX;
 	if (families.mac[1] || families.macCatalyst[1] || families.apple[2])
 		capabilities.limits[LIMIT_RENDER_TARGETS] = 8;
 	else
 		capabilities.limits[LIMIT_RENDER_TARGETS] = 4;
 	capabilities.limits[LIMIT_TEXTURE_MSAA] = msaa;
 	capabilities.limits[LIMIT_ANISOTROPY] = 16.0f;
-	static_assert(LIMIT_MAX_ENUM == 10, "Graphics::initCapabilities must be updated when adding a new system limit!");
+	static_assert(LIMIT_MAX_ENUM == 13, "Graphics::initCapabilities must be updated when adding a new system limit!");
 
 	for (int i = 0; i < TEXTURE_MAX_ENUM; i++)
 		capabilities.textureTypes[i] = true;

+ 5 - 5
src/modules/graphics/metal/Shader.h

@@ -80,17 +80,17 @@ public:
 
 		bool isMainTexture;
 
-		uint8 textureStages[ShaderStage::STAGE_MAX_ENUM];
-		uint8 samplerStages[ShaderStage::STAGE_MAX_ENUM];
+		uint8 textureStages[SHADERSTAGE_MAX_ENUM];
+		uint8 samplerStages[SHADERSTAGE_MAX_ENUM];
 	};
 
 	struct BufferBinding
 	{
 		id<MTLBuffer> buffer;
-		uint8 stages[ShaderStage::STAGE_MAX_ENUM];
+		uint8 stages[SHADERSTAGE_MAX_ENUM];
 	};
 
-	Shader(id<MTLDevice> device, love::graphics::ShaderStage *vertex, love::graphics::ShaderStage *pixel);
+	Shader(id<MTLDevice> device, StrongRef<love::graphics::ShaderStage> stages[SHADERSTAGE_MAX_ENUM]);
 	virtual ~Shader();
 
 	// Implements Shader.
@@ -128,7 +128,7 @@ private:
 
 	void compileFromGLSLang(id<MTLDevice> device, const glslang::TProgram &program);
 
-	id<MTLFunction> functions[ShaderStage::STAGE_MAX_ENUM];
+	id<MTLFunction> functions[SHADERSTAGE_MAX_ENUM];
 
 	UniformInfo *builtinUniformInfo[BUILTIN_MAX_ENUM];
 	std::map<std::string, UniformInfo> uniforms;

+ 18 - 17
src/modules/graphics/metal/Shader.mm

@@ -237,19 +237,20 @@ static inline id<MTLSamplerState> getMTLSampler(love::graphics::Texture *tex)
 	return tex ? (__bridge id<MTLSamplerState>)(void *) tex->getSamplerHandle() : nil;
 }
 
-static EShLanguage getGLSLangStage(ShaderStage::StageType stage)
+static EShLanguage getGLSLangStage(ShaderStageType stage)
 {
 	switch (stage)
 	{
-		case ShaderStage::STAGE_VERTEX: return EShLangVertex;
-		case ShaderStage::STAGE_PIXEL: return EShLangFragment;
-		case ShaderStage::STAGE_MAX_ENUM: return EShLangCount;
+		case SHADERSTAGE_VERTEX: return EShLangVertex;
+		case SHADERSTAGE_PIXEL: return EShLangFragment;
+		case SHADERSTAGE_COMPUTE: return EShLangCompute;
+		case SHADERSTAGE_MAX_ENUM: return EShLangCount;
 	}
 	return EShLangCount;
 }
 
-Shader::Shader(id<MTLDevice> device, love::graphics::ShaderStage *vertex, love::graphics::ShaderStage *pixel)
-	: love::graphics::Shader(vertex, pixel)
+Shader::Shader(id<MTLDevice> device, StrongRef<love::graphics::ShaderStage> stages[SHADERSTAGE_MAX_ENUM])
+	: love::graphics::Shader(stages)
 	, functions()
 	, builtinUniformInfo()
 	, localUniformStagingData(nullptr)
@@ -259,25 +260,25 @@ Shader::Shader(id<MTLDevice> device, love::graphics::ShaderStage *vertex, love::
 { @autoreleasepool {
 	using namespace glslang;
 
-	TShader *glslangShaders[ShaderStage::STAGE_MAX_ENUM] = {};
+	TShader *glslangShaders[SHADERSTAGE_MAX_ENUM] = {};
 
 	TProgram *program = new TProgram();
 
 	auto cleanup = [&]()
 	{
 		delete program;
-		for (int i = 0; i < ShaderStage::STAGE_MAX_ENUM; i++)
+		for (int i = 0; i < SHADERSTAGE_MAX_ENUM; i++)
 			delete glslangShaders[i];
 	};
 
 	// We can't do this in ShaderStage because the mapIO call modifies the
 	// TShader internals in a manner that prevents it from being shared.
-	for (int i = 0; i < ShaderStage::STAGE_MAX_ENUM; i++)
+	for (int i = 0; i < SHADERSTAGE_MAX_ENUM; i++)
 	{
 		if (!stages[i])
 			continue;
 
-		auto stage = (ShaderStage::StageType) i;
+		auto stage = (ShaderStageType) i;
 		auto glslangstage = getGLSLangStage(stage);
 		auto tshader = new TShader(glslangstage);
 
@@ -358,9 +359,9 @@ void Shader::compileFromGLSLang(id<MTLDevice> device, const glslang::TProgram &p
 	std::map<std::string, int> varyings;
 	int nextVaryingLocation = 0;
 
-	for (int stageindex = 0; stageindex < ShaderStage::STAGE_MAX_ENUM; stageindex++)
+	for (int stageindex = 0; stageindex < SHADERSTAGE_MAX_ENUM; stageindex++)
 	{
-		auto glslangstage = getGLSLangStage((ShaderStage::StageType) stageindex);
+		auto glslangstage = getGLSLangStage((ShaderStageType) stageindex);
 		auto intermediate = program.getIntermediate(glslangstage);
 		if (intermediate == nullptr)
 			continue;
@@ -561,7 +562,7 @@ void Shader::compileFromGLSLang(id<MTLDevice> device, const glslang::TProgram &p
 				// TODO
 			}
 
-			if (stageindex == ShaderStage::STAGE_VERTEX)
+			if (stageindex == SHADERSTAGE_VERTEX)
 			{
 				int nextattributeindex = ATTRIB_MAX_ENUM;
 
@@ -592,7 +593,7 @@ void Shader::compileFromGLSLang(id<MTLDevice> device, const glslang::TProgram &p
 					msl.set_decoration(varying.id, spv::DecorationLocation, nextVaryingLocation++);
 				}
 			}
-			else if (stageindex == ShaderStage::STAGE_PIXEL)
+			else if (stageindex == SHADERSTAGE_PIXEL)
 			{
 				for (const auto &varying : resources.stage_inputs)
 				{
@@ -723,7 +724,7 @@ void Shader::compileFromGLSLang(id<MTLDevice> device, const glslang::TProgram &p
 
 Shader::~Shader()
 { @autoreleasepool {
-	for (int i = 0; i < ShaderStage::STAGE_MAX_ENUM; i++)
+	for (int i = 0; i < SHADERSTAGE_MAX_ENUM; i++)
 		functions[i] = nil;
 
 	for (const auto &kvp : cachedRenderPipelines)
@@ -912,8 +913,8 @@ id<MTLRenderPipelineState> Shader::getCachedRenderPipeline(const RenderPipelineK
 
 	MTLRenderPipelineDescriptor *desc = [MTLRenderPipelineDescriptor new];
 
-	desc.vertexFunction = functions[ShaderStage::STAGE_VERTEX];
-	desc.fragmentFunction = functions[ShaderStage::STAGE_PIXEL];
+	desc.vertexFunction = functions[SHADERSTAGE_VERTEX];
+	desc.fragmentFunction = functions[SHADERSTAGE_PIXEL];
 
 	desc.rasterSampleCount = std::max((int) key.msaa, 1);
 

+ 1 - 1
src/modules/graphics/metal/ShaderStage.h

@@ -33,7 +33,7 @@ class ShaderStage final : public love::graphics::ShaderStage
 {
 public:
 
-	ShaderStage(love::graphics::Graphics *gfx, StageType stage, const std::string &source, bool gles, const std::string &cachekey);
+	ShaderStage(love::graphics::Graphics *gfx, ShaderStageType stage, const std::string &source, bool gles, const std::string &cachekey);
 	virtual ~ShaderStage();
 	ptrdiff_t getHandle() const override { return 0; }
 

+ 1 - 1
src/modules/graphics/metal/ShaderStage.mm

@@ -29,7 +29,7 @@ namespace graphics
 namespace metal
 {
 
-ShaderStage::ShaderStage(love::graphics::Graphics *gfx, StageType stage, const std::string &source, bool gles, const std::string &cachekey)
+ShaderStage::ShaderStage(love::graphics::Graphics *gfx, ShaderStageType stage, const std::string &source, bool gles, const std::string &cachekey)
 	: love::graphics::ShaderStage(gfx, stage, source, gles, cachekey)
 {
 	// Can't store anything in here since the next part of the compilation

+ 1 - 1
src/modules/graphics/opengl/Graphics.cpp

@@ -1712,7 +1712,7 @@ PixelFormat Graphics::getSizedFormat(PixelFormat format, bool rendertarget, bool
 
 bool Graphics::isPixelFormatSupported(PixelFormat format, PixelFormatUsageFlags usage, bool sRGB)
 {
-	if (sRGB && format == PIXELFORMAT_RGBA8_UNORM)
+	if (sRGB)
 	{
 		format = getSRGBPixelFormat(format);
 		sRGB = false;