Browse Source

Added tristrip support.

Branimir Karadžić 11 years ago
parent
commit
7bc62b1d07
7 changed files with 353 additions and 159 deletions
  1. 11 4
      include/bgfx.h
  2. 14 4
      src/bgfx.cpp
  3. 8 8
      src/bgfx_p.h
  4. 118 45
      src/renderer_d3d11.cpp
  5. 129 57
      src/renderer_d3d9.cpp
  6. 58 30
      src/renderer_gl.cpp
  7. 15 11
      tools/shaderc/shaderc.cpp

+ 11 - 4
include/bgfx.h

@@ -58,8 +58,9 @@
 #define BGFX_STATE_ALPHA_REF_SHIFT       40
 #define BGFX_STATE_ALPHA_REF_MASK        UINT64_C(0x0000ff0000000000)
 
-#define BGFX_STATE_PT_LINES              UINT64_C(0x0001000000000000)
-#define BGFX_STATE_PT_POINTS             UINT64_C(0x0002000000000000)
+#define BGFX_STATE_PT_TRISTRIP           UINT64_C(0x0001000000000000)
+#define BGFX_STATE_PT_LINES              UINT64_C(0x0002000000000000)
+#define BGFX_STATE_PT_POINTS             UINT64_C(0x0003000000000000)
 #define BGFX_STATE_PT_SHIFT              48
 #define BGFX_STATE_PT_MASK               UINT64_C(0x0003000000000000)
 
@@ -1257,7 +1258,10 @@ namespace bgfx
 	void setIndexBuffer(DynamicIndexBufferHandle _handle, uint32_t _firstIndex = 0, uint32_t _numIndices = UINT32_MAX);
 
 	/// Set index buffer for draw primitive.
-	void setIndexBuffer(const TransientIndexBuffer* _tib, uint32_t _numIndices = UINT32_MAX);
+	void setIndexBuffer(const TransientIndexBuffer* _tib);
+
+	/// Set index buffer for draw primitive.
+	void setIndexBuffer(const TransientIndexBuffer* _tib, uint32_t _firstIndex, uint32_t _numIndices);
 
 	/// Set vertex buffer for draw primitive.
 	void setVertexBuffer(VertexBufferHandle _handle);
@@ -1269,7 +1273,10 @@ namespace bgfx
 	void setVertexBuffer(DynamicVertexBufferHandle _handle, uint32_t _numVertices = UINT32_MAX);
 
 	/// Set vertex buffer for draw primitive.
-	void setVertexBuffer(const TransientVertexBuffer* _tvb, uint32_t _numVertices = UINT32_MAX);
+	void setVertexBuffer(const TransientVertexBuffer* _tvb);
+
+	/// Set vertex buffer for draw primitive.
+	void setVertexBuffer(const TransientVertexBuffer* _tvb, uint32_t _startVertex, uint32_t _numVertices);
 
 	/// Set instance data buffer for draw primitive.
 	void setInstanceDataBuffer(const InstanceDataBuffer* _idb, uint16_t _num = UINT16_MAX);

+ 14 - 4
src/bgfx.cpp

@@ -2334,12 +2334,17 @@ namespace bgfx
 		s_ctx->setIndexBuffer(_handle, _firstIndex, _numIndices);
 	}
 
-	void setIndexBuffer(const TransientIndexBuffer* _tib, uint32_t _numIndices)
+	void setIndexBuffer(const TransientIndexBuffer* _tib)
+	{
+		setIndexBuffer(_tib, 0, UINT32_MAX);
+	}
+
+	void setIndexBuffer(const TransientIndexBuffer* _tib, uint32_t _firstIndex, uint32_t _numIndices)
 	{
 		BGFX_CHECK_MAIN_THREAD();
 		BX_CHECK(NULL != _tib, "_tib can't be NULL");
 		uint32_t numIndices = bx::uint32_min(_numIndices, _tib->size/2);
-		s_ctx->setIndexBuffer(_tib, numIndices);
+		s_ctx->setIndexBuffer(_tib, _tib->startIndex + _firstIndex, numIndices);
 	}
 
 	void setVertexBuffer(VertexBufferHandle _handle)
@@ -2359,11 +2364,16 @@ namespace bgfx
 		s_ctx->setVertexBuffer(_handle, _numVertices);
 	}
 
-	void setVertexBuffer(const TransientVertexBuffer* _tvb, uint32_t _numVertices)
+	void setVertexBuffer(const TransientVertexBuffer* _tvb)
+	{
+		setVertexBuffer(_tvb, 0, UINT32_MAX);
+	}
+
+	void setVertexBuffer(const TransientVertexBuffer* _tvb, uint32_t _startVertex, uint32_t _numVertices)
 	{
 		BGFX_CHECK_MAIN_THREAD();
 		BX_CHECK(NULL != _tvb, "_tvb can't be NULL");
-		s_ctx->setVertexBuffer(_tvb, _numVertices);
+		s_ctx->setVertexBuffer(_tvb, _tvb->startVertex + _startVertex, _numVertices);
 	}
 
 	void setInstanceDataBuffer(const InstanceDataBuffer* _idb, uint16_t _num)

+ 8 - 8
src/bgfx_p.h

@@ -1146,10 +1146,10 @@ namespace bgfx
 			m_state.m_indexBuffer = _handle;
 		}
 
-		void setIndexBuffer(const TransientIndexBuffer* _tib, uint32_t _numIndices)
+		void setIndexBuffer(const TransientIndexBuffer* _tib, uint32_t _firstIndex, uint32_t _numIndices)
 		{
 			m_state.m_indexBuffer = _tib->handle;
-			m_state.m_startIndex = _tib->startIndex;
+			m_state.m_startIndex = _firstIndex;
 			m_state.m_numIndices = _numIndices;
 			m_discard = 0 == _numIndices;
 		}
@@ -1170,9 +1170,9 @@ namespace bgfx
 			m_state.m_vertexDecl = _dvb.m_decl;
 		}
 
-		void setVertexBuffer(const TransientVertexBuffer* _tvb, uint32_t _numVertices)
+		void setVertexBuffer(const TransientVertexBuffer* _tvb, uint32_t _startVertex, uint32_t _numVertices)
 		{
-			m_state.m_startVertex = _tvb->startVertex;
+			m_state.m_startVertex = _startVertex;
 			m_state.m_numVertices = bx::uint32_min(_tvb->size/_tvb->stride, _numVertices);
 			m_state.m_vertexBuffer = _tvb->handle;
 			m_state.m_vertexDecl = _tvb->decl;
@@ -2589,9 +2589,9 @@ namespace bgfx
 			m_submit->setIndexBuffer(m_dynamicIndexBuffers[_handle.idx].m_handle, _firstIndex, _numIndices);
 		}
 
-		BGFX_API_FUNC(void setIndexBuffer(const TransientIndexBuffer* _tib, uint32_t _numIndices) )
+		BGFX_API_FUNC(void setIndexBuffer(const TransientIndexBuffer* _tib, uint32_t _firstIndex, uint32_t _numIndices) )
 		{
-			m_submit->setIndexBuffer(_tib, _numIndices);
+			m_submit->setIndexBuffer(_tib, _firstIndex, _numIndices);
 		}
 
 		BGFX_API_FUNC(void setVertexBuffer(VertexBufferHandle _handle, uint32_t _numVertices, uint32_t _startVertex) )
@@ -2604,9 +2604,9 @@ namespace bgfx
 			m_submit->setVertexBuffer(m_dynamicVertexBuffers[_handle.idx], _numVertices);
 		}
 
-		BGFX_API_FUNC(void setVertexBuffer(const TransientVertexBuffer* _tvb, uint32_t _numVertices) )
+		BGFX_API_FUNC(void setVertexBuffer(const TransientVertexBuffer* _tvb, uint32_t _startVertex, uint32_t _numVertices) )
 		{
-			m_submit->setVertexBuffer(_tvb, _numVertices);
+			m_submit->setVertexBuffer(_tvb, _startVertex, _numVertices);
 		}
 
 		BGFX_API_FUNC(void setInstanceDataBuffer(const InstanceDataBuffer* _idb, uint16_t _num) )

+ 118 - 45
src/renderer_d3d11.cpp

@@ -12,11 +12,28 @@ namespace bgfx
 {
 	static wchar_t s_viewNameW[BGFX_CONFIG_MAX_VIEWS][256];
 
-	static const D3D11_PRIMITIVE_TOPOLOGY s_primType[] =
+	struct PrimInfo
 	{
-		D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST,
-		D3D11_PRIMITIVE_TOPOLOGY_LINELIST,
-		D3D11_PRIMITIVE_TOPOLOGY_POINTLIST,
+		D3D11_PRIMITIVE_TOPOLOGY m_type;
+		uint32_t m_min;
+		uint32_t m_div;
+		uint32_t m_sub;
+	};
+
+	static const PrimInfo s_primInfo[] =
+	{
+		{ D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST,  3, 3, 0 },
+		{ D3D11_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP, 3, 1, 2 },
+		{ D3D11_PRIMITIVE_TOPOLOGY_LINELIST,      2, 2, 0 },
+		{ D3D11_PRIMITIVE_TOPOLOGY_POINTLIST,     1, 1, 0 },
+	};
+
+	static const char* s_primName[] =
+	{
+		"TriList",
+		"TriStrip",
+		"Line",
+		"Point",
 	};
 
 	static const uint32_t s_checkMsaa[] =
@@ -498,6 +515,31 @@ namespace bgfx
 										);
 			BGFX_FATAL(SUCCEEDED(hr), Fatal::UnableToInitialize, "Failed to create swap chain.");
 
+			if (BX_ENABLED(BGFX_CONFIG_DEBUG) )
+			{
+				ID3D11InfoQueue* infoQueue;
+				hr = m_device->QueryInterface(__uuidof(ID3D11InfoQueue), (void**)&infoQueue);
+				BGFX_FATAL(SUCCEEDED(hr), Fatal::UnableToInitialize, "Unable to create Direct3D11 device.");
+
+				infoQueue->SetBreakOnSeverity(D3D11_MESSAGE_SEVERITY_CORRUPTION, true);
+				infoQueue->SetBreakOnSeverity(D3D11_MESSAGE_SEVERITY_ERROR,      true);
+				infoQueue->SetBreakOnSeverity(D3D11_MESSAGE_SEVERITY_WARNING,    false);
+
+				D3D11_INFO_QUEUE_FILTER filter;
+				memset(&filter, 0, sizeof(filter) );
+
+				D3D11_MESSAGE_CATEGORY categies[] =
+				{
+					D3D11_MESSAGE_CATEGORY_STATE_SETTING,
+					D3D11_MESSAGE_CATEGORY_EXECUTION,
+				};
+				filter.DenyList.NumCategories = BX_COUNTOF(categies);
+				filter.DenyList.pCategoryList = categies;
+				infoQueue->PushStorageFilter(&filter);
+
+				DX_RELEASE(infoQueue, 3);
+			}
+
 			UniformHandle handle = BGFX_INVALID_HANDLE;
 			for (uint32_t ii = 0; ii < PredefinedUniform::Count; ++ii)
 			{
@@ -1423,7 +1465,7 @@ namespace bgfx
 				data = (const char*)s_renderCtx->m_uniforms[handle.idx];
 			}
 
-#define CASE_IMPLEMENT_UNIFORM(_uniform, _glsuffix, _dxsuffix, _type) \
+#define CASE_IMPLEMENT_UNIFORM(_uniform, _dxsuffix, _type) \
 		case UniformType::_uniform: \
 		case UniformType::_uniform|BGFX_UNIFORM_FRAGMENTBIT: \
 			{ \
@@ -1431,17 +1473,40 @@ namespace bgfx
 			} \
 			break;
 
-			switch ((int32_t)type)
+			switch ( (int32_t)type)
 			{
-				CASE_IMPLEMENT_UNIFORM(Uniform1i, 1iv, I, int);
-				CASE_IMPLEMENT_UNIFORM(Uniform1f, 1fv, F, float);
-				CASE_IMPLEMENT_UNIFORM(Uniform1iv, 1iv, I, int);
-				CASE_IMPLEMENT_UNIFORM(Uniform1fv, 1fv, F, float);
-				CASE_IMPLEMENT_UNIFORM(Uniform2fv, 2fv, F, float);
-				CASE_IMPLEMENT_UNIFORM(Uniform3fv, 3fv, F, float);
-				CASE_IMPLEMENT_UNIFORM(Uniform4fv, 4fv, F, float);
-				CASE_IMPLEMENT_UNIFORM(Uniform3x3fv, Matrix3fv, F, float);
-				CASE_IMPLEMENT_UNIFORM(Uniform4x4fv, Matrix4fv, F, float);
+			case UniformType::Uniform3x3fv:
+			case UniformType::Uniform3x3fv|BGFX_UNIFORM_FRAGMENTBIT: \
+				{
+					float* value = (float*)data;
+					for (uint32_t ii = 0, count = num/3; ii < count; ++ii,  loc += 3*16, value += 9)
+					{
+						Matrix4 mtx;
+						mtx.un.val[ 0] = value[0];
+						mtx.un.val[ 1] = value[1];
+						mtx.un.val[ 2] = value[2];
+						mtx.un.val[ 3] = 0.0f;
+						mtx.un.val[ 4] = value[3];
+						mtx.un.val[ 5] = value[4];
+						mtx.un.val[ 6] = value[5];
+						mtx.un.val[ 7] = 0.0f;
+						mtx.un.val[ 8] = value[6];
+						mtx.un.val[ 9] = value[7];
+						mtx.un.val[10] = value[8];
+						mtx.un.val[11] = 0.0f;
+						s_renderCtx->setShaderConstant(type, loc, &mtx.un.val[0], 3);
+					}
+				}
+				break;
+
+				CASE_IMPLEMENT_UNIFORM(Uniform1i,    I, int);
+				CASE_IMPLEMENT_UNIFORM(Uniform1f,    F, float);
+				CASE_IMPLEMENT_UNIFORM(Uniform1iv,   I, int);
+				CASE_IMPLEMENT_UNIFORM(Uniform1fv,   F, float);
+				CASE_IMPLEMENT_UNIFORM(Uniform2fv,   F, float);
+				CASE_IMPLEMENT_UNIFORM(Uniform3fv,   F, float);
+				CASE_IMPLEMENT_UNIFORM(Uniform4fv,   F, float);
+				CASE_IMPLEMENT_UNIFORM(Uniform4x4fv, F, float);
 
 			case UniformType::End:
 				break;
@@ -2340,17 +2405,20 @@ namespace bgfx
 		uint8_t view = 0xff;
 		FrameBufferHandle fbh = BGFX_INVALID_HANDLE;
 		float alphaRef = 0.0f;
-		D3D11_PRIMITIVE_TOPOLOGY primType = D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST;
-		deviceCtx->IASetPrimitiveTopology(primType);
-		uint32_t primNumVerts = 3;
+
+		const uint64_t pt = m_render->m_debug&BGFX_DEBUG_WIREFRAME ? BGFX_STATE_PT_LINES : 0;
+		uint8_t primIndex = uint8_t(pt>>BGFX_STATE_PT_SHIFT);
+		PrimInfo prim = s_primInfo[primIndex];
+		deviceCtx->IASetPrimitiveTopology(prim.m_type);
+
 		bool viewHasScissor = false;
 		Rect viewScissorRect;
 		viewScissorRect.clear();
 
-		uint32_t statsNumPrimsSubmitted = 0;
+		uint32_t statsNumPrimsSubmitted[BX_COUNTOF(s_primInfo)] = {};
+		uint32_t statsNumPrimsRendered[BX_COUNTOF(s_primInfo)] = {};
+		uint32_t statsNumInstances[BX_COUNTOF(s_primInfo)] = {};
 		uint32_t statsNumIndices = 0;
-		uint32_t statsNumInstances = 0;
-		uint32_t statsNumPrimsRendered = 0;
 
 		if (0 == (m_render->m_debug&BGFX_DEBUG_IFH) )
 		{
@@ -2411,12 +2479,12 @@ namespace bgfx
 					s_renderCtx->setBlendState(newFlags);
 					s_renderCtx->setDepthStencilState(newFlags, packStencil(BGFX_STENCIL_DEFAULT, BGFX_STENCIL_DEFAULT) );
 
-					uint8_t primIndex = uint8_t( (newFlags&BGFX_STATE_PT_MASK)>>BGFX_STATE_PT_SHIFT);
-					if (primType != s_primType[primIndex])
+					const uint64_t pt = newFlags&BGFX_STATE_PT_MASK;
+					primIndex = uint8_t(pt>>BGFX_STATE_PT_SHIFT);
+					if (prim.m_type != s_primInfo[primIndex].m_type)
 					{
-						primType = s_primType[primIndex];
-						primNumVerts = 3-primIndex;
-						deviceCtx->IASetPrimitiveTopology(primType);
+						prim = s_primInfo[primIndex];
+						deviceCtx->IASetPrimitiveTopology(prim.m_type);
 					}
 				}
 
@@ -2488,12 +2556,12 @@ namespace bgfx
 						alphaRef = ref/255.0f;
 					}
 
-					uint8_t primIndex = uint8_t( (newFlags&BGFX_STATE_PT_MASK)>>BGFX_STATE_PT_SHIFT);
-					if (primType != s_primType[primIndex])
+					const uint64_t pt = newFlags&BGFX_STATE_PT_MASK;
+					primIndex = uint8_t(pt>>BGFX_STATE_PT_SHIFT);
+					if (prim.m_type != s_primInfo[primIndex].m_type)
 					{
-						primType = s_primType[primIndex];
-						primNumVerts = 3-primIndex;
-						deviceCtx->IASetPrimitiveTopology(primType);
+						prim = s_primInfo[primIndex];
+						deviceCtx->IASetPrimitiveTopology(prim.m_type);
 					}
 				}
 
@@ -2768,7 +2836,7 @@ namespace bgfx
 						if (UINT32_MAX == state.m_numIndices)
 						{
 							numIndices = s_renderCtx->m_indexBuffers[state.m_indexBuffer.idx].m_size/2;
-							numPrimsSubmitted = numIndices/primNumVerts;
+							numPrimsSubmitted = numIndices/prim.m_div - prim.m_sub;
 							numInstances = state.m_numInstances;
 							numPrimsRendered = numPrimsSubmitted*state.m_numInstances;
 
@@ -2779,10 +2847,10 @@ namespace bgfx
 								, 0
 								);
 						}
-						else if (primNumVerts <= state.m_numIndices)
+						else if (prim.m_min <= state.m_numIndices)
 						{
 							numIndices = state.m_numIndices;
-							numPrimsSubmitted = numIndices/primNumVerts;
+							numPrimsSubmitted = numIndices/prim.m_div - prim.m_sub;
 							numInstances = state.m_numInstances;
 							numPrimsRendered = numPrimsSubmitted*state.m_numInstances;
 
@@ -2796,7 +2864,7 @@ namespace bgfx
 					}
 					else
 					{
-						numPrimsSubmitted = numVertices/primNumVerts;
+						numPrimsSubmitted = numVertices/prim.m_div - prim.m_sub;
 						numInstances = state.m_numInstances;
 						numPrimsRendered = numPrimsSubmitted*state.m_numInstances;
 
@@ -2807,10 +2875,10 @@ namespace bgfx
 							);
 					}
 
-					statsNumPrimsSubmitted += numPrimsSubmitted;
+					statsNumPrimsSubmitted[primIndex] += numPrimsSubmitted;
+					statsNumPrimsRendered[primIndex]  += numPrimsRendered;
+					statsNumInstances[primIndex]      += numInstances;
 					statsNumIndices += numIndices;
-					statsNumInstances += numInstances;
-					statsNumPrimsRendered += numPrimsRendered;
 				}
 			}
 
@@ -2882,18 +2950,23 @@ namespace bgfx
 					, m_render->m_num
 					, elapsedCpuMs
 					);
-				tvm.printf(10, pos++, 0x8e, "      Prims: %7d (#inst: %5d), submitted: %7d"
-					, statsNumPrimsRendered
-					, statsNumInstances
-					, statsNumPrimsSubmitted
-					);
+				for (uint32_t ii = 0; ii < BX_COUNTOF(s_primInfo); ++ii)
+				{
+					tvm.printf(10, pos++, 0x8e, "    %8s: %7d (#inst: %5d), submitted: %7d"
+						, s_primName[ii]
+						, statsNumPrimsRendered[ii]
+						, statsNumInstances[ii]
+						, statsNumPrimsSubmitted[ii]
+						);
+				}
 
-				double captureMs = double(captureElapsed)*toMs;
-				tvm.printf(10, pos++, 0x8e, "     Capture: %3.4f [ms]", captureMs);
 				tvm.printf(10, pos++, 0x8e, "     Indices: %7d", statsNumIndices);
 				tvm.printf(10, pos++, 0x8e, "    DVB size: %7d", m_render->m_vboffset);
 				tvm.printf(10, pos++, 0x8e, "    DIB size: %7d", m_render->m_iboffset);
 
+				double captureMs = double(captureElapsed)*toMs;
+				tvm.printf(10, pos++, 0x8e, "     Capture: %3.4f [ms]", captureMs);
+
 				uint8_t attr[2] = { 0x89, 0x8a };
 				uint8_t attrIndex = m_render->m_waitSubmit < m_render->m_waitRender;
 

+ 129 - 57
src/renderer_d3d9.cpp

@@ -12,11 +12,28 @@ namespace bgfx
 {
 	static wchar_t s_viewNameW[BGFX_CONFIG_MAX_VIEWS][256];
 
-	static const D3DPRIMITIVETYPE s_primType[] =
+	struct PrimInfo
 	{
-		D3DPT_TRIANGLELIST,
-		D3DPT_LINELIST,
-		D3DPT_POINTLIST,
+		D3DPRIMITIVETYPE m_type;
+		uint32_t m_min;
+		uint32_t m_div;
+		uint32_t m_sub;
+	};
+
+	static const PrimInfo s_primInfo[] =
+	{
+		{ D3DPT_TRIANGLELIST,  3, 3, 0 },
+		{ D3DPT_TRIANGLESTRIP, 3, 1, 2 },
+		{ D3DPT_LINELIST,      2, 2, 0 },
+		{ D3DPT_POINTLIST,     1, 1, 0 },
+	};
+
+	static const char* s_primName[] =
+	{
+		"TriList",
+		"TriStrip",
+		"Line",
+		"Point",
 	};
 
 	static const D3DMULTISAMPLE_TYPE s_checkMsaa[] =
@@ -2047,6 +2064,8 @@ namespace bgfx
 	{
 		reset();
 
+		IDirect3DDevice9* device = s_renderCtx->m_device;
+
 		do
 		{
 			uint32_t opcode = read();
@@ -2074,32 +2093,77 @@ namespace bgfx
 				data = (const char*)s_renderCtx->m_uniforms[handle.idx];
 			}
 
-#define CASE_IMPLEMENT_UNIFORM(_uniform, _glsuffix, _dxsuffix, _type) \
-		case UniformType::_uniform: \
-		{ \
-			_type* value = (_type*)data; \
-			s_renderCtx->m_device->SetVertexShaderConstant##_dxsuffix(loc, value, num); \
-		} \
-		break; \
-		\
-		case UniformType::_uniform|BGFX_UNIFORM_FRAGMENTBIT: \
-		{ \
-			_type* value = (_type*)data; \
-			s_renderCtx->m_device->SetPixelShaderConstant##_dxsuffix(loc, value, num); \
-		} \
-		break
-
-			switch ((int32_t)type)
-			{
-			CASE_IMPLEMENT_UNIFORM(Uniform1i, 1iv, I, int);
-			CASE_IMPLEMENT_UNIFORM(Uniform1f, 1fv, F, float);
-			CASE_IMPLEMENT_UNIFORM(Uniform1iv, 1iv, I, int);
-			CASE_IMPLEMENT_UNIFORM(Uniform1fv, 1fv, F, float);
-			CASE_IMPLEMENT_UNIFORM(Uniform2fv, 2fv, F, float);
-			CASE_IMPLEMENT_UNIFORM(Uniform3fv, 3fv, F, float);
-			CASE_IMPLEMENT_UNIFORM(Uniform4fv, 4fv, F, float);
-			CASE_IMPLEMENT_UNIFORM(Uniform3x3fv, Matrix3fv, F, float);
-			CASE_IMPLEMENT_UNIFORM(Uniform4x4fv, Matrix4fv, F, float);
+#define CASE_IMPLEMENT_UNIFORM(_uniform, _dxsuffix, _type) \
+				case UniformType::_uniform: \
+				{ \
+					_type* value = (_type*)data; \
+					DX_CHECK(device->SetVertexShaderConstant##_dxsuffix(loc, value, num) ); \
+				} \
+				break; \
+				\
+				case UniformType::_uniform|BGFX_UNIFORM_FRAGMENTBIT: \
+				{ \
+					_type* value = (_type*)data; \
+					DX_CHECK(device->SetPixelShaderConstant##_dxsuffix(loc, value, num) ); \
+				} \
+				break
+
+			switch ( (int32_t)type)
+			{
+			case UniformType::Uniform3x3fv:
+				{
+					float* value = (float*)data;
+					for (uint32_t ii = 0, count = num/3; ii < count; ++ii,  loc += 3, value += 9)
+					{
+						Matrix4 mtx;
+						mtx.un.val[ 0] = value[0];
+						mtx.un.val[ 1] = value[1];
+						mtx.un.val[ 2] = value[2];
+						mtx.un.val[ 3] = 0.0f;
+						mtx.un.val[ 4] = value[3];
+						mtx.un.val[ 5] = value[4];
+						mtx.un.val[ 6] = value[5];
+						mtx.un.val[ 7] = 0.0f;
+						mtx.un.val[ 8] = value[6];
+						mtx.un.val[ 9] = value[7];
+						mtx.un.val[10] = value[8];
+						mtx.un.val[11] = 0.0f;
+						DX_CHECK(device->SetVertexShaderConstantF(loc, &mtx.un.val[0], 3) );
+					}
+				}
+				break;
+
+			case UniformType::Uniform3x3fv|BGFX_UNIFORM_FRAGMENTBIT:
+				{
+					float* value = (float*)data;
+					for (uint32_t ii = 0, count = num/3; ii < count; ++ii, loc += 3, value += 9)
+					{
+						Matrix4 mtx;
+						mtx.un.val[ 0] = value[0];
+						mtx.un.val[ 1] = value[1];
+						mtx.un.val[ 2] = value[2];
+						mtx.un.val[ 3] = 0.0f;
+						mtx.un.val[ 4] = value[3];
+						mtx.un.val[ 5] = value[4];
+						mtx.un.val[ 6] = value[5];
+						mtx.un.val[ 7] = 0.0f;
+						mtx.un.val[ 8] = value[6];
+						mtx.un.val[ 9] = value[7];
+						mtx.un.val[10] = value[8];
+						mtx.un.val[11] = 0.0f;
+						DX_CHECK(device->SetPixelShaderConstantF(loc, &mtx.un.val[0], 3) );
+					}
+				}
+				break;
+
+			CASE_IMPLEMENT_UNIFORM(Uniform1i,    I, int);
+			CASE_IMPLEMENT_UNIFORM(Uniform1f,    F, float);
+			CASE_IMPLEMENT_UNIFORM(Uniform1iv,   I, int);
+			CASE_IMPLEMENT_UNIFORM(Uniform1fv,   F, float);
+			CASE_IMPLEMENT_UNIFORM(Uniform2fv,   F, float);
+			CASE_IMPLEMENT_UNIFORM(Uniform3fv,   F, float);
+			CASE_IMPLEMENT_UNIFORM(Uniform4fv,   F, float);
+			CASE_IMPLEMENT_UNIFORM(Uniform4x4fv, F, float);
 
 			case UniformType::End:
 				break;
@@ -2142,8 +2206,8 @@ namespace bgfx
 		DX_CHECK(device->SetRenderState(D3DRS_FILLMODE, D3DFILL_SOLID) );
 
 		Program& program = s_renderCtx->m_program[m_program.idx];
-		device->SetVertexShader( (IDirect3DVertexShader9*)program.m_vsh->m_ptr);
-		device->SetPixelShader( (IDirect3DPixelShader9*)program.m_fsh->m_ptr);
+		DX_CHECK(device->SetVertexShader( (IDirect3DVertexShader9*)program.m_vsh->m_ptr) );
+		DX_CHECK(device->SetPixelShader( (IDirect3DPixelShader9*)program.m_fsh->m_ptr) );
 
 		VertexBuffer& vb = s_renderCtx->m_vertexBuffers[m_vb->handle.idx];
 		VertexDeclaration& vertexDecl = s_renderCtx->m_vertexDecls[m_vb->decl.idx];
@@ -2407,16 +2471,19 @@ namespace bgfx
 		FrameBufferHandle fbh = BGFX_INVALID_HANDLE;
 		float alphaRef = 0.0f;
 		uint32_t blendFactor = 0;
-		D3DPRIMITIVETYPE primType = D3DPT_TRIANGLELIST;
-		uint32_t primNumVerts = 3;
+
+		const uint64_t pt = m_render->m_debug&BGFX_DEBUG_WIREFRAME ? BGFX_STATE_PT_LINES : 0;
+		uint8_t primIndex = uint8_t(pt>>BGFX_STATE_PT_SHIFT);
+		PrimInfo prim = s_primInfo[primIndex];
+
 		bool viewHasScissor = false;
 		Rect viewScissorRect;
 		viewScissorRect.clear();
 
-		uint32_t statsNumPrimsSubmitted = 0;
+		uint32_t statsNumPrimsSubmitted[BX_COUNTOF(s_primInfo)] = {};
+		uint32_t statsNumPrimsRendered[BX_COUNTOF(s_primInfo)] = {};
+		uint32_t statsNumInstances[BX_COUNTOF(s_primInfo)] = {};
 		uint32_t statsNumIndices = 0;
-		uint32_t statsNumInstances = 0;
-		uint32_t statsNumPrimsRendered = 0;
 
 		s_renderCtx->invalidateSamplerState();
 
@@ -2713,9 +2780,9 @@ namespace bgfx
 						blendFactor = state.m_rgba;
 					}
 
-					uint8_t primIndex = uint8_t( (newFlags&BGFX_STATE_PT_MASK)>>BGFX_STATE_PT_SHIFT);
-					primType = s_primType[primIndex];
-					primNumVerts = 3-primIndex;
+					const uint64_t pt = m_render->m_debug&BGFX_DEBUG_WIREFRAME ? BGFX_STATE_PT_LINES : newFlags&BGFX_STATE_PT_MASK;
+					primIndex = uint8_t(pt>>BGFX_STATE_PT_SHIFT);
+					prim = s_primInfo[primIndex];
 				}
 
 				bool programChanged = false;
@@ -2963,11 +3030,11 @@ namespace bgfx
 						if (UINT32_MAX == state.m_numIndices)
 						{
 							numIndices = s_renderCtx->m_indexBuffers[state.m_indexBuffer.idx].m_size/2;
-							numPrimsSubmitted = numIndices/primNumVerts;
+							numPrimsSubmitted = numIndices/prim.m_div - prim.m_sub;
 							numInstances = state.m_numInstances;
 							numPrimsRendered = numPrimsSubmitted*state.m_numInstances;
 
-							DX_CHECK(device->DrawIndexedPrimitive(primType
+							DX_CHECK(device->DrawIndexedPrimitive(prim.m_type
 								, state.m_startVertex
 								, 0
 								, numVertices
@@ -2975,14 +3042,14 @@ namespace bgfx
 								, numPrimsSubmitted
 								) );
 						}
-						else if (primNumVerts <= state.m_numIndices)
+						else if (prim.m_min <= state.m_numIndices)
 						{
 							numIndices = state.m_numIndices;
-							numPrimsSubmitted = numIndices/primNumVerts;
+							numPrimsSubmitted = numIndices/prim.m_div - prim.m_sub;
 							numInstances = state.m_numInstances;
 							numPrimsRendered = numPrimsSubmitted*state.m_numInstances;
 
-							DX_CHECK(device->DrawIndexedPrimitive(primType
+							DX_CHECK(device->DrawIndexedPrimitive(prim.m_type
 								, state.m_startVertex
 								, 0
 								, numVertices
@@ -2993,20 +3060,20 @@ namespace bgfx
 					}
 					else
 					{
-						numPrimsSubmitted = numVertices/primNumVerts;
+						numPrimsSubmitted = numVertices/prim.m_div - prim.m_sub;
 						numInstances = state.m_numInstances;
 						numPrimsRendered = numPrimsSubmitted*state.m_numInstances;
 
-						DX_CHECK(device->DrawPrimitive(primType
+						DX_CHECK(device->DrawPrimitive(prim.m_type
 							, state.m_startVertex
 							, numPrimsSubmitted
 							) );
 					}
 
-					statsNumPrimsSubmitted += numPrimsSubmitted;
+					statsNumPrimsSubmitted[primIndex] += numPrimsSubmitted;
+					statsNumPrimsRendered[primIndex]  += numPrimsRendered;
+					statsNumInstances[primIndex]      += numInstances;
 					statsNumIndices += numIndices;
-					statsNumInstances += numInstances;
-					statsNumPrimsRendered += numPrimsRendered;
 				}
 			}
 
@@ -3074,18 +3141,23 @@ namespace bgfx
 					, m_render->m_num
 					, elapsedCpuMs
 					);
-				tvm.printf(10, pos++, 0x8e, "       Prims: %7d (#inst: %5d), submitted: %7d"
-					, statsNumPrimsRendered
-					, statsNumInstances
-					, statsNumPrimsSubmitted
-					);
+				for (uint32_t ii = 0; ii < BX_COUNTOF(s_primInfo); ++ii)
+				{
+					tvm.printf(10, pos++, 0x8e, "    %8s: %7d (#inst: %5d), submitted: %7d"
+						, s_primName[ii]
+						, statsNumPrimsRendered[ii]
+						, statsNumInstances[ii]
+						, statsNumPrimsSubmitted[ii]
+						);
+				}
 
-				double captureMs = double(captureElapsed)*toMs;
-				tvm.printf(10, pos++, 0x8e, "     Capture: %3.4f [ms]", captureMs);
 				tvm.printf(10, pos++, 0x8e, "     Indices: %7d", statsNumIndices);
 				tvm.printf(10, pos++, 0x8e, "    DVB size: %7d", m_render->m_vboffset);
 				tvm.printf(10, pos++, 0x8e, "    DIB size: %7d", m_render->m_iboffset);
 
+				double captureMs = double(captureElapsed)*toMs;
+				tvm.printf(10, pos++, 0x8e, "     Capture: %3.4f [ms]", captureMs);
+
 				uint8_t attr[2] = { 0x89, 0x8a };
 				uint8_t attrIndex = m_render->m_waitSubmit < m_render->m_waitRender;
 

+ 58 - 30
src/renderer_gl.cpp

@@ -14,11 +14,28 @@ namespace bgfx
 {
 	static char s_viewName[BGFX_CONFIG_MAX_VIEWS][256];
 
-	static const GLenum s_primType[] =
+	struct PrimInfo
 	{
-		GL_TRIANGLES,
-		GL_LINES,
-		GL_POINTS,
+		GLenum m_type;
+		uint32_t m_min;
+		uint32_t m_div;
+		uint32_t m_sub;
+	};
+
+	static const PrimInfo s_primInfo[] =
+	{
+		{ GL_TRIANGLES,      3, 3, 0 },
+		{ GL_TRIANGLE_STRIP, 3, 1, 2 },
+		{ GL_LINES,          2, 2, 0 },
+		{ GL_POINTS,         1, 1, 0 },
+	};
+
+	static const char* s_primName[] =
+	{
+		"TriList",
+		"TriStrip",
+		"Line",
+		"Point",
 	};
 
 	static const char* s_attribName[Attrib::Count] =
@@ -1660,6 +1677,9 @@ namespace bgfx
 	{
 		switch (_type)
 		{
+		case GL_INT:
+			return UniformType::Uniform1iv;
+
 		case GL_FLOAT:
 			return UniformType::Uniform1fv;
 
@@ -1698,6 +1718,7 @@ namespace bgfx
 			return UniformType::Uniform1iv;
 		};
 
+		BX_CHECK(false, "Unrecognized GL type 0x%04x.", _type);
 		return UniformType::End;
 	}
 
@@ -3570,8 +3591,11 @@ namespace bgfx
 		int32_t height = m_render->m_resolution.m_height;
 		float alphaRef = 0.0f;
 		uint32_t blendFactor = 0;
-		GLenum primType = m_render->m_debug&BGFX_DEBUG_WIREFRAME ? GL_LINES : GL_TRIANGLES;
-		uint32_t primNumVerts = 3;
+
+		const uint64_t pt = m_render->m_debug&BGFX_DEBUG_WIREFRAME ? BGFX_STATE_PT_LINES : 0;
+		uint8_t primIndex = uint8_t(pt>>BGFX_STATE_PT_SHIFT);
+		PrimInfo prim = s_primInfo[primIndex];
+
 		uint32_t baseVertex = 0;
 		GLuint currentVao = 0;
 		bool viewHasScissor = false;
@@ -3580,10 +3604,10 @@ namespace bgfx
 
 		const bool blendIndependentSupported = s_extension[Extension::ARB_draw_buffers_blend].m_supported;
 
-		uint32_t statsNumPrimsSubmitted = 0;
+		uint32_t statsNumPrimsSubmitted[BX_COUNTOF(s_primInfo)] = {};
+		uint32_t statsNumPrimsRendered[BX_COUNTOF(s_primInfo)] = {};
+		uint32_t statsNumInstances[BX_COUNTOF(s_primInfo)] = {};
 		uint32_t statsNumIndices = 0;
-		uint32_t statsNumInstances = 0;
-		uint32_t statsNumPrimsRendered = 0;
 
 		if (0 == (m_render->m_debug&BGFX_DEBUG_IFH) )
 		{
@@ -3901,9 +3925,9 @@ namespace bgfx
 						blendFactor = state.m_rgba;
 					}
 
-					uint8_t primIndex = uint8_t( (newFlags&BGFX_STATE_PT_MASK)>>BGFX_STATE_PT_SHIFT);
-					primType = m_render->m_debug&BGFX_DEBUG_WIREFRAME ? GL_LINES : s_primType[primIndex];
-					primNumVerts = 3-primIndex;
+					const uint64_t pt = m_render->m_debug&BGFX_DEBUG_WIREFRAME ? BGFX_STATE_PT_LINES : newFlags&BGFX_STATE_PT_MASK;
+					primIndex = uint8_t(pt>>BGFX_STATE_PT_SHIFT);
+					prim = s_primInfo[primIndex];
 				}
 
 				bool programChanged = false;
@@ -4259,25 +4283,25 @@ namespace bgfx
 							if (UINT32_MAX == state.m_numIndices)
 							{
 								numIndices = s_renderCtx->m_indexBuffers[state.m_indexBuffer.idx].m_size/2;
-								numPrimsSubmitted = numIndices/primNumVerts;
+								numPrimsSubmitted = numIndices/prim.m_div - prim.m_sub;
 								numInstances = state.m_numInstances;
 								numPrimsRendered = numPrimsSubmitted*state.m_numInstances;
 
-								GL_CHECK(glDrawElementsInstanced(primType
+								GL_CHECK(glDrawElementsInstanced(prim.m_type
 									, numIndices
 									, GL_UNSIGNED_SHORT
 									, (void*)0
 									, state.m_numInstances
 									) );
 							}
-							else if (primNumVerts <= state.m_numIndices)
+							else if (prim.m_min <= state.m_numIndices)
 							{
 								numIndices = state.m_numIndices;
-								numPrimsSubmitted = numIndices/primNumVerts;
+								numPrimsSubmitted = numIndices/prim.m_div - prim.m_sub;
 								numInstances = state.m_numInstances;
 								numPrimsRendered = numPrimsSubmitted*state.m_numInstances;
 
-								GL_CHECK(glDrawElementsInstanced(primType
+								GL_CHECK(glDrawElementsInstanced(prim.m_type
 									, numIndices
 									, GL_UNSIGNED_SHORT
 									, (void*)(uintptr_t)(state.m_startIndex*2)
@@ -4287,21 +4311,21 @@ namespace bgfx
 						}
 						else
 						{
-							numPrimsSubmitted = numVertices/primNumVerts;
+							numPrimsSubmitted = numVertices/prim.m_div - prim.m_sub;
 							numInstances = state.m_numInstances;
 							numPrimsRendered = numPrimsSubmitted*state.m_numInstances;
 
-							GL_CHECK(glDrawArraysInstanced(primType
+							GL_CHECK(glDrawArraysInstanced(prim.m_type
 								, 0
 								, numVertices
 								, state.m_numInstances
 								) );
 						}
 
-						statsNumPrimsSubmitted += numPrimsSubmitted;
+						statsNumPrimsSubmitted[primIndex] += numPrimsSubmitted;
+						statsNumPrimsRendered[primIndex]  += numPrimsRendered;
+						statsNumInstances[primIndex]      += numInstances;
 						statsNumIndices += numIndices;
-						statsNumInstances += numInstances;
-						statsNumPrimsRendered += numPrimsRendered;
 					}
 				}
 			}
@@ -4377,19 +4401,23 @@ namespace bgfx
 					, elapsedCpuMs > elapsedGpuMs ? '>' : '<'
 					, elapsedGpuMs
 					);
-				tvm.printf(10, pos++, 0x8e, "      Prims: %7d (#inst: %5d), submitted: %7d"
-					, statsNumPrimsRendered
-					, statsNumInstances
-					, statsNumPrimsSubmitted
-					);
-
-				double captureMs = double(captureElapsed)*toMs;
-				tvm.printf(10, pos++, 0x8e, "    Capture: %3.4f [ms]", captureMs);
+				for (uint32_t ii = 0; ii < BX_COUNTOF(s_primInfo); ++ii)
+				{
+					tvm.printf(10, pos++, 0x8e, "   %8s: %7d (#inst: %5d), submitted: %7d"
+						, s_primName[ii]
+						, statsNumPrimsRendered[ii]
+						, statsNumInstances[ii]
+						, statsNumPrimsSubmitted[ii]
+						);
+				}
 
 				tvm.printf(10, pos++, 0x8e, "    Indices: %7d", statsNumIndices);
 				tvm.printf(10, pos++, 0x8e, "   DVB size: %7d", m_render->m_vboffset);
 				tvm.printf(10, pos++, 0x8e, "   DIB size: %7d", m_render->m_iboffset);
 
+				double captureMs = double(captureElapsed)*toMs;
+				tvm.printf(10, pos++, 0x8e, "    Capture: %3.4f [ms]", captureMs);
+
 #if BGFX_CONFIG_RENDERER_OPENGL
 				if (s_extension[Extension::ATI_meminfo].m_supported)
 				{

+ 15 - 11
tools/shaderc/shaderc.cpp

@@ -265,20 +265,18 @@ static const UniformRemapDx9 s_constRemapDx9[7] =
 	{ UniformType::Uniform2fv,   D3DXPC_VECTOR,         D3DXPT_FLOAT,  8 },
 	{ UniformType::Uniform3fv,   D3DXPC_VECTOR,         D3DXPT_FLOAT, 12 },
 	{ UniformType::Uniform4fv,   D3DXPC_VECTOR,         D3DXPT_FLOAT, 16 },
-	{ UniformType::Uniform3x3fv, D3DXPC_MATRIX_COLUMNS, D3DXPT_FLOAT, 36 },
+	{ UniformType::Uniform3x3fv, D3DXPC_MATRIX_COLUMNS, D3DXPT_FLOAT, 48 },
 	{ UniformType::Uniform4x4fv, D3DXPC_MATRIX_COLUMNS, D3DXPT_FLOAT, 64 },
 };
 
 UniformType::Enum findUniformTypeDx9(const D3DXCONSTANT_DESC& constDesc)
 {
-	uint32_t count = sizeof(s_constRemapDx9)/sizeof(UniformRemapDx9);
-	for (uint32_t ii = 0; ii < count; ++ii)
+	for (uint32_t ii = 0; ii < BX_COUNTOF(s_constRemapDx9); ++ii)
 	{
 		const UniformRemapDx9& remap = s_constRemapDx9[ii];
 
 		if (remap.paramClass == constDesc.Class
-		&&  remap.paramType == constDesc.Type
-		&&  (constDesc.Bytes%remap.paramBytes) == 0)
+		&&  remap.paramType == constDesc.Type)
 		{
 			return remap.id;
 		}
@@ -314,16 +312,14 @@ static const UniformRemapDx11 s_constRemapDx11[7] =
 	{ UniformType::Uniform4x4fv, D3D_SVC_MATRIX_COLUMNS, D3D_SVT_FLOAT, 64 },
 };
 
-UniformType::Enum findUniformTypeDx11(const D3D11_SHADER_TYPE_DESC& constDesc, uint32_t _size)
+UniformType::Enum findUniformTypeDx11(const D3D11_SHADER_TYPE_DESC& constDesc)
 {
-	uint32_t count = sizeof(s_constRemapDx11)/sizeof(UniformRemapDx9);
-	for (uint32_t ii = 0; ii < count; ++ii)
+	for (uint32_t ii = 0; ii < BX_COUNTOF(s_constRemapDx11); ++ii)
 	{
 		const UniformRemapDx11& remap = s_constRemapDx11[ii];
 
 		if (remap.paramClass == constDesc.Class
-		&&  remap.paramType == constDesc.Type
-		&&  (_size%remap.paramBytes) == 0)
+		&&  remap.paramType == constDesc.Type)
 		{
 			return remap.id;
 		}
@@ -809,6 +805,8 @@ bool compileGLSLShader(bx::CommandLine& _cmdLine, uint32_t _gles, const std::str
 bool compileHLSLShaderDx9(bx::CommandLine& _cmdLine, const std::string& _code, bx::WriterI* _writer)
 {
 #if BX_PLATFORM_WINDOWS
+	BX_TRACE("DX9");
+
 	const char* profile = _cmdLine.findOption('p', "profile");
 	if (NULL == profile)
 	{
@@ -1030,6 +1028,8 @@ bool compileHLSLShaderDx9(bx::CommandLine& _cmdLine, const std::string& _code, b
 bool compileHLSLShaderDx11(bx::CommandLine& _cmdLine, const std::string& _code, bx::WriterI* _writer)
 {
 #if BX_PLATFORM_WINDOWS
+	BX_TRACE("DX11");
+
 	const char* profile = _cmdLine.findOption('p', "profile");
 	if (NULL == profile)
 	{
@@ -1207,7 +1207,7 @@ bool compileHLSLShaderDx11(bx::CommandLine& _cmdLine, const std::string& _code,
 					hr = type->GetDesc(&constDesc);
 					if (SUCCEEDED(hr) )
 					{
-						UniformType::Enum type = findUniformTypeDx11(constDesc, varDesc.Size);
+						UniformType::Enum type = findUniformTypeDx11(constDesc);
 
 						if (UniformType::Count != type
 						&&  0 != (varDesc.uFlags & D3D_SVF_USED) )
@@ -1228,6 +1228,10 @@ bool compileHLSLShaderDx11(bx::CommandLine& _cmdLine, const std::string& _code,
 								, type
 								);
 						}
+						else
+						{
+							BX_TRACE("\t%s, unknown type", varDesc.Name);
+						}
 					}
 				}
 			}