Просмотр исходного кода

Fixed vertex decl attribute size calculation.

bkaradzic 13 лет назад
Родитель
Сommit
9e681bb2ed
7 измененных файлов с 183 добавлено и 218 удалено
  1. 30 7
      include/bgfx.h
  2. 42 17
      src/bgfx.cpp
  3. 39 106
      src/renderer_d3d11.cpp
  4. 29 75
      src/renderer_d3d9.cpp
  5. 23 3
      src/renderer_gl.cpp
  6. BIN
      tools/bin/shaderc.exe
  7. 20 10
      tools/shaderc.cpp

+ 30 - 7
include/bgfx.h

@@ -85,6 +85,9 @@
 					| BGFX_STATE_MSAA \
 					)
 
+#define BGFX_STATE_ALPHA_REF(_ref) ( (uint64_t(_ref)<<BGFX_STATE_ALPHA_REF_SHIFT)&BGFX_STATE_ALPHA_REF_MASK)
+#define BGFX_STATE_POINT_SIZE(_size) ( (uint64_t(_size)<<BGFX_STATE_POINT_SIZE_SHIFT)&BGFX_STATE_POINT_SIZE_MASK)
+
 #define BGFX_CLEAR_NONE                 UINT8_C(0x00)
 #define BGFX_CLEAR_COLOR_BIT            UINT8_C(0x01)
 #define BGFX_CLEAR_DEPTH_BIT            UINT8_C(0x02)
@@ -175,12 +178,14 @@ namespace bgfx
 	{
 		enum Enum
 		{
-			Null = 0,
+			Null,
 			Direct3D9,
 			Direct3D11,
 			OpenGLES2,
 			OpenGLES3,
 			OpenGL,
+
+			Count
 		};
 	};
 
@@ -188,7 +193,7 @@ namespace bgfx
 	{
 		enum Enum
 		{
-			Position = 0,
+			Position,
 			Normal,
 			Tangent,
 			Color0,
@@ -204,7 +209,7 @@ namespace bgfx
 			TexCoord6,
 			TexCoord7,
 
-			Count,
+			Count
 		};
 	};
 
@@ -214,9 +219,10 @@ namespace bgfx
 		{
 			Uint8,
 			Uint16,
+			Half,
 			Float,
 
-			Count,
+			Count
 		};
 	};
 
@@ -312,12 +318,29 @@ namespace bgfx
 
 	struct VertexDecl
 	{
-		void begin();
+		/// Start VertexDecl.
+		void begin(RendererType::Enum _renderer = RendererType::Null);
+
+		/// End VertexDecl.
 		void end();
+
+		/// Add attribute to VertexDecl. Note: Must be called between begin/end.
 		void add(Attrib::Enum _attrib, uint8_t _num, AttribType::Enum _type, bool _normalized = false);
+
+		/// Decode attribute.
 		void decode(Attrib::Enum _attrib, uint8_t& _num, AttribType::Enum& _type, bool& _normalized) const;
-		bool has(Attrib::Enum _attrib) const;
-		uint16_t getOffset(Attrib::Enum _attrib) const;
+
+		/// Returns true if VertexDecl contains attribute.
+		bool has(Attrib::Enum _attrib) const { return 0xff != m_attributes[_attrib]; }
+
+		/// Returns relative attribute offset from the vertex.
+		uint16_t getOffset(Attrib::Enum _attrib) const { return m_offset[_attrib]; }
+
+		/// Returns vertex stride.
+		uint16_t getStride() const { return m_stride; }
+
+		/// Returns size of vertex buffer for number of vertices.
+		uint32_t getSize(uint32_t _num) const { return _num*m_stride; }
 
 		uint32_t m_hash;
 		uint16_t m_stride;

+ 42 - 17
src/bgfx.cpp

@@ -566,16 +566,51 @@ namespace bgfx
 		return s_ctx.renderFrame();
 	}
 
-	static const uint32_t s_attribTypeSize[AttribType::Count] =
+	static const uint8_t s_attribTypeSizeDx9[AttribType::Count][4] =
 	{
-		1,
-		2,
-		4,
+		{  4,  4,  4,  4 },
+		{  4,  4,  8,  8 },
+		{  4,  4,  8,  8 },
+		{  4,  8, 12, 16 },
 	};
 
-	void VertexDecl::begin()
+	static const uint8_t s_attribTypeSizeDx11[AttribType::Count][4] =
 	{
-		m_hash = 0;
+		{  1,  2,  4,  4 },
+		{  2,  4,  8,  8 },
+		{  2,  4,  8,  8 },
+		{  4,  8, 12, 16 },
+	};
+
+	static const uint8_t s_attribTypeSizeGl[AttribType::Count][4] =
+	{
+		{  1,  2,  4,  4 },
+		{  2,  4,  6,  8 },
+		{  2,  4,  6,  8 },
+		{  4,  8, 12, 16 },
+	};
+
+	static const uint8_t (*s_attribTypeSize[RendererType::Count])[AttribType::Count][4] =
+	{
+#if BGFX_CONFIG_RENDERER_DIRECT3D9
+		&s_attribTypeSizeDx9,
+#elif BGFX_CONFIG_RENDERER_DIRECT3D11
+		&s_attribTypeSizeDx11,
+#elif BGFX_CONFIG_RENDERER_OPENGL|BGFX_CONFIG_RENDERER_OPENGLES2|BGFX_CONFIG_RENDERER_OPENGLES3
+		&s_attribTypeSizeGl,
+#else
+		&s_attribTypeSizeDx9,
+#endif // BGFX_CONFIG_RENDERER_
+		&s_attribTypeSizeDx9,
+		&s_attribTypeSizeDx11,
+		&s_attribTypeSizeGl,
+		&s_attribTypeSizeGl,
+		&s_attribTypeSizeGl,
+	};
+
+	void VertexDecl::begin(RendererType::Enum _renderer)
+	{
+		m_hash = _renderer; // use hash to store renderer type while building VertexDecl.
 		m_stride = 0;
 		memset(m_attributes, 0xff, sizeof(m_attributes) );
 		memset(m_offset, 0, sizeof(m_offset) );
@@ -594,7 +629,7 @@ namespace bgfx
 
 		m_attributes[_attrib] = encoded_norm|encoded_type|encoded_num;
 		m_offset[_attrib] = m_stride;
-		m_stride += s_attribTypeSize[_type]*_num;
+		m_stride += (*s_attribTypeSize[m_hash])[_type][_num-1];
 	}
 
 	void VertexDecl::decode(Attrib::Enum _attrib, uint8_t& _num, AttribType::Enum& _type, bool& _normalized) const
@@ -605,16 +640,6 @@ namespace bgfx
 		_normalized = !!(val&(1<<6) );
 	}
 
-	bool VertexDecl::has(Attrib::Enum _attrib) const
-	{
-		return 0xff != m_attributes[_attrib];
-	}
-
-	uint16_t VertexDecl::getOffset(Attrib::Enum _attrib) const
-	{
-		return m_offset[_attrib];
-	}
-
 	const char* getAttribName(Attrib::Enum _attr)
 	{
 		static const char* attrName[Attrib::Count] = 

+ 39 - 106
src/renderer_d3d11.cpp

@@ -117,6 +117,34 @@ namespace bgfx
 		{ "TEXCOORD",     7, DXGI_FORMAT_R32G32_FLOAT,    0, D3D11_APPEND_ALIGNED_ELEMENT, D3D11_INPUT_PER_VERTEX_DATA, 0 },
 	};
 
+	static const DXGI_FORMAT s_attribType[AttribType::Count][4][2] =
+	{
+		{
+			{ DXGI_FORMAT_R8_UINT,            DXGI_FORMAT_R8_UNORM           },
+			{ DXGI_FORMAT_R8G8_UINT,          DXGI_FORMAT_R8G8_UNORM         },
+			{ DXGI_FORMAT_R8G8B8A8_UINT,      DXGI_FORMAT_R8G8B8A8_UNORM     },
+			{ DXGI_FORMAT_R8G8B8A8_UINT,      DXGI_FORMAT_R8G8B8A8_UNORM     },
+		},
+		{
+			{ DXGI_FORMAT_R16_UINT,           DXGI_FORMAT_R16_UNORM          },
+			{ DXGI_FORMAT_R16G16_UINT,        DXGI_FORMAT_R16G16_UNORM       },
+			{ DXGI_FORMAT_R16G16B16A16_UINT,  DXGI_FORMAT_R16G16B16A16_UNORM },
+			{ DXGI_FORMAT_R16G16B16A16_UINT,  DXGI_FORMAT_R16G16B16A16_UNORM },
+		},
+		{
+			{ DXGI_FORMAT_R16_FLOAT,          DXGI_FORMAT_R16_FLOAT          },
+			{ DXGI_FORMAT_R16G16_FLOAT,       DXGI_FORMAT_R16G16_FLOAT       },
+			{ DXGI_FORMAT_R16G16B16A16_FLOAT, DXGI_FORMAT_R16G16B16A16_FLOAT },
+			{ DXGI_FORMAT_R16G16B16A16_FLOAT, DXGI_FORMAT_R16G16B16A16_FLOAT },
+		},
+		{
+			{ DXGI_FORMAT_R32_FLOAT,          DXGI_FORMAT_R32_FLOAT          },
+			{ DXGI_FORMAT_R32G32_FLOAT,       DXGI_FORMAT_R32G32_FLOAT       },
+			{ DXGI_FORMAT_R32G32B32_FLOAT,    DXGI_FORMAT_R32G32B32_FLOAT    },
+			{ DXGI_FORMAT_R32G32B32A32_FLOAT, DXGI_FORMAT_R32G32B32A32_FLOAT },
+		},
+	};
+
 	static D3D11_INPUT_ELEMENT_DESC* fillVertexDecl(D3D11_INPUT_ELEMENT_DESC* _out, uint32_t _count, const VertexDecl& _decl)
 	{
 		D3D11_INPUT_ELEMENT_DESC* elem = _out;
@@ -137,110 +165,7 @@ namespace bgfx
 					AttribType::Enum type;
 					bool normalized;
 					_decl.decode(Attrib::Enum(attr), num, type, normalized);
-
-					DXGI_FORMAT format = elem->Format;
-
-					switch (type)
-					{
-					case AttribType::Uint8:
-						if (normalized)
-						{
-							switch (num)
-							{
-							case 1:
-								format = DXGI_FORMAT_R8_UNORM;
-								break;
-
-							case 2:
-								format = DXGI_FORMAT_R8G8_UNORM;
-								break;
-
-							default:
-							case 4:
-								format = DXGI_FORMAT_R8G8B8A8_UNORM;
-								break;
-							}
-						}
-						else
-						{
-							switch (num)
-							{
-							case 1:
-								format = DXGI_FORMAT_R8_UINT;
-								break;
-
-							case 2:
-								format = DXGI_FORMAT_R8G8_UINT;
-								break;
-
-							default:
-							case 4:
-								format = DXGI_FORMAT_R8G8B8A8_UINT;
-								break;
-							}
-						}
-						break;
-
-					case AttribType::Uint16:
-						if (normalized)
-						{
-							switch (num)
-							{
-							default:
-							case 2:
-								format = DXGI_FORMAT_R16G16_UNORM;
-								break;
-
-							case 4:
-								format = DXGI_FORMAT_R16G16B16A16_UNORM;
-								break;
-							}
-						}
-						else
-						{
-							switch (num)
-							{
-							default:
-							case 2:
-								format = DXGI_FORMAT_R16G16_UINT;
-								break;
-
-							case 4:
-								format = DXGI_FORMAT_R16G16B16A16_UINT;
-								break;
-							}
-						}
-						break;
-
-					case AttribType::Float:
-						switch (num)
-						{
-						case 1:
-							format = DXGI_FORMAT_R32_FLOAT;
-							break;
-
-						case 2:
-							format = DXGI_FORMAT_R32G32_FLOAT;
-							break;
-
-						default:
-						case 3:
-							format = DXGI_FORMAT_R32G32B32_FLOAT;
-							break;
-
-						case 4:
-							format = DXGI_FORMAT_R32G32B32A32_FLOAT;
-							break;
-						}
-
-						break;
-
-					default:
-						BX_CHECK(false, "Invalid attrib type.");
-						break;
-					}
-
-					elem->Format = format;
+					elem->Format = s_attribType[type][num-1][normalized];
 					elem->AlignedByteOffset = _decl.m_offset[attr];
 				}
 
@@ -823,7 +748,7 @@ namespace bgfx
 		}
 		else
 		{
-			desc.Usage = D3D11_USAGE_DEFAULT;
+			desc.Usage = D3D11_USAGE_IMMUTABLE;
 			desc.CPUAccessFlags = 0;
 
 			D3D11_SUBRESOURCE_DATA srd;
@@ -874,7 +799,7 @@ namespace bgfx
 		}
 		else
 		{
-			desc.Usage = D3D11_USAGE_DEFAULT;
+			desc.Usage = D3D11_USAGE_IMMUTABLE;
 			desc.CPUAccessFlags = 0;
 			desc.StructureByteStride = 0;
 
@@ -1915,6 +1840,14 @@ namespace bgfx
 					{
 						s_renderCtx.setRasterizerState(newFlags, wireframe);
 					}
+
+					uint8_t primIndex = uint8_t( (newFlags&BGFX_STATE_PT_MASK)>>BGFX_STATE_PT_SHIFT);
+					if (primType != s_primType[primIndex])
+					{
+						primType = s_primType[primIndex];
+						primNumVerts = s_primNumVerts[primIndex];
+						deviceCtx->IASetPrimitiveTopology(primType);
+					}
 				}
 
 				bool programChanged = false;

+ 29 - 75
src/renderer_d3d9.cpp

@@ -860,6 +860,34 @@ namespace bgfx
 		D3DDECL_END()
 	};
 
+	static const D3DDECLTYPE s_attribType[AttribType::Count][4][2] =
+	{
+		{
+			{ D3DDECLTYPE_UBYTE4,    D3DDECLTYPE_UBYTE4N   },
+			{ D3DDECLTYPE_UBYTE4,    D3DDECLTYPE_UBYTE4N   },
+			{ D3DDECLTYPE_UBYTE4,    D3DDECLTYPE_UBYTE4N   },
+			{ D3DDECLTYPE_UBYTE4,    D3DDECLTYPE_UBYTE4N   },
+		},
+		{
+			{ D3DDECLTYPE_SHORT2,    D3DDECLTYPE_SHORT2N   },
+			{ D3DDECLTYPE_SHORT2,    D3DDECLTYPE_SHORT2N   },
+			{ D3DDECLTYPE_SHORT4,    D3DDECLTYPE_SHORT4N   },
+			{ D3DDECLTYPE_SHORT4,    D3DDECLTYPE_SHORT4N   },
+		},
+		{
+			{ D3DDECLTYPE_FLOAT16_2, D3DDECLTYPE_FLOAT16_2 },
+			{ D3DDECLTYPE_FLOAT16_2, D3DDECLTYPE_FLOAT16_2 },
+			{ D3DDECLTYPE_FLOAT16_4, D3DDECLTYPE_FLOAT16_4 },
+			{ D3DDECLTYPE_FLOAT16_4, D3DDECLTYPE_FLOAT16_4 },
+		},
+		{
+			{ D3DDECLTYPE_FLOAT1,    D3DDECLTYPE_FLOAT1    },
+			{ D3DDECLTYPE_FLOAT2,    D3DDECLTYPE_FLOAT2    },
+			{ D3DDECLTYPE_FLOAT3,    D3DDECLTYPE_FLOAT3    },
+			{ D3DDECLTYPE_FLOAT4,    D3DDECLTYPE_FLOAT4    },
+		},
+	};
+
 	static D3DVERTEXELEMENT9* fillVertexDecl(D3DVERTEXELEMENT9* _out, uint32_t _count, const VertexDecl& _decl)
 	{
 		D3DVERTEXELEMENT9* elem = _out;
@@ -875,81 +903,7 @@ namespace bgfx
 
 				memcpy(elem, &s_attrib[attr], sizeof(D3DVERTEXELEMENT9) );
 
-				D3DDECLTYPE declType = D3DDECLTYPE(elem->Type);
-
-				switch (type)
-				{
-				case AttribType::Uint8:
-					if (normalized)
-					{
-						declType = D3DDECLTYPE_UBYTE4N;
-					}
-					else
-					{
-						declType = D3DDECLTYPE_UBYTE4;
-					}
-					break;
-
-				case AttribType::Uint16:
-					if (normalized)
-					{
-						switch (num)
-						{
-						default:
-						case 2:
-							declType = D3DDECLTYPE_SHORT2N;
-							break;
-
-						case 4:
-							declType = D3DDECLTYPE_SHORT4N;
-							break;
-						}
-					}
-					else
-					{
-						switch (num)
-						{
-						default:
-						case 2:
-							declType = D3DDECLTYPE_SHORT2;
-							break;
-
-						case 4:
-							declType = D3DDECLTYPE_SHORT4;
-							break;
-						}
-					}
-					break;
-
-				case AttribType::Float:
-					switch (num)
-					{
-					case 1:
-						declType = D3DDECLTYPE_FLOAT1;
-						break;
-
-					case 2:
-						declType = D3DDECLTYPE_FLOAT2;
-						break;
-
-					default:
-					case 3:
-						declType = D3DDECLTYPE_FLOAT3;
-						break;
-
-					case 4:
-						declType = D3DDECLTYPE_FLOAT4;
-						break;
-					}
-
-					break;
-
-				default:
-					BX_CHECK(false, "Invalid attrib type.");
-					break;
-				}
-
-				elem->Type = declType;
+				elem->Type = s_attribType[type][num-1][normalized];
 				elem->Offset = _decl.m_offset[attr];
 				++elem;
 			}

+ 23 - 3
src/renderer_gl.cpp

@@ -598,10 +598,15 @@ namespace bgfx
 			ANGLE_translated_shader_source,
 			ARB_instanced_arrays,
 			ANGLE_instanced_arrays,
+			ARB_texture_float,
 			OES_texture_float,
 			OES_texture_float_linear,
 			OES_texture_half_float,
 			OES_texture_half_float_linear,
+			ARB_half_float_vertex,
+			OES_vertex_half_float,
+			ARB_vertex_type_2_10_10_10_rev,
+			OES_vertex_type_10_10_10_2,
 			EXT_occlusion_query_boolean,
 			ATI_meminfo,
 			NVX_gpu_memory_info,
@@ -637,10 +642,15 @@ namespace bgfx
 		{ "GL_ANGLE_translated_shader_source",    false, true },
 		{ "GL_ARB_instanced_arrays",              false, true },
 		{ "GL_ANGLE_instanced_arrays",            false, true },
+		{ "GL_ARB_texture_float",                 false, true },
 		{ "GL_OES_texture_float",                 false, true },
 		{ "GL_OES_texture_float_linear",          false, true },
 		{ "GL_OES_texture_half_float",            false, true },
 		{ "GL_OES_texture_half_float_linear",     false, true },
+		{ "GL_ARB_half_float_vertex",             false, true },
+		{ "GL_OES_vertex_half_float",             false, true },
+		{ "GL_ARB_vertex_type_2_10_10_10_rev",    false, true },
+		{ "GL_OES_vertex_type_10_10_10_2",        false, true },
 		{ "GL_EXT_occlusion_query_boolean",       false, true },
 		{ "GL_ATI_meminfo",                       false, true },
 		{ "GL_NVX_gpu_memory_info",               false, true },
@@ -692,6 +702,7 @@ namespace bgfx
 	{
 		GL_UNSIGNED_BYTE,
 		GL_UNSIGNED_SHORT,
+		GL_HALF_FLOAT,
 		GL_FLOAT,
 	};
 
@@ -2524,7 +2535,7 @@ namespace bgfx
 						||  bindAttribs)
 						{
 							baseVertex = state.m_startVertex;
-							VertexBuffer& vb = s_renderCtx.m_vertexBuffers[state.m_vertexBuffer.idx];
+							const VertexBuffer& vb = s_renderCtx.m_vertexBuffers[state.m_vertexBuffer.idx];
 							uint16_t decl = vb.m_decl.idx == invalidHandle ? state.m_vertexDecl.idx : vb.m_decl.idx;
 							const Program& program = s_renderCtx.m_program[programIdx];
 							program.bindAttributes(s_renderCtx.m_vertexDecls[decl], state.m_startVertex);
@@ -2536,6 +2547,15 @@ namespace bgfx
 							}
 						}
 
+						uint32_t numVertices = state.m_numVertices;
+						if (UINT32_C(0xffffffff) == numVertices)
+						{
+							const VertexBuffer& vb = s_renderCtx.m_vertexBuffers[currentState.m_vertexBuffer.idx];
+							uint16_t decl = vb.m_decl.idx == invalidHandle ? state.m_vertexDecl.idx : vb.m_decl.idx;
+							const VertexDecl& vertexDecl = s_renderCtx.m_vertexDecls[decl];
+							numVertices = vb.m_size/vertexDecl.m_stride;
+						}
+
 						uint32_t numIndices = 0;
 						uint32_t numPrimsSubmitted = 0;
 						uint32_t numInstances = 0;
@@ -2574,13 +2594,13 @@ namespace bgfx
 						}
 						else
 						{
-							numPrimsSubmitted = state.m_numVertices/primNumVerts;
+							numPrimsSubmitted = numVertices/primNumVerts;
 							numInstances = state.m_numInstances;
 							numPrimsRendered = numPrimsSubmitted*state.m_numInstances;
 
 							GL_CHECK(s_drawArraysInstanced(primType
 								, 0
-								, state.m_numVertices
+								, numVertices
 								, state.m_numInstances
 								) );
 						}

BIN
tools/bin/shaderc.exe


+ 20 - 10
tools/shaderc.cpp

@@ -978,7 +978,7 @@ bool compileHLSLShaderDx11(CommandLine& _cmdLine, const std::string& _code, IStr
 	{
 		D3D11_SIGNATURE_PARAMETER_DESC spd;
 		reflect->GetInputParameterDesc(ii, &spd);
-		BX_TRACE("\t%2d: %s%d, %d, %d, %x, %d"
+		BX_TRACE("\t%2d: %s%d, vt %d, ct %d, mask %x, reg %d"
 			, ii
 			, spd.SemanticName
 			, spd.SemanticIndex
@@ -1664,6 +1664,13 @@ int main(int _argc, const char* _argv[])
 
 		if (glsl)
 		{
+			preprocessor.writef(
+				"#define ivec2 vec2\n"
+				"#define ivec3 vec3\n"
+				"#define ivec4 vec4\n"
+				);
+
+
 			for (InOut::const_iterator it = shaderInputs.begin(), itEnd = shaderInputs.end(); it != itEnd; ++it)
 			{
 				VaryingMap::const_iterator varyingIt = varyingMap.find(*it);
@@ -1696,15 +1703,18 @@ int main(int _argc, const char* _argv[])
 		else
 		{
 			preprocessor.writef(
-					"#define lowp\n"
-					"#define mediump\n"
-					"#define highp\n"
-					"#define vec2 float2\n"
-					"#define vec3 float3\n"
-					"#define vec4 float4\n"
-					"#define mat2 float2x2\n"
-					"#define mat3 float3x3\n"
-					"#define mat4 float4x4\n"
+				"#define lowp\n"
+				"#define mediump\n"
+				"#define highp\n"
+				"#define ivec2 int2\n"
+				"#define ivec3 int3\n"
+				"#define ivec4 int4\n"
+				"#define vec2 float2\n"
+				"#define vec3 float3\n"
+				"#define vec4 float4\n"
+				"#define mat2 float2x2\n"
+				"#define mat3 float3x3\n"
+				"#define mat4 float4x4\n"
 				);
 
 			char* entry = strstr(data, "void main()");