Przeglądaj źródła

Fixed update texture.

bkaradzic 13 lat temu
rodzic
commit
ff656de290
7 zmienionych plików z 277 dodań i 214 usunięć
  1. 42 32
      include/bgfx.h
  2. 39 39
      src/bgfx.cpp
  3. 12 17
      src/bgfx_p.h
  4. 22 19
      src/renderer_d3d11.cpp
  5. 20 17
      src/renderer_d3d9.cpp
  6. 138 86
      src/renderer_gl.cpp
  7. 4 4
      src/renderer_null.cpp

+ 42 - 32
include/bgfx.h

@@ -243,6 +243,26 @@ namespace bgfx
 		};
 	};
 
+	struct UniformType
+	{
+		enum Enum
+		{
+			Uniform1i,
+			Uniform1f,
+			End,
+
+			Uniform1iv,
+			Uniform1fv,
+			Uniform2fv,
+			Uniform3fv,
+			Uniform4fv,
+			Uniform3x3fv,
+			Uniform4x4fv,
+
+			Count
+		};
+	};
+
 	static const uint16_t invalidHandle = UINT16_MAX;
 
 	BGFX_HANDLE(DynamicIndexBufferHandle);
@@ -257,6 +277,11 @@ namespace bgfx
 	BGFX_HANDLE(VertexDeclHandle);
 	BGFX_HANDLE(VertexShaderHandle);
 
+	typedef void (*FatalFn)(Fatal::Enum _code, const char* _str);
+	typedef void* (*ReallocFn)(void* _ptr, size_t _size);
+	typedef void (*FreeFn)(void* _ptr);
+	typedef void (*CacheFn)(uint64_t _id, bool _store, void* _data, uint32_t& _length);
+
 	struct Memory
 	{
 		uint8_t* data;
@@ -291,31 +316,14 @@ namespace bgfx
 		VertexBufferHandle handle;
 	};
 
-	struct UniformType
+	struct TextureInfo
 	{
-		enum Enum
-		{
-			Uniform1i,
-			Uniform1f,
-			End,
-
-			Uniform1iv,
-			Uniform1fv,
-			Uniform2fv,
-			Uniform3fv,
-			Uniform4fv,
-			Uniform3x3fv,
-			Uniform4x4fv,
-
-			Count
-		};
+		TextureFormat::Enum format;
+		uint16_t width;
+		uint16_t height;
+		uint16_t depth;
 	};
 
-	typedef void (*FatalFn)(Fatal::Enum _code, const char* _str);
-	typedef void* (*ReallocFn)(void* _ptr, size_t _size);
-	typedef void (*FreeFn)(void* _ptr);
-	typedef void (*CacheFn)(uint64_t _id, bool _store, void* _data, uint32_t& _length);
-
 	struct VertexDecl
 	{
 		/// Start VertexDecl.
@@ -432,13 +440,13 @@ namespace bgfx
 	///
 	void destroyDynamicVertexBuffer(DynamicVertexBufferHandle _handle);
 
-	///
+	/// Returns true if internal transient index buffer has enough space.
 	bool checkAvailTransientIndexBuffer(uint16_t _num);
 
 	///
 	const TransientIndexBuffer* allocTransientIndexBuffer(uint16_t _num);
 
-	///
+	/// Returns true if internal transient vertex buffer has enough space.
 	bool checkAvailTransientVertexBuffer(uint16_t _num, const VertexDecl& _decl);
 
 	///
@@ -447,26 +455,28 @@ namespace bgfx
 	///
 	const InstanceDataBuffer* allocInstanceDataBuffer(uint16_t _num, uint16_t _stride);
 
-	///
+	/// Create vertex shader from memory buffer.
 	VertexShaderHandle createVertexShader(const Memory* _mem);
 
-	///
+	/// Destroy vertex shader. Once program is created with vertex shader
+	/// it is safe to destroy vertex shader.
 	void destroyVertexShader(VertexShaderHandle _handle);
 
-	///
+	/// Create fragment shader from memory buffer.
 	FragmentShaderHandle createFragmentShader(const Memory* _mem);
 
-	///
+	/// Destroy fragment shader. Once program is created with fragment shader
+	/// it is safe to destroy fragment shader.
 	void destroyFragmentShader(FragmentShaderHandle _handle);
 
-	///
+	/// Create program with vertex and fragment shaders.
 	ProgramHandle createProgram(VertexShaderHandle _vsh, FragmentShaderHandle _fsh);
 
-	///
+	/// Destroy program.
 	void destroyProgram(ProgramHandle _handle);
 
-	///
-	TextureHandle createTexture(const Memory* _mem, uint32_t _flags = BGFX_TEXTURE_NONE, uint16_t* _width = NULL, uint16_t* _height = NULL);
+	/// Create texture from memory buffer.
+	TextureHandle createTexture(const Memory* _mem, uint32_t _flags = BGFX_TEXTURE_NONE, TextureInfo* _info = NULL);
 
 	///
 	TextureHandle createTexture2D(uint16_t _width, uint16_t _height, uint8_t _numMips, TextureFormat::Enum _format, uint32_t _flags = BGFX_TEXTURE_NONE, const Memory* _mem = NULL);

+ 39 - 39
src/bgfx.cpp

@@ -979,79 +979,79 @@ namespace bgfx
 		s_ctx.destroyProgram(_handle);
 	}
 
-	TextureHandle createTexture(const Memory* _mem, uint32_t _flags, uint16_t* _width, uint16_t* _height)
+	TextureHandle createTexture(const Memory* _mem, uint32_t _flags, TextureInfo* _info)
 	{
 		BX_CHECK(NULL != _mem, "_mem can't be NULL");
-		return s_ctx.createTexture(_mem, _flags, _width, _height);
+		return s_ctx.createTexture(_mem, _flags, _info);
 	}
 
 	TextureHandle createTexture2D(uint16_t _width, uint16_t _height, uint8_t _numMips, TextureFormat::Enum _format, uint32_t _flags, const Memory* _mem)
 	{
-		uint32_t size = sizeof(uint32_t)+sizeof(TextureInfo);
+		uint32_t size = sizeof(uint32_t)+sizeof(TextureCreate);
 		const bgfx::Memory* mem = alloc(size);
 
 		StreamWrite stream(mem->data, mem->size);
 		uint32_t magic = BGFX_MAGIC;
 		stream.write(magic);
 
-		TextureInfo ti;
-		ti.m_flags = _flags;
-		ti.m_width = _width;
-		ti.m_height = _height;
-		ti.m_depth = 0;
-		ti.m_numMips = _numMips;
-		ti.m_type = uint8_t(_format);
-		ti.m_cubeMap = false;
-		ti.m_mem = _mem;
-		stream.write(ti);
+		TextureCreate tc;
+		tc.m_flags = _flags;
+		tc.m_width = _width;
+		tc.m_height = _height;
+		tc.m_depth = 0;
+		tc.m_numMips = _numMips;
+		tc.m_type = uint8_t(_format);
+		tc.m_cubeMap = false;
+		tc.m_mem = _mem;
+		stream.write(tc);
 
-		return s_ctx.createTexture(mem, _flags, NULL, NULL);
+		return s_ctx.createTexture(mem, _flags, NULL);
 	}
 
 	TextureHandle createTexture3D(uint16_t _width, uint16_t _height, uint16_t _depth, uint8_t _numMips, TextureFormat::Enum _format, uint32_t _flags, const Memory* _mem)
 	{
-		uint32_t size = sizeof(uint32_t)+sizeof(TextureInfo);
+		uint32_t size = sizeof(uint32_t)+sizeof(TextureCreate);
 		const bgfx::Memory* mem = alloc(size);
 
 		StreamWrite stream(mem->data, mem->size);
 		uint32_t magic = BGFX_MAGIC;
 		stream.write(magic);
 
-		TextureInfo ti;
-		ti.m_flags = _flags;
-		ti.m_width = _width;
-		ti.m_height = _height;
-		ti.m_depth = _depth;
-		ti.m_numMips = _numMips;
-		ti.m_type = uint8_t(_format);
-		ti.m_cubeMap = false;
-		ti.m_mem = _mem;
-		stream.write(ti);
+		TextureCreate tc;
+		tc.m_flags = _flags;
+		tc.m_width = _width;
+		tc.m_height = _height;
+		tc.m_depth = _depth;
+		tc.m_numMips = _numMips;
+		tc.m_type = uint8_t(_format);
+		tc.m_cubeMap = false;
+		tc.m_mem = _mem;
+		stream.write(tc);
 
-		return s_ctx.createTexture(mem, _flags, NULL, NULL);
+		return s_ctx.createTexture(mem, _flags, NULL);
 	}
 
 	TextureHandle createTextureCube(uint16_t _sides, uint16_t _width, uint8_t _numMips, TextureFormat::Enum _format, uint32_t _flags, const Memory* _mem)
 	{
-		uint32_t size = sizeof(uint32_t)+sizeof(TextureInfo);
+		uint32_t size = sizeof(uint32_t)+sizeof(TextureCreate);
 		const bgfx::Memory* mem = alloc(size);
 
 		StreamWrite stream(mem->data, mem->size);
 		uint32_t magic = BGFX_MAGIC;
 		stream.write(magic);
 
-		TextureInfo ti;
-		ti.m_flags = _flags;
-		ti.m_width = _width;
-		ti.m_sides = _sides;
-		ti.m_depth = 0;
-		ti.m_numMips = _numMips;
-		ti.m_type = uint8_t(_format);
-		ti.m_cubeMap = true;
-		ti.m_mem = _mem;
-		stream.write(ti);
-
-		return s_ctx.createTexture(mem, _flags, NULL, NULL);
+		TextureCreate tc;
+		tc.m_flags = _flags;
+		tc.m_width = _width;
+		tc.m_sides = _sides;
+		tc.m_depth = 0;
+		tc.m_numMips = _numMips;
+		tc.m_type = uint8_t(_format);
+		tc.m_cubeMap = true;
+		tc.m_mem = _mem;
+		stream.write(tc);
+
+		return s_ctx.createTexture(mem, _flags, NULL);
 	}
 
 	void destroyTexture(TextureHandle _handle)

+ 12 - 17
src/bgfx_p.h

@@ -163,7 +163,7 @@ namespace bgfx
 		uint16_t m_height;
 	};
 
-	struct TextureInfo
+	struct TextureCreate
 	{
 		uint32_t m_flags;
 		uint16_t m_width;
@@ -2014,29 +2014,24 @@ namespace bgfx
 			fragmentShaderDecRef(m_programRef[_handle.idx].m_fsh);
 		}
 
-		TextureHandle createTexture(const Memory* _mem, uint32_t _flags, uint16_t* _width, uint16_t* _height)
+		TextureHandle createTexture(const Memory* _mem, uint32_t _flags, TextureInfo* _info = NULL)
 		{
-			if (NULL != _width
-			||  NULL != _height)
+			if (NULL != _info)
 			{
-				int width = 0;
-				int height = 0;
-
 				Dds dds;
 				if (parseDds(dds, _mem) )
 				{
-					width = dds.m_width;
-					height = dds.m_height;
-				}
-
-				if (NULL != _width)
-				{
-					*_width = (uint16_t)width;
+					_info->format = dds.m_type;
+					_info->width = (uint16_t)dds.m_width;
+					_info->height = (uint16_t)dds.m_height;
+					_info->depth = (uint16_t)dds.m_depth;
 				}
-
-				if (NULL != _height)
+				else
 				{
-					*_height = (uint16_t)height;
+					_info->format = TextureFormat::Unknown;
+					_info->width = 0;
+					_info->height = 0;
+					_info->depth = 0;
 				}
 			}
 

+ 22 - 19
src/renderer_d3d11.cpp

@@ -1362,40 +1362,42 @@ namespace bgfx
 
 			if (BGFX_MAGIC == magic)
 			{
-				TextureInfo ti;
-				stream.read(ti);
+				TextureCreate tc;
+				stream.read(tc);
 
 				D3D11_TEXTURE2D_DESC desc;
-				desc.Width = ti.m_width;
-				desc.Height = ti.m_height;
-				desc.MipLevels = ti.m_numMips;
+				desc.Width = tc.m_width;
+				desc.Height = tc.m_height;
+				desc.MipLevels = tc.m_numMips;
 				desc.ArraySize = 1;
-				desc.Format = s_textureFormat[ti.m_type].m_fmt;
+				desc.Format = s_textureFormat[tc.m_type].m_fmt;
 				desc.SampleDesc.Count = 1;
 				desc.SampleDesc.Quality = 0;
 				desc.BindFlags = D3D11_BIND_SHADER_RESOURCE;
 				desc.CPUAccessFlags = 0;
 				desc.MiscFlags = 0;
 
-				m_numMips = ti.m_numMips;
+				m_numMips = tc.m_numMips;
 
-				if (NULL != ti.m_mem)
+				if (NULL != tc.m_mem)
 				{
 					desc.Usage = D3D11_USAGE_IMMUTABLE;
 
-					D3D11_SUBRESOURCE_DATA* srd = (D3D11_SUBRESOURCE_DATA*)alloca(ti.m_numMips*sizeof(D3D11_SUBRESOURCE_DATA) );
-					uint32_t bpp = s_textureFormat[ti.m_type].m_bpp;
-					uint8_t* data = ti.m_mem->data;
+					D3D11_SUBRESOURCE_DATA* srd = (D3D11_SUBRESOURCE_DATA*)alloca(tc.m_numMips*sizeof(D3D11_SUBRESOURCE_DATA) );
+					uint32_t bpp = s_textureFormat[tc.m_type].m_bpp;
+					uint8_t* data = tc.m_mem->data;
 
-					for (uint8_t side = 0, numSides = ti.m_cubeMap ? 6 : 1; side < numSides; ++side)
+					for (uint8_t side = 0, numSides = tc.m_cubeMap ? 6 : 1; side < numSides; ++side)
 					{
-						uint32_t width = ti.m_width;
-						uint32_t height = ti.m_height;
+						uint32_t width = tc.m_width;
+						uint32_t height = tc.m_height;
+						uint32_t depth = tc.m_depth;
 
-						for (uint32_t lod = 0, num = ti.m_numMips; lod < num; ++lod)
+						for (uint32_t lod = 0, num = tc.m_numMips; lod < num; ++lod)
 						{
-							width = uint32_max(width, 1);
-							height = uint32_max(height, 1);
+							width = uint32_max(1, width);
+							height = uint32_max(1, height);
+							depth = uint32_max(1, depth);
 
 							srd[lod].pSysMem = data;
 							srd[lod].SysMemPitch = width*bpp;
@@ -1405,12 +1407,13 @@ namespace bgfx
 
 							width >>= 1;
 							height >>= 1;
+							depth >>= 1;
 						}
 					}
 
 					DX_CHECK(s_renderCtx.m_device->CreateTexture2D(&desc, srd, &m_texture2d) );
 
-					release(ti.m_mem);
+					release(tc.m_mem);
 				}
 				else
 				{
@@ -1422,7 +1425,7 @@ namespace bgfx
 				D3D11_SHADER_RESOURCE_VIEW_DESC srv;
 				memset(&srv, 0, sizeof(srv) );
 				srv.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2D;
-				srv.Texture2D.MipLevels = ti.m_numMips;
+				srv.Texture2D.MipLevels = tc.m_numMips;
 				DX_CHECK(s_renderCtx.m_device->CreateShaderResourceView(m_ptr, &srv, &m_srv) );
 			}
 			else

+ 20 - 17
src/renderer_d3d9.cpp

@@ -1285,36 +1285,38 @@ namespace bgfx
 
 			if (BGFX_MAGIC == magic)
 			{
-				TextureInfo ti;
-				stream.read(ti);
+				TextureCreate tc;
+				stream.read(tc);
 
-				if (ti.m_cubeMap)
+				if (tc.m_cubeMap)
 				{
-					createCubeTexture(ti.m_width, ti.m_numMips, s_textureFormat[ti.m_type].m_fmt);
+					createCubeTexture(tc.m_width, tc.m_numMips, s_textureFormat[tc.m_type].m_fmt);
 				}
-				else if (ti.m_depth > 1)
+				else if (tc.m_depth > 1)
 				{
-					createVolumeTexture(ti.m_width, ti.m_height, ti.m_depth, ti.m_numMips, s_textureFormat[ti.m_type].m_fmt);
+					createVolumeTexture(tc.m_width, tc.m_height, tc.m_depth, tc.m_numMips, s_textureFormat[tc.m_type].m_fmt);
 				}
 				else
 				{
-					createTexture(ti.m_width, ti.m_height, ti.m_numMips, s_textureFormat[ti.m_type].m_fmt);
+					createTexture(tc.m_width, tc.m_height, tc.m_numMips, s_textureFormat[tc.m_type].m_fmt);
 				}
 
-				if (NULL != ti.m_mem)
+				if (NULL != tc.m_mem)
 				{
-					uint32_t bpp = s_textureFormat[ti.m_type].m_bpp;
-					uint8_t* data = ti.m_mem->data;
+					uint32_t bpp = s_textureFormat[tc.m_type].m_bpp;
+					uint8_t* data = tc.m_mem->data;
 
-					for (uint8_t side = 0, numSides = ti.m_cubeMap ? 6 : 1; side < numSides; ++side)
+					for (uint8_t side = 0, numSides = tc.m_cubeMap ? 6 : 1; side < numSides; ++side)
 					{
-						uint32_t width = ti.m_width;
-						uint32_t height = ti.m_height;
+						uint32_t width = tc.m_width;
+						uint32_t height = tc.m_height;
+						uint32_t depth = tc.m_depth;
 
-						for (uint32_t lod = 0, num = ti.m_numMips; lod < num; ++lod)
+						for (uint32_t lod = 0, num = tc.m_numMips; lod < num; ++lod)
 						{
-							width = uint32_max(width, 1);
-							height = uint32_max(height, 1);
+							width = uint32_max(1, width);
+							height = uint32_max(1, height);
+							depth = uint32_max(1, depth);
 
 							uint32_t pitch;
 							uint32_t slicePitch;
@@ -1326,10 +1328,11 @@ namespace bgfx
 
 							width >>= 1;
 							height >>= 1;
+							depth >>= 1;
 						}
 					}
 
-					release(ti.m_mem);
+					release(tc.m_mem);
 				}
 			}
 			else

+ 138 - 86
src/renderer_gl.cpp

@@ -1158,6 +1158,72 @@ namespace bgfx
 		}
 	}
 
+	static void texImage(GLenum _target, GLint _level, GLint _internalFormat, GLsizei _width, GLsizei _height, GLsizei _depth, GLint _border, GLenum _format, GLenum _type, const GLvoid* _pixels)
+	{
+#if BGFX_CONFIG_RENDERER_OPENGL|BGFX_CONFIG_RENDERER_OPENGLES3
+		if (_target == GL_TEXTURE_3D)
+		{
+			GL_CHECK(glTexImage3D(_target
+				, _level
+				, _internalFormat
+				, _width
+				, _height
+				, _depth
+				, _border
+				, _format
+				, _type
+				, _pixels
+				) );
+		}
+		else
+#endif // BGFX_CONFIG_RENDERER_OPENGL|BGFX_CONFIG_RENDERER_OPENGLES3
+		{
+			BX_UNUSED(_depth);
+			GL_CHECK(glTexImage2D(_target
+				, _level
+				, _internalFormat
+				, _width
+				, _height
+				, _border
+				, _format
+				, _type
+				, _pixels
+				) );
+		}
+	}
+
+	static void compressedTexImage(GLenum _target, GLint _level, GLenum _internalformat, GLsizei _width, GLsizei _height, GLsizei _depth, GLint _border, GLsizei _imageSize, const GLvoid* _data)
+	{
+#if BGFX_CONFIG_RENDERER_OPENGL|BGFX_CONFIG_RENDERER_OPENGLES3
+		if (_target == GL_TEXTURE_3D)
+		{
+			GL_CHECK(glCompressedTexImage3D(_target
+				, _level
+				, _internalformat
+				, _width
+				, _height
+				, _depth
+				, _border
+				, _imageSize
+				, _data
+				) );
+		}
+		else
+#endif // BGFX_CONFIG_RENDERER_OPENGL|BGFX_CONFIG_RENDERER_OPENGLES3
+		{
+			BX_UNUSED(_depth);
+			GL_CHECK(glCompressedTexImage2D(_target
+				, _level
+				, _internalformat
+				, _width
+				, _height
+				, _border
+				, _imageSize
+				, _data
+				) );
+		}
+	}
+
 	void Texture::create(const Memory* _mem, uint32_t _flags)
 	{
 		Dds dds;
@@ -1171,12 +1237,12 @@ namespace bgfx
 			{
 				m_target = GL_TEXTURE_CUBE_MAP;
 			}
-#if BGFX_CONFIG_RENDERER_OPENGL
+#if BGFX_CONFIG_RENDERER_OPENGL|BGFX_CONFIG_RENDERER_OPENGLES3
 			else if (dds.m_depth > 1)
 			{
 				m_target = GL_TEXTURE_3D;
 			}
-#endif // BGFX_CONFIG_RENDERER_OPENGL
+#endif // BGFX_CONFIG_RENDERER_OPENGL|BGFX_CONFIG_RENDERER_OPENGLES3
 			else
 			{
 				m_target = GL_TEXTURE_2D;
@@ -1250,35 +1316,17 @@ namespace bgfx
 								}
 							}
 
-#if BGFX_CONFIG_RENDERER_OPENGL
-							if (target == GL_TEXTURE_3D)
-							{
-								GL_CHECK(glTexImage3D(target
-									, lod
-									, internalFmt
-									, width
-									, height
-									, depth
-									, 0
-									, m_fmt
-									, m_type
-									, bits
-									) );
-							}
-							else
-#endif // BGFX_CONFIG_RENDERER_OPENGL
-							{
-								GL_CHECK(glTexImage2D(target+side
-									, lod
-									, internalFmt
-									, width
-									, height
-									, 0
-									, m_fmt
-									, m_type
-									, bits
-									) );
-							}
+							texImage(target+side
+								, lod
+								, internalFmt
+								, width
+								, height
+								, depth
+								, 0
+								, m_fmt
+								, m_type
+								, bits
+								);
 						}
 
 						width >>= 1;
@@ -1306,33 +1354,16 @@ namespace bgfx
 						Mip mip;
 						if (getRawImageData(dds, side, ii, _mem, mip) )
 						{
-#if BGFX_CONFIG_RENDERER_OPENGL
-							if (m_target == GL_TEXTURE_3D)
-							{
-								GL_CHECK(glCompressedTexImage3D(target
-									, ii
-									, internalFmt
-									, width
-									, height
-									, depth
-									, 0
-									, mip.m_size
-									, mip.m_data
-									) );
-							}
-							else
-#endif // BGFX_CONFIG_RENDERER_OPENGL
-							{
-								GL_CHECK(glCompressedTexImage2D(target+side
-									, ii
-									, internalFmt
-									, width
-									, height
-									, 0
-									, mip.m_size
-									, mip.m_data
-									) );
-							}
+							compressedTexImage(target+side
+								, ii
+								, internalFmt
+								, width
+								, height
+								, depth
+								, 0
+								, mip.m_size
+								, mip.m_data
+								);
 						}
 
 						width >>= 1;
@@ -1341,15 +1372,9 @@ namespace bgfx
 					}
 				}
 			}
-
 		}
 		else
 		{
-			m_target = GL_TEXTURE_2D;
-			GL_CHECK(glGenTextures(1, &m_id) );
-			BX_CHECK(0 != m_id, "Failed to generate texture id.");
-			GL_CHECK(glBindTexture(m_target, m_id) );
-
 			StreamRead stream(_mem->data, _mem->size);
 
 			uint32_t magic;
@@ -1357,37 +1382,63 @@ namespace bgfx
 
 			if (BGFX_MAGIC == magic)
 			{
-				TextureInfo ti;
-				stream.read(ti);
+				TextureCreate tc;
+				stream.read(tc);
+
+				if (tc.m_cubeMap)
+				{
+					m_target = GL_TEXTURE_CUBE_MAP;
+				}
+				else if (tc.m_depth > 1)
+				{
+					m_target = GL_TEXTURE_3D;
+				}
+				else
+				{
+					m_target = GL_TEXTURE_2D;
+				}
 
-				const TextureFormatInfo& tfi = s_textureFormat[ti.m_type];
+				GL_CHECK(glGenTextures(1, &m_id) );
+				BX_CHECK(0 != m_id, "Failed to generate texture id.");
+				GL_CHECK(glBindTexture(m_target, m_id) );
+
+				const TextureFormatInfo& tfi = s_textureFormat[tc.m_type];
 				GLenum internalFmt = tfi.m_internalFmt;
 				m_fmt = tfi.m_fmt;
 				m_type = tfi.m_type;
 
-				uint32_t bpp = s_textureFormat[ti.m_type].m_bpp;
-				uint8_t* data = NULL != ti.m_mem ? ti.m_mem->data : NULL;
+				GLenum target = m_target;
+				if (tc.m_cubeMap)
+				{
+					target = GL_TEXTURE_CUBE_MAP_POSITIVE_X;
+				}
+
+				uint32_t bpp = s_textureFormat[tc.m_type].m_bpp;
+				uint8_t* data = NULL != tc.m_mem ? tc.m_mem->data : NULL;
 
-				for (uint8_t side = 0, numSides = ti.m_cubeMap ? 6 : 1; side < numSides; ++side)
+				for (uint8_t side = 0, numSides = tc.m_cubeMap ? 6 : 1; side < numSides; ++side)
 				{
-					uint32_t width = ti.m_width;
-					uint32_t height = ti.m_height;
+					uint32_t width = tc.m_width;
+					uint32_t height = tc.m_height;
+					uint32_t depth = tc.m_depth;
 
-					for (uint32_t lod = 0, num = ti.m_numMips; lod < num; ++lod)
+					for (uint32_t lod = 0, num = tc.m_numMips; lod < num; ++lod)
 					{
 						width = uint32_max(width, 1);
 						height = uint32_max(height, 1);
-
-						GL_CHECK(glTexImage2D(m_target
-							, lod
-							, internalFmt
-							, width
-							, height
-							, 0
-							, m_fmt
-							, m_type
-							, data
-							) );
+						depth = uint32_max(1, depth);
+
+						texImage(target+side
+							, lod
+							, internalFmt
+							, width
+							, height
+							, depth
+							, 0
+							, m_fmt
+							, m_type
+							, data
+							);
 
 						if (NULL != data)
 						{
@@ -1396,12 +1447,13 @@ namespace bgfx
 
 						width >>= 1;
 						height >>= 1;
+						depth >>= 1;
 					}
 				}
 
-				if (NULL != ti.m_mem)
+				if (NULL != tc.m_mem)
 				{
-					release(ti.m_mem);
+					release(tc.m_mem);
 				}
 			}
 			else

+ 4 - 4
src/renderer_null.cpp

@@ -114,12 +114,12 @@ namespace bgfx
 
 		if (BGFX_MAGIC == magic)
 		{
-			TextureInfo ti;
-			stream.read(ti);
+			TextureCreate tc;
+			stream.read(tc);
 
-			if (NULL != ti.m_mem)
+			if (NULL != tc.m_mem)
 			{
-				release(ti.m_mem);
+				release(tc.m_mem);
 			}
 		}
 	}