Browse Source

Restructured internal code for graphics capabilities. Added love.graphics.getTextureTypes which returns a table of Texture Type to boolean supported fields.

--HG--
branch : minor
Alex Szpakowski 8 years ago
parent
commit
54a049e206

+ 7 - 6
src/modules/graphics/Canvas.cpp

@@ -72,6 +72,7 @@ Canvas::Canvas(const Settings &settings)
 	}
 	}
 
 
 	auto gfx = Module::getInstance<Graphics>(Module::M_GRAPHICS);
 	auto gfx = Module::getInstance<Graphics>(Module::M_GRAPHICS);
+	const Graphics::Capabilities &caps = gfx->getCapabilities();
 
 
 	if (!gfx->isCanvasFormatSupported(format, readable))
 	if (!gfx->isCanvasFormatSupported(format, readable))
 	{
 	{
@@ -89,7 +90,7 @@ Canvas::Canvas(const Settings &settings)
 	if (!readable && texType != TEXTURE_2D)
 	if (!readable && texType != TEXTURE_2D)
 		throw love::Exception("Non-readable pixel formats are only supported for 2D texture types.");
 		throw love::Exception("Non-readable pixel formats are only supported for 2D texture types.");
 
 
-	if (!gfx->isTextureTypeSupported(texType))
+	if (!caps.textureTypes[texType])
 	{
 	{
 		const char *textypestr = "unknown";
 		const char *textypestr = "unknown";
 		Texture::getConstant(texType, textypestr);
 		Texture::getConstant(texType, textypestr);
@@ -100,14 +101,14 @@ Canvas::Canvas(const Settings &settings)
 	switch (texType)
 	switch (texType)
 	{
 	{
 	case TEXTURE_2D:
 	case TEXTURE_2D:
-		maxsize = gfx->getSystemLimit(Graphics::LIMIT_TEXTURE_SIZE);
+		maxsize = (int) caps.limits[Graphics::LIMIT_TEXTURE_SIZE];
 		if (pixelWidth > maxsize)
 		if (pixelWidth > maxsize)
 			throw TextureTooLargeException("width", pixelWidth);
 			throw TextureTooLargeException("width", pixelWidth);
 		else if (pixelHeight > maxsize)
 		else if (pixelHeight > maxsize)
 			throw TextureTooLargeException("height", pixelHeight);
 			throw TextureTooLargeException("height", pixelHeight);
 		break;
 		break;
 	case TEXTURE_VOLUME:
 	case TEXTURE_VOLUME:
-		maxsize = gfx->getSystemLimit(Graphics::LIMIT_VOLUME_TEXTURE_SIZE);
+		maxsize = (int) caps.limits[Graphics::LIMIT_VOLUME_TEXTURE_SIZE];
 		if (pixelWidth > maxsize)
 		if (pixelWidth > maxsize)
 			throw TextureTooLargeException("width", pixelWidth);
 			throw TextureTooLargeException("width", pixelWidth);
 		else if (pixelHeight > maxsize)
 		else if (pixelHeight > maxsize)
@@ -116,18 +117,18 @@ Canvas::Canvas(const Settings &settings)
 			throw TextureTooLargeException("depth", depth);
 			throw TextureTooLargeException("depth", depth);
 		break;
 		break;
 	case TEXTURE_2D_ARRAY:
 	case TEXTURE_2D_ARRAY:
-		maxsize = gfx->getSystemLimit(Graphics::LIMIT_TEXTURE_SIZE);
+		maxsize = (int) caps.limits[Graphics::LIMIT_TEXTURE_SIZE];
 		if (pixelWidth > maxsize)
 		if (pixelWidth > maxsize)
 			throw TextureTooLargeException("width", pixelWidth);
 			throw TextureTooLargeException("width", pixelWidth);
 		else if (pixelHeight > maxsize)
 		else if (pixelHeight > maxsize)
 			throw TextureTooLargeException("height", pixelHeight);
 			throw TextureTooLargeException("height", pixelHeight);
-		else if (layers > gfx->getSystemLimit(Graphics::LIMIT_TEXTURE_LAYERS))
+		else if (layers > (int) caps.limits[Graphics::LIMIT_TEXTURE_LAYERS])
 			throw TextureTooLargeException("array layer count", layers);
 			throw TextureTooLargeException("array layer count", layers);
 		break;
 		break;
 	case TEXTURE_CUBE:
 	case TEXTURE_CUBE:
 		if (pixelWidth != pixelHeight)
 		if (pixelWidth != pixelHeight)
 			throw love::Exception("Cubemap textures must have equal width and height.");
 			throw love::Exception("Cubemap textures must have equal width and height.");
-		else if (pixelWidth > gfx->getSystemLimit(Graphics::LIMIT_CUBE_TEXTURE_SIZE))
+		else if (pixelWidth > (int) caps.limits[Graphics::LIMIT_CUBE_TEXTURE_SIZE])
 			throw TextureTooLargeException("width", pixelWidth);
 			throw TextureTooLargeException("width", pixelWidth);
 		break;
 		break;
 	default:
 	default:

+ 4 - 1
src/modules/graphics/Font.cpp

@@ -99,7 +99,10 @@ Font::TextureSize Font::getNextTextureSize() const
 	int maxsize = 2048;
 	int maxsize = 2048;
 	auto gfx = Module::getInstance<Graphics>(Module::M_GRAPHICS);
 	auto gfx = Module::getInstance<Graphics>(Module::M_GRAPHICS);
 	if (gfx != nullptr)
 	if (gfx != nullptr)
-		maxsize = (int) gfx->getSystemLimit(Graphics::LIMIT_TEXTURE_SIZE);
+	{
+		const auto &caps = gfx->getCapabilities();
+		maxsize = (int) caps.limits[Graphics::LIMIT_TEXTURE_SIZE];
+	}
 
 
 	int maxwidth  = std::min(8192, maxsize);
 	int maxwidth  = std::min(8192, maxsize);
 	int maxheight = std::min(4096, maxsize);
 	int maxheight = std::min(4096, maxsize);

+ 6 - 2
src/modules/graphics/Graphics.cpp

@@ -112,6 +112,7 @@ Graphics::Graphics()
 	, streamBufferState()
 	, streamBufferState()
 	, projectionMatrix()
 	, projectionMatrix()
 	, canvasSwitchCount(0)
 	, canvasSwitchCount(0)
+	, capabilities()
 {
 {
 	transformStack.reserve(16);
 	transformStack.reserve(16);
 	transformStack.push_back(Matrix4());
 	transformStack.push_back(Matrix4());
@@ -1142,6 +1143,11 @@ void Graphics::polygon(DrawMode mode, const float *coords, size_t count)
 	}
 	}
 }
 }
 
 
+const Graphics::Capabilities &Graphics::getCapabilities() const
+{
+	return capabilities;
+}
+
 Graphics::Stats Graphics::getStats() const
 Graphics::Stats Graphics::getStats() const
 {
 {
 	Stats stats;
 	Stats stats;
@@ -1451,8 +1457,6 @@ StringMap<Graphics::Feature, Graphics::FEATURE_MAX_ENUM>::Entry Graphics::featur
 	{ "lighten",            FEATURE_LIGHTEN              },
 	{ "lighten",            FEATURE_LIGHTEN              },
 	{ "fullnpot",           FEATURE_FULL_NPOT            },
 	{ "fullnpot",           FEATURE_FULL_NPOT            },
 	{ "pixelshaderhighp",   FEATURE_PIXEL_SHADER_HIGHP   },
 	{ "pixelshaderhighp",   FEATURE_PIXEL_SHADER_HIGHP   },
-	{ "arraytexture",       FEATURE_ARRAY_TEXTURE        },
-	{ "volumetexture",      FEATURE_VOLUME_TEXTURE       },
 	{ "glsl3",              FEATURE_GLSL3                },
 	{ "glsl3",              FEATURE_GLSL3                },
 	{ "instancing",         FEATURE_INSTANCING           },
 	{ "instancing",         FEATURE_INSTANCING           },
 };
 };

+ 13 - 14
src/modules/graphics/Graphics.h

@@ -159,8 +159,6 @@ public:
 		FEATURE_LIGHTEN,
 		FEATURE_LIGHTEN,
 		FEATURE_FULL_NPOT,
 		FEATURE_FULL_NPOT,
 		FEATURE_PIXEL_SHADER_HIGHP,
 		FEATURE_PIXEL_SHADER_HIGHP,
-		FEATURE_ARRAY_TEXTURE,
-		FEATURE_VOLUME_TEXTURE,
 		FEATURE_GLSL3,
 		FEATURE_GLSL3,
 		FEATURE_INSTANCING,
 		FEATURE_INSTANCING,
 		FEATURE_MAX_ENUM
 		FEATURE_MAX_ENUM
@@ -199,6 +197,13 @@ public:
 		TEMPORARY_RT_STENCIL = (1 << 1),
 		TEMPORARY_RT_STENCIL = (1 << 1),
 	};
 	};
 
 
+	struct Capabilities
+	{
+		double limits[LIMIT_MAX_ENUM];
+		bool features[FEATURE_MAX_ENUM];
+		bool textureTypes[TEXTURE_MAX_ENUM];
+	};
+
 	struct RendererInfo
 	struct RendererInfo
 	{
 	{
 		std::string name;
 		std::string name;
@@ -696,19 +701,10 @@ public:
 	void polygon(DrawMode mode, const float *coords, size_t count);
 	void polygon(DrawMode mode, const float *coords, size_t count);
 
 
 	/**
 	/**
-	 * Gets whether a graphics feature is supported on this system.
-	 **/
-	virtual bool isSupported(Feature feature) const = 0;
-
-	/**
-	 * Gets whether the given texture type is supported on this system.
+	 * Gets the graphics capabilities (feature support, limit values, and
+	 * supported texture types) of this system.
 	 **/
 	 **/
-	virtual bool isTextureTypeSupported(TextureType textype) const = 0;
-
-	/**
-	 * Gets the system-dependent numeric limit for the specified parameter.
-	 **/
-	virtual double getSystemLimit(SystemLimit limittype) const = 0;
+	const Capabilities &getCapabilities() const;
 
 
 	/**
 	/**
 	 * Gets whether the specified pixel format is supported by Canvases or
 	 * Gets whether the specified pixel format is supported by Canvases or
@@ -864,6 +860,7 @@ protected:
 
 
 	virtual StreamBuffer *newStreamBuffer(BufferType type, size_t size) = 0;
 	virtual StreamBuffer *newStreamBuffer(BufferType type, size_t size) = 0;
 
 
+	virtual void initCapabilities() = 0;
 	virtual void getAPIStats(int &drawcalls, int &shaderswitches) const = 0;
 	virtual void getAPIStats(int &drawcalls, int &shaderswitches) const = 0;
 
 
 	Canvas *getTemporaryCanvas(PixelFormat format, int w, int h, int samples);
 	Canvas *getTemporaryCanvas(PixelFormat format, int w, int h, int samples);
@@ -903,6 +900,8 @@ protected:
 
 
 	int canvasSwitchCount;
 	int canvasSwitchCount;
 
 
+	Capabilities capabilities;
+
 	static const size_t MAX_USER_STACK_DEPTH = 64;
 	static const size_t MAX_USER_STACK_DEPTH = 64;
 
 
 private:
 private:

+ 1 - 1
src/modules/graphics/Mesh.cpp

@@ -303,7 +303,7 @@ bool Mesh::isAttributeEnabled(const std::string &name) const
 void Mesh::attachAttribute(const std::string &name, Mesh *mesh, const std::string &attachname, AttributeStep step)
 void Mesh::attachAttribute(const std::string &name, Mesh *mesh, const std::string &attachname, AttributeStep step)
 {
 {
 	auto gfx = Module::getInstance<Graphics>(Module::M_GRAPHICS);
 	auto gfx = Module::getInstance<Graphics>(Module::M_GRAPHICS);
-	if (step == STEP_PER_INSTANCE && !gfx->isSupported(Graphics::FEATURE_INSTANCING))
+	if (step == STEP_PER_INSTANCE && !gfx->getCapabilities().features[Graphics::FEATURE_INSTANCING])
 		throw love::Exception("Vertex attribute instancing is not supported on this system.");
 		throw love::Exception("Vertex attribute instancing is not supported on this system.");
 
 
 	if (mesh != this)
 	if (mesh != this)

+ 1 - 1
src/modules/graphics/Shader.cpp

@@ -233,7 +233,7 @@ bool Shader::validate(Graphics *gfx, bool gles, const ShaderSource &source, bool
 		return false;
 		return false;
 	}
 	}
 
 
-	bool supportsGLSL3 = gfx->isSupported(Graphics::FEATURE_GLSL3);
+	bool supportsGLSL3 = gfx->getCapabilities().features[Graphics::FEATURE_GLSL3];
 
 
 	int defaultversion = gles ? 100 : 120;
 	int defaultversion = gles ? 100 : 120;
 	EProfile defaultprofile = ENoProfile;
 	EProfile defaultprofile = ENoProfile;

+ 25 - 56
src/modules/graphics/opengl/Graphics.cpp

@@ -202,6 +202,7 @@ bool Graphics::setMode(int width, int height, int pixelwidth, int pixelheight, b
 	gl.setupContext();
 	gl.setupContext();
 
 
 	created = true;
 	created = true;
+	initCapabilities();
 
 
 	setViewportSize(width, height, pixelwidth, pixelheight);
 	setViewportSize(width, height, pixelwidth, pixelheight);
 
 
@@ -272,7 +273,7 @@ bool Graphics::setMode(int width, int height, int pixelwidth, int pixelheight, b
 	// We always need a default shader.
 	// We always need a default shader.
 	for (int i = 0; i < Shader::STANDARD_MAX_ENUM; i++)
 	for (int i = 0; i < Shader::STANDARD_MAX_ENUM; i++)
 	{
 	{
-		if (i == Shader::STANDARD_ARRAY && !isSupported(FEATURE_ARRAY_TEXTURE))
+		if (i == Shader::STANDARD_ARRAY && !capabilities.textureTypes[TEXTURE_2D_ARRAY])
 			continue;
 			continue;
 
 
 		if (!Shader::standardShaders[i])
 		if (!Shader::standardShaders[i])
@@ -1282,7 +1283,7 @@ void Graphics::setBlendMode(BlendMode mode, BlendAlpha alphamode)
 
 
 	if (mode == BLEND_LIGHTEN || mode == BLEND_DARKEN)
 	if (mode == BLEND_LIGHTEN || mode == BLEND_DARKEN)
 	{
 	{
-		if (!isSupported(FEATURE_LIGHTEN))
+		if (!capabilities.features[FEATURE_LIGHTEN])
 			throw love::Exception("The 'lighten' and 'darken' blend modes are not supported on this system.");
 			throw love::Exception("The 'lighten' and 'darken' blend modes are not supported on this system.");
 	}
 	}
 
 
@@ -1410,61 +1411,29 @@ void Graphics::getAPIStats(int &drawcalls, int &shaderswitches) const
 	shaderswitches = gl.stats.shaderSwitches;
 	shaderswitches = gl.stats.shaderSwitches;
 }
 }
 
 
-double Graphics::getSystemLimit(SystemLimit limittype) const
+void Graphics::initCapabilities()
 {
 {
-	switch (limittype)
-	{
-	case LIMIT_POINT_SIZE:
-		return (double) gl.getMaxPointSize();
-	case LIMIT_TEXTURE_SIZE:
-		return (double) gl.getMax2DTextureSize();
-	case LIMIT_TEXTURE_LAYERS:
-		return (double) gl.getMaxTextureLayers();
-	case LIMIT_VOLUME_TEXTURE_SIZE:
-		return (double) gl.getMax3DTextureSize();
-	case LIMIT_CUBE_TEXTURE_SIZE:
-		return (double) gl.getMaxCubeTextureSize();
-	case LIMIT_MULTI_CANVAS:
-		return (double) gl.getMaxRenderTargets();
-	case LIMIT_CANVAS_MSAA:
-		return (double) gl.getMaxRenderbufferSamples();
-	case LIMIT_ANISOTROPY:
-		return (double) gl.getMaxAnisotropy();
-	default:
-		return 0.0;
-	}
-}
-
-bool Graphics::isSupported(Feature feature) const
-{
-	switch (feature)
-	{
-	case FEATURE_MULTI_CANVAS_FORMATS:
-		return Canvas::isMultiFormatMultiCanvasSupported();
-	case FEATURE_CLAMP_ZERO:
-		return gl.isClampZeroTextureWrapSupported();
-	case FEATURE_LIGHTEN:
-		return GLAD_VERSION_1_4 || GLAD_ES_VERSION_3_0 || GLAD_EXT_blend_minmax;
-	case FEATURE_FULL_NPOT:
-		return GLAD_VERSION_2_0 || GLAD_ES_VERSION_3_0 || GLAD_OES_texture_npot;
-	case FEATURE_PIXEL_SHADER_HIGHP:
-		return gl.isPixelShaderHighpSupported();
-	case FEATURE_ARRAY_TEXTURE:
-		return gl.isTextureTypeSupported(TEXTURE_2D_ARRAY);
-	case FEATURE_VOLUME_TEXTURE:
-		return gl.isTextureTypeSupported(TEXTURE_VOLUME);
-	case FEATURE_GLSL3:
-		return GLAD_ES_VERSION_3_0 || gl.isCoreProfile();
-	case FEATURE_INSTANCING:
-		return gl.isInstancingSupported();
-	default:
-		return false;
-	}
-}
-
-bool Graphics::isTextureTypeSupported(TextureType textype) const
-{
-	return gl.isTextureTypeSupported(textype);
+	capabilities.features[FEATURE_MULTI_CANVAS_FORMATS] = Canvas::isMultiFormatMultiCanvasSupported();
+	capabilities.features[FEATURE_CLAMP_ZERO] = gl.isClampZeroTextureWrapSupported();
+	capabilities.features[FEATURE_LIGHTEN] = GLAD_VERSION_1_4 || GLAD_ES_VERSION_3_0 || GLAD_EXT_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_GLSL3] = GLAD_ES_VERSION_3_0 || gl.isCoreProfile();
+	capabilities.features[FEATURE_INSTANCING] = gl.isInstancingSupported();
+	static_assert(FEATURE_MAX_ENUM == 7, "Graphics::initCapabilities must be updated when adding a new graphics feature!");
+
+	capabilities.limits[LIMIT_POINT_SIZE] = gl.getMaxPointSize();
+	capabilities.limits[LIMIT_TEXTURE_SIZE] = gl.getMax2DTextureSize();
+	capabilities.limits[LIMIT_TEXTURE_LAYERS] = gl.getMaxTextureLayers();
+	capabilities.limits[LIMIT_VOLUME_TEXTURE_SIZE] = gl.getMax3DTextureSize();
+	capabilities.limits[LIMIT_CUBE_TEXTURE_SIZE] = gl.getMaxCubeTextureSize();
+	capabilities.limits[LIMIT_MULTI_CANVAS] = gl.getMaxRenderTargets();
+	capabilities.limits[LIMIT_CANVAS_MSAA] = gl.getMaxRenderbufferSamples();
+	capabilities.limits[LIMIT_ANISOTROPY] = gl.getMaxAnisotropy();
+	static_assert(LIMIT_MAX_ENUM == 8, "Graphics::initCapabilities must be updated when adding a new system limit!");
+
+	for (int i = 0; i < TEXTURE_MAX_ENUM; i++)
+		capabilities.textureTypes[i] = gl.isTextureTypeSupported((TextureType) i);
 }
 }
 
 
 bool Graphics::isCanvasFormatSupported(PixelFormat format) const
 bool Graphics::isCanvasFormatSupported(PixelFormat format) const

+ 1 - 3
src/modules/graphics/opengl/Graphics.h

@@ -117,9 +117,6 @@ public:
 
 
 	void setWireframe(bool enable) override;
 	void setWireframe(bool enable) override;
 
 
-	bool isSupported(Feature feature) const override;
-	bool isTextureTypeSupported(TextureType textype) const override;
-	double getSystemLimit(SystemLimit limittype) const override;
 	bool isCanvasFormatSupported(PixelFormat format) const override;
 	bool isCanvasFormatSupported(PixelFormat format) const override;
 	bool isCanvasFormatSupported(PixelFormat format, bool readable) const override;
 	bool isCanvasFormatSupported(PixelFormat format, bool readable) const override;
 	bool isImageFormatSupported(PixelFormat format) const override;
 	bool isImageFormatSupported(PixelFormat format) const override;
@@ -131,6 +128,7 @@ public:
 private:
 private:
 
 
 	love::graphics::StreamBuffer *newStreamBuffer(BufferType type, size_t size) override;
 	love::graphics::StreamBuffer *newStreamBuffer(BufferType type, size_t size) override;
+	void initCapabilities() override;
 	void getAPIStats(int &drawcalls, int &shaderswitches) const override;
 	void getAPIStats(int &drawcalls, int &shaderswitches) const override;
 
 
 	void endPass();
 	void endPass();

+ 25 - 2
src/modules/graphics/wrap_Graphics.cpp

@@ -1926,6 +1926,7 @@ int w_setDefaultShaderCode(lua_State *L)
 
 
 int w_getSupported(lua_State *L)
 int w_getSupported(lua_State *L)
 {
 {
+	const Graphics::Capabilities &caps = instance()->getCapabilities();
 	lua_createtable(L, 0, (int) Graphics::FEATURE_MAX_ENUM);
 	lua_createtable(L, 0, (int) Graphics::FEATURE_MAX_ENUM);
 
 
 	for (int i = 0; i < (int) Graphics::FEATURE_MAX_ENUM; i++)
 	for (int i = 0; i < (int) Graphics::FEATURE_MAX_ENUM; i++)
@@ -1936,7 +1937,7 @@ int w_getSupported(lua_State *L)
 		if (!Graphics::getConstant(feature, name))
 		if (!Graphics::getConstant(feature, name))
 			continue;
 			continue;
 
 
-		luax_pushboolean(L, instance()->isSupported(feature));
+		luax_pushboolean(L, caps.features[i]);
 		lua_setfield(L, -2, name);
 		lua_setfield(L, -2, name);
 	}
 	}
 
 
@@ -2011,6 +2012,26 @@ int w_getImageFormats(lua_State *L)
 	return w__getFormats(L, supported, ignore);
 	return w__getFormats(L, supported, ignore);
 }
 }
 
 
+int w_getTextureTypes(lua_State *L)
+{
+	const Graphics::Capabilities &caps = instance()->getCapabilities();
+	lua_createtable(L, 0, (int) TEXTURE_MAX_ENUM);
+
+	for (int i = 0; i < (int) TEXTURE_MAX_ENUM; i++)
+	{
+		TextureType textype = (TextureType) i;
+		const char *name = nullptr;
+
+		if (!Texture::getConstant(textype, name))
+			continue;
+
+		lua_pushnumber(L, caps.textureTypes[i]);
+		lua_setfield(L, -2, name);
+	}
+
+	return 1;
+}
+
 int w_getRendererInfo(lua_State *L)
 int w_getRendererInfo(lua_State *L)
 {
 {
 	Graphics::RendererInfo info;
 	Graphics::RendererInfo info;
@@ -2025,6 +2046,7 @@ int w_getRendererInfo(lua_State *L)
 
 
 int w_getSystemLimits(lua_State *L)
 int w_getSystemLimits(lua_State *L)
 {
 {
+	const Graphics::Capabilities &caps = instance()->getCapabilities();
 	lua_createtable(L, 0, (int) Graphics::LIMIT_MAX_ENUM);
 	lua_createtable(L, 0, (int) Graphics::LIMIT_MAX_ENUM);
 
 
 	for (int i = 0; i < (int) Graphics::LIMIT_MAX_ENUM; i++)
 	for (int i = 0; i < (int) Graphics::LIMIT_MAX_ENUM; i++)
@@ -2035,7 +2057,7 @@ int w_getSystemLimits(lua_State *L)
 		if (!Graphics::getConstant(limittype, name))
 		if (!Graphics::getConstant(limittype, name))
 			continue;
 			continue;
 
 
-		lua_pushnumber(L, instance()->getSystemLimit(limittype));
+		lua_pushnumber(L, caps.limits[i]);
 		lua_setfield(L, -2, name);
 		lua_setfield(L, -2, name);
 	}
 	}
 
 
@@ -2685,6 +2707,7 @@ static const luaL_Reg functions[] =
 	{ "getImageFormats", w_getImageFormats },
 	{ "getImageFormats", w_getImageFormats },
 	{ "getRendererInfo", w_getRendererInfo },
 	{ "getRendererInfo", w_getRendererInfo },
 	{ "getSystemLimits", w_getSystemLimits },
 	{ "getSystemLimits", w_getSystemLimits },
+	{ "getTextureTypes", w_getTextureTypes },
 	{ "getStats", w_getStats },
 	{ "getStats", w_getStats },
 
 
 	{ "captureScreenshot", w_captureScreenshot },
 	{ "captureScreenshot", w_captureScreenshot },