Browse Source

Exposed renderer capabilities.

bkaradzic 12 years ago
parent
commit
f440f160f9

+ 0 - 1
README.md

@@ -291,7 +291,6 @@ Todo
  - DX11: MSAA.
  - Fullscreen mode.
  - ETC2, PVRTC1/2 decoding fallback for targets that don't support it natively.
- - Capabilities flags for user to have idea what features are available.
 
 Contact
 -------

+ 59 - 45
examples/05-instancing/instancing.cpp

@@ -113,9 +113,12 @@ int _main_(int /*_argc*/, char** /*_argv*/)
 		, 0
 		);
 
+	// Get renderer capabilities info.
+	const bgfx::Caps* caps = bgfx::getCaps();
+
 	// Setup root path for binary shaders. Shader binaries are different 
 	// for each renderer.
-	switch (bgfx::getRendererType() )
+	switch (caps->rendererType)
 	{
 	default:
 	case bgfx::RendererType::Direct3D9:
@@ -195,59 +198,70 @@ int _main_(int /*_argc*/, char** /*_argv*/)
 		bgfx::dbgTextPrintf(0, 2, 0x6f, "Description: Geometry instancing.");
 		bgfx::dbgTextPrintf(0, 3, 0x0f, "Frame: % 7.3f[ms]", double(frameTime)*toMs);
 
-		float at[3] = { 0.0f, 0.0f, 0.0f };
-		float eye[3] = { 0.0f, 0.0f, -35.0f };
-		
-		float view[16];
-		float proj[16];
-		mtxLookAt(view, eye, at);
-		mtxProj(proj, 60.0f, float(width)/float(height), 0.1f, 100.0f);
-
-		// Set view and projection matrix for view 0.
-		bgfx::setViewTransform(0, view, proj);
-
-		const uint16_t instanceStride = 80;
-		const bgfx::InstanceDataBuffer* idb = bgfx::allocInstanceDataBuffer(121, instanceStride);
-		if (NULL != idb)
+		// Check if instancing is supported.
+		if (0 == (BGFX_CAPS_INSTANCING & caps->supported) )
 		{
-			uint8_t* data = idb->data;
-
-			// Write instance data for 11x11 cubes.
-			for (uint32_t yy = 0; yy < 11; ++yy)
+			// When instancing is not supported by GPU, implement alternative
+			// code path that doesn't use instancing.
+			bool blink = uint32_t(time*3.0f)&1;
+			bgfx::dbgTextPrintf(0, 5, blink ? 0x1f : 0x01, " Instancing is not supported by GPU. ");
+		}
+		else
+		{
+			float at[3] = { 0.0f, 0.0f, 0.0f };
+			float eye[3] = { 0.0f, 0.0f, -35.0f };
+			
+			float view[16];
+			float proj[16];
+			mtxLookAt(view, eye, at);
+			mtxProj(proj, 60.0f, float(width)/float(height), 0.1f, 100.0f);
+
+			// Set view and projection matrix for view 0.
+			bgfx::setViewTransform(0, view, proj);
+
+			const uint16_t instanceStride = 80;
+			const bgfx::InstanceDataBuffer* idb = bgfx::allocInstanceDataBuffer(121, instanceStride);
+			if (NULL != idb)
 			{
-				for (uint32_t xx = 0; xx < 11; ++xx)
+				uint8_t* data = idb->data;
+
+				// Write instance data for 11x11 cubes.
+				for (uint32_t yy = 0; yy < 11; ++yy)
 				{
-					float* mtx = (float*)data;
-					mtxRotateXY(mtx, time + xx*0.21f, time + yy*0.37f);
-					mtx[12] = -15.0f + float(xx)*3.0f;
-					mtx[13] = -15.0f + float(yy)*3.0f;
-					mtx[14] = 0.0f;
-
-					float* color = (float*)&data[64];
-					color[0] = sin(time+float(xx)/11.0f)*0.5f+0.5f;
-					color[1] = cos(time+float(yy)/11.0f)*0.5f+0.5f;
-					color[2] = sin(time*3.0f)*0.5f+0.5f;
-					color[3] = 1.0f;
-
-					data += instanceStride;
+					for (uint32_t xx = 0; xx < 11; ++xx)
+					{
+						float* mtx = (float*)data;
+						mtxRotateXY(mtx, time + xx*0.21f, time + yy*0.37f);
+						mtx[12] = -15.0f + float(xx)*3.0f;
+						mtx[13] = -15.0f + float(yy)*3.0f;
+						mtx[14] = 0.0f;
+
+						float* color = (float*)&data[64];
+						color[0] = sin(time+float(xx)/11.0f)*0.5f+0.5f;
+						color[1] = cos(time+float(yy)/11.0f)*0.5f+0.5f;
+						color[2] = sin(time*3.0f)*0.5f+0.5f;
+						color[3] = 1.0f;
+
+						data += instanceStride;
+					}
 				}
-			}
 
-			// Set vertex and fragment shaders.
-			bgfx::setProgram(program);
+				// Set vertex and fragment shaders.
+				bgfx::setProgram(program);
 
-			// Set vertex and index buffer.
-			bgfx::setVertexBuffer(vbh);
-			bgfx::setIndexBuffer(ibh);
+				// Set vertex and index buffer.
+				bgfx::setVertexBuffer(vbh);
+				bgfx::setIndexBuffer(ibh);
 
-			// Set instance data buffer.
-			bgfx::setInstanceDataBuffer(idb);
+				// Set instance data buffer.
+				bgfx::setInstanceDataBuffer(idb);
 
-			// Set render states.
-			bgfx::setState(BGFX_STATE_DEFAULT);
+				// Set render states.
+				bgfx::setState(BGFX_STATE_DEFAULT);
 
-			// Submit primitive for rendering to view 0.
-			bgfx::submit(0);
+				// Submit primitive for rendering to view 0.
+				bgfx::submit(0);
+			}
 		}
 
 		// Advance to next frame. Rendering thread will be kicked to 

+ 80 - 32
examples/06-bump/bump.cpp

@@ -268,9 +268,14 @@ int _main_(int /*_argc*/, char** /*_argv*/)
 		, 0
 		);
 
+	// Get renderer capabilities info.
+	const bgfx::Caps* caps = bgfx::getCaps();
+
+	bool instancingSupported = 0 != (caps->supported & BGFX_CAPS_INSTANCING);
+
 	// Setup root path for binary shaders. Shader binaries are different 
 	// for each renderer.
-	switch (bgfx::getRendererType() )
+	switch (caps->rendererType)
 	{
 	default:
 	case bgfx::RendererType::Direct3D9:
@@ -320,7 +325,7 @@ int _main_(int /*_argc*/, char** /*_argv*/)
 	bgfx::UniformHandle u_lightRgbInnerR = bgfx::createUniform("u_lightRgbInnerR", bgfx::UniformType::Uniform4fv, numLights);
 
 	// Load vertex shader.
-	mem = loadShader("vs_bump");
+	mem = loadShader(instancingSupported ? "vs_bump_instanced" : "vs_bump");
 	bgfx::VertexShaderHandle vsh = bgfx::createVertexShader(mem);
 
 	// Load fragment shader.
@@ -406,50 +411,93 @@ int _main_(int /*_argc*/, char** /*_argv*/)
 		const uint16_t instanceStride = 64;
 		const uint16_t numInstances = 3;
 
-		// Write instance data for 3x3 cubes.
-		for (uint32_t yy = 0; yy < 3; ++yy)
+		if (instancingSupported)
 		{
-			const bgfx::InstanceDataBuffer* idb = bgfx::allocInstanceDataBuffer(numInstances, instanceStride);
-			if (NULL != idb)
+			// Write instance data for 3x3 cubes.
+			for (uint32_t yy = 0; yy < 3; ++yy)
+			{
+				const bgfx::InstanceDataBuffer* idb = bgfx::allocInstanceDataBuffer(numInstances, instanceStride);
+				if (NULL != idb)
+				{
+					uint8_t* data = idb->data;
+
+					for (uint32_t xx = 0; xx < 3; ++xx)
+					{
+						float* mtx = (float*)data;
+						mtxRotateXY(mtx, time*0.023f + xx*0.21f, time*0.03f + yy*0.37f);
+						mtx[12] = -3.0f + float(xx)*3.0f;
+						mtx[13] = -3.0f + float(yy)*3.0f;
+						mtx[14] = 0.0f;
+
+						data += instanceStride;
+					}
+
+					// Set instance data buffer.
+					bgfx::setInstanceDataBuffer(idb, numInstances);
+
+					// Set vertex and fragment shaders.
+					bgfx::setProgram(program);
+
+					// Set vertex and index buffer.
+					bgfx::setVertexBuffer(vbh);
+					bgfx::setIndexBuffer(ibh);
+
+					// Bind textures.
+					bgfx::setTexture(0, u_texColor, textureColor);
+					bgfx::setTexture(1, u_texNormal, textureNormal);
+
+					// Set render states.
+					bgfx::setState(0
+						|BGFX_STATE_RGB_WRITE
+						|BGFX_STATE_ALPHA_WRITE
+						|BGFX_STATE_DEPTH_WRITE
+						|BGFX_STATE_DEPTH_TEST_LESS
+						|BGFX_STATE_MSAA
+						);
+
+					// Submit primitive for rendering to view 0.
+					bgfx::submit(0);
+				}
+			}
+		}
+		else
+		{
+			for (uint32_t yy = 0; yy < 3; ++yy)
 			{
-				uint8_t* data = idb->data;
-
 				for (uint32_t xx = 0; xx < 3; ++xx)
 				{
-					float* mtx = (float*)data;
+					float mtx[16];
 					mtxRotateXY(mtx, time*0.023f + xx*0.21f, time*0.03f + yy*0.37f);
 					mtx[12] = -3.0f + float(xx)*3.0f;
 					mtx[13] = -3.0f + float(yy)*3.0f;
 					mtx[14] = 0.0f;
 
-					data += instanceStride;
-				}
-
-				// Set vertex and fragment shaders.
-				bgfx::setProgram(program);
+					// Set transform for draw call.
+					bgfx::setTransform(mtx);
 
-				// Set vertex and index buffer.
-				bgfx::setVertexBuffer(vbh);
-				bgfx::setIndexBuffer(ibh);
+					// Set vertex and fragment shaders.
+					bgfx::setProgram(program);
 
-				// Set instance data buffer.
-				bgfx::setInstanceDataBuffer(idb, numInstances);
+					// Set vertex and index buffer.
+					bgfx::setVertexBuffer(vbh);
+					bgfx::setIndexBuffer(ibh);
 
-				// Bind textures.
-				bgfx::setTexture(0, u_texColor, textureColor);
-				bgfx::setTexture(1, u_texNormal, textureNormal);
+					// Bind textures.
+					bgfx::setTexture(0, u_texColor, textureColor);
+					bgfx::setTexture(1, u_texNormal, textureNormal);
 
-				// Set render states.
-				bgfx::setState(0
-					|BGFX_STATE_RGB_WRITE
-					|BGFX_STATE_ALPHA_WRITE
-					|BGFX_STATE_DEPTH_WRITE
-					|BGFX_STATE_DEPTH_TEST_LESS
-					|BGFX_STATE_MSAA
-					);
+					// Set render states.
+					bgfx::setState(0
+						|BGFX_STATE_RGB_WRITE
+						|BGFX_STATE_ALPHA_WRITE
+						|BGFX_STATE_DEPTH_WRITE
+						|BGFX_STATE_DEPTH_TEST_LESS
+						|BGFX_STATE_MSAA
+						);
 
-				// Submit primitive for rendering to view 0.
-				bgfx::submit(0);
+					// Submit primitive for rendering to view 0.
+					bgfx::submit(0);
+				}
 			}
 		}
 

+ 5 - 11
examples/06-bump/vs_bump.sc

@@ -1,4 +1,4 @@
-$input a_position, a_normal, a_tangent, a_texcoord0, i_data0, i_data1, i_data2, i_data3
+$input a_position, a_normal, a_tangent, a_texcoord0
 $output v_wpos, v_view, v_normal, v_tangent, v_bitangent, v_texcoord0
 
 /*
@@ -10,20 +10,14 @@ $output v_wpos, v_view, v_normal, v_tangent, v_bitangent, v_texcoord0
 
 void main()
 {
-	mat4 model;
-	model[0] = i_data0;
-	model[1] = i_data1;
-	model[2] = i_data2;
-	model[3] = i_data3;
-
-	vec3 wpos = instMul(model, vec4(a_position, 1.0) ).xyz;
+	vec3 wpos = mul(u_model[0], vec4(a_position, 1.0) ).xyz;
 	gl_Position = mul(u_viewProj, vec4(wpos, 1.0) );
 	
 	vec4 normal = a_normal * 2.0f - 1.0f;
-	vec3 wnormal = instMul(model, vec4(normal.xyz, 0.0) ).xyz;
+	vec3 wnormal = mul(u_model[0], vec4(normal.xyz, 0.0) ).xyz;
 
 	vec4 tangent = a_tangent * 2.0f - 1.0f;
-	vec3 wtangent = instMul(model, vec4(tangent.xyz, 0.0) ).xyz;
+	vec3 wtangent = mul(u_model[0], vec4(tangent.xyz, 0.0) ).xyz;
 
 	vec3 viewNormal = normalize(mul(u_view, vec4(wnormal, 0.0) ).xyz);
 	vec3 viewTangent = normalize(mul(u_view, vec4(wtangent, 0.0) ).xyz);
@@ -33,7 +27,7 @@ void main()
 	v_wpos = wpos;
 
 	vec3 view = mul(u_view, vec4(wpos, 0.0) ).xyz;
-	v_view = instMul(view, tbn);
+	v_view = mul(view, tbn);
 
 	v_normal = viewNormal;
 	v_tangent = viewTangent;

+ 43 - 0
examples/06-bump/vs_bump_instanced.sc

@@ -0,0 +1,43 @@
+$input a_position, a_normal, a_tangent, a_texcoord0, i_data0, i_data1, i_data2, i_data3
+$output v_wpos, v_view, v_normal, v_tangent, v_bitangent, v_texcoord0
+
+/*
+ * Copyright 2011-2013 Branimir Karadzic. All rights reserved.
+ * License: http://www.opensource.org/licenses/BSD-2-Clause
+ */
+
+#include "../common/common.sh"
+
+void main()
+{
+	mat4 model;
+	model[0] = i_data0;
+	model[1] = i_data1;
+	model[2] = i_data2;
+	model[3] = i_data3;
+
+	vec3 wpos = instMul(model, vec4(a_position, 1.0) ).xyz;
+	gl_Position = mul(u_viewProj, vec4(wpos, 1.0) );
+	
+	vec4 normal = a_normal * 2.0f - 1.0f;
+	vec3 wnormal = instMul(model, vec4(normal.xyz, 0.0) ).xyz;
+
+	vec4 tangent = a_tangent * 2.0f - 1.0f;
+	vec3 wtangent = instMul(model, vec4(tangent.xyz, 0.0) ).xyz;
+
+	vec3 viewNormal = normalize(mul(u_view, vec4(wnormal, 0.0) ).xyz);
+	vec3 viewTangent = normalize(mul(u_view, vec4(wtangent, 0.0) ).xyz);
+	vec3 viewBitangent = cross(viewNormal, viewTangent) * tangent.w;
+	mat3 tbn = mat3(viewTangent, viewBitangent, viewNormal);
+
+	v_wpos = wpos;
+
+	vec3 view = mul(u_view, vec4(wpos, 0.0) ).xyz;
+	v_view = instMul(view, tbn);
+
+	v_normal = viewNormal;
+	v_tangent = viewTangent;
+	v_bitangent = viewBitangent;
+
+	v_texcoord0 = a_texcoord0;
+}

BIN
examples/runtime/shaders/dx11/vs_bump.bin


BIN
examples/runtime/shaders/dx11/vs_bump_instanced.bin


BIN
examples/runtime/shaders/dx9/vs_bump.bin


BIN
examples/runtime/shaders/dx9/vs_bump_instanced.bin


BIN
examples/runtime/shaders/gles/vs_bump.bin


BIN
examples/runtime/shaders/gles/vs_bump_instanced.bin


BIN
examples/runtime/shaders/glsl/vs_bump.bin


BIN
examples/runtime/shaders/glsl/vs_bump_instanced.bin


+ 42 - 0
include/bgfx.h

@@ -226,6 +226,25 @@
 #define BGFX_RESET_VSYNC                 UINT32_C(0x00000080)
 #define BGFX_RESET_CAPTURE               UINT32_C(0x00000100)
 
+///
+#define BGFX_CAPS_TEXTURE_FORMAT_BC1     UINT64_C(0x0000000000000001)
+#define BGFX_CAPS_TEXTURE_FORMAT_BC2     UINT64_C(0x0000000000000002)
+#define BGFX_CAPS_TEXTURE_FORMAT_BC3     UINT64_C(0x0000000000000004)
+#define BGFX_CAPS_TEXTURE_FORMAT_BC4     UINT64_C(0x0000000000000008)
+#define BGFX_CAPS_TEXTURE_FORMAT_BC5     UINT64_C(0x0000000000000010)
+#define BGFX_CAPS_TEXTURE_FORMAT_ETC1    UINT64_C(0x0000000000000020)
+#define BGFX_CAPS_TEXTURE_FORMAT_ETC2    UINT64_C(0x0000000000000040)
+#define BGFX_CAPS_TEXTURE_FORMAT_ETC2A   UINT64_C(0x0000000000000080)
+#define BGFX_CAPS_TEXTURE_FORMAT_ETC2A1  UINT64_C(0x0000000000000100)
+#define BGFX_CAPS_TEXTURE_FORMAT_PTC12   UINT64_C(0x0000000000000200)
+#define BGFX_CAPS_TEXTURE_FORMAT_PTC14   UINT64_C(0x0000000000000400)
+#define BGFX_CAPS_TEXTURE_FORMAT_PTC14A  UINT64_C(0x0000000000000800)
+#define BGFX_CAPS_TEXTURE_FORMAT_PTC12A  UINT64_C(0x0000000000001000)
+#define BGFX_CAPS_TEXTURE_FORMAT_PTC22   UINT64_C(0x0000000000002000)
+#define BGFX_CAPS_TEXTURE_FORMAT_PTC24   UINT64_C(0x0000000000004000)
+#define BGFX_CAPS_TEXTURE_3D             UINT64_C(0x0000000000010000)
+#define BGFX_CAPS_INSTANCING             UINT64_C(0x0000000000020000)
+
 ///
 #define BGFX_HANDLE(_name) \
 			struct _name { uint16_t idx; }; \
@@ -419,6 +438,26 @@ namespace bgfx
 		uint32_t size;
 	};
 
+	/// Renderer capabilities.
+	struct Caps
+	{
+		/// Renderer backend type.
+		RendererType::Enum rendererType;
+
+		/// Supported functionality, it includes emulated functionality. 
+		/// Checking supported and not emulated will give functionality 
+		/// natively supported by renderer.
+		uint64_t supported;
+
+		/// Emulated functionality. For example some texture compression 
+		/// modes are not natively supported by all renderers. The library
+		/// internally decompresses texture into supported format.
+		uint64_t emulated;
+
+		/// Maximum texture size.
+		uint16_t maxTextureSize;
+	};
+
 	struct TransientIndexBuffer
 	{
 		uint8_t* data;
@@ -568,6 +607,9 @@ namespace bgfx
 	/// singlethreaded renderer this call does frame rendering.
 	void frame();
 
+	/// Returns renderer capabilities.
+	const Caps* getCaps();
+
 	/// Allocate buffer to pass to bgfx calls. Data will be freed inside bgfx.
 	const Memory* alloc(uint32_t _size);
 

+ 27 - 1
src/bgfx.cpp

@@ -10,7 +10,9 @@ namespace bgfx
 #define BGFX_MAIN_THREAD_MAGIC 0x78666762
 
 #if BGFX_CONFIG_MULTITHREADED && !BX_PLATFORM_OSX && !BX_PLATFORM_IOS
-#	define BGFX_CHECK_MAIN_THREAD() BX_CHECK(BGFX_MAIN_THREAD_MAGIC == s_threadIndex, "Must be called from main thread.")
+#	define BGFX_CHECK_MAIN_THREAD() \
+				BX_CHECK(NULL != s_ctx, "Library is not initialized yet."); \
+				BX_CHECK(BGFX_MAIN_THREAD_MAGIC == s_threadIndex, "Must be called from main thread.")
 #	define BGFX_CHECK_RENDER_THREAD() BX_CHECK(BGFX_MAIN_THREAD_MAGIC != s_threadIndex, "Must be called from render thread.")
 #else
 #	define BGFX_CHECK_MAIN_THREAD()
@@ -189,6 +191,8 @@ namespace bgfx
 	CallbackI* g_callback = NULL;
 	bx::ReallocatorI* g_allocator = NULL;
 
+	Caps g_caps;
+
 	static BX_THREAD uint32_t s_threadIndex = 0;
 	static Context* s_ctx = NULL;
 
@@ -619,6 +623,12 @@ namespace bgfx
 		bx::radixSort64(m_sortKeys, s_ctx->m_tempKeys, m_sortValues, s_ctx->m_tempValues, m_num);
 	}
 
+	const Caps* getCaps()
+	{
+		BGFX_CHECK_MAIN_THREAD();
+		return &g_caps;
+	}
+
 	RendererType::Enum getRendererType()
 	{
 #if BGFX_CONFIG_RENDERER_DIRECT3D9
@@ -640,6 +650,20 @@ namespace bgfx
 	{
 		BX_TRACE("Init...");
 
+		memset(&g_caps, 0, sizeof(g_caps) );
+		g_caps.rendererType = getRendererType();
+		g_caps.emulated = 0
+						| BGFX_CAPS_TEXTURE_FORMAT_BC1
+						| BGFX_CAPS_TEXTURE_FORMAT_BC2
+						| BGFX_CAPS_TEXTURE_FORMAT_BC3
+						| BGFX_CAPS_TEXTURE_FORMAT_BC4
+						| BGFX_CAPS_TEXTURE_FORMAT_BC5
+						| BGFX_CAPS_TEXTURE_FORMAT_ETC1
+						| BGFX_CAPS_TEXTURE_FORMAT_ETC2
+						| BGFX_CAPS_TEXTURE_FORMAT_ETC2A
+						| BGFX_CAPS_TEXTURE_FORMAT_ETC2A1
+						;
+
 		if (NULL != _allocator)
 		{
 			g_allocator = _allocator;
@@ -1696,6 +1720,7 @@ namespace bgfx
 	const InstanceDataBuffer* allocInstanceDataBuffer(uint32_t _num, uint16_t _stride)
 	{
 		BGFX_CHECK_MAIN_THREAD();
+		BX_CHECK(0 != (g_caps.supported & BGFX_CAPS_INSTANCING), "Instancing is not supported! Use bgfx::getCaps to check backend renderer capabilities.");
 		BX_CHECK(0 < _num, "Requesting 0 instanced data vertices.");
 		return s_ctx->allocInstanceDataBuffer(_num, _stride);
 	}
@@ -1823,6 +1848,7 @@ namespace bgfx
 	TextureHandle createTexture3D(uint16_t _width, uint16_t _height, uint16_t _depth, uint8_t _numMips, TextureFormat::Enum _format, uint32_t _flags, const Memory* _mem)
 	{
 		BGFX_CHECK_MAIN_THREAD();
+		BX_CHECK(0 != (g_caps.supported & BGFX_CAPS_TEXTURE_3D), "Texture3D is not supported! Use bgfx::getCaps to check backend renderer capabilities.");
 
 #if BGFX_CONFIG_DEBUG
 		if (NULL != _mem)

+ 1 - 0
src/bgfx_p.h

@@ -227,6 +227,7 @@ namespace bgfx
 	extern const uint32_t g_uniformTypeSize[UniformType::Count+1];
 	extern CallbackI* g_callback;
 	extern bx::ReallocatorI* g_allocator;
+	extern Caps g_caps;
 
 	void release(const Memory* _mem);
 	const char* getAttribName(Attrib::Enum _attr);

+ 12 - 0
src/renderer_d3d11.cpp

@@ -478,6 +478,18 @@ namespace bgfx
 				m_uniformReg.add(getPredefinedUniformName(PredefinedUniform::Enum(ii) ), &m_predefinedUniforms[ii]);
 			}
 
+			g_caps.emulated &= ~( 0
+								| BGFX_CAPS_TEXTURE_FORMAT_BC1
+								| BGFX_CAPS_TEXTURE_FORMAT_BC2
+								| BGFX_CAPS_TEXTURE_FORMAT_BC3
+								| BGFX_CAPS_TEXTURE_FORMAT_BC4
+								);
+			g_caps.supported |= ( 0
+								| BGFX_CAPS_INSTANCING
+								| BGFX_CAPS_TEXTURE_3D
+								);
+			g_caps.maxTextureSize = D3D11_REQ_TEXTURE2D_U_OR_V_DIMENSION;
+
 			postReset();
 		}
 

+ 14 - 0
src/renderer_d3d9.cpp

@@ -409,6 +409,14 @@ namespace bgfx
 			BX_TRACE("Max fragment shader 2.0 instr. slots: %d", m_caps.PS20Caps.NumInstructionSlots);
 			BX_TRACE("Max fragment shader 3.0 instr. slots: %d", m_caps.MaxPixelShader30InstructionSlots);
 
+			g_caps.emulated &= ~( 0
+								| BGFX_CAPS_TEXTURE_FORMAT_BC1
+								| BGFX_CAPS_TEXTURE_FORMAT_BC2
+								| BGFX_CAPS_TEXTURE_FORMAT_BC3
+								);
+			g_caps.supported |= BGFX_CAPS_TEXTURE_3D;
+			g_caps.maxTextureSize = bx::uint32_min(m_caps.MaxTextureWidth, m_caps.MaxTextureHeight);
+
 #if BGFX_CONFIG_RENDERER_USE_EXTENSIONS
 			BX_TRACE("Extended formats:");
 			for (uint32_t ii = 0; ii < ExtendedFormat::Count; ++ii)
@@ -434,6 +442,12 @@ namespace bgfx
 
 			s_textureFormat[TextureFormat::BC4].m_fmt = s_extendedFormats[ExtendedFormat::Ati1].m_supported ? D3DFMT_ATI1 : D3DFMT_UNKNOWN;
 			s_textureFormat[TextureFormat::BC5].m_fmt = s_extendedFormats[ExtendedFormat::Ati2].m_supported ? D3DFMT_ATI2 : D3DFMT_UNKNOWN;
+
+			g_caps.emulated &= ~( 0
+								| (D3DFMT_UNKNOWN != s_textureFormat[TextureFormat::BC4].m_fmt ? BGFX_CAPS_TEXTURE_FORMAT_BC4 : 0)
+								| (D3DFMT_UNKNOWN != s_textureFormat[TextureFormat::BC5].m_fmt ? BGFX_CAPS_TEXTURE_FORMAT_BC5 : 0)
+								);
+			g_caps.supported |= m_instancing ? BGFX_CAPS_INSTANCING : 0;
 #endif // BGFX_CONFIG_RENDERER_USE_EXTENSIONS
 
 			uint32_t index = 1;

+ 18 - 4
src/renderer_gl.cpp

@@ -2210,8 +2210,7 @@ namespace bgfx
 		glGetIntegerv(_pname, &result);
 		GLenum err = glGetError();
 		BX_WARN(0 == err, "glGetIntegerv(0x%04x, ...) failed with GL error: 0x%04x.", _pname, err);
-		BX_UNUSED(err);
-		return result;
+		return 0 == err ? result : 0;
 	}
 
 	void Context::rendererInit()
@@ -2370,7 +2369,8 @@ namespace bgfx
 		s_textureFormat[TextureFormat::BC4].m_supported = bc45Supported;
 		s_textureFormat[TextureFormat::BC5].m_supported = bc45Supported;
 
-		s_textureFormat[TextureFormat::ETC1].m_supported = s_extension[Extension::OES_compressed_ETC1_RGB8_texture].m_supported;
+		bool etc1Supported = s_extension[Extension::OES_compressed_ETC1_RGB8_texture].m_supported;
+		s_textureFormat[TextureFormat::ETC1].m_supported = etc1Supported;
 
 		bool etc2Supported = !!BGFX_CONFIG_RENDERER_OPENGLES3
 			|| s_extension[Extension::ARB_ES3_compatibility].m_supported
@@ -2398,6 +2398,17 @@ namespace bgfx
 		s_textureFormat[TextureFormat::PTC22].m_supported  = ptc2Supported;
 		s_textureFormat[TextureFormat::PTC24].m_supported  = ptc2Supported;
 
+		g_caps.emulated &= ~( 0
+							| bc123Supported ? BGFX_CAPS_TEXTURE_FORMAT_BC1|BGFX_CAPS_TEXTURE_FORMAT_BC2|BGFX_CAPS_TEXTURE_FORMAT_BC3 : 0
+							| bc45Supported  ? BGFX_CAPS_TEXTURE_FORMAT_BC4|BGFX_CAPS_TEXTURE_FORMAT_BC5 : 0
+							| etc1Supported  ? BGFX_CAPS_TEXTURE_FORMAT_ETC1 : 0
+							| etc2Supported  ? BGFX_CAPS_TEXTURE_FORMAT_ETC2|BGFX_CAPS_TEXTURE_FORMAT_ETC2A|BGFX_CAPS_TEXTURE_FORMAT_ETC2A1 : 0
+							| ptc1Supported  ? BGFX_CAPS_TEXTURE_FORMAT_PTC12|BGFX_CAPS_TEXTURE_FORMAT_PTC14|BGFX_CAPS_TEXTURE_FORMAT_PTC14A|BGFX_CAPS_TEXTURE_FORMAT_PTC12A : 0
+							| ptc2Supported  ? BGFX_CAPS_TEXTURE_FORMAT_PTC22|BGFX_CAPS_TEXTURE_FORMAT_PTC24 : 0
+							);
+		g_caps.supported |= !!(BGFX_CONFIG_RENDERER_OPENGL|BGFX_CONFIG_RENDERER_OPENGLES3) ? BGFX_CAPS_TEXTURE_3D : 0;
+		g_caps.maxTextureSize = glGet(GL_MAX_TEXTURE_SIZE);
+
 		s_renderCtx->m_vaoSupport = !!BGFX_CONFIG_RENDERER_OPENGLES3
 			|| s_extension[Extension::ARB_vertex_array_object].m_supported
 			|| s_extension[Extension::OES_vertex_array_object].m_supported
@@ -2485,7 +2496,9 @@ namespace bgfx
 			s_textureFormat[TextureFormat::BC5].m_internalFmt = GL_COMPRESSED_RED_GREEN_RGTC2_EXT;
 		}
 
-#if !BGFX_CONFIG_RENDERER_OPENGLES3
+#if BGFX_CONFIG_RENDERER_OPENGLES3
+		g_caps.supported |= BGFX_CAPS_INSTANCING;
+#else
 		s_vertexAttribDivisor = stubVertexAttribDivisor;
 		s_drawArraysInstanced = stubDrawArraysInstanced;
 		s_drawElementsInstanced = stubDrawElementsInstanced;
@@ -2501,6 +2514,7 @@ namespace bgfx
 				s_vertexAttribDivisor   = glVertexAttribDivisor;
 				s_drawArraysInstanced   = glDrawArraysInstanced;
 				s_drawElementsInstanced = glDrawElementsInstanced;
+				g_caps.supported |= BGFX_CAPS_INSTANCING;
 			}
 		}
 #	endif // !BX_PLATFORM_IOS