Explorar el Código

Added ability to skip top level mips when parsing texture format.

Branimir Karadžić hace 12 años
padre
commit
753b9fdd15
Se han modificado 10 ficheros con 70 adiciones y 47 borrados
  1. 2 1
      include/bgfx.h
  2. 6 3
      src/bgfx.cpp
  3. 5 2
      src/bgfx_p.h
  4. 24 18
      src/renderer_d3d11.cpp
  5. 1 1
      src/renderer_d3d11.h
  6. 16 10
      src/renderer_d3d9.cpp
  7. 1 1
      src/renderer_d3d9.h
  8. 13 9
      src/renderer_gl.cpp
  9. 1 1
      src/renderer_gl.h
  10. 1 1
      src/renderer_null.cpp

+ 2 - 1
include/bgfx.h

@@ -860,10 +860,11 @@ namespace bgfx
 	///   BGFX_TEXTURE_[MIN/MAG/MIP]_[POINT/ANISOTROPIC] - Point or anisotropic
 	///     sampling.
 	///
+	/// @param _skip Skip top level mips when parsing texture.
 	/// @param _info Returns parsed DDS texture information.
 	/// @returns Texture handle.
 	///
-	TextureHandle createTexture(const Memory* _mem, uint32_t _flags = BGFX_TEXTURE_NONE, TextureInfo* _info = NULL);
+	TextureHandle createTexture(const Memory* _mem, uint32_t _flags = BGFX_TEXTURE_NONE, uint8_t _skip = 0, TextureInfo* _info = NULL);
 
 	/// Create 2D texture.
 	///

+ 6 - 3
src/bgfx.cpp

@@ -1492,7 +1492,10 @@ namespace bgfx
 					uint32_t flags;
 					_cmdbuf.read(flags);
 
-					rendererCreateTexture(handle, mem, flags);
+					uint8_t skip;
+					_cmdbuf.read(skip);
+
+					rendererCreateTexture(handle, mem, flags, skip);
 
 					bx::MemoryReader reader(mem->data, mem->size);
 
@@ -1909,11 +1912,11 @@ namespace bgfx
 		_info.bitsPerPixel = bpp;
 	}
 
-	TextureHandle createTexture(const Memory* _mem, uint32_t _flags, TextureInfo* _info)
+	TextureHandle createTexture(const Memory* _mem, uint32_t _flags, uint8_t _skip, TextureInfo* _info)
 	{
 		BGFX_CHECK_MAIN_THREAD();
 		BX_CHECK(NULL != _mem, "_mem can't be NULL");
-		return s_ctx->createTexture(_mem, _flags, _info);
+		return s_ctx->createTexture(_mem, _flags, _skip, _info);
 	}
 
 	TextureHandle createTexture2D(uint16_t _width, uint16_t _height, uint8_t _numMips, TextureFormat::Enum _format, uint32_t _flags, const Memory* _mem)

+ 5 - 2
src/bgfx_p.h

@@ -153,6 +153,8 @@ namespace stl
 #	define BGFX_RENDERER_NAME "OpenGL ES 2"
 #elif BGFX_CONFIG_RENDERER_OPENGLES3
 #	define BGFX_RENDERER_NAME "OpenGL ES 3"
+#else
+#	define BGFX_RENDERER_NAME "NULL"
 #endif // BGFX_CONFIG_RENDERER_
 
 namespace bgfx
@@ -2146,7 +2148,7 @@ namespace bgfx
 			fragmentShaderDecRef(m_programRef[_handle.idx].m_fsh);
 		}
 
-		BGFX_API_FUNC(TextureHandle createTexture(const Memory* _mem, uint32_t _flags, TextureInfo* _info = NULL) )
+		BGFX_API_FUNC(TextureHandle createTexture(const Memory* _mem, uint32_t _flags, uint8_t _skip, TextureInfo* _info = NULL) )
 		{
 			if (NULL != _info)
 			{
@@ -2184,6 +2186,7 @@ namespace bgfx
 				cmdbuf.write(handle);
 				cmdbuf.write(_mem);
 				cmdbuf.write(_flags);
+				cmdbuf.write(_skip);
 			}
 
 			return handle;
@@ -2635,7 +2638,7 @@ namespace bgfx
 		void rendererDestroyFragmentShader(FragmentShaderHandle _handle);
 		void rendererCreateProgram(ProgramHandle _handle, VertexShaderHandle _vsh, FragmentShaderHandle _fsh);
 		void rendererDestroyProgram(FragmentShaderHandle _handle);
-		void rendererCreateTexture(TextureHandle _handle, Memory* _mem, uint32_t _flags);
+		void rendererCreateTexture(TextureHandle _handle, Memory* _mem, uint32_t _flags, uint8_t _skip);
 		void rendererUpdateTextureBegin(TextureHandle _handle, uint8_t _side, uint8_t _mip);
 		void rendererUpdateTexture(TextureHandle _handle, uint8_t _side, uint8_t _mip, const Rect& _rect, uint16_t _z, uint16_t _depth, uint16_t _pitch, const Memory* _mem);
 		void rendererUpdateTextureEnd();

+ 24 - 18
src/renderer_d3d11.cpp

@@ -1692,7 +1692,7 @@ namespace bgfx
 		}
 	}
 
-	void Texture::create(const Memory* _mem, uint32_t _flags)
+	void Texture::create(const Memory* _mem, uint32_t _flags, uint8_t _skip)
 	{
 		m_sampler = s_renderCtx->getSamplerState(_flags);
 
@@ -1700,6 +1700,12 @@ namespace bgfx
 
 		if (imageParse(imageContainer, _mem->data, _mem->size) )
 		{
+			uint8_t numMips = imageContainer.m_numMips;
+			const uint32_t startLod = bx::uint32_min(_skip, numMips-1);
+			numMips -= startLod;
+			const uint32_t textureWidth  = bx::uint32_max(1, imageContainer.m_width >>startLod);
+			const uint32_t textureHeight = bx::uint32_max(1, imageContainer.m_height>>startLod);
+
 			m_flags = _flags;
 			m_requestedFormat = (uint8_t)imageContainer.m_format;
 			m_textureFormat   = (uint8_t)imageContainer.m_format;
@@ -1727,27 +1733,27 @@ namespace bgfx
 				m_type = Texture2D;
 			}
 
-			m_numMips = imageContainer.m_numMips;
+			m_numMips = numMips;
 
-			uint32_t numSrd = imageContainer.m_numMips*(imageContainer.m_cubeMap ? 6 : 1);
+			uint32_t numSrd = numMips*(imageContainer.m_cubeMap ? 6 : 1);
 			D3D11_SUBRESOURCE_DATA* srd = (D3D11_SUBRESOURCE_DATA*)alloca(numSrd*sizeof(D3D11_SUBRESOURCE_DATA) );
 
 			uint32_t kk = 0;
 
 			for (uint8_t side = 0, numSides = imageContainer.m_cubeMap ? 6 : 1; side < numSides; ++side)
 			{
-				uint32_t width  = imageContainer.m_width;
-				uint32_t height = imageContainer.m_height;
+				uint32_t width  = textureWidth;
+				uint32_t height = textureHeight;
 				uint32_t depth  = imageContainer.m_depth;
 
-				for (uint32_t lod = 0, num = m_numMips; lod < num; ++lod)
+				for (uint32_t lod = 0, num = numMips; lod < num; ++lod)
 				{
 					width  = bx::uint32_max(1, width);
 					height = bx::uint32_max(1, height);
 					depth  = bx::uint32_max(1, depth);
 
 					ImageMip mip;
-					if (imageGetRawData(imageContainer, side, lod, _mem->data, _mem->size, mip) )
+					if (imageGetRawData(imageContainer, side, lod+startLod, _mem->data, _mem->size, mip) )
 					{
 						srd[kk].pSysMem = mip.m_data;
 
@@ -1797,9 +1803,9 @@ namespace bgfx
 			case TextureCube:
 				{
 					D3D11_TEXTURE2D_DESC desc;
-					desc.Width = imageContainer.m_width;
-					desc.Height = imageContainer.m_height;
-					desc.MipLevels = imageContainer.m_numMips;
+					desc.Width = textureWidth;
+					desc.Height = textureHeight;
+					desc.MipLevels = numMips;
 					desc.Format = format;
 					desc.SampleDesc = msaa;
 					desc.Usage = kk == 0 ? D3D11_USAGE_DEFAULT : D3D11_USAGE_IMMUTABLE;
@@ -1822,14 +1828,14 @@ namespace bgfx
 						desc.ArraySize = 6;
 						desc.MiscFlags = D3D11_RESOURCE_MISC_TEXTURECUBE;
 						srvd.ViewDimension = D3D11_SRV_DIMENSION_TEXTURECUBE;
-						srvd.TextureCube.MipLevels = imageContainer.m_numMips;
+						srvd.TextureCube.MipLevels = numMips;
 					}
 					else
 					{
 						desc.ArraySize = 1;
 						desc.MiscFlags = 0;
 						srvd.ViewDimension = 1 < msaa.Count ? D3D11_SRV_DIMENSION_TEXTURE2DMS : D3D11_SRV_DIMENSION_TEXTURE2D;
-						srvd.Texture2D.MipLevels = imageContainer.m_numMips;
+						srvd.Texture2D.MipLevels = numMips;
 					}
 
 					DX_CHECK(s_renderCtx->m_device->CreateTexture2D(&desc, kk == 0 ? NULL : srd, &m_texture2d) );
@@ -1839,8 +1845,8 @@ namespace bgfx
 			case Texture3D:
 				{
 					D3D11_TEXTURE3D_DESC desc;
-					desc.Width = imageContainer.m_width;
-					desc.Height = imageContainer.m_height;
+					desc.Width = textureWidth;
+					desc.Height = textureHeight;
 					desc.Depth = imageContainer.m_depth;
 					desc.MipLevels = imageContainer.m_numMips;
 					desc.Format = format;
@@ -1850,7 +1856,7 @@ namespace bgfx
 					desc.MiscFlags = 0;
 
 					srvd.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE3D;
-					srvd.Texture3D.MipLevels = imageContainer.m_numMips;
+					srvd.Texture3D.MipLevels = numMips;
 
 					DX_CHECK(s_renderCtx->m_device->CreateTexture3D(&desc, kk == 0 ? NULL : srd, &m_texture3d) );
 				}
@@ -1868,7 +1874,7 @@ namespace bgfx
 				kk = 0;
 				for (uint8_t side = 0, numSides = imageContainer.m_cubeMap ? 6 : 1; side < numSides; ++side)
 				{
-					for (uint32_t lod = 0, num = imageContainer.m_numMips; lod < num; ++lod)
+					for (uint32_t lod = 0, num = numMips; lod < num; ++lod)
 					{
 						BX_FREE(g_allocator, const_cast<void*>(srd[kk].pSysMem) );
 						++kk;
@@ -2134,9 +2140,9 @@ namespace bgfx
 		s_renderCtx->m_program[_handle.idx].destroy();
 	}
 
-	void Context::rendererCreateTexture(TextureHandle _handle, Memory* _mem, uint32_t _flags)
+	void Context::rendererCreateTexture(TextureHandle _handle, Memory* _mem, uint32_t _flags, uint8_t _skip)
 	{
-		s_renderCtx->m_textures[_handle.idx].create(_mem, _flags);
+		s_renderCtx->m_textures[_handle.idx].create(_mem, _flags, _skip);
 	}
 
 	void Context::rendererUpdateTextureBegin(TextureHandle /*_handle*/, uint8_t /*_side*/, uint8_t /*_mip*/)

+ 1 - 1
src/renderer_d3d11.h

@@ -256,7 +256,7 @@ namespace bgfx
 		{
 		}
 
-		void create(const Memory* _mem, uint32_t _flags);
+		void create(const Memory* _mem, uint32_t _flags, uint8_t _skip);
 		void destroy();
 		void update(uint8_t _side, uint8_t _mip, const Rect& _rect, uint16_t _z, uint16_t _depth, uint16_t _pitch, const Memory* _mem);
 		void commit(uint8_t _stage, uint32_t _flags = BGFX_SAMPLER_DEFAULT_FLAGS);

+ 16 - 10
src/renderer_d3d9.cpp

@@ -1633,7 +1633,7 @@ namespace bgfx
 		BX_CHECK(false, "You should not be here.");
 	}
 
-	void Texture::create(const Memory* _mem, uint32_t _flags)
+	void Texture::create(const Memory* _mem, uint32_t _flags, uint8_t _skip)
 	{
 		m_flags = _flags;
 
@@ -1641,6 +1641,12 @@ namespace bgfx
 
 		if (imageParse(imageContainer, _mem->data, _mem->size) )
 		{
+			uint8_t numMips = imageContainer.m_numMips;
+			const uint32_t startLod = bx::uint32_min(_skip, numMips-1);
+			numMips -= startLod;
+			const uint32_t textureWidth  = bx::uint32_max(1, imageContainer.m_width >>startLod);
+			const uint32_t textureHeight = bx::uint32_max(1, imageContainer.m_height>>startLod);
+
 			m_requestedFormat = (uint8_t)imageContainer.m_format;
 			m_textureFormat   = (uint8_t)imageContainer.m_format;
 
@@ -1656,15 +1662,15 @@ namespace bgfx
 
 			if (imageContainer.m_cubeMap)
 			{
-				createCubeTexture(imageContainer.m_width, imageContainer.m_numMips);
+				createCubeTexture(textureWidth, numMips);
 			}
 			else if (imageContainer.m_depth > 1)
 			{
-				createVolumeTexture(imageContainer.m_width, imageContainer.m_height, imageContainer.m_depth, imageContainer.m_numMips);
+				createVolumeTexture(textureWidth, textureHeight, imageContainer.m_depth, numMips);
 			}
 			else
 			{
-				createTexture(imageContainer.m_width, imageContainer.m_height, imageContainer.m_numMips);
+				createTexture(textureWidth, textureHeight, numMips);
 			}
 
 			if (0 != (_flags&BGFX_TEXTURE_RT_BUFFER_ONLY) )
@@ -1685,13 +1691,13 @@ namespace bgfx
 
 			for (uint8_t side = 0, numSides = imageContainer.m_cubeMap ? 6 : 1; side < numSides; ++side)
 			{
-				uint32_t width     = imageContainer.m_width;
-				uint32_t height    = imageContainer.m_height;
+				uint32_t width     = textureWidth;
+				uint32_t height    = textureHeight;
 				uint32_t depth     = imageContainer.m_depth;
 				uint32_t mipWidth  = imageContainer.m_width;
 				uint32_t mipHeight = imageContainer.m_height;
 
-				for (uint32_t lod = 0, num = imageContainer.m_numMips; lod < num; ++lod)
+				for (uint32_t lod = 0, num = numMips; lod < num; ++lod)
 				{
 					width     = bx::uint32_max(1, width);
 					height    = bx::uint32_max(1, height);
@@ -1701,7 +1707,7 @@ namespace bgfx
 					uint32_t mipSize = width*height*depth*bpp/8;
 
 					ImageMip mip;
-					if (imageGetRawData(imageContainer, side, lod, _mem->data, _mem->size, mip) )
+					if (imageGetRawData(imageContainer, side, lod+startLod, _mem->data, _mem->size, mip) )
 					{
 						uint32_t pitch;
 						uint32_t slicePitch;
@@ -2232,9 +2238,9 @@ namespace bgfx
 		s_renderCtx->m_program[_handle.idx].destroy();
 	}
 
-	void Context::rendererCreateTexture(TextureHandle _handle, Memory* _mem, uint32_t _flags)
+	void Context::rendererCreateTexture(TextureHandle _handle, Memory* _mem, uint32_t _flags, uint8_t _skip)
 	{
-		s_renderCtx->m_textures[_handle.idx].create(_mem, _flags);
+		s_renderCtx->m_textures[_handle.idx].create(_mem, _flags, _skip);
 	}
 
 	void Context::rendererUpdateTextureBegin(TextureHandle _handle, uint8_t _side, uint8_t _mip)

+ 1 - 1
src/renderer_d3d9.h

@@ -311,7 +311,7 @@ namespace bgfx
 		void unlock(uint8_t _side, uint8_t _lod);
 		void dirty(uint8_t _side, const Rect& _rect, uint16_t _z, uint16_t _depth);
 
-		void create(const Memory* _mem, uint32_t _flags);
+		void create(const Memory* _mem, uint32_t _flags, uint8_t _skip);
 
 		void destroy()
 		{

+ 13 - 9
src/renderer_gl.cpp

@@ -1499,13 +1499,17 @@ namespace bgfx
 		return true;
 	}
 
-	void Texture::create(const Memory* _mem, uint32_t _flags)
+	void Texture::create(const Memory* _mem, uint32_t _flags, uint8_t _skip)
 	{
 		ImageContainer imageContainer;
 
 		if (imageParse(imageContainer, _mem->data, _mem->size) )
 		{
 			uint8_t numMips = imageContainer.m_numMips;
+			const uint32_t startLod = bx::uint32_min(_skip, numMips-1);
+			numMips -= startLod;
+			const uint32_t textureWidth  = bx::uint32_max(1, imageContainer.m_width >>startLod);
+			const uint32_t textureHeight = bx::uint32_max(1, imageContainer.m_height>>startLod);
 
 			GLenum target = GL_TEXTURE_2D;
 			if (imageContainer.m_cubeMap)
@@ -1518,8 +1522,8 @@ namespace bgfx
 			}
 
 			if (!init(target
-					, imageContainer.m_width
-					, imageContainer.m_height
+					, textureWidth
+					, textureHeight
 					, imageContainer.m_format
 					, numMips
 					, _flags
@@ -1552,13 +1556,13 @@ namespace bgfx
 			uint8_t* temp = NULL;
 			if (convert || swizzle)
 			{
-				temp = (uint8_t*)BX_ALLOC(g_allocator, imageContainer.m_width*imageContainer.m_height*4);
+				temp = (uint8_t*)BX_ALLOC(g_allocator, textureWidth*textureHeight*4);
 			}
 
 			for (uint8_t side = 0, numSides = imageContainer.m_cubeMap ? 6 : 1; side < numSides; ++side)
 			{
-				uint32_t width  = imageContainer.m_width;
-				uint32_t height = imageContainer.m_height;
+				uint32_t width  = textureWidth;
+				uint32_t height = textureHeight;
 				uint32_t depth  = imageContainer.m_depth;
 
 				for (uint32_t lod = 0, num = numMips; lod < num; ++lod)
@@ -1568,7 +1572,7 @@ namespace bgfx
 					depth  = bx::uint32_max(1, depth);
 
 					ImageMip mip;
-					if (imageGetRawData(imageContainer, side, lod, _mem->data, _mem->size, mip) )
+					if (imageGetRawData(imageContainer, side, lod+startLod, _mem->data, _mem->size, mip) )
 					{
 						if (compressed)
 						{
@@ -2962,9 +2966,9 @@ namespace bgfx
 		s_renderCtx->m_program[_handle.idx].destroy();
 	}
 
-	void Context::rendererCreateTexture(TextureHandle _handle, Memory* _mem, uint32_t _flags)
+	void Context::rendererCreateTexture(TextureHandle _handle, Memory* _mem, uint32_t _flags, uint8_t _skip)
 	{
-		s_renderCtx->m_textures[_handle.idx].create(_mem, _flags);
+		s_renderCtx->m_textures[_handle.idx].create(_mem, _flags, _skip);
 	}
 
 	void Context::rendererUpdateTextureBegin(TextureHandle /*_handle*/, uint8_t /*_side*/, uint8_t /*_mip*/)

+ 1 - 1
src/renderer_gl.h

@@ -549,7 +549,7 @@ namespace bgfx
 		}
 
 		bool init(GLenum _target, uint32_t _width, uint32_t _height, uint8_t _format, uint8_t _numMips, uint32_t _flags);
-		void create(const Memory* _mem, uint32_t _flags);
+		void create(const Memory* _mem, uint32_t _flags, uint8_t _skip);
 		void destroy();
 		void update(uint8_t _side, uint8_t _mip, const Rect& _rect, uint16_t _z, uint16_t _depth, uint16_t _pitch, const Memory* _mem);
 		void setSamplerState(uint32_t _flags);

+ 1 - 1
src/renderer_null.cpp

@@ -105,7 +105,7 @@ namespace bgfx
 	{
 	}
 
-	void Context::rendererCreateTexture(TextureHandle /*_handle*/, Memory* /*_mem*/, uint32_t /*_flags*/)
+	void Context::rendererCreateTexture(TextureHandle /*_handle*/, Memory* /*_mem*/, uint32_t /*_flags*/, uint8_t /*_skip*/)
 	{
 	}