Browse Source

Minimum required opengl version is now OpenGL 3.3 / OpenGL ES 3.0.

Sasha Szpakowski 1 year ago
parent
commit
54a31ec615

+ 0 - 3
src/modules/graphics/Buffer.cpp

@@ -86,9 +86,6 @@ Buffer::Buffer(Graphics *gfx, const Settings &settings, const std::vector<DataDe
 
 
 		if (indexbuffer)
 		if (indexbuffer)
 		{
 		{
-			if (!caps.features[Graphics::FEATURE_INDEX_BUFFER_32BIT] && format == DATAFORMAT_UINT32)
-				throw love::Exception("32 bit index buffer formats are not supported on this system.");
-
 			if (format != DATAFORMAT_UINT16 && format != DATAFORMAT_UINT32)
 			if (format != DATAFORMAT_UINT16 && format != DATAFORMAT_UINT32)
 				throw love::Exception("Index buffers only support uint16 and uint32 data types.");
 				throw love::Exception("Index buffers only support uint16 and uint32 data types.");
 
 

+ 0 - 15
src/modules/graphics/Graphics.cpp

@@ -1604,9 +1604,6 @@ void Graphics::captureScreenshot(const ScreenshotInfo &info)
 
 
 void Graphics::copyBuffer(Buffer *source, Buffer *dest, size_t sourceoffset, size_t destoffset, size_t size)
 void Graphics::copyBuffer(Buffer *source, Buffer *dest, size_t sourceoffset, size_t destoffset, size_t size)
 {
 {
-	if (!capabilities.features[FEATURE_COPY_BUFFER])
-		throw love::Exception("Buffer copying is not supported on this system.");
-
 	Range sourcerange(sourceoffset, size);
 	Range sourcerange(sourceoffset, size);
 	Range destrange(destoffset, size);
 	Range destrange(destoffset, size);
 
 
@@ -1640,9 +1637,6 @@ void Graphics::copyTextureToBuffer(Texture *source, Buffer *dest, int slice, int
 	{
 	{
 		if (!source->isRenderTarget())
 		if (!source->isRenderTarget())
 			throw love::Exception("Copying a non-render target Texture to a Buffer is not supported on this system.");
 			throw love::Exception("Copying a non-render target Texture to a Buffer is not supported on this system.");
-
-		if (!capabilities.features[FEATURE_COPY_RENDER_TARGET_TO_BUFFER])
-			throw love::Exception("Copying a render target Texture to a Buffer is not supported on this system.");
 	}
 	}
 
 
 	PixelFormat format = source->getPixelFormat();
 	PixelFormat format = source->getPixelFormat();
@@ -1728,9 +1722,6 @@ void Graphics::copyTextureToBuffer(Texture *source, Buffer *dest, int slice, int
 
 
 void Graphics::copyBufferToTexture(Buffer *source, Texture *dest, size_t sourceoffset, int sourcewidth, int slice, int mipmap, const Rect &rect)
 void Graphics::copyBufferToTexture(Buffer *source, Texture *dest, size_t sourceoffset, int sourcewidth, int slice, int mipmap, const Rect &rect)
 {
 {
-	if (!capabilities.features[FEATURE_COPY_BUFFER_TO_TEXTURE])
-		throw love::Exception("Copying a Buffer to a Texture is not supported on this system.");
-
 	if (source->getDataUsage() == BUFFERDATAUSAGE_READBACK)
 	if (source->getDataUsage() == BUFFERDATAUSAGE_READBACK)
 		throw love::Exception("Buffers created with 'readback' data usage cannot be used as a copy source.");
 		throw love::Exception("Buffers created with 'readback' data usage cannot be used as a copy source.");
 
 
@@ -2914,7 +2905,6 @@ STRINGMAP_CLASS_BEGIN(Graphics, Graphics::Feature, Graphics::FEATURE_MAX_ENUM, f
 	{ "multirendertargetformats", Graphics::FEATURE_MULTI_RENDER_TARGET_FORMATS },
 	{ "multirendertargetformats", Graphics::FEATURE_MULTI_RENDER_TARGET_FORMATS },
 	{ "clampzero",                Graphics::FEATURE_CLAMP_ZERO           },
 	{ "clampzero",                Graphics::FEATURE_CLAMP_ZERO           },
 	{ "clampone",                 Graphics::FEATURE_CLAMP_ONE            },
 	{ "clampone",                 Graphics::FEATURE_CLAMP_ONE            },
-	{ "blendminmax",              Graphics::FEATURE_BLEND_MINMAX         },
 	{ "lighten",                  Graphics::FEATURE_LIGHTEN              },
 	{ "lighten",                  Graphics::FEATURE_LIGHTEN              },
 	{ "fullnpot",                 Graphics::FEATURE_FULL_NPOT            },
 	{ "fullnpot",                 Graphics::FEATURE_FULL_NPOT            },
 	{ "pixelshaderhighp",         Graphics::FEATURE_PIXEL_SHADER_HIGHP   },
 	{ "pixelshaderhighp",         Graphics::FEATURE_PIXEL_SHADER_HIGHP   },
@@ -2923,12 +2913,7 @@ STRINGMAP_CLASS_BEGIN(Graphics, Graphics::Feature, Graphics::FEATURE_MAX_ENUM, f
 	{ "glsl4",                    Graphics::FEATURE_GLSL4                },
 	{ "glsl4",                    Graphics::FEATURE_GLSL4                },
 	{ "instancing",               Graphics::FEATURE_INSTANCING           },
 	{ "instancing",               Graphics::FEATURE_INSTANCING           },
 	{ "texelbuffer",              Graphics::FEATURE_TEXEL_BUFFER         },
 	{ "texelbuffer",              Graphics::FEATURE_TEXEL_BUFFER         },
-	{ "indexbuffer32bit",         Graphics::FEATURE_INDEX_BUFFER_32BIT   },
-	{ "copybuffer",               Graphics::FEATURE_COPY_BUFFER          },
-	{ "copybuffertotexture",      Graphics::FEATURE_COPY_BUFFER_TO_TEXTURE },
 	{ "copytexturetobuffer",      Graphics::FEATURE_COPY_TEXTURE_TO_BUFFER },
 	{ "copytexturetobuffer",      Graphics::FEATURE_COPY_TEXTURE_TO_BUFFER },
-	{ "copyrendertargettobuffer", Graphics::FEATURE_COPY_RENDER_TARGET_TO_BUFFER },
-	{ "mipmaprange",              Graphics::FEATURE_MIPMAP_RANGE         },
 	{ "indirectdraw",             Graphics::FEATURE_INDIRECT_DRAW        },
 	{ "indirectdraw",             Graphics::FEATURE_INDIRECT_DRAW        },
 }
 }
 STRINGMAP_CLASS_END(Graphics, Graphics::Feature, Graphics::FEATURE_MAX_ENUM, feature)
 STRINGMAP_CLASS_END(Graphics, Graphics::Feature, Graphics::FEATURE_MAX_ENUM, feature)

+ 6 - 12
src/modules/graphics/Graphics.h

@@ -147,24 +147,18 @@ public:
 
 
 	enum Feature
 	enum Feature
 	{
 	{
-		FEATURE_MULTI_RENDER_TARGET_FORMATS,
+		FEATURE_MULTI_RENDER_TARGET_FORMATS, // Deprecated
 		FEATURE_CLAMP_ZERO,
 		FEATURE_CLAMP_ZERO,
 		FEATURE_CLAMP_ONE,
 		FEATURE_CLAMP_ONE,
-		FEATURE_BLEND_MINMAX,
 		FEATURE_LIGHTEN, // Deprecated
 		FEATURE_LIGHTEN, // Deprecated
-		FEATURE_FULL_NPOT,
-		FEATURE_PIXEL_SHADER_HIGHP,
-		FEATURE_SHADER_DERIVATIVES,
-		FEATURE_GLSL3,
+		FEATURE_FULL_NPOT, // Deprecated
+		FEATURE_PIXEL_SHADER_HIGHP, // Deprecated
+		FEATURE_SHADER_DERIVATIVES, // Deprecated
+		FEATURE_GLSL3, // Deprecated
 		FEATURE_GLSL4,
 		FEATURE_GLSL4,
-		FEATURE_INSTANCING,
+		FEATURE_INSTANCING, // Deprecated
 		FEATURE_TEXEL_BUFFER,
 		FEATURE_TEXEL_BUFFER,
-		FEATURE_INDEX_BUFFER_32BIT,
-		FEATURE_COPY_BUFFER,
-		FEATURE_COPY_BUFFER_TO_TEXTURE,
 		FEATURE_COPY_TEXTURE_TO_BUFFER,
 		FEATURE_COPY_TEXTURE_TO_BUFFER,
-		FEATURE_COPY_RENDER_TARGET_TO_BUFFER,
-		FEATURE_MIPMAP_RANGE,
 		FEATURE_INDIRECT_DRAW,
 		FEATURE_INDIRECT_DRAW,
 		FEATURE_MAX_ENUM
 		FEATURE_MAX_ENUM
 	};
 	};

+ 1 - 6
src/modules/graphics/GraphicsReadback.cpp

@@ -40,9 +40,6 @@ GraphicsReadback::GraphicsReadback(Graphics *gfx, ReadbackMethod method, Buffer
 {
 {
 	const auto &caps = gfx->getCapabilities();
 	const auto &caps = gfx->getCapabilities();
 
 
-	if (!caps.features[Graphics::FEATURE_COPY_BUFFER])
-		throw love::Exception("readbackBuffer is not supported on this system (buffer copy support is required).");
-
 	if (offset + size > buffer->getSize())
 	if (offset + size > buffer->getSize())
 		throw love::Exception("Invalid offset or size for the given Buffer.");
 		throw love::Exception("Invalid offset or size for the given Buffer.");
 
 
@@ -94,9 +91,7 @@ GraphicsReadback::GraphicsReadback(Graphics *gfx, ReadbackMethod method, Texture
 
 
 	if (method == READBACK_ASYNC)
 	if (method == READBACK_ASYNC)
 	{
 	{
-		if (isRT && !caps.features[Graphics::FEATURE_COPY_RENDER_TARGET_TO_BUFFER])
-			throw love::Exception("readbackTextureAsync is not supported on this system.");
-		else if (!isRT && !caps.features[Graphics::FEATURE_COPY_TEXTURE_TO_BUFFER])
+		if (!isRT && !caps.features[Graphics::FEATURE_COPY_TEXTURE_TO_BUFFER])
 			throw love::Exception("readbackTextureAsync with a non-render-target texture is not supported on this system.");
 			throw love::Exception("readbackTextureAsync with a non-render-target texture is not supported on this system.");
 	}
 	}
 	else
 	else

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

@@ -51,11 +51,7 @@ static const char global_syntax[] = R"(
 	#define mediump
 	#define mediump
 	#define highp
 	#define highp
 #endif
 #endif
-#if defined(VERTEX) || __VERSION__ > 100 || defined(GL_FRAGMENT_PRECISION_HIGH)
-	#define LOVE_HIGHP_OR_MEDIUMP highp
-#else
-	#define LOVE_HIGHP_OR_MEDIUMP mediump
-#endif
+#define LOVE_HIGHP_OR_MEDIUMP highp
 #if __VERSION__ >= 300
 #if __VERSION__ >= 300
 #define LOVE_IO_LOCATION(x) layout (location = x)
 #define LOVE_IO_LOCATION(x) layout (location = x)
 #else
 #else
@@ -88,15 +84,7 @@ static const char global_syntax[] = R"(
 )";
 )";
 
 
 static const char render_uniforms[] = R"(
 static const char render_uniforms[] = R"(
-// According to the GLSL ES 1.0 spec, uniform precision must match between stages,
-// but we can't guarantee that highp is always supported in fragment shaders...
-// We *really* don't want to use mediump for these in vertex shaders though.
-#ifdef LOVE_SPLIT_UNIFORMS_PER_DRAW
-uniform LOVE_HIGHP_OR_MEDIUMP vec4 love_UniformsPerDraw[11];
-uniform LOVE_HIGHP_OR_MEDIUMP vec4 love_UniformsPerDraw2[1];
-#else
-uniform LOVE_HIGHP_OR_MEDIUMP vec4 love_UniformsPerDraw[12];
-#endif
+uniform highp vec4 love_UniformsPerDraw[12];
 
 
 // Older GLSL doesn't support preprocessor line continuations...
 // Older GLSL doesn't support preprocessor line continuations...
 #define TransformMatrix mat4(love_UniformsPerDraw[0], love_UniformsPerDraw[1], love_UniformsPerDraw[2], love_UniformsPerDraw[3])
 #define TransformMatrix mat4(love_UniformsPerDraw[0], love_UniformsPerDraw[1], love_UniformsPerDraw[2], love_UniformsPerDraw[3])
@@ -105,16 +93,9 @@ uniform LOVE_HIGHP_OR_MEDIUMP vec4 love_UniformsPerDraw[12];
 
 
 #define CurrentDPIScale (love_UniformsPerDraw[8].x)
 #define CurrentDPIScale (love_UniformsPerDraw[8].x)
 #define ConstantPointSize (love_UniformsPerDraw[8].y)
 #define ConstantPointSize (love_UniformsPerDraw[8].y)
-
 #define love_ClipSpaceParams (love_UniformsPerDraw[9])
 #define love_ClipSpaceParams (love_UniformsPerDraw[9])
-
 #define ConstantColor (love_UniformsPerDraw[10])
 #define ConstantColor (love_UniformsPerDraw[10])
-
-#ifdef LOVE_SPLIT_UNIFORMS_PER_DRAW
-#define love_ScreenSize (love_UniformsPerDraw2[0])
-#else
 #define love_ScreenSize (love_UniformsPerDraw[11])
 #define love_ScreenSize (love_UniformsPerDraw[11])
-#endif
 
 
 // Alternate names
 // Alternate names
 #define ViewSpaceFromLocal TransformMatrix
 #define ViewSpaceFromLocal TransformMatrix
@@ -667,11 +648,6 @@ std::string Shader::createShaderStageCode(Graphics *gfx, ShaderStageType stage,
 	if (info.usesMRT)
 	if (info.usesMRT)
 		ss << "#define LOVE_MULTI_RENDER_TARGETS 1\n";
 		ss << "#define LOVE_MULTI_RENDER_TARGETS 1\n";
 
 
-	// Note: backends are expected to handle this situation if highp is ever
-	// conditional in that backend.
-	if (!gfx->getCapabilities().features[Graphics::FEATURE_PIXEL_SHADER_HIGHP])
-		ss << "#define LOVE_SPLIT_UNIFORMS_PER_DRAW 1\n";
-
 	for (const auto &def : options.defines)
 	for (const auto &def : options.defines)
 		ss << "#define " + def.first + " " + def.second + "\n";
 		ss << "#define " + def.first + " " + def.second + "\n";
 
 

+ 0 - 3
src/modules/graphics/Texture.cpp

@@ -253,9 +253,6 @@ Texture::Texture(Graphics *gfx, const Settings &settings, const Slices *slices)
 			mipmapCount = std::min(totalMipmapCount, requestedMipmapCount);
 			mipmapCount = std::min(totalMipmapCount, requestedMipmapCount);
 		else
 		else
 			mipmapCount = totalMipmapCount;
 			mipmapCount = totalMipmapCount;
-
-		if (mipmapCount != totalMipmapCount && !caps.features[Graphics::FEATURE_MIPMAP_RANGE])
-			throw love::Exception("Custom mipmap ranges for a texture are not supported on this system (%d mipmap levels are required but only %d levels were provided.)", totalMipmapCount, mipmapCount);
 	}
 	}
 
 
 	const char *miperr = nullptr;
 	const char *miperr = nullptr;

+ 1 - 7
src/modules/graphics/metal/Graphics.mm

@@ -2227,7 +2227,6 @@ void Graphics::initCapabilities()
 		if (families.mac[1] || families.macCatalyst[1] || families.apple[7])
 		if (families.mac[1] || families.macCatalyst[1] || families.apple[7])
 			capabilities.features[FEATURE_CLAMP_ONE] = true;
 			capabilities.features[FEATURE_CLAMP_ONE] = true;
 	}
 	}
-	capabilities.features[FEATURE_BLEND_MINMAX] = true;
 	capabilities.features[FEATURE_LIGHTEN] = true;
 	capabilities.features[FEATURE_LIGHTEN] = true;
 	capabilities.features[FEATURE_FULL_NPOT] = true;
 	capabilities.features[FEATURE_FULL_NPOT] = true;
 	capabilities.features[FEATURE_PIXEL_SHADER_HIGHP] = true;
 	capabilities.features[FEATURE_PIXEL_SHADER_HIGHP] = true;
@@ -2236,19 +2235,14 @@ void Graphics::initCapabilities()
 	capabilities.features[FEATURE_GLSL4] = true;
 	capabilities.features[FEATURE_GLSL4] = true;
 	capabilities.features[FEATURE_INSTANCING] = true;
 	capabilities.features[FEATURE_INSTANCING] = true;
 	capabilities.features[FEATURE_TEXEL_BUFFER] = true;
 	capabilities.features[FEATURE_TEXEL_BUFFER] = true;
-	capabilities.features[FEATURE_INDEX_BUFFER_32BIT] = true;
-	capabilities.features[FEATURE_COPY_BUFFER] = true;
-	capabilities.features[FEATURE_COPY_BUFFER_TO_TEXTURE] = true;
 	capabilities.features[FEATURE_COPY_TEXTURE_TO_BUFFER] = true;
 	capabilities.features[FEATURE_COPY_TEXTURE_TO_BUFFER] = true;
-	capabilities.features[FEATURE_COPY_RENDER_TARGET_TO_BUFFER] = true;
-	capabilities.features[FEATURE_MIPMAP_RANGE] = true;
 
 
 	if (families.mac[1] || families.macCatalyst[1] || families.apple[3])
 	if (families.mac[1] || families.macCatalyst[1] || families.apple[3])
 		capabilities.features[FEATURE_INDIRECT_DRAW] = true;
 		capabilities.features[FEATURE_INDIRECT_DRAW] = true;
 	else
 	else
 		capabilities.features[FEATURE_INDIRECT_DRAW] = false;
 		capabilities.features[FEATURE_INDIRECT_DRAW] = false;
 	
 	
-	static_assert(FEATURE_MAX_ENUM == 19, "Graphics::initCapabilities must be updated when adding a new graphics feature!");
+	static_assert(FEATURE_MAX_ENUM == 13, "Graphics::initCapabilities must be updated when adding a new graphics feature!");
 
 
 	// https://developer.apple.com/metal/Metal-Feature-Set-Tables.pdf
 	// https://developer.apple.com/metal/Metal-Feature-Set-Tables.pdf
 	capabilities.limits[LIMIT_POINT_SIZE] = 511;
 	capabilities.limits[LIMIT_POINT_SIZE] = 511;

+ 1 - 5
src/modules/graphics/opengl/Buffer.cpp

@@ -196,11 +196,7 @@ void *Buffer::map(MapType map, size_t offset, size_t size)
 	if (map == MAP_READ_ONLY)
 	if (map == MAP_READ_ONLY)
 	{
 	{
 		gl.bindBuffer(mapUsage, buffer);
 		gl.bindBuffer(mapUsage, buffer);
-
-		if (GLAD_VERSION_3_0 || GLAD_ES_VERSION_3_0)
-			data = (char *) glMapBufferRange(target, offset, size, GL_MAP_READ_BIT);
-		else if (GLAD_VERSION_1_1)
-			data = (char *) glMapBuffer(target, GL_READ_ONLY) + offset;
+		data = (char *) glMapBufferRange(target, offset, size, GL_MAP_READ_BIT);
 	}
 	}
 	else if (ownsMemoryMap)
 	else if (ownsMemoryMap)
 	{
 	{

+ 24 - 77
src/modules/graphics/opengl/Graphics.cpp

@@ -225,14 +225,6 @@ void Graphics::backbufferChanged(int width, int height, int pixelwidth, int pixe
 	if (msaa > 1)
 	if (msaa > 1)
 		useinternalbackbuffer = true;
 		useinternalbackbuffer = true;
 
 
-	// Our internal backbuffer code needs glBlitFramebuffer.
-	if (!(GLAD_VERSION_3_0 || GLAD_ARB_framebuffer_object || GLAD_ES_VERSION_3_0
-		  || GLAD_EXT_framebuffer_blit || GLAD_ANGLE_framebuffer_blit || GLAD_NV_framebuffer_blit))
-	{
-		if (!(msaa > 1 && GLAD_APPLE_framebuffer_multisample))
-			useinternalbackbuffer = false;
-	}
-
 	GLuint prevFBO = gl.getFramebuffer(OpenGL::FRAMEBUFFER_ALL);
 	GLuint prevFBO = gl.getFramebuffer(OpenGL::FRAMEBUFFER_ALL);
 	bool restoreFBO = prevFBO != getInternalBackbufferFBO();
 	bool restoreFBO = prevFBO != getInternalBackbufferFBO();
 
 
@@ -350,8 +342,7 @@ bool Graphics::setMode(void */*context*/, int width, int height, int pixelwidth,
 		glEnable(GL_TEXTURE_CUBE_MAP_SEAMLESS);
 		glEnable(GL_TEXTURE_CUBE_MAP_SEAMLESS);
 
 
 	// Set whether drawing converts input from linear -> sRGB colorspace.
 	// Set whether drawing converts input from linear -> sRGB colorspace.
-	if (!gl.bugs.brokenSRGB && (GLAD_VERSION_3_0 || GLAD_ARB_framebuffer_sRGB
-		|| GLAD_EXT_framebuffer_sRGB || GLAD_ES_VERSION_3_0))
+	if (!gl.bugs.brokenSRGB)
 	{
 	{
 		if (GLAD_VERSION_1_0 || GLAD_EXT_sRGB_write_control)
 		if (GLAD_VERSION_1_0 || GLAD_EXT_sRGB_write_control)
 			gl.setEnableState(OpenGL::ENABLE_FRAMEBUFFER_SRGB, isGammaCorrect());
 			gl.setEnableState(OpenGL::ENABLE_FRAMEBUFFER_SRGB, isGammaCorrect());
@@ -947,7 +938,6 @@ void Graphics::clear(const std::vector<OptionalColorD> &colors, OptionalInt sten
 
 
 	flushBatchedDraws();
 	flushBatchedDraws();
 
 
-	bool drawbuffersmodified = false;
 	ncolors = std::min(ncolors, ncolorRTs);
 	ncolors = std::min(ncolors, ncolorRTs);
 
 
 	for (int i = 0; i < ncolors; i++)
 	for (int i = 0; i < ncolors; i++)
@@ -961,51 +951,25 @@ void Graphics::clear(const std::vector<OptionalColorD> &colors, OptionalInt sten
 
 
 		ColorD c = colors[i].value;
 		ColorD c = colors[i].value;
 
 
-		if (GLAD_ES_VERSION_3_0 || GLAD_VERSION_3_0)
+		if (datatype == PIXELFORMATTYPE_SINT)
 		{
 		{
-			if (datatype == PIXELFORMATTYPE_SINT)
-			{
-				const GLint carray[] = {(GLint)c.r, (GLint)c.g, (GLint)c.b, (GLint)c.a};
-				glClearBufferiv(GL_COLOR, i, carray);
-			}
-			else if (datatype == PIXELFORMATTYPE_UINT)
-			{
-				const GLuint carray[] = {(GLuint)c.r, (GLuint)c.g, (GLuint)c.b, (GLuint)c.a};
-				glClearBufferuiv(GL_COLOR, i, carray);
-			}
-			else
-			{
-				Colorf cf((float)c.r, (float)c.g, (float)c.b, (float)c.a);
-				gammaCorrectColor(cf);
-				const GLfloat carray[] = {cf.r, cf.g, cf.b, cf.a};
-				glClearBufferfv(GL_COLOR, i, carray);
-			}
+			const GLint carray[] = {(GLint)c.r, (GLint)c.g, (GLint)c.b, (GLint)c.a};
+			glClearBufferiv(GL_COLOR, i, carray);
+		}
+		else if (datatype == PIXELFORMATTYPE_UINT)
+		{
+			const GLuint carray[] = {(GLuint)c.r, (GLuint)c.g, (GLuint)c.b, (GLuint)c.a};
+			glClearBufferuiv(GL_COLOR, i, carray);
 		}
 		}
 		else
 		else
 		{
 		{
 			Colorf cf((float)c.r, (float)c.g, (float)c.b, (float)c.a);
 			Colorf cf((float)c.r, (float)c.g, (float)c.b, (float)c.a);
 			gammaCorrectColor(cf);
 			gammaCorrectColor(cf);
-
-			glDrawBuffer(GL_COLOR_ATTACHMENT0 + i);
-			glClearColor(cf.r, cf.g, cf.b, cf.a);
-			glClear(GL_COLOR_BUFFER_BIT);
-
-			drawbuffersmodified = true;
+			const GLfloat carray[] = {cf.r, cf.g, cf.b, cf.a};
+			glClearBufferfv(GL_COLOR, i, carray);
 		}
 		}
 	}
 	}
 
 
-	// Revert to the expected draw buffers once we're done, if glClearBuffer
-	// wasn't supported.
-	if (drawbuffersmodified)
-	{
-		GLenum bufs[MAX_COLOR_RENDER_TARGETS];
-
-		for (int i = 0; i < ncolorRTs; i++)
-			bufs[i] = GL_COLOR_ATTACHMENT0 + i;
-
-		glDrawBuffers(ncolorRTs, bufs);
-	}
-
 	GLbitfield flags = 0;
 	GLbitfield flags = 0;
 
 
 	if (stencil.hasValue)
 	if (stencil.hasValue)
@@ -1145,7 +1109,7 @@ GLuint Graphics::bindCachedFBO(const RenderTargets &targets)
 		auto attachRT = [&](const RenderTarget &rt)
 		auto attachRT = [&](const RenderTarget &rt)
 		{
 		{
 			bool renderbuffer = msaa > 1 || !rt.texture->isReadable();
 			bool renderbuffer = msaa > 1 || !rt.texture->isReadable();
-			OpenGL::TextureFormat fmt = OpenGL::convertPixelFormat(rt.texture->getPixelFormat(), renderbuffer);
+			OpenGL::TextureFormat fmt = OpenGL::convertPixelFormat(rt.texture->getPixelFormat());
 
 
 			if (fmt.framebufferAttachments[0] == GL_COLOR_ATTACHMENT0)
 			if (fmt.framebufferAttachments[0] == GL_COLOR_ATTACHMENT0)
 			{
 			{
@@ -1183,14 +1147,10 @@ GLuint Graphics::bindCachedFBO(const RenderTargets &targets)
 
 
 		if (ncolortargets > 1)
 		if (ncolortargets > 1)
 			glDrawBuffers(ncolortargets, drawbuffers);
 			glDrawBuffers(ncolortargets, drawbuffers);
-		else if (ncolortargets == 0 && hasDS && (GLAD_ES_VERSION_3_0 || !GLAD_ES_VERSION_2_0))
+		else if (ncolortargets == 0 && hasDS)
 		{
 		{
-			// glDrawBuffers is an ext in GL2. glDrawBuffer doesn't exist in ES3.
 			GLenum none = GL_NONE;
 			GLenum none = GL_NONE;
-			if (GLAD_ES_VERSION_3_0)
-				glDrawBuffers(1, &none);
-			else
-				glDrawBuffer(GL_NONE);
+			glDrawBuffers(1, &none);
 			glReadBuffer(GL_NONE);
 			glReadBuffer(GL_NONE);
 		}
 		}
 
 
@@ -1521,13 +1481,6 @@ void Graphics::setBlendState(const BlendState &blend)
 	if (!(blend == states.back().blend))
 	if (!(blend == states.back().blend))
 		flushBatchedDraws();
 		flushBatchedDraws();
 
 
-	if (blend.operationRGB == BLENDOP_MAX || blend.operationA == BLENDOP_MAX
-		|| blend.operationRGB == BLENDOP_MIN || blend.operationA == BLENDOP_MIN)
-	{
-		if (!capabilities.features[FEATURE_BLEND_MINMAX])
-			throw love::Exception("The 'min' and 'max' blend operations are not supported on this system.");
-	}
-
 	if (blend.enable != gl.isStateEnabled(OpenGL::ENABLE_BLEND))
 	if (blend.enable != gl.isStateEnabled(OpenGL::ENABLE_BLEND))
 		gl.setEnableState(OpenGL::ENABLE_BLEND, blend.enable);
 		gl.setEnableState(OpenGL::ENABLE_BLEND, blend.enable);
 
 
@@ -1629,26 +1582,20 @@ void Graphics::getAPIStats(int &shaderswitches) const
 
 
 void Graphics::initCapabilities()
 void Graphics::initCapabilities()
 {
 {
-	capabilities.features[FEATURE_MULTI_RENDER_TARGET_FORMATS] = gl.isMultiFormatMRTSupported();
+	capabilities.features[FEATURE_MULTI_RENDER_TARGET_FORMATS] = true;
 	capabilities.features[FEATURE_CLAMP_ZERO] = gl.isClampZeroOneTextureWrapSupported();
 	capabilities.features[FEATURE_CLAMP_ZERO] = gl.isClampZeroOneTextureWrapSupported();
 	capabilities.features[FEATURE_CLAMP_ONE] = gl.isClampZeroOneTextureWrapSupported();
 	capabilities.features[FEATURE_CLAMP_ONE] = gl.isClampZeroOneTextureWrapSupported();
-	capabilities.features[FEATURE_BLEND_MINMAX] = GLAD_VERSION_1_4 || GLAD_ES_VERSION_3_0 || GLAD_EXT_blend_minmax;
-	capabilities.features[FEATURE_LIGHTEN] = capabilities.features[FEATURE_BLEND_MINMAX];
-	capabilities.features[FEATURE_FULL_NPOT] = GLAD_VERSION_2_0 || GLAD_ES_VERSION_3_0 || GLAD_OES_texture_npot;
-	capabilities.features[FEATURE_PIXEL_SHADER_HIGHP] = gl.isPixelShaderHighpSupported();
-	capabilities.features[FEATURE_SHADER_DERIVATIVES] = GLAD_VERSION_2_0 || GLAD_ES_VERSION_3_0 || GLAD_OES_standard_derivatives;
-	capabilities.features[FEATURE_GLSL3] = GLAD_ES_VERSION_3_0 || gl.isCoreProfile();
+	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] = GLAD_ES_VERSION_3_1 || (gl.isCoreProfile() && GLAD_VERSION_4_3);
 	capabilities.features[FEATURE_GLSL4] = GLAD_ES_VERSION_3_1 || (gl.isCoreProfile() && GLAD_VERSION_4_3);
-	capabilities.features[FEATURE_INSTANCING] = gl.isInstancingSupported();
+	capabilities.features[FEATURE_INSTANCING] = true;
 	capabilities.features[FEATURE_TEXEL_BUFFER] = gl.isBufferUsageSupported(BUFFERUSAGE_TEXEL);
 	capabilities.features[FEATURE_TEXEL_BUFFER] = gl.isBufferUsageSupported(BUFFERUSAGE_TEXEL);
-	capabilities.features[FEATURE_INDEX_BUFFER_32BIT] = GLAD_VERSION_1_1 || GLAD_ES_VERSION_3_0 || GLAD_OES_element_index_uint;
-	capabilities.features[FEATURE_COPY_BUFFER] = gl.isCopyBufferSupported();
-	capabilities.features[FEATURE_COPY_BUFFER_TO_TEXTURE] = gl.isCopyBufferToTextureSupported();
 	capabilities.features[FEATURE_COPY_TEXTURE_TO_BUFFER] = gl.isCopyTextureToBufferSupported();
 	capabilities.features[FEATURE_COPY_TEXTURE_TO_BUFFER] = gl.isCopyTextureToBufferSupported();
-	capabilities.features[FEATURE_COPY_RENDER_TARGET_TO_BUFFER] = gl.isCopyRenderTargetToBufferSupported();
-	capabilities.features[FEATURE_MIPMAP_RANGE] = GLAD_VERSION_1_2 || GLAD_ES_VERSION_3_0;
 	capabilities.features[FEATURE_INDIRECT_DRAW] = capabilities.features[FEATURE_GLSL4];
 	capabilities.features[FEATURE_INDIRECT_DRAW] = capabilities.features[FEATURE_GLSL4];
-	static_assert(FEATURE_MAX_ENUM == 19, "Graphics::initCapabilities must be updated when adding a new graphics feature!");
+	static_assert(FEATURE_MAX_ENUM == 13, "Graphics::initCapabilities must be updated when adding a new graphics feature!");
 
 
 	capabilities.limits[LIMIT_POINT_SIZE] = gl.getMaxPointSize();
 	capabilities.limits[LIMIT_POINT_SIZE] = gl.getMaxPointSize();
 	capabilities.limits[LIMIT_TEXTURE_SIZE] = gl.getMax2DTextureSize();
 	capabilities.limits[LIMIT_TEXTURE_SIZE] = gl.getMax2DTextureSize();
@@ -1666,7 +1613,7 @@ void Graphics::initCapabilities()
 	static_assert(LIMIT_MAX_ENUM == 13, "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++)
 	for (int i = 0; i < TEXTURE_MAX_ENUM; i++)
-		capabilities.textureTypes[i] = gl.isTextureTypeSupported((TextureType) i);
+		capabilities.textureTypes[i] = true;
 
 
 	for (int i = 0; i < PIXELFORMAT_MAX_ENUM; i++)
 	for (int i = 0; i < PIXELFORMAT_MAX_ENUM; i++)
 	{
 	{
@@ -1708,7 +1655,7 @@ uint32 Graphics::computePixelFormatUsage(PixelFormat format, bool readable)
 		GLuint texture = 0;
 		GLuint texture = 0;
 		GLuint renderbuffer = 0;
 		GLuint renderbuffer = 0;
 
 
-		OpenGL::TextureFormat fmt = OpenGL::convertPixelFormat(format, !readable);
+		OpenGL::TextureFormat fmt = OpenGL::convertPixelFormat(format);
 
 
 		GLuint current_fbo = gl.getFramebuffer(OpenGL::FRAMEBUFFER_ALL);
 		GLuint current_fbo = gl.getFramebuffer(OpenGL::FRAMEBUFFER_ALL);
 
 

+ 57 - 356
src/modules/graphics/opengl/OpenGL.cpp

@@ -130,7 +130,6 @@ OpenGL::OpenGL()
 	: stats()
 	: stats()
 	, bugs()
 	, bugs()
 	, contextInitialized(false)
 	, contextInitialized(false)
-	, pixelShaderHighpSupported(false)
 	, baseVertexSupported(false)
 	, baseVertexSupported(false)
 	, maxAnisotropy(1.0f)
 	, maxAnisotropy(1.0f)
 	, maxLODBias(0.0f)
 	, maxLODBias(0.0f)
@@ -166,16 +165,6 @@ bool OpenGL::initContext()
 
 
 	bugs = {};
 	bugs = {};
 
 
-	if (GLAD_ES_VERSION_3_0 && !GLAD_ES_VERSION_3_1)
-	{
-		const char *device = (const char *) glGetString(GL_RENDERER);
-		if (getVendor() == VENDOR_VIVANTE && strstr(device, "Vivante GC7000UL"))
-			bugs.brokenGLES3 = true;
-	}
-
-	if (bugs.brokenGLES3)
-		GLAD_ES_VERSION_3_0 = false;
-
 	if (GLAD_VERSION_3_2)
 	if (GLAD_VERSION_3_2)
 	{
 	{
 		GLint profileMask = 0;
 		GLint profileMask = 0;
@@ -274,11 +263,8 @@ void OpenGL::setupContext()
 	setEnableState(ENABLE_SCISSOR_TEST, state.enableState[ENABLE_SCISSOR_TEST]);
 	setEnableState(ENABLE_SCISSOR_TEST, state.enableState[ENABLE_SCISSOR_TEST]);
 	setEnableState(ENABLE_FACE_CULL, state.enableState[ENABLE_FACE_CULL]);
 	setEnableState(ENABLE_FACE_CULL, state.enableState[ENABLE_FACE_CULL]);
 
 
-	if (!bugs.brokenSRGB && (GLAD_VERSION_3_0 || GLAD_ARB_framebuffer_sRGB
-		|| GLAD_EXT_framebuffer_sRGB || GLAD_EXT_sRGB_write_control))
-	{
+	if (!bugs.brokenSRGB)
 		setEnableState(ENABLE_FRAMEBUFFER_SRGB, state.enableState[ENABLE_FRAMEBUFFER_SRGB]);
 		setEnableState(ENABLE_FRAMEBUFFER_SRGB, state.enableState[ENABLE_FRAMEBUFFER_SRGB]);
-	}
 	else
 	else
 		state.enableState[ENABLE_FRAMEBUFFER_SRGB] = false;
 		state.enableState[ENABLE_FRAMEBUFFER_SRGB] = false;
 
 
@@ -310,9 +296,7 @@ void OpenGL::setupContext()
 		for (int j = 0; j < TEXTURE_MAX_ENUM; j++)
 		for (int j = 0; j < TEXTURE_MAX_ENUM; j++)
 		{
 		{
 			TextureType textype = (TextureType) j;
 			TextureType textype = (TextureType) j;
-
-			if (isTextureTypeSupported(textype))
-				glBindTexture(getGLTextureType(textype), 0);
+			glBindTexture(getGLTextureType(textype), 0);
 		}
 		}
 	}
 	}
 
 
@@ -374,89 +358,6 @@ void OpenGL::initVendor()
 
 
 void OpenGL::initOpenGLFunctions()
 void OpenGL::initOpenGLFunctions()
 {
 {
-	// Alias extension-suffixed framebuffer functions to core versions since
-	// there are so many different-named extensions that do the same things...
-	if (!(GLAD_ES_VERSION_3_0 || GLAD_VERSION_3_0 || GLAD_ARB_framebuffer_object))
-	{
-		if (GLAD_VERSION_1_0 && GLAD_EXT_framebuffer_object)
-		{
-			fp_glBindRenderbuffer = fp_glBindRenderbufferEXT;
-			fp_glDeleteRenderbuffers = fp_glDeleteRenderbuffersEXT;
-			fp_glGenRenderbuffers = fp_glGenRenderbuffersEXT;
-			fp_glRenderbufferStorage = fp_glRenderbufferStorageEXT;
-			fp_glGetRenderbufferParameteriv = fp_glGetRenderbufferParameterivEXT;
-			fp_glBindFramebuffer = fp_glBindFramebufferEXT;
-			fp_glDeleteFramebuffers = fp_glDeleteFramebuffersEXT;
-			fp_glGenFramebuffers = fp_glGenFramebuffersEXT;
-			fp_glCheckFramebufferStatus = fp_glCheckFramebufferStatusEXT;
-			fp_glFramebufferTexture2D = fp_glFramebufferTexture2DEXT;
-			fp_glFramebufferTexture3D = fp_glFramebufferTexture3DEXT;
-			fp_glFramebufferRenderbuffer = fp_glFramebufferRenderbufferEXT;
-			fp_glGetFramebufferAttachmentParameteriv = fp_glGetFramebufferAttachmentParameterivEXT;
-			fp_glGenerateMipmap = fp_glGenerateMipmapEXT;
-		}
-
-		if (GLAD_VERSION_1_0 && GLAD_EXT_texture_array)
-			fp_glFramebufferTextureLayer = fp_glFramebufferTextureLayerEXT;
-
-		if (GLAD_EXT_framebuffer_blit)
-			fp_glBlitFramebuffer = fp_glBlitFramebufferEXT;
-		else if (GLAD_ANGLE_framebuffer_blit)
-			fp_glBlitFramebuffer = fp_glBlitFramebufferANGLE;
-		else if (GLAD_NV_framebuffer_blit)
-			fp_glBlitFramebuffer = fp_glBlitFramebufferNV;
-
-		if (GLAD_EXT_framebuffer_multisample)
-			fp_glRenderbufferStorageMultisample = fp_glRenderbufferStorageMultisampleEXT;
-		else if (GLAD_APPLE_framebuffer_multisample)
-			fp_glRenderbufferStorageMultisample = fp_glRenderbufferStorageMultisampleAPPLE;
-		else if (GLAD_ANGLE_framebuffer_multisample)
-			fp_glRenderbufferStorageMultisample = fp_glRenderbufferStorageMultisampleANGLE;
-		else if (GLAD_NV_framebuffer_multisample)
-			fp_glRenderbufferStorageMultisample = fp_glRenderbufferStorageMultisampleNV;
-	}
-
-	if (isInstancingSupported() && !(GLAD_VERSION_3_3 || GLAD_ES_VERSION_3_0))
-	{
-		if (GLAD_ARB_instanced_arrays)
-		{
-			fp_glDrawArraysInstanced = fp_glDrawArraysInstancedARB;
-			fp_glDrawElementsInstanced = fp_glDrawElementsInstancedARB;
-			fp_glVertexAttribDivisor = fp_glVertexAttribDivisorARB;
-		}
-		else if (GLAD_EXT_instanced_arrays)
-		{
-			fp_glDrawArraysInstanced = fp_glDrawArraysInstancedEXT;
-			fp_glDrawElementsInstanced = fp_glDrawElementsInstancedEXT;
-			fp_glVertexAttribDivisor = fp_glVertexAttribDivisorEXT;
-		}
-		else if (GLAD_ANGLE_instanced_arrays)
-		{
-			fp_glDrawArraysInstanced = fp_glDrawArraysInstancedANGLE;
-			fp_glDrawElementsInstanced = fp_glDrawElementsInstancedANGLE;
-			fp_glVertexAttribDivisor = fp_glVertexAttribDivisorANGLE;
-		}
-	}
-
-	if (GLAD_ES_VERSION_2_0 && !GLAD_ES_VERSION_3_0)
-	{
-		// The Nvidia Tegra 3 driver (used by Ouya) claims to support GL_EXT_texture_array but
-		// segfaults if you actually try to use it. OpenGL ES 2.0 devices should use OES_texture_3D.
-		// GL_EXT_texture_array is for desktops.
-		GLAD_EXT_texture_array = false;
-
-		if (GLAD_OES_texture_3D)
-		{
-			// Function signatures don't match, we'll have to conditionally call it
-			//fp_glTexImage3D = fp_glTexImage3DOES;
-			fp_glTexSubImage3D = fp_glTexSubImage3DOES;
-			fp_glCopyTexSubImage3D = fp_glCopyTexSubImage3DOES;
-			fp_glCompressedTexImage3D = fp_glCompressedTexImage3DOES;
-			fp_glCompressedTexSubImage3D = fp_glCompressedTexSubImage3DOES;
-			fp_glFramebufferTexture3D = fp_glFramebufferTexture3DOES;
-		}
-	}
-
 	if (!GLAD_VERSION_3_2 && !GLAD_ES_VERSION_3_2 && !GLAD_ARB_draw_elements_base_vertex)
 	if (!GLAD_VERSION_3_2 && !GLAD_ES_VERSION_3_2 && !GLAD_ARB_draw_elements_base_vertex)
 	{
 	{
 		if (GLAD_OES_draw_elements_base_vertex)
 		if (GLAD_OES_draw_elements_base_vertex)
@@ -486,16 +387,6 @@ void OpenGL::initOpenGLFunctions()
 
 
 void OpenGL::initMaxValues()
 void OpenGL::initMaxValues()
 {
 {
-	if (GLAD_ES_VERSION_2_0 && !GLAD_ES_VERSION_3_0)
-	{
-		GLint range = 0;
-		GLint precision = 0;
-		glGetShaderPrecisionFormat(GL_FRAGMENT_SHADER, GL_HIGH_FLOAT, &range, &precision);
-		pixelShaderHighpSupported = range > 0;
-	}
-	else
-		pixelShaderHighpSupported = true;
-
 	baseVertexSupported = GLAD_VERSION_3_2 || GLAD_ES_VERSION_3_2 || GLAD_ARB_draw_elements_base_vertex
 	baseVertexSupported = GLAD_VERSION_3_2 || GLAD_ES_VERSION_3_2 || GLAD_ARB_draw_elements_base_vertex
 		|| GLAD_OES_draw_elements_base_vertex || GLAD_EXT_draw_elements_base_vertex;
 		|| GLAD_OES_draw_elements_base_vertex || GLAD_EXT_draw_elements_base_vertex;
 
 
@@ -507,16 +398,8 @@ void OpenGL::initMaxValues()
 
 
 	glGetIntegerv(GL_MAX_TEXTURE_SIZE, &max2DTextureSize);
 	glGetIntegerv(GL_MAX_TEXTURE_SIZE, &max2DTextureSize);
 	glGetIntegerv(GL_MAX_CUBE_MAP_TEXTURE_SIZE, &maxCubeTextureSize);
 	glGetIntegerv(GL_MAX_CUBE_MAP_TEXTURE_SIZE, &maxCubeTextureSize);
-
-	if (isTextureTypeSupported(TEXTURE_VOLUME))
-		glGetIntegerv(GL_MAX_3D_TEXTURE_SIZE, &max3DTextureSize);
-	else
-		max3DTextureSize = 0;
-
-	if (isTextureTypeSupported(TEXTURE_2D_ARRAY))
-		glGetIntegerv(GL_MAX_ARRAY_TEXTURE_LAYERS, &maxTextureArrayLayers);
-	else
-		maxTextureArrayLayers = 0;
+	glGetIntegerv(GL_MAX_3D_TEXTURE_SIZE, &max3DTextureSize);
+	glGetIntegerv(GL_MAX_ARRAY_TEXTURE_LAYERS, &maxTextureArrayLayers);
 
 
 	if (isBufferUsageSupported(BUFFERUSAGE_TEXEL))
 	if (isBufferUsageSupported(BUFFERUSAGE_TEXEL))
 		glGetIntegerv(GL_MAX_TEXTURE_BUFFER_SIZE, &maxTexelBufferSize);
 		glGetIntegerv(GL_MAX_TEXTURE_BUFFER_SIZE, &maxTexelBufferSize);
@@ -549,23 +432,12 @@ void OpenGL::initMaxValues()
 
 
 	int maxattachments = 1;
 	int maxattachments = 1;
 	int maxdrawbuffers = 1;
 	int maxdrawbuffers = 1;
-
-	if (GLAD_ES_VERSION_3_0 || GLAD_VERSION_2_0)
-	{
-		glGetIntegerv(GL_MAX_COLOR_ATTACHMENTS, &maxattachments);
-		glGetIntegerv(GL_MAX_DRAW_BUFFERS, &maxdrawbuffers);
-	}
+	glGetIntegerv(GL_MAX_COLOR_ATTACHMENTS, &maxattachments);
+	glGetIntegerv(GL_MAX_DRAW_BUFFERS, &maxdrawbuffers);
 
 
 	maxRenderTargets = std::max(std::min(maxattachments, maxdrawbuffers), 1);
 	maxRenderTargets = std::max(std::min(maxattachments, maxdrawbuffers), 1);
 
 
-	if (GLAD_ES_VERSION_3_0 || GLAD_VERSION_3_0 || GLAD_ARB_framebuffer_object
-		|| GLAD_EXT_framebuffer_multisample || GLAD_APPLE_framebuffer_multisample
-		|| GLAD_ANGLE_framebuffer_multisample)
-	{
-		glGetIntegerv(GL_MAX_SAMPLES, &maxSamples);
-	}
-	else
-		maxSamples = 1;
+	glGetIntegerv(GL_MAX_SAMPLES, &maxSamples);
 
 
 	glGetIntegerv(GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS, &maxTextureUnits);
 	glGetIntegerv(GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS, &maxTextureUnits);
 
 
@@ -794,8 +666,7 @@ GLenum OpenGL::getGLBufferDataUsage(BufferDataUsage usage)
 		case BUFFERDATAUSAGE_STREAM: return GL_STREAM_DRAW;
 		case BUFFERDATAUSAGE_STREAM: return GL_STREAM_DRAW;
 		case BUFFERDATAUSAGE_DYNAMIC: return GL_DYNAMIC_DRAW;
 		case BUFFERDATAUSAGE_DYNAMIC: return GL_DYNAMIC_DRAW;
 		case BUFFERDATAUSAGE_STATIC: return GL_STATIC_DRAW;
 		case BUFFERDATAUSAGE_STATIC: return GL_STATIC_DRAW;
-		case BUFFERDATAUSAGE_READBACK:
-			return (GLAD_VERSION_1_1 || GLAD_ES_VERSION_3_0) ? GL_STREAM_READ : GL_STREAM_DRAW;
+		case BUFFERDATAUSAGE_READBACK: return GL_STREAM_READ;
 		default: return 0;
 		default: return 0;
 	}
 	}
 }
 }
@@ -1285,42 +1156,27 @@ void OpenGL::setSamplerState(TextureType target, SamplerState &s)
 		s.maxAnisotropy = 1;
 		s.maxAnisotropy = 1;
 	}
 	}
 
 
-	if (GLAD_ES_VERSION_3_0 || GLAD_VERSION_1_0)
-	{
-		glTexParameterf(gltarget, GL_TEXTURE_MIN_LOD, (float)s.minLod);
-		glTexParameterf(gltarget, GL_TEXTURE_MAX_LOD, (float)s.maxLod);
-	}
-	else
-	{
-		s.minLod = 0;
-		s.maxLod = LOVE_UINT8_MAX;
-	}
+	glTexParameterf(gltarget, GL_TEXTURE_MIN_LOD, (float)s.minLod);
+	glTexParameterf(gltarget, GL_TEXTURE_MAX_LOD, (float)s.maxLod);
 
 
-	if (isDepthCompareSampleSupported())
+	if (s.depthSampleMode.hasValue)
 	{
 	{
-		if (s.depthSampleMode.hasValue)
-		{
-			// See the comment in renderstate.h
-			GLenum glmode = getGLCompareMode(getReversedCompareMode(s.depthSampleMode.value));
+		// See the comment in renderstate.h
+		GLenum glmode = getGLCompareMode(getReversedCompareMode(s.depthSampleMode.value));
 
 
-			glTexParameteri(gltarget, GL_TEXTURE_COMPARE_MODE, GL_COMPARE_REF_TO_TEXTURE);
-			glTexParameteri(gltarget, GL_TEXTURE_COMPARE_FUNC, glmode);
-		}
-		else
-		{
-			glTexParameteri(gltarget, GL_TEXTURE_COMPARE_MODE, GL_NONE);
-		}
+		glTexParameteri(gltarget, GL_TEXTURE_COMPARE_MODE, GL_COMPARE_REF_TO_TEXTURE);
+		glTexParameteri(gltarget, GL_TEXTURE_COMPARE_FUNC, glmode);
 	}
 	}
 	else
 	else
 	{
 	{
-		s.depthSampleMode.hasValue = false;
+		glTexParameteri(gltarget, GL_TEXTURE_COMPARE_MODE, GL_NONE);
 	}
 	}
 }
 }
 
 
 bool OpenGL::rawTexStorage(TextureType target, int levels, PixelFormat pixelformat, int width, int height, int depth)
 bool OpenGL::rawTexStorage(TextureType target, int levels, PixelFormat pixelformat, int width, int height, int depth)
 {
 {
 	GLenum gltarget = getGLTextureType(target);
 	GLenum gltarget = getGLTextureType(target);
-	TextureFormat fmt = convertPixelFormat(pixelformat, false);
+	TextureFormat fmt = convertPixelFormat(pixelformat);
 
 
 	// This shouldn't be needed for glTexStorage, but some drivers don't follow
 	// This shouldn't be needed for glTexStorage, but some drivers don't follow
 	// the spec apparently.
 	// the spec apparently.
@@ -1375,16 +1231,8 @@ bool OpenGL::rawTexStorage(TextureType target, int levels, PixelFormat pixelform
 			}
 			}
 			else if (target == TEXTURE_2D_ARRAY || target == TEXTURE_VOLUME)
 			else if (target == TEXTURE_2D_ARRAY || target == TEXTURE_VOLUME)
 			{
 			{
-				if (target == TEXTURE_VOLUME && GLAD_ES_VERSION_2_0 && GLAD_OES_texture_3D && !GLAD_ES_VERSION_3_0)
-				{
-					glTexImage3DOES(gltarget, level, fmt.internalformat, w, h,
-					                d, 0, fmt.externalformat, fmt.type, nullptr);
-				}
-				else
-				{
-					glTexImage3D(gltarget, level, fmt.internalformat, w, h, d,
-					             0, fmt.externalformat, fmt.type, nullptr);
-				}
+				glTexImage3D(gltarget, level, fmt.internalformat, w, h, d,
+				             0, fmt.externalformat, fmt.type, nullptr);
 			}
 			}
 
 
 			w = std::max(w / 2, 1);
 			w = std::max(w / 2, 1);
@@ -1406,24 +1254,6 @@ bool OpenGL::isTexStorageSupported()
 	return GLAD_ES_VERSION_3_0 || GLAD_VERSION_4_2 || GLAD_ARB_texture_storage;
 	return GLAD_ES_VERSION_3_0 || GLAD_VERSION_4_2 || GLAD_ARB_texture_storage;
 }
 }
 
 
-bool OpenGL::isTextureTypeSupported(TextureType type) const
-{
-	switch (type)
-	{
-	case TEXTURE_2D:
-		return true;
-	case TEXTURE_VOLUME:
-		return GLAD_VERSION_1_1 || GLAD_ES_VERSION_3_0 || GLAD_OES_texture_3D;
-	case TEXTURE_2D_ARRAY:
-		return GLAD_VERSION_3_0 || GLAD_ES_VERSION_3_0 || GLAD_EXT_texture_array;
-	case TEXTURE_CUBE:
-		return GLAD_VERSION_1_3 || GLAD_ES_VERSION_2_0;
-	case TEXTURE_MAX_ENUM:
-		return false;
-	}
-	return false;
-}
-
 bool OpenGL::isBufferUsageSupported(BufferUsage usage) const
 bool OpenGL::isBufferUsageSupported(BufferUsage usage) const
 {
 {
 	switch (usage)
 	switch (usage)
@@ -1434,7 +1264,7 @@ bool OpenGL::isBufferUsageSupported(BufferUsage usage) const
 	case BUFFERUSAGE_TEXEL:
 	case BUFFERUSAGE_TEXEL:
 		return GLAD_VERSION_3_1 || GLAD_ES_VERSION_3_2;
 		return GLAD_VERSION_3_1 || GLAD_ES_VERSION_3_2;
 	case BUFFERUSAGE_UNIFORM:
 	case BUFFERUSAGE_UNIFORM:
-		return GLAD_VERSION_3_1 || GLAD_ES_VERSION_3_0;
+		return true;
 	case BUFFERUSAGE_SHADER_STORAGE:
 	case BUFFERUSAGE_SHADER_STORAGE:
 		return (GLAD_VERSION_4_3 && isCoreProfile()) || GLAD_ES_VERSION_3_1;
 		return (GLAD_VERSION_4_3 && isCoreProfile()) || GLAD_ES_VERSION_3_1;
 	case BUFFERUSAGE_INDIRECT_ARGUMENTS:
 	case BUFFERUSAGE_INDIRECT_ARGUMENTS:
@@ -1450,24 +1280,6 @@ bool OpenGL::isClampZeroOneTextureWrapSupported() const
 	return GLAD_VERSION_1_3 || GLAD_EXT_texture_border_clamp || GLAD_NV_texture_border_clamp;
 	return GLAD_VERSION_1_3 || GLAD_EXT_texture_border_clamp || GLAD_NV_texture_border_clamp;
 }
 }
 
 
-bool OpenGL::isPixelShaderHighpSupported() const
-{
-	return pixelShaderHighpSupported;
-}
-
-bool OpenGL::isInstancingSupported() const
-{
-	return GLAD_ES_VERSION_3_0 || GLAD_VERSION_3_3
-		|| GLAD_ARB_instanced_arrays || GLAD_EXT_instanced_arrays || GLAD_ANGLE_instanced_arrays;
-}
-
-bool OpenGL::isDepthCompareSampleSupported() const
-{
-	// Our official API only supports this in GLSL3 shaders, but unofficially
-	// the requirements are more lax.
-	return GLAD_VERSION_2_0 || GLAD_ES_VERSION_3_0 || GLAD_EXT_shadow_samplers;
-}
-
 bool OpenGL::isSamplerLODBiasSupported() const
 bool OpenGL::isSamplerLODBiasSupported() const
 {
 {
 	return GLAD_VERSION_1_4;
 	return GLAD_VERSION_1_4;
@@ -1478,34 +1290,12 @@ bool OpenGL::isBaseVertexSupported() const
 	return baseVertexSupported;
 	return baseVertexSupported;
 }
 }
 
 
-bool OpenGL::isMultiFormatMRTSupported() const
-{
-	return getMaxRenderTargets() > 1 && (GLAD_ES_VERSION_3_0 || GLAD_VERSION_3_0 || GLAD_ARB_framebuffer_object);
-}
-
-bool OpenGL::isCopyBufferSupported() const
-{
-	return GLAD_VERSION_3_1 || GLAD_ES_VERSION_3_0;
-}
-
-bool OpenGL::isCopyBufferToTextureSupported() const
-{
-	// Requires pixel unpack buffer binding support.
-	return GLAD_VERSION_2_0 || GLAD_ES_VERSION_3_0;
-}
-
 bool OpenGL::isCopyTextureToBufferSupported() const
 bool OpenGL::isCopyTextureToBufferSupported() const
 {
 {
 	// Requires glGetTextureSubImage support.
 	// Requires glGetTextureSubImage support.
 	return GLAD_VERSION_4_5 || GLAD_ARB_get_texture_sub_image;
 	return GLAD_VERSION_4_5 || GLAD_ARB_get_texture_sub_image;
 }
 }
 
 
-bool OpenGL::isCopyRenderTargetToBufferSupported() const
-{
-	// Requires pixel pack buffer binding support.
-	return GLAD_VERSION_2_0 || GLAD_ES_VERSION_3_0;
-}
-
 int OpenGL::getMax2DTextureSize() const
 int OpenGL::getMax2DTextureSize() const
 {
 {
 	return std::max(max2DTextureSize, 1);
 	return std::max(max2DTextureSize, 1);
@@ -1596,7 +1386,7 @@ OpenGL::Vendor OpenGL::getVendor() const
 	return vendor;
 	return vendor;
 }
 }
 
 
-OpenGL::TextureFormat OpenGL::convertPixelFormat(PixelFormat pixelformat, bool renderbuffer)
+OpenGL::TextureFormat OpenGL::convertPixelFormat(PixelFormat pixelformat)
 {
 {
 	TextureFormat f;
 	TextureFormat f;
 
 
@@ -1613,8 +1403,7 @@ OpenGL::TextureFormat OpenGL::convertPixelFormat(PixelFormat pixelformat, bool r
 	switch (pixelformat)
 	switch (pixelformat)
 	{
 	{
 	case PIXELFORMAT_R8_UNORM:
 	case PIXELFORMAT_R8_UNORM:
-		if ((GLAD_VERSION_3_0 || GLAD_ES_VERSION_3_0 || GLAD_ARB_texture_rg || GLAD_EXT_texture_rg)
-			&& !gl.bugs.brokenR8PixelFormat)
+		if (!gl.bugs.brokenR8PixelFormat)
 		{
 		{
 			f.internalformat = GL_R8;
 			f.internalformat = GL_R8;
 			f.externalformat = GL_RED;
 			f.externalformat = GL_RED;
@@ -1639,10 +1428,7 @@ OpenGL::TextureFormat OpenGL::convertPixelFormat(PixelFormat pixelformat, bool r
 	case PIXELFORMAT_RGBA8_sRGB:
 	case PIXELFORMAT_RGBA8_sRGB:
 		f.internalformat = GL_SRGB8_ALPHA8;
 		f.internalformat = GL_SRGB8_ALPHA8;
 		f.type = GL_UNSIGNED_BYTE;
 		f.type = GL_UNSIGNED_BYTE;
-		if (GLAD_ES_VERSION_2_0 && !GLAD_ES_VERSION_3_0)
-			f.externalformat = GL_SRGB_ALPHA;
-		else
-			f.externalformat = GL_RGBA;
+		f.externalformat = GL_RGBA;
 		break;
 		break;
 	case PIXELFORMAT_BGRA8_UNORM:
 	case PIXELFORMAT_BGRA8_UNORM:
 	case PIXELFORMAT_BGRA8_sRGB:
 	case PIXELFORMAT_BGRA8_sRGB:
@@ -1841,28 +1627,10 @@ OpenGL::TextureFormat OpenGL::convertPixelFormat(PixelFormat pixelformat, bool r
 
 
 	case PIXELFORMAT_STENCIL8:
 	case PIXELFORMAT_STENCIL8:
 		// Prefer a combined depth/stencil buffer due to driver issues.
 		// Prefer a combined depth/stencil buffer due to driver issues.
-		if (GLAD_ES_VERSION_3_0 || GLAD_VERSION_3_0 || GLAD_ARB_framebuffer_object)
-		{
-			f.internalformat = GL_DEPTH24_STENCIL8;
-			f.externalformat = GL_DEPTH_STENCIL;
-			f.type = GL_UNSIGNED_INT_24_8;
-			f.framebufferAttachments[0] = GL_DEPTH_STENCIL_ATTACHMENT;
-		}
-		else if (GLAD_EXT_packed_depth_stencil || GLAD_OES_packed_depth_stencil)
-		{
-			f.internalformat = GL_DEPTH24_STENCIL8;
-			f.externalformat = GL_DEPTH_STENCIL;
-			f.type = GL_UNSIGNED_INT_24_8;
-			f.framebufferAttachments[0] = GL_DEPTH_ATTACHMENT;
-			f.framebufferAttachments[1] = GL_STENCIL_ATTACHMENT;
-		}
-		else
-		{
-			f.internalformat = GL_STENCIL_INDEX8;
-			f.externalformat = GL_STENCIL;
-			f.type = GL_UNSIGNED_BYTE;
-			f.framebufferAttachments[0] = GL_STENCIL_ATTACHMENT;
-		}
+		f.internalformat = GL_DEPTH24_STENCIL8;
+		f.externalformat = GL_DEPTH_STENCIL;
+		f.type = GL_UNSIGNED_INT_24_8;
+		f.framebufferAttachments[0] = GL_DEPTH_STENCIL_ATTACHMENT;
 		break;
 		break;
 
 
 	case PIXELFORMAT_DEPTH16_UNORM:
 	case PIXELFORMAT_DEPTH16_UNORM:
@@ -1873,21 +1641,10 @@ OpenGL::TextureFormat OpenGL::convertPixelFormat(PixelFormat pixelformat, bool r
 		break;
 		break;
 
 
 	case PIXELFORMAT_DEPTH24_UNORM:
 	case PIXELFORMAT_DEPTH24_UNORM:
-		if (GLAD_ES_VERSION_2_0 && !GLAD_ES_VERSION_3_0 && !GLAD_OES_depth24 && GLAD_OES_packed_depth_stencil)
-		{
-			f.internalformat = GL_DEPTH24_STENCIL8;
-			f.externalformat = GL_DEPTH_STENCIL;
-			f.type = GL_UNSIGNED_INT_24_8;
-			f.framebufferAttachments[0] = GL_DEPTH_ATTACHMENT;
-			f.framebufferAttachments[1] = GL_STENCIL_ATTACHMENT;
-		}
-		else
-		{
-			f.internalformat = GL_DEPTH_COMPONENT24;
-			f.externalformat = GL_DEPTH_COMPONENT;
-			f.type = GL_UNSIGNED_INT;
-			f.framebufferAttachments[0] = GL_DEPTH_ATTACHMENT;
-		}
+		f.internalformat = GL_DEPTH_COMPONENT24;
+		f.externalformat = GL_DEPTH_COMPONENT;
+		f.type = GL_UNSIGNED_INT;
+		f.framebufferAttachments[0] = GL_DEPTH_ATTACHMENT;
 		break;
 		break;
 
 
 	case PIXELFORMAT_DEPTH32_FLOAT:
 	case PIXELFORMAT_DEPTH32_FLOAT:
@@ -1901,15 +1658,7 @@ OpenGL::TextureFormat OpenGL::convertPixelFormat(PixelFormat pixelformat, bool r
 		f.internalformat = GL_DEPTH24_STENCIL8;
 		f.internalformat = GL_DEPTH24_STENCIL8;
 		f.externalformat = GL_DEPTH_STENCIL;
 		f.externalformat = GL_DEPTH_STENCIL;
 		f.type = GL_UNSIGNED_INT_24_8;
 		f.type = GL_UNSIGNED_INT_24_8;
-		if (GLAD_ES_VERSION_3_0 || GLAD_VERSION_3_0 || GLAD_ARB_framebuffer_object)
-		{
-			f.framebufferAttachments[0] = GL_DEPTH_STENCIL_ATTACHMENT;
-		}
-		else if (GLAD_EXT_packed_depth_stencil || GLAD_OES_packed_depth_stencil)
-		{
-			f.framebufferAttachments[0] = GL_DEPTH_ATTACHMENT;
-			f.framebufferAttachments[1] = GL_STENCIL_ATTACHMENT;
-		}
+		f.framebufferAttachments[0] = GL_DEPTH_STENCIL_ATTACHMENT;
 		break;
 		break;
 
 
 	case PIXELFORMAT_DEPTH32_FLOAT_STENCIL8:
 	case PIXELFORMAT_DEPTH32_FLOAT_STENCIL8:
@@ -2111,22 +1860,6 @@ OpenGL::TextureFormat OpenGL::convertPixelFormat(PixelFormat pixelformat, bool r
 		break;
 		break;
 	}
 	}
 
 
-	if (!isPixelFormatCompressed(pixelformat))
-	{
-		// glTexImage in OpenGL ES 2 only accepts internal format enums that
-		// match the external format. GLES3 doesn't have that restriction - 
-		// except for GL_LUMINANCE_ALPHA which doesn't have a sized version in
-		// ES3. However we always use RG8 for PIXELFORMAT_LA8 on GLES3 so it
-		// doesn't matter there.
-		// Also note that GLES2+extension sRGB format enums are different from
-		// desktop GL and GLES3+ (this is handled above).
-		if (GLAD_ES_VERSION_2_0 && !GLAD_ES_VERSION_3_0
-			&& !renderbuffer && !isTexStorageSupported())
-		{
-			f.internalformat = f.externalformat;
-		}
-	}
-
 	return f;
 	return f;
 }
 }
 
 
@@ -2142,28 +1875,19 @@ uint32 OpenGL::getPixelFormatUsageFlags(PixelFormat pixelformat)
 	{
 	{
 	case PIXELFORMAT_R8_UNORM:
 	case PIXELFORMAT_R8_UNORM:
 	case PIXELFORMAT_RG8_UNORM:
 	case PIXELFORMAT_RG8_UNORM:
-		if (GLAD_VERSION_3_0 || GLAD_ES_VERSION_3_0 || GLAD_ARB_texture_rg || GLAD_EXT_texture_rg)
-			flags |= commonsample | commonrender;
-		else if (pixelformat == PIXELFORMAT_R8_UNORM && (GLAD_ES_VERSION_2_0 || GLAD_VERSION_1_1))
-			flags |= commonsample; // We'll use OpenGL's luminance format internally.
+		flags |= commonsample | commonrender;
 		if (GLAD_VERSION_4_3)
 		if (GLAD_VERSION_4_3)
 			flags |= computewrite;
 			flags |= computewrite;
 		break;
 		break;
 	case PIXELFORMAT_RGBA8_UNORM:
 	case PIXELFORMAT_RGBA8_UNORM:
-		flags |= commonsample;
-		if (GLAD_VERSION_1_0 || GLAD_ES_VERSION_3_0 || GLAD_OES_rgb8_rgba8 || GLAD_ARM_rgba8)
-			flags |= commonrender;
+		flags |= commonsample | commonrender;
 		if (GLAD_VERSION_4_3 || GLAD_ES_VERSION_3_1)
 		if (GLAD_VERSION_4_3 || GLAD_ES_VERSION_3_1)
 			flags |= computewrite;
 			flags |= computewrite;
 		break;
 		break;
 	case PIXELFORMAT_RGBA8_sRGB:
 	case PIXELFORMAT_RGBA8_sRGB:
 		if (gl.bugs.brokenSRGB)
 		if (gl.bugs.brokenSRGB)
 			break;
 			break;
-		if (GLAD_ES_VERSION_3_0 || GLAD_VERSION_2_1 || GLAD_EXT_texture_sRGB)
-			flags |= commonsample;
-		if (GLAD_ES_VERSION_3_0 || GLAD_VERSION_3_0
-			|| ((GLAD_ARB_framebuffer_sRGB || GLAD_EXT_framebuffer_sRGB) && (GLAD_VERSION_2_1 || GLAD_EXT_texture_sRGB)))
-			flags |= commonrender;
+		flags |= commonsample | commonrender;
 		break;
 		break;
 	case PIXELFORMAT_BGRA8_UNORM:
 	case PIXELFORMAT_BGRA8_UNORM:
 	case PIXELFORMAT_BGRA8_sRGB:
 	case PIXELFORMAT_BGRA8_sRGB:
@@ -2171,9 +1895,7 @@ uint32 OpenGL::getPixelFormatUsageFlags(PixelFormat pixelformat)
 		break;
 		break;
 	case PIXELFORMAT_R16_UNORM:
 	case PIXELFORMAT_R16_UNORM:
 	case PIXELFORMAT_RG16_UNORM:
 	case PIXELFORMAT_RG16_UNORM:
-		if (GLAD_VERSION_3_0
-			|| (GLAD_VERSION_1_1 && GLAD_ARB_texture_rg)
-			|| (GLAD_EXT_texture_norm16 && (GLAD_ES_VERSION_3_0 || GLAD_EXT_texture_rg)))
+		if (GLAD_VERSION_3_0 || (GLAD_EXT_texture_norm16 && GLAD_ES_VERSION_3_0))
 			flags |= commonsample | commonrender;
 			flags |= commonsample | commonrender;
 		if (GLAD_VERSION_4_3)
 		if (GLAD_VERSION_4_3)
 			flags |= computewrite;
 			flags |= computewrite;
@@ -2186,26 +1908,20 @@ uint32 OpenGL::getPixelFormatUsageFlags(PixelFormat pixelformat)
 		break;
 		break;
 	case PIXELFORMAT_R16_FLOAT:
 	case PIXELFORMAT_R16_FLOAT:
 	case PIXELFORMAT_RG16_FLOAT:
 	case PIXELFORMAT_RG16_FLOAT:
-		if (GLAD_VERSION_1_0 && (GLAD_VERSION_3_0 || (GLAD_ARB_texture_float && GLAD_ARB_half_float_pixel && GLAD_ARB_texture_rg)))
-			flags |= commonsample | commonrender;
-		if (GLAD_ES_VERSION_3_0 || (GLAD_OES_texture_half_float && GLAD_EXT_texture_rg))
-			flags |= commonsample;
-		if ((GLAD_EXT_color_buffer_half_float || GLAD_EXT_color_buffer_float) && (GLAD_ES_VERSION_3_0 || GLAD_EXT_texture_rg))
+		flags |= commonsample;
+		if (GLAD_VERSION_3_0)
+			flags |= commonrender;
+		if ((GLAD_EXT_color_buffer_half_float || GLAD_EXT_color_buffer_float) && GLAD_ES_VERSION_3_0)
 			flags |= commonrender;
 			flags |= commonrender;
-		if (!(GLAD_VERSION_1_1 || GLAD_ES_VERSION_3_0 || GLAD_OES_texture_half_float_linear))
-			flags &= ~PIXELFORMATUSAGEFLAGS_LINEAR;
 		if (GLAD_VERSION_4_3)
 		if (GLAD_VERSION_4_3)
 			flags |= computewrite;
 			flags |= computewrite;
 		break;
 		break;
 	case PIXELFORMAT_RGBA16_FLOAT:
 	case PIXELFORMAT_RGBA16_FLOAT:
-		if (GLAD_VERSION_3_0 || (GLAD_VERSION_1_0 && GLAD_ARB_texture_float && GLAD_ARB_half_float_pixel))
-			flags |= commonsample | commonrender;
-		if (GLAD_ES_VERSION_3_0 || GLAD_OES_texture_half_float)
-			flags |= commonsample;
+		flags |= commonsample;
+		if (GLAD_VERSION_3_0)
+			flags |= commonrender;
 		if (GLAD_EXT_color_buffer_half_float || GLAD_EXT_color_buffer_float)
 		if (GLAD_EXT_color_buffer_half_float || GLAD_EXT_color_buffer_float)
 			flags |= commonrender;
 			flags |= commonrender;
-		if (!(GLAD_VERSION_1_1 || GLAD_ES_VERSION_3_0 || GLAD_OES_texture_half_float_linear))
-			flags &= ~PIXELFORMATUSAGEFLAGS_LINEAR;
 		if (GLAD_VERSION_4_3 || GLAD_ES_VERSION_3_1)
 		if (GLAD_VERSION_4_3 || GLAD_ES_VERSION_3_1)
 			flags |= computewrite;
 			flags |= computewrite;
 		break;
 		break;
@@ -2214,22 +1930,20 @@ uint32 OpenGL::getPixelFormatUsageFlags(PixelFormat pixelformat)
 			flags |= computewrite;
 			flags |= computewrite;
 		// Fallthrough.
 		// Fallthrough.
 	case PIXELFORMAT_RG32_FLOAT:
 	case PIXELFORMAT_RG32_FLOAT:
-		if (GLAD_VERSION_3_0 || (GLAD_VERSION_1_0 && GLAD_ARB_texture_float && GLAD_ARB_texture_rg))
-			flags |= commonsample | commonrender;
-		if (GLAD_ES_VERSION_3_0 || (GLAD_OES_texture_float && GLAD_EXT_texture_rg))
-			flags |= commonsample;
+		flags |= commonsample;
+		if (GLAD_VERSION_3_0)
+			flags |= commonrender;
 		if (GLAD_EXT_color_buffer_float)
 		if (GLAD_EXT_color_buffer_float)
 			flags |= commonrender;
 			flags |= commonrender;
-		if (!(GLAD_VERSION_1_1 || GLAD_ES_VERSION_3_0 || GLAD_OES_texture_half_float_linear))
+		if (!(GLAD_VERSION_1_1 || GLAD_OES_texture_float_linear))
 			flags &= ~PIXELFORMATUSAGEFLAGS_LINEAR;
 			flags &= ~PIXELFORMATUSAGEFLAGS_LINEAR;
 		if (GLAD_VERSION_4_3)
 		if (GLAD_VERSION_4_3)
 			flags |= computewrite;
 			flags |= computewrite;
 		break;
 		break;
 	case PIXELFORMAT_RGBA32_FLOAT:
 	case PIXELFORMAT_RGBA32_FLOAT:
-		if (GLAD_VERSION_3_0 || (GLAD_VERSION_1_0 && GLAD_ARB_texture_float))
-			flags |= commonsample | commonrender;
-		if (GLAD_ES_VERSION_3_0 || GLAD_OES_texture_float)
-			flags |= commonsample;
+		flags |= commonsample;
+		if (GLAD_VERSION_3_0)
+			flags |= commonrender;
 		if (GLAD_EXT_color_buffer_float)
 		if (GLAD_EXT_color_buffer_float)
 			flags |= commonrender;
 			flags |= commonrender;
 		if (!(GLAD_VERSION_1_1 || GLAD_OES_texture_float_linear))
 		if (!(GLAD_VERSION_1_1 || GLAD_OES_texture_float_linear))
@@ -2256,8 +1970,7 @@ uint32 OpenGL::getPixelFormatUsageFlags(PixelFormat pixelformat)
 	case PIXELFORMAT_RG32_UINT:
 	case PIXELFORMAT_RG32_UINT:
 	case PIXELFORMAT_RGBA32_INT:
 	case PIXELFORMAT_RGBA32_INT:
 	case PIXELFORMAT_RGBA32_UINT:
 	case PIXELFORMAT_RGBA32_UINT:
-		if (GLAD_VERSION_3_0 || GLAD_ES_VERSION_3_0)
-			flags |= PIXELFORMATUSAGEFLAGS_SAMPLE | PIXELFORMATUSAGEFLAGS_RENDERTARGET;
+		flags |= PIXELFORMATUSAGEFLAGS_SAMPLE | PIXELFORMATUSAGEFLAGS_RENDERTARGET;
 		if (GLAD_VERSION_4_3)
 		if (GLAD_VERSION_4_3)
 			flags |= computewrite;
 			flags |= computewrite;
 		if (GLAD_ES_VERSION_3_1)
 		if (GLAD_ES_VERSION_3_1)
@@ -2293,8 +2006,7 @@ uint32 OpenGL::getPixelFormatUsageFlags(PixelFormat pixelformat)
 			flags |= commonsample | commonrender;
 			flags |= commonsample | commonrender;
 		break;
 		break;
 	case PIXELFORMAT_RGB10A2_UNORM:
 	case PIXELFORMAT_RGB10A2_UNORM:
-		if (GLAD_ES_VERSION_3_0 || GLAD_VERSION_1_0)
-			flags |= commonsample | commonrender;
+		flags |= commonsample | commonrender;
 		if (GLAD_VERSION_4_3)
 		if (GLAD_VERSION_4_3)
 			flags |= computewrite;
 			flags |= computewrite;
 		break;
 		break;
@@ -2314,31 +2026,20 @@ uint32 OpenGL::getPixelFormatUsageFlags(PixelFormat pixelformat)
 		break;
 		break;
 
 
 	case PIXELFORMAT_DEPTH16_UNORM:
 	case PIXELFORMAT_DEPTH16_UNORM:
-		flags |= PIXELFORMATUSAGEFLAGS_RENDERTARGET | PIXELFORMATUSAGEFLAGS_MSAA;
-		if (GLAD_VERSION_2_0 || GLAD_ES_VERSION_3_0 || GLAD_OES_depth_texture)
-			flags |= commonsample;
+		flags |= commonsample | PIXELFORMATUSAGEFLAGS_RENDERTARGET | PIXELFORMATUSAGEFLAGS_MSAA;
 		break;
 		break;
 
 
 	case PIXELFORMAT_DEPTH24_UNORM:
 	case PIXELFORMAT_DEPTH24_UNORM:
-		if (GLAD_VERSION_2_0 || GLAD_ES_VERSION_3_0 || GLAD_OES_depth24 || GLAD_OES_depth_texture)
-			flags |= PIXELFORMATUSAGEFLAGS_RENDERTARGET | PIXELFORMATUSAGEFLAGS_MSAA;
-
-		if (GLAD_VERSION_2_0 || GLAD_ES_VERSION_3_0 || (GLAD_OES_depth_texture && (GLAD_OES_depth24 || GLAD_OES_depth_texture)))
-			flags |= commonsample;
+		flags |= commonsample | PIXELFORMATUSAGEFLAGS_RENDERTARGET | PIXELFORMATUSAGEFLAGS_MSAA;
 		break;
 		break;
 
 
 	case PIXELFORMAT_DEPTH24_UNORM_STENCIL8:
 	case PIXELFORMAT_DEPTH24_UNORM_STENCIL8:
-		if (GLAD_VERSION_3_0 || GLAD_ES_VERSION_3_0 || GLAD_EXT_packed_depth_stencil || GLAD_OES_packed_depth_stencil)
-			flags |= PIXELFORMATUSAGEFLAGS_RENDERTARGET | PIXELFORMATUSAGEFLAGS_MSAA;
-
-		if (GLAD_VERSION_3_0 || GLAD_ES_VERSION_3_0 || GLAD_EXT_packed_depth_stencil || (GLAD_OES_depth_texture && GLAD_OES_packed_depth_stencil))
-			flags |= commonsample;
+		flags |= commonsample | PIXELFORMATUSAGEFLAGS_RENDERTARGET | PIXELFORMATUSAGEFLAGS_MSAA;
 		break;
 		break;
 
 
 	case PIXELFORMAT_DEPTH32_FLOAT:
 	case PIXELFORMAT_DEPTH32_FLOAT:
 	case PIXELFORMAT_DEPTH32_FLOAT_STENCIL8:
 	case PIXELFORMAT_DEPTH32_FLOAT_STENCIL8:
-		if (GLAD_VERSION_3_0 || GLAD_ES_VERSION_3_0 || GLAD_ARB_depth_buffer_float)
-			flags |= commonsample | PIXELFORMATUSAGEFLAGS_RENDERTARGET | PIXELFORMATUSAGEFLAGS_MSAA;
+		flags |= commonsample | PIXELFORMATUSAGEFLAGS_RENDERTARGET | PIXELFORMATUSAGEFLAGS_MSAA;
 		break;
 		break;
 
 
 	case PIXELFORMAT_DXT1_UNORM:
 	case PIXELFORMAT_DXT1_UNORM:
@@ -2386,7 +2087,7 @@ uint32 OpenGL::getPixelFormatUsageFlags(PixelFormat pixelformat)
 		break;
 		break;
 	case PIXELFORMAT_ETC1_UNORM:
 	case PIXELFORMAT_ETC1_UNORM:
 		// ETC2 support guarantees ETC1 support as well.
 		// ETC2 support guarantees ETC1 support as well.
-		if (GLAD_ES_VERSION_3_0 || GLAD_VERSION_4_3 || GLAD_ARB_ES3_compatibility || GLAD_OES_compressed_ETC1_RGB8_texture)
+		if (GLAD_ES_VERSION_3_0 || GLAD_VERSION_4_3 || GLAD_ARB_ES3_compatibility)
 			flags |= commonsample;
 			flags |= commonsample;
 		break;
 		break;
 	case PIXELFORMAT_ETC2_RGB_UNORM:
 	case PIXELFORMAT_ETC2_RGB_UNORM:

+ 1 - 17
src/modules/graphics/opengl/OpenGL.h

@@ -200,13 +200,6 @@ public:
 		 **/
 		 **/
 		bool brokenSRGB;
 		bool brokenSRGB;
 
 
-		/**
-		 * Some Android graphics drivers claim to support GLES3.0 but have bugs
-		 * with certain aspects that users expect to work. For example:
-		 * https://github.com/love2d/love-android/issues/204
-		 **/
-		bool brokenGLES3;
-
 		/**
 		/**
 		 * Other bugs which have workarounds that don't use conditional code at
 		 * Other bugs which have workarounds that don't use conditional code at
 		 * the moment:
 		 * the moment:
@@ -369,19 +362,11 @@ public:
 	 **/
 	 **/
 	bool rawTexStorage(TextureType target, int levels, PixelFormat pixelformat, int width, int height, int depth = 1);
 	bool rawTexStorage(TextureType target, int levels, PixelFormat pixelformat, int width, int height, int depth = 1);
 
 
-	bool isTextureTypeSupported(TextureType type) const;
 	bool isBufferUsageSupported(BufferUsage usage) const;
 	bool isBufferUsageSupported(BufferUsage usage) const;
 	bool isClampZeroOneTextureWrapSupported() const;
 	bool isClampZeroOneTextureWrapSupported() const;
-	bool isPixelShaderHighpSupported() const;
-	bool isInstancingSupported() const;
-	bool isDepthCompareSampleSupported() const;
 	bool isSamplerLODBiasSupported() const;
 	bool isSamplerLODBiasSupported() const;
 	bool isBaseVertexSupported() const;
 	bool isBaseVertexSupported() const;
-	bool isMultiFormatMRTSupported() const;
-	bool isCopyBufferSupported() const;
-	bool isCopyBufferToTextureSupported() const;
 	bool isCopyTextureToBufferSupported() const;
 	bool isCopyTextureToBufferSupported() const;
-	bool isCopyRenderTargetToBufferSupported() const;
 
 
 	/**
 	/**
 	 * Returns the maximum supported width or height of a texture.
 	 * Returns the maximum supported width or height of a texture.
@@ -461,7 +446,7 @@ public:
 	static GLint getGLWrapMode(SamplerState::WrapMode wmode);
 	static GLint getGLWrapMode(SamplerState::WrapMode wmode);
 	static GLint getGLCompareMode(CompareMode mode);
 	static GLint getGLCompareMode(CompareMode mode);
 
 
-	static TextureFormat convertPixelFormat(PixelFormat pixelformat, bool renderbuffer);
+	static TextureFormat convertPixelFormat(PixelFormat pixelformat);
 	static bool isTexStorageSupported();
 	static bool isTexStorageSupported();
 	static uint32 getPixelFormatUsageFlags(PixelFormat pixelformat);
 	static uint32 getPixelFormatUsageFlags(PixelFormat pixelformat);
 
 
@@ -481,7 +466,6 @@ private:
 
 
 	bool contextInitialized;
 	bool contextInitialized;
 
 
-	bool pixelShaderHighpSupported;
 	bool baseVertexSupported;
 	bool baseVertexSupported;
 
 
 	float maxAnisotropy;
 	float maxAnisotropy;

+ 4 - 28
src/modules/graphics/opengl/Shader.cpp

@@ -41,7 +41,6 @@ namespace opengl
 Shader::Shader(StrongRef<love::graphics::ShaderStage> stages[SHADERSTAGE_MAX_ENUM], const CompileOptions &options)
 Shader::Shader(StrongRef<love::graphics::ShaderStage> stages[SHADERSTAGE_MAX_ENUM], const CompileOptions &options)
 	: love::graphics::Shader(stages, options)
 	: love::graphics::Shader(stages, options)
 	, program(0)
 	, program(0)
-	, splitUniformsPerDraw(false)
 	, builtinUniforms()
 	, builtinUniforms()
 	, builtinUniformInfo()
 	, builtinUniformInfo()
 {
 {
@@ -158,7 +157,7 @@ void Shader::mapActiveUniforms()
 			else if ((u.access & ACCESS_READ) != 0)
 			else if ((u.access & ACCESS_READ) != 0)
 				binding.access = GL_READ_ONLY;
 				binding.access = GL_READ_ONLY;
 
 
-			auto fmt = OpenGL::convertPixelFormat(u.storageTextureFormat, false);
+			auto fmt = OpenGL::convertPixelFormat(u.storageTextureFormat);
 			binding.internalFormat = fmt.internalformat;
 			binding.internalFormat = fmt.internalformat;
 
 
 			for (int i = 0; i < u.count; i++)
 			for (int i = 0; i < u.count; i++)
@@ -283,11 +282,6 @@ bool Shader::loadVolatile()
 {
 {
 	OpenGL::TempDebugGroup debuggroup("Shader load");
 	OpenGL::TempDebugGroup debuggroup("Shader load");
 
 
-	// love::graphics::Shader sets up the shader code-side of this.
-	auto gfx = Module::getInstance<love::graphics::Graphics>(Module::M_GRAPHICS);
-	if (gfx != nullptr)
-		splitUniformsPerDraw = !gfx->getCapabilities().features[Graphics::FEATURE_PIXEL_SHADER_HIGHP];
-
 	// zero out active texture list
 	// zero out active texture list
 	textureUnits.clear();
 	textureUnits.clear();
 	textureUnits.push_back(TextureUnit());
 	textureUnits.push_back(TextureUnit());
@@ -813,27 +807,9 @@ void Shader::updateBuiltinUniforms(love::graphics::Graphics *gfx, int viewportW,
 	data.constantColor = gfx->getColor();
 	data.constantColor = gfx->getColor();
 	gammaCorrectColor(data.constantColor);
 	gammaCorrectColor(data.constantColor);
 
 
-	// This branch is to avoid always declaring the whole array as highp in the
-	// vertex shader and mediump in the pixel shader for love's default shaders,
-	// on systems that don't support highp in pixel shaders. The default shaders
-	// use the transform matrices in vertex shaders and screen size params in
-	// pixel shaders. If there's a single array containing both and each shader
-	// stage declares a different precision, that's a compile error.
-	if (splitUniformsPerDraw)
-	{
-		GLint location = builtinUniforms[BUILTIN_UNIFORMS_PER_DRAW];
-		if (location >= 0)
-			glUniform4fv(location, 11, (const GLfloat *) &data);
-		GLint location2 = builtinUniforms[BUILTIN_UNIFORMS_PER_DRAW_2];
-		if (location2 >= 0)
-			glUniform4fv(location2, 1, (const GLfloat *) &data.screenSizeParams);
-	}
-	else
-	{
-		GLint location = builtinUniforms[BUILTIN_UNIFORMS_PER_DRAW];
-		if (location >= 0)
-			glUniform4fv(location, 12, (const GLfloat *) &data);
-	}
+	GLint location = builtinUniforms[BUILTIN_UNIFORMS_PER_DRAW];
+	if (location >= 0)
+		glUniform4fv(location, 12, (const GLfloat *) &data);
 }
 }
 
 
 } // opengl
 } // opengl

+ 0 - 2
src/modules/graphics/opengl/Shader.h

@@ -106,8 +106,6 @@ private:
 	// volatile
 	// volatile
 	GLuint program;
 	GLuint program;
 
 
-	bool splitUniformsPerDraw;
-
 	// Location values for any built-in uniform variables.
 	// Location values for any built-in uniform variables.
 	GLint builtinUniforms[BUILTIN_MAX_ENUM];
 	GLint builtinUniforms[BUILTIN_MAX_ENUM];
 	UniformInfo *builtinUniformInfo[BUILTIN_MAX_ENUM];
 	UniformInfo *builtinUniformInfo[BUILTIN_MAX_ENUM];

+ 13 - 39
src/modules/graphics/opengl/Texture.cpp

@@ -45,18 +45,14 @@ static GLenum createFBO(GLuint &framebuffer, TextureType texType, PixelFormat fo
 
 
 	if (texture != 0)
 	if (texture != 0)
 	{
 	{
-		if (isPixelFormatDepthStencil(format) && (GLAD_ES_VERSION_3_0 || !GLAD_ES_VERSION_2_0))
+		if (isPixelFormatDepthStencil(format))
 		{
 		{
-			// glDrawBuffers is an ext in GL2. glDrawBuffer doesn't exist in ES3.
 			GLenum none = GL_NONE;
 			GLenum none = GL_NONE;
-			if (GLAD_ES_VERSION_3_0)
-				glDrawBuffers(1, &none);
-			else
-				glDrawBuffer(GL_NONE);
+			glDrawBuffers(1, &none);
 			glReadBuffer(GL_NONE);
 			glReadBuffer(GL_NONE);
 		}
 		}
 
 
-		OpenGL::TextureFormat fmt = OpenGL::convertPixelFormat(format, false);
+		OpenGL::TextureFormat fmt = OpenGL::convertPixelFormat(format);
 
 
 		int faces = texType == TEXTURE_CUBE ? 6 : 1;
 		int faces = texType == TEXTURE_CUBE ? 6 : 1;
 
 
@@ -124,7 +120,7 @@ static GLenum createFBO(GLuint &framebuffer, TextureType texType, PixelFormat fo
 
 
 static GLenum newRenderbuffer(int width, int height, int &samples, PixelFormat pixelformat, GLuint &buffer)
 static GLenum newRenderbuffer(int width, int height, int &samples, PixelFormat pixelformat, GLuint &buffer)
 {
 {
-	OpenGL::TextureFormat fmt = OpenGL::convertPixelFormat(pixelformat, true);
+	OpenGL::TextureFormat fmt = OpenGL::convertPixelFormat(pixelformat);
 
 
 	GLuint current_fbo = gl.getFramebuffer(OpenGL::FRAMEBUFFER_ALL);
 	GLuint current_fbo = gl.getFramebuffer(OpenGL::FRAMEBUFFER_ALL);
 
 
@@ -133,14 +129,10 @@ static GLenum newRenderbuffer(int width, int height, int &samples, PixelFormat p
 	glGenFramebuffers(1, &fbo);
 	glGenFramebuffers(1, &fbo);
 	gl.bindFramebuffer(OpenGL::FRAMEBUFFER_ALL, fbo);
 	gl.bindFramebuffer(OpenGL::FRAMEBUFFER_ALL, fbo);
 
 
-	if (isPixelFormatDepthStencil(pixelformat) && (GLAD_ES_VERSION_3_0 || !GLAD_ES_VERSION_2_0))
+	if (isPixelFormatDepthStencil(pixelformat))
 	{
 	{
-		// glDrawBuffers is an ext in GL2. glDrawBuffer doesn't exist in ES3.
 		GLenum none = GL_NONE;
 		GLenum none = GL_NONE;
-		if (GLAD_ES_VERSION_3_0)
-			glDrawBuffers(1, &none);
-		else
-			glDrawBuffer(GL_NONE);
+		glDrawBuffers(1, &none);
 		glReadBuffer(GL_NONE);
 		glReadBuffer(GL_NONE);
 	}
 	}
 
 
@@ -278,7 +270,7 @@ void Texture::createTexture()
 
 
 	if (parentView.texture != this)
 	if (parentView.texture != this)
 	{
 	{
-		OpenGL::TextureFormat fmt = gl.convertPixelFormat(format, false);
+		OpenGL::TextureFormat fmt = gl.convertPixelFormat(format);
 		Texture *basetex = (Texture *) parentView.texture;
 		Texture *basetex = (Texture *) parentView.texture;
 		int layers = texType == TEXTURE_CUBE ? 6 : getLayerCount();
 		int layers = texType == TEXTURE_CUBE ? 6 : getLayerCount();
 
 
@@ -317,14 +309,14 @@ void Texture::createTexture()
 		gl.rawTexStorage(texType, mipcount, format, pixelWidth, pixelHeight, texType == TEXTURE_VOLUME ? depth : layers);
 		gl.rawTexStorage(texType, mipcount, format, pixelWidth, pixelHeight, texType == TEXTURE_VOLUME ? depth : layers);
 
 
 	// rawTexStorage handles this for uncompressed textures.
 	// rawTexStorage handles this for uncompressed textures.
-	if (isCompressed() && (GLAD_VERSION_1_1 || GLAD_ES_VERSION_3_0))
+	if (isCompressed())
 		glTexParameteri(gltype, GL_TEXTURE_MAX_LEVEL, mipcount - 1);
 		glTexParameteri(gltype, GL_TEXTURE_MAX_LEVEL, mipcount - 1);
 
 
 	int w = pixelWidth;
 	int w = pixelWidth;
 	int h = pixelHeight;
 	int h = pixelHeight;
 	int d = depth;
 	int d = depth;
 
 
-	OpenGL::TextureFormat fmt = gl.convertPixelFormat(format, false);
+	OpenGL::TextureFormat fmt = gl.convertPixelFormat(format);
 
 
 	for (int mip = 0; mip < mipcount; mip++)
 	for (int mip = 0; mip < mipcount; mip++)
 	{
 	{
@@ -413,14 +405,6 @@ bool Texture::loadVolatile()
 
 
 	OpenGL::TempDebugGroup debuggroup("Texture load");
 	OpenGL::TempDebugGroup debuggroup("Texture load");
 
 
-	// NPOT textures don't support mipmapping without full NPOT support.
-	if ((GLAD_ES_VERSION_2_0 && !(GLAD_ES_VERSION_3_0 || GLAD_OES_texture_npot))
-		&& (pixelWidth != nextP2(pixelWidth) || pixelHeight != nextP2(pixelHeight)))
-	{
-		mipmapCount = 1;
-		samplerState.mipmapFilter = SamplerState::MIPMAP_FILTER_NONE;
-	}
-
 	actualSamples = std::max(1, std::min(getRequestedMSAA(), gl.getMaxSamples()));
 	actualSamples = std::max(1, std::min(getRequestedMSAA(), gl.getMaxSamples()));
 
 
 	while (glGetError() != GL_NO_ERROR); // Clear errors.
 	while (glGetError() != GL_NO_ERROR); // Clear errors.
@@ -512,7 +496,7 @@ void Texture::uploadByteData(const void *data, size_t size, int level, int slice
 
 
 	gl.bindTextureToUnit(this, 0, false);
 	gl.bindTextureToUnit(this, 0, false);
 
 
-	OpenGL::TextureFormat fmt = OpenGL::convertPixelFormat(format, false);
+	OpenGL::TextureFormat fmt = OpenGL::convertPixelFormat(format);
 	GLenum gltarget = OpenGL::getGLTextureType(texType);
 	GLenum gltarget = OpenGL::getGLTextureType(texType);
 
 
 	if (texType == TEXTURE_CUBE)
 	if (texType == TEXTURE_CUBE)
@@ -555,12 +539,12 @@ void Texture::generateMipmapsInternal()
 void Texture::readbackInternal(int slice, int mipmap, const Rect &rect, int destwidth, size_t size, void *dest)
 void Texture::readbackInternal(int slice, int mipmap, const Rect &rect, int destwidth, size_t size, void *dest)
 {
 {
 	// Not supported in GL with compressed textures...
 	// Not supported in GL with compressed textures...
-	if ((GLAD_VERSION_1_1 || GLAD_ES_VERSION_3_0) && !isCompressed())
+	if (!isCompressed())
 		glPixelStorei(GL_PACK_ROW_LENGTH, destwidth);
 		glPixelStorei(GL_PACK_ROW_LENGTH, destwidth);
 
 
 	gl.bindTextureToUnit(this, 0, false);
 	gl.bindTextureToUnit(this, 0, false);
 
 
-	OpenGL::TextureFormat fmt = gl.convertPixelFormat(format, false);
+	OpenGL::TextureFormat fmt = gl.convertPixelFormat(format);
 
 
 	if (gl.isCopyTextureToBufferSupported())
 	if (gl.isCopyTextureToBufferSupported())
 	{
 	{
@@ -589,7 +573,7 @@ void Texture::readbackInternal(int slice, int mipmap, const Rect &rect, int dest
 		gl.bindFramebuffer(OpenGL::FRAMEBUFFER_ALL, current_fbo);
 		gl.bindFramebuffer(OpenGL::FRAMEBUFFER_ALL, current_fbo);
 	}
 	}
 
 
-	if ((GLAD_VERSION_1_1 || GLAD_ES_VERSION_3_0) && !isCompressed())
+	if (!isCompressed())
 		glPixelStorei(GL_PACK_ROW_LENGTH, 0);
 		glPixelStorei(GL_PACK_ROW_LENGTH, 0);
 }
 }
 
 
@@ -630,18 +614,8 @@ void Texture::copyToBuffer(love::graphics::Buffer *dest, int slice, int mipmap,
 
 
 void Texture::setSamplerState(const SamplerState &s)
 void Texture::setSamplerState(const SamplerState &s)
 {
 {
-	if (s.depthSampleMode.hasValue && !gl.isDepthCompareSampleSupported())
-		throw love::Exception("Depth comparison sampling in shaders is not supported on this system.");
-
 	samplerState = validateSamplerState(s);
 	samplerState = validateSamplerState(s);
 
 
-	// If we only have limited NPOT support then the wrap mode must be CLAMP.
-	if ((GLAD_ES_VERSION_2_0 && !(GLAD_ES_VERSION_3_0 || GLAD_OES_texture_npot))
-		&& (pixelWidth != nextP2(pixelWidth) || pixelHeight != nextP2(pixelHeight) || depth != nextP2(depth)))
-	{
-		samplerState.wrapU = samplerState.wrapV = samplerState.wrapW = SamplerState::WRAP_CLAMP;
-	}
-
 	gl.bindTextureToUnit(this, 0, false);
 	gl.bindTextureToUnit(this, 0, false);
 	gl.setSamplerState(texType, samplerState);
 	gl.setSamplerState(texType, samplerState);
 }
 }

+ 4 - 9
src/modules/graphics/vulkan/Graphics.cpp

@@ -739,7 +739,6 @@ void Graphics::initCapabilities()
 	capabilities.features[FEATURE_MULTI_RENDER_TARGET_FORMATS] = true;
 	capabilities.features[FEATURE_MULTI_RENDER_TARGET_FORMATS] = true;
 	capabilities.features[FEATURE_CLAMP_ZERO] = true;
 	capabilities.features[FEATURE_CLAMP_ZERO] = true;
 	capabilities.features[FEATURE_CLAMP_ONE] = true;
 	capabilities.features[FEATURE_CLAMP_ONE] = true;
-	capabilities.features[FEATURE_BLEND_MINMAX] = true;
 	capabilities.features[FEATURE_LIGHTEN] = true;
 	capabilities.features[FEATURE_LIGHTEN] = true;
 	capabilities.features[FEATURE_FULL_NPOT] = true;
 	capabilities.features[FEATURE_FULL_NPOT] = true;
 	capabilities.features[FEATURE_PIXEL_SHADER_HIGHP] = true;
 	capabilities.features[FEATURE_PIXEL_SHADER_HIGHP] = true;
@@ -748,14 +747,9 @@ void Graphics::initCapabilities()
 	capabilities.features[FEATURE_GLSL4] = true;
 	capabilities.features[FEATURE_GLSL4] = true;
 	capabilities.features[FEATURE_INSTANCING] = true;
 	capabilities.features[FEATURE_INSTANCING] = true;
 	capabilities.features[FEATURE_TEXEL_BUFFER] = true;
 	capabilities.features[FEATURE_TEXEL_BUFFER] = true;
-	capabilities.features[FEATURE_INDEX_BUFFER_32BIT] = true;
-	capabilities.features[FEATURE_COPY_BUFFER] = true;
-	capabilities.features[FEATURE_COPY_BUFFER_TO_TEXTURE] = true;
 	capabilities.features[FEATURE_COPY_TEXTURE_TO_BUFFER] = true;
 	capabilities.features[FEATURE_COPY_TEXTURE_TO_BUFFER] = true;
-	capabilities.features[FEATURE_COPY_RENDER_TARGET_TO_BUFFER] = true;
-	capabilities.features[FEATURE_MIPMAP_RANGE] = true;
 	capabilities.features[FEATURE_INDIRECT_DRAW] = true;
 	capabilities.features[FEATURE_INDIRECT_DRAW] = true;
-	static_assert(FEATURE_MAX_ENUM == 19, "Graphics::initCapabilities must be updated when adding a new graphics feature!");
+	static_assert(FEATURE_MAX_ENUM == 13, "Graphics::initCapabilities must be updated when adding a new graphics feature!");
 
 
 	VkPhysicalDeviceProperties properties;
 	VkPhysicalDeviceProperties properties;
 	vkGetPhysicalDeviceProperties(physicalDevice, &properties);
 	vkGetPhysicalDeviceProperties(physicalDevice, &properties);
@@ -1410,7 +1404,7 @@ graphics::Shader::BuiltinUniformData Graphics::getCurrentBuiltinUniformData()
 	data.projectionMatrix = getDeviceProjection();
 	data.projectionMatrix = getDeviceProjection();
 
 
 	data.scaleParams.x = (float) getCurrentDPIScale();
 	data.scaleParams.x = (float) getCurrentDPIScale();
-	data.scaleParams.y = getPointSize();;
+	data.scaleParams.y = getPointSize();
 
 
 	// Flip y to convert input y-up [-1, 1] to vulkan's y-down [-1, 1].
 	// Flip y to convert input y-up [-1, 1] to vulkan's y-down [-1, 1].
 	// Convert input z [-1, 1] to vulkan [0, 1].
 	// Convert input z [-1, 1] to vulkan [0, 1].
@@ -2809,7 +2803,8 @@ VkPipeline Graphics::createGraphicsPipeline(GraphicsPipelineConfiguration &confi
 	return graphicsPipeline;
 	return graphicsPipeline;
 }
 }
 
 
-void Graphics::ensureGraphicsPipelineConfiguration(GraphicsPipelineConfiguration &configuration) {
+void Graphics::ensureGraphicsPipelineConfiguration(GraphicsPipelineConfiguration &configuration)
+{
 	auto it = graphicsPipelines.find(configuration);
 	auto it = graphicsPipelines.find(configuration);
 	if (it != graphicsPipelines.end())
 	if (it != graphicsPipelines.end())
 	{
 	{

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

@@ -259,9 +259,6 @@ std::vector<Window::ContextAttribs> Window::getContextAttribsList() const
 	// Do we want a debug context?
 	// Do we want a debug context?
 	bool debug = love::graphics::isDebugEnabled();
 	bool debug = love::graphics::isDebugEnabled();
 
 
-	const char *preferGL2hint = SDL_GetHint("LOVE_GRAPHICS_USE_GL2");
-	bool preferGL2 = (preferGL2hint != nullptr && preferGL2hint[0] != '0');
-
 	const char *preferGL3hint = SDL_GetHint("LOVE_GRAPHICS_USE_GL3");
 	const char *preferGL3hint = SDL_GetHint("LOVE_GRAPHICS_USE_GL3");
 	bool preferGL3 = (preferGL3hint != nullptr && preferGL3hint[0] != '0');
 	bool preferGL3 = (preferGL3hint != nullptr && preferGL3hint[0] != '0');
 
 
@@ -269,22 +266,15 @@ std::vector<Window::ContextAttribs> Window::getContextAttribsList() const
 	{
 	{
 		{4, 3, false, debug},
 		{4, 3, false, debug},
 		{3, 3, false, debug},
 		{3, 3, false, debug},
-		{2, 1, false, debug},
 	};
 	};
 
 
 	std::vector<ContextAttribs> glescontexts =
 	std::vector<ContextAttribs> glescontexts =
 	{
 	{
 		{3, 2, true, debug},
 		{3, 2, true, debug},
 		{3, 0, true, debug},
 		{3, 0, true, debug},
-		{2, 0, true, debug}
 	};
 	};
 
 
-	if (preferGL2)
-	{
-		std::swap(glcontexts[0], glcontexts[2]);
-		std::swap(glescontexts[0], glescontexts[2]);
-	}
-	else if (preferGL3)
+	if (preferGL3)
 	{
 	{
 		std::swap(glcontexts[0], glcontexts[1]);
 		std::swap(glcontexts[0], glcontexts[1]);
 		std::swap(glescontexts[0], glescontexts[1]);
 		std::swap(glescontexts[0], glescontexts[1]);
@@ -458,7 +448,7 @@ bool Window::createWindowAndContext(int x, int y, int w, int h, Uint32 windowfla
 	if (failed)
 	if (failed)
 	{
 	{
 		std::string title = "Unable to create renderer";
 		std::string title = "Unable to create renderer";
-		std::string message = "This program requires a graphics card and video drivers which support OpenGL 2.1 or OpenGL ES 2.";
+		std::string message = "This program requires a graphics card and video drivers which support OpenGL 3.3 or OpenGL ES 3.0.";
 
 
 		if (!glversion.empty())
 		if (!glversion.empty())
 			message += "\n\nDetected OpenGL version:\n" + glversion;
 			message += "\n\nDetected OpenGL version:\n" + glversion;

+ 3 - 4
testing/tests/graphics.lua

@@ -2805,10 +2805,9 @@ love.test.graphics.getSupported = function(test)
   -- table match what the documentation lists
   -- table match what the documentation lists
   local gfs = {
   local gfs = {
     'clampzero', 'lighten', 'glsl3', 'instancing', 'fullnpot', 
     'clampzero', 'lighten', 'glsl3', 'instancing', 'fullnpot', 
-    'pixelshaderhighp', 'shaderderivatives', 'indirectdraw', 'mipmaprange',
-    'copyrendertargettobuffer', 'copytexturetobuffer', 'copybuffer',
-    'copybuffertotexture', 'indexbuffer32bit', 'multirendertargetformats', 
-    'clampone', 'blendminmax', 'glsl4'
+    'pixelshaderhighp', 'shaderderivatives', 'indirectdraw',
+    'copytexturetobuffer', 'multirendertargetformats', 
+    'clampone', 'glsl4'
   }
   }
   local features = love.graphics.getSupported()
   local features = love.graphics.getSupported()
   for g=1,#gfs do
   for g=1,#gfs do