From 753b9fdd158268734340fdb7d44506807d2b8e5e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Branimir=20Karad=C5=BEi=C4=87?= Date: Wed, 19 Feb 2014 22:34:53 -0800 Subject: [PATCH] Added ability to skip top level mips when parsing texture format. --- include/bgfx.h | 3 ++- src/bgfx.cpp | 9 ++++++--- src/bgfx_p.h | 7 +++++-- src/renderer_d3d11.cpp | 42 ++++++++++++++++++++++++------------------ src/renderer_d3d11.h | 2 +- src/renderer_d3d9.cpp | 26 ++++++++++++++++---------- src/renderer_d3d9.h | 2 +- src/renderer_gl.cpp | 22 +++++++++++++--------- src/renderer_gl.h | 2 +- src/renderer_null.cpp | 2 +- 10 files changed, 70 insertions(+), 47 deletions(-) diff --git a/include/bgfx.h b/include/bgfx.h index c413f28a..4c4ca056 100644 --- a/include/bgfx.h +++ b/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. /// diff --git a/src/bgfx.cpp b/src/bgfx.cpp index bf1b1bee..a9f17e30 100644 --- a/src/bgfx.cpp +++ b/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) diff --git a/src/bgfx_p.h b/src/bgfx_p.h index 4eabe859..e7b5fea6 100644 --- a/src/bgfx_p.h +++ b/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(); diff --git a/src/renderer_d3d11.cpp b/src/renderer_d3d11.cpp index a3abd764..babc0a6b 100644 --- a/src/renderer_d3d11.cpp +++ b/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(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*/) diff --git a/src/renderer_d3d11.h b/src/renderer_d3d11.h index 8681c452..0aec6ea2 100644 --- a/src/renderer_d3d11.h +++ b/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); diff --git a/src/renderer_d3d9.cpp b/src/renderer_d3d9.cpp index d0ae6da5..d321eb51 100644 --- a/src/renderer_d3d9.cpp +++ b/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) diff --git a/src/renderer_d3d9.h b/src/renderer_d3d9.h index bd7eec19..7337c798 100644 --- a/src/renderer_d3d9.h +++ b/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() { diff --git a/src/renderer_gl.cpp b/src/renderer_gl.cpp index 2a19fcd9..c076477c 100644 --- a/src/renderer_gl.cpp +++ b/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*/) diff --git a/src/renderer_gl.h b/src/renderer_gl.h index e45b120b..6eedff52 100644 --- a/src/renderer_gl.h +++ b/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); diff --git a/src/renderer_null.cpp b/src/renderer_null.cpp index 5e6078cc..43e99122 100644 --- a/src/renderer_null.cpp +++ b/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*/) { }