summaryrefslogtreecommitdiffstatshomepage
path: root/3rdparty/bgfx/src/image.cpp
diff options
context:
space:
mode:
Diffstat (limited to '3rdparty/bgfx/src/image.cpp')
-rw-r--r--3rdparty/bgfx/src/image.cpp1236
1 files changed, 1138 insertions, 98 deletions
diff --git a/3rdparty/bgfx/src/image.cpp b/3rdparty/bgfx/src/image.cpp
index 69bad82e943..34dcae9e54c 100644
--- a/3rdparty/bgfx/src/image.cpp
+++ b/3rdparty/bgfx/src/image.cpp
@@ -4,8 +4,6 @@
*/
#include "bgfx_p.h"
-#include <math.h> // powf, sqrtf
-
#include "image.h"
namespace bgfx
@@ -253,7 +251,7 @@ namespace bgfx
uint8_t numMips = 0;
for (uint32_t width = _width, height = _height, depth = _depth
- ; blockWidth < width && blockHeight < height && 1 < depth
+ ; blockWidth < width || blockHeight < height || 1 < depth
; ++numMips)
{
width = bx::uint32_max(blockWidth * minBlockX, ( (width + blockWidth - 1) / blockWidth )*blockWidth);
@@ -326,7 +324,7 @@ namespace bgfx
}
}
- void imageRgba8Downsample2x2Ref(uint32_t _width, uint32_t _height, uint32_t _srcPitch, const void* _src, void* _dst)
+ void imageRgba8Downsample2x2Ref(uint32_t _width, uint32_t _height, uint32_t _pitch, const void* _src, void* _dst)
{
const uint32_t dstwidth = _width/2;
const uint32_t dstheight = _height/2;
@@ -340,35 +338,35 @@ namespace bgfx
uint8_t* dst = (uint8_t*)_dst;
const uint8_t* src = (const uint8_t*)_src;
- for (uint32_t yy = 0, ystep = _srcPitch*2; yy < dstheight; ++yy, src += ystep)
+ for (uint32_t yy = 0, ystep = _pitch*2; yy < dstheight; ++yy, src += ystep)
{
const uint8_t* rgba = src;
for (uint32_t xx = 0; xx < dstwidth; ++xx, rgba += 8, dst += 4)
{
- float rr = powf(rgba[ 0], 2.2f);
- float gg = powf(rgba[ 1], 2.2f);
- float bb = powf(rgba[ 2], 2.2f);
- float aa = rgba[ 3];
- rr += powf(rgba[ 4], 2.2f);
- gg += powf(rgba[ 5], 2.2f);
- bb += powf(rgba[ 6], 2.2f);
- aa += rgba[ 7];
- rr += powf(rgba[_srcPitch+0], 2.2f);
- gg += powf(rgba[_srcPitch+1], 2.2f);
- bb += powf(rgba[_srcPitch+2], 2.2f);
- aa += rgba[_srcPitch+3];
- rr += powf(rgba[_srcPitch+4], 2.2f);
- gg += powf(rgba[_srcPitch+5], 2.2f);
- bb += powf(rgba[_srcPitch+6], 2.2f);
- aa += rgba[_srcPitch+7];
+ float rr = bx::fpow(rgba[ 0], 2.2f);
+ float gg = bx::fpow(rgba[ 1], 2.2f);
+ float bb = bx::fpow(rgba[ 2], 2.2f);
+ float aa = rgba[ 3];
+ rr += bx::fpow(rgba[ 4], 2.2f);
+ gg += bx::fpow(rgba[ 5], 2.2f);
+ bb += bx::fpow(rgba[ 6], 2.2f);
+ aa += rgba[ 7];
+ rr += bx::fpow(rgba[_pitch+0], 2.2f);
+ gg += bx::fpow(rgba[_pitch+1], 2.2f);
+ bb += bx::fpow(rgba[_pitch+2], 2.2f);
+ aa += rgba[_pitch+3];
+ rr += bx::fpow(rgba[_pitch+4], 2.2f);
+ gg += bx::fpow(rgba[_pitch+5], 2.2f);
+ bb += bx::fpow(rgba[_pitch+6], 2.2f);
+ aa += rgba[_pitch+7];
rr *= 0.25f;
gg *= 0.25f;
bb *= 0.25f;
aa *= 0.25f;
- rr = powf(rr, 1.0f/2.2f);
- gg = powf(gg, 1.0f/2.2f);
- bb = powf(bb, 1.0f/2.2f);
+ rr = bx::fpow(rr, 1.0f/2.2f);
+ gg = bx::fpow(gg, 1.0f/2.2f);
+ bb = bx::fpow(bb, 1.0f/2.2f);
dst[0] = (uint8_t)rr;
dst[1] = (uint8_t)gg;
dst[2] = (uint8_t)bb;
@@ -377,7 +375,7 @@ namespace bgfx
}
}
- void imageRgba8Downsample2x2(uint32_t _width, uint32_t _height, uint32_t _srcPitch, const void* _src, void* _dst)
+ void imageRgba8Downsample2x2(uint32_t _width, uint32_t _height, uint32_t _pitch, const void* _src, void* _dst)
{
const uint32_t dstwidth = _width/2;
const uint32_t dstheight = _height/2;
@@ -402,15 +400,15 @@ namespace bgfx
const float4_t linear = float4_ld(2.2f, 2.2f, 2.2f, 1.0f);
const float4_t quater = float4_splat(0.25f);
- for (uint32_t yy = 0, ystep = _srcPitch*2; yy < dstheight; ++yy, src += ystep)
+ for (uint32_t yy = 0, ystep = _pitch*2; yy < dstheight; ++yy, src += ystep)
{
const uint8_t* rgba = src;
for (uint32_t xx = 0; xx < dstwidth; ++xx, rgba += 8, dst += 4)
{
const float4_t abgr0 = float4_splat(rgba);
const float4_t abgr1 = float4_splat(rgba+4);
- const float4_t abgr2 = float4_splat(rgba+_srcPitch);
- const float4_t abgr3 = float4_splat(rgba+_srcPitch+4);
+ const float4_t abgr2 = float4_splat(rgba+_pitch);
+ const float4_t abgr3 = float4_splat(rgba+_pitch+4);
const float4_t abgr0m = float4_and(abgr0, umask);
const float4_t abgr1m = float4_and(abgr1, umask);
@@ -458,13 +456,56 @@ namespace bgfx
}
}
- void imageSwizzleBgra8Ref(uint32_t _width, uint32_t _height, uint32_t _srcPitch, const void* _src, void* _dst)
+ void imageRgba32fDownsample2x2NormalMapRef(uint32_t _width, uint32_t _height, uint32_t _pitch, const void* _src, void* _dst)
+ {
+ const uint32_t dstwidth = _width/2;
+ const uint32_t dstheight = _height/2;
+
+ if (0 == dstwidth
+ || 0 == dstheight)
+ {
+ return;
+ }
+
+ const uint8_t* src = (const uint8_t*)_src;
+ uint8_t* dst = (uint8_t*)_dst;
+
+ for (uint32_t yy = 0, ystep = _pitch*2; yy < dstheight; ++yy, src += ystep)
+ {
+ const float* rgba0 = (const float*)&src[0];
+ const float* rgba1 = (const float*)&src[_pitch];
+ for (uint32_t xx = 0; xx < dstwidth; ++xx, rgba0 += 8, rgba1 += 8, dst += 16)
+ {
+ float xyz[3];
+ xyz[0] = rgba0[0];
+ xyz[1] = rgba0[1];
+ xyz[2] = rgba0[2];
+ xyz[0] += rgba0[4];
+ xyz[1] += rgba0[5];
+ xyz[2] += rgba0[6];
+ xyz[0] += rgba1[0];
+ xyz[1] += rgba1[1];
+ xyz[2] += rgba1[2];
+ xyz[0] += rgba1[4];
+ xyz[1] += rgba1[5];
+ xyz[2] += rgba1[6];
+ bx::vec3Norm( (float*)dst, xyz);
+ }
+ }
+ }
+
+ void imageRgba32fDownsample2x2NormalMap(uint32_t _width, uint32_t _height, uint32_t _pitch, const void* _src, void* _dst)
+ {
+ imageRgba32fDownsample2x2NormalMapRef(_width, _height, _pitch, _src, _dst);
+ }
+
+ void imageSwizzleBgra8Ref(uint32_t _width, uint32_t _height, uint32_t _pitch, const void* _src, void* _dst)
{
const uint8_t* src = (uint8_t*) _src;
- const uint8_t* next = src + _srcPitch;
+ const uint8_t* next = src + _pitch;
uint8_t* dst = (uint8_t*)_dst;
- for (uint32_t yy = 0; yy < _height; ++yy, src = next, next += _srcPitch)
+ for (uint32_t yy = 0; yy < _height; ++yy, src = next, next += _pitch)
{
for (uint32_t xx = 0; xx < _width; ++xx, src += 4, dst += 4)
{
@@ -480,7 +521,7 @@ namespace bgfx
}
}
- void imageSwizzleBgra8(uint32_t _width, uint32_t _height, uint32_t _srcPitch, const void* _src, void* _dst)
+ void imageSwizzleBgra8(uint32_t _width, uint32_t _height, uint32_t _pitch, const void* _src, void* _dst)
{
// Test can we do four 4-byte pixels at the time.
if (0 != (_width&0x3)
@@ -492,7 +533,7 @@ namespace bgfx
BX_WARN(bx::isPtrAligned(_src, 16), "Source %p is not 16-byte aligned.", _src);
BX_WARN(bx::isPtrAligned(_dst, 16), "Destination %p is not 16-byte aligned.", _dst);
BX_WARN(_width < 4, "Image width must be multiple of 4 (width %d).", _width);
- imageSwizzleBgra8Ref(_width, _height, _srcPitch, _src, _dst);
+ imageSwizzleBgra8Ref(_width, _height, _pitch, _src, _dst);
return;
}
@@ -501,12 +542,12 @@ namespace bgfx
const float4_t mf0f0 = float4_isplat(0xff00ff00);
const float4_t m0f0f = float4_isplat(0x00ff00ff);
const uint8_t* src = (uint8_t*) _src;
- const uint8_t* next = src + _srcPitch;
+ const uint8_t* next = src + _pitch;
uint8_t* dst = (uint8_t*)_dst;
const uint32_t width = _width/4;
- for (uint32_t yy = 0; yy < _height; ++yy, src = next, next += _srcPitch)
+ for (uint32_t yy = 0; yy < _height; ++yy, src = next, next += _pitch)
{
for (uint32_t xx = 0; xx < width; ++xx, src += 16, dst += 16)
{
@@ -534,10 +575,856 @@ namespace bgfx
}
}
- void imageCopy(uint32_t _width, uint32_t _height, uint32_t _bpp, uint32_t _srcPitch, const void* _src, void* _dst)
+ void imageCopy(uint32_t _width, uint32_t _height, uint32_t _bpp, uint32_t _pitch, const void* _src, void* _dst)
{
const uint32_t dstPitch = _width*_bpp/8;
- imageCopy(_height, _srcPitch, _src, dstPitch, _dst);
+ imageCopy(_height, _pitch, _src, dstPitch, _dst);
+ }
+
+ uint32_t toUnorm(float _value, float _scale)
+ {
+ return uint32_t(bx::fround(
+ bx::fsaturate(_value) * _scale)
+ );
+ }
+
+ float fromUnorm(uint32_t _value, float _scale)
+ {
+ return float(_value) / _scale;
+ }
+
+ int32_t toSnorm(float _value, float _scale)
+ {
+ return int32_t(bx::fround(
+ bx::fclamp(_value, -1.0f, 1.0f) * _scale)
+ );
+ }
+
+ float fromSnorm(int32_t _value, float _scale)
+ {
+ return bx::fmax(-1.0f, float(_value) / _scale);
+ }
+
+ // R8
+ void packR8(void* _dst, const float* _src)
+ {
+ uint8_t* dst = (uint8_t*)_dst;
+ dst[0] = uint8_t(toUnorm(_src[0], 255.0f) );
+ }
+
+ void unpackR8(float* _dst, const void* _src)
+ {
+ const uint8_t* src = (const uint8_t*)_src;
+ _dst[0] = fromUnorm(src[0], 255.0f);
+ }
+
+ // R8S
+ void packR8S(void* _dst, const float* _src)
+ {
+ int8_t* dst = (int8_t*)_dst;
+ dst[0] = int8_t(toSnorm(_src[0], 127.0f) );
+ }
+
+ void unpackR8S(float* _dst, const void* _src)
+ {
+ const int8_t* src = (const int8_t*)_src;
+ _dst[0] = fromSnorm(src[0], 127.0f);
+ }
+
+ // R8I
+ void packR8I(void* _dst, const float* _src)
+ {
+ int8_t* dst = (int8_t*)_dst;
+ dst[0] = int8_t(_src[0]);
+ }
+
+ void unpackR8I(float* _dst, const void* _src)
+ {
+ const int8_t* src = (const int8_t*)_src;
+ _dst[0] = float(src[0]);
+ }
+
+ // R8U
+ void packR8U(void* _dst, const float* _src)
+ {
+ uint8_t* dst = (uint8_t*)_dst;
+ dst[0] = uint8_t(_src[0]);
+ }
+
+ void unpackR8U(float* _dst, const void* _src)
+ {
+ const uint8_t* src = (const uint8_t*)_src;
+ _dst[0] = float(src[0]);
+ }
+
+ // RG8
+ void packRg8(void* _dst, const float* _src)
+ {
+ uint8_t* dst = (uint8_t*)_dst;
+ dst[0] = uint8_t(toUnorm(_src[0], 255.0f) );
+ dst[1] = uint8_t(toUnorm(_src[1], 255.0f) );
+ }
+
+ void unpackRg8(float* _dst, const void* _src)
+ {
+ const uint8_t* src = (const uint8_t*)_src;
+ _dst[0] = fromUnorm(src[0], 255.0f);
+ _dst[1] = fromUnorm(src[1], 255.0f);
+ }
+
+ // RG8S
+ void packRg8S(void* _dst, const float* _src)
+ {
+ int8_t* dst = (int8_t*)_dst;
+ dst[0] = int8_t(toSnorm(_src[0], 127.0f) );
+ dst[1] = int8_t(toSnorm(_src[1], 127.0f) );
+ }
+
+ void unpackRg8S(float* _dst, const void* _src)
+ {
+ const int8_t* src = (const int8_t*)_src;
+ _dst[0] = fromSnorm(src[0], 127.0f);
+ _dst[1] = fromSnorm(src[1], 127.0f);
+ }
+
+ // RG8I
+ void packRg8I(void* _dst, const float* _src)
+ {
+ int8_t* dst = (int8_t*)_dst;
+ dst[0] = int8_t(_src[0]);
+ dst[1] = int8_t(_src[1]);
+ }
+
+ void unpackRg8I(float* _dst, const void* _src)
+ {
+ const int8_t* src = (const int8_t*)_src;
+ _dst[0] = float(src[0]);
+ _dst[1] = float(src[1]);
+ }
+
+ // RG8U
+ void packRg8U(void* _dst, const float* _src)
+ {
+ uint8_t* dst = (uint8_t*)_dst;
+ dst[0] = uint8_t(_src[0]);
+ dst[1] = uint8_t(_src[1]);
+ }
+
+ void unpackRg8U(float* _dst, const void* _src)
+ {
+ const uint8_t* src = (const uint8_t*)_src;
+ _dst[0] = float(src[0]);
+ _dst[1] = float(src[1]);
+ }
+
+ // RGBA8
+ void packRgba8(void* _dst, const float* _src)
+ {
+ uint8_t* dst = (uint8_t*)_dst;
+ dst[0] = uint8_t(toUnorm(_src[0], 255.0f) );
+ dst[1] = uint8_t(toUnorm(_src[1], 255.0f) );
+ dst[2] = uint8_t(toUnorm(_src[2], 255.0f) );
+ dst[3] = uint8_t(toUnorm(_src[3], 255.0f) );
+ }
+
+ void unpackRgba8(float* _dst, const void* _src)
+ {
+ const uint8_t* src = (const uint8_t*)_src;
+ _dst[0] = fromUnorm(src[0], 255.0f);
+ _dst[1] = fromUnorm(src[1], 255.0f);
+ _dst[2] = fromUnorm(src[2], 255.0f);
+ _dst[3] = fromUnorm(src[3], 255.0f);
+ }
+
+ // BGRA8
+ void packBgra8(void* _dst, const float* _src)
+ {
+ uint8_t* dst = (uint8_t*)_dst;
+ dst[2] = uint8_t(toUnorm(_src[0], 255.0f) );
+ dst[1] = uint8_t(toUnorm(_src[1], 255.0f) );
+ dst[0] = uint8_t(toUnorm(_src[2], 255.0f) );
+ dst[3] = uint8_t(toUnorm(_src[3], 255.0f) );
+ }
+
+ void unpackBgra8(float* _dst, const void* _src)
+ {
+ const uint8_t* src = (const uint8_t*)_src;
+ _dst[0] = fromUnorm(src[2], 255.0f);
+ _dst[1] = fromUnorm(src[1], 255.0f);
+ _dst[2] = fromUnorm(src[0], 255.0f);
+ _dst[3] = fromUnorm(src[3], 255.0f);
+ }
+
+ // RGBA8S
+ void packRgba8S(void* _dst, const float* _src)
+ {
+ int8_t* dst = (int8_t*)_dst;
+ dst[0] = int8_t(toSnorm(_src[0], 127.0f) );
+ dst[1] = int8_t(toSnorm(_src[1], 127.0f) );
+ dst[2] = int8_t(toSnorm(_src[2], 127.0f) );
+ dst[3] = int8_t(toSnorm(_src[3], 127.0f) );
+ }
+
+ void unpackRgba8S(float* _dst, const void* _src)
+ {
+ const int8_t* src = (const int8_t*)_src;
+ _dst[0] = fromSnorm(src[0], 127.0f);
+ _dst[1] = fromSnorm(src[1], 127.0f);
+ _dst[2] = fromSnorm(src[2], 127.0f);
+ _dst[3] = fromSnorm(src[3], 127.0f);
+ }
+
+ // RGBA8I
+ void packRgba8I(void* _dst, const float* _src)
+ {
+ int8_t* dst = (int8_t*)_dst;
+ dst[0] = int8_t(_src[0]);
+ dst[1] = int8_t(_src[1]);
+ dst[2] = int8_t(_src[2]);
+ dst[3] = int8_t(_src[3]);
+ }
+
+ void unpackRgba8I(float* _dst, const void* _src)
+ {
+ const int8_t* src = (const int8_t*)_src;
+ _dst[0] = float(src[0]);
+ _dst[1] = float(src[1]);
+ _dst[2] = float(src[2]);
+ _dst[3] = float(src[3]);
+ }
+
+ // RGBA8U
+ void packRgba8U(void* _dst, const float* _src)
+ {
+ uint8_t* dst = (uint8_t*)_dst;
+ dst[0] = uint8_t(_src[0]);
+ dst[1] = uint8_t(_src[1]);
+ dst[2] = uint8_t(_src[2]);
+ dst[3] = uint8_t(_src[3]);
+ }
+
+ void unpackRgba8U(float* _dst, const void* _src)
+ {
+ const uint8_t* src = (const uint8_t*)_src;
+ _dst[0] = float(src[0]);
+ _dst[1] = float(src[1]);
+ _dst[2] = float(src[2]);
+ _dst[3] = float(src[3]);
+ }
+
+ // R16
+ void packR16(void* _dst, const float* _src)
+ {
+ uint16_t* dst = (uint16_t*)_dst;
+ dst[0] = uint16_t(toUnorm(_src[0], 65535.0f) );
+ }
+
+ void unpackR16(float* _dst, const void* _src)
+ {
+ const uint16_t* src = (const uint16_t*)_src;
+ _dst[0] = fromUnorm(src[0], 65535.0f);
+ }
+
+ // R16S
+ void packR16S(void* _dst, const float* _src)
+ {
+ int16_t* dst = (int16_t*)_dst;
+ dst[0] = int16_t(toSnorm(_src[0], 32767.0f) );
+ }
+
+ void unpackR16S(float* _dst, const void* _src)
+ {
+ const int16_t* src = (const int16_t*)_src;
+ _dst[0] = fromSnorm(src[0], 32767.0f);
+ }
+
+ // R16I
+ void packR16I(void* _dst, const float* _src)
+ {
+ int16_t* dst = (int16_t*)_dst;
+ dst[0] = int16_t(_src[0]);
+ }
+
+ void unpackR16I(float* _dst, const void* _src)
+ {
+ const int16_t* src = (const int16_t*)_src;
+ _dst[0] = float(src[0]);
+ }
+
+ // R16U
+ void packR16U(void* _dst, const float* _src)
+ {
+ uint16_t* dst = (uint16_t*)_dst;
+ dst[0] = uint16_t(_src[0]);
+ }
+
+ void unpackR16U(float* _dst, const void* _src)
+ {
+ const uint16_t* src = (const uint16_t*)_src;
+ _dst[0] = float(src[0]);
+ }
+
+ // R16F
+ void packR16F(void* _dst, const float* _src)
+ {
+ uint16_t* dst = (uint16_t*)_dst;
+ dst[0] = bx::halfFromFloat(_src[0]);
+ }
+
+ void unpackR16F(float* _dst, const void* _src)
+ {
+ const uint16_t* src = (const uint16_t*)_src;
+ _dst[0] = bx::halfToFloat(src[0]);
+ }
+
+ // RG16
+ void packRg16(void* _dst, const float* _src)
+ {
+ uint16_t* dst = (uint16_t*)_dst;
+ dst[0] = uint16_t(toUnorm(_src[0], 65535.0f) );
+ dst[1] = uint16_t(toUnorm(_src[1], 65535.0f) );
+ }
+
+ void unpackRg16(float* _dst, const void* _src)
+ {
+ const uint16_t* src = (const uint16_t*)_src;
+ _dst[0] = fromUnorm(src[0], 65535.0f);
+ _dst[1] = fromUnorm(src[1], 65535.0f);
+ }
+
+ // RG16S
+ void packRg16S(void* _dst, const float* _src)
+ {
+ int16_t* dst = (int16_t*)_dst;
+ dst[0] = int16_t(toSnorm(_src[0], 32767.0f) );
+ dst[1] = int16_t(toSnorm(_src[1], 32767.0f) );
+ }
+
+ void unpackRg16S(float* _dst, const void* _src)
+ {
+ const int16_t* src = (const int16_t*)_src;
+ _dst[0] = fromSnorm(src[0], 32767.0f);
+ _dst[1] = fromSnorm(src[1], 32767.0f);
+ }
+
+ // RG16I
+ void packRg16I(void* _dst, const float* _src)
+ {
+ int16_t* dst = (int16_t*)_dst;
+ dst[0] = int16_t(_src[0]);
+ dst[1] = int16_t(_src[1]);
+ }
+
+ void unpackRg16I(float* _dst, const void* _src)
+ {
+ const int16_t* src = (const int16_t*)_src;
+ _dst[0] = float(src[0]);
+ _dst[1] = float(src[1]);
+ }
+
+ // RG16U
+ void packRg16U(void* _dst, const float* _src)
+ {
+ uint16_t* dst = (uint16_t*)_dst;
+ dst[0] = uint16_t(_src[0]);
+ dst[1] = uint16_t(_src[1]);
+ }
+
+ void unpackRg16U(float* _dst, const void* _src)
+ {
+ const uint16_t* src = (const uint16_t*)_src;
+ _dst[0] = float(src[0]);
+ _dst[1] = float(src[1]);
+ }
+
+ // RG16F
+ void packRg16F(void* _dst, const float* _src)
+ {
+ uint16_t* dst = (uint16_t*)_dst;
+ dst[0] = bx::halfFromFloat(_src[0]);
+ dst[1] = bx::halfFromFloat(_src[1]);
+ }
+
+ void unpackRg16F(float* _dst, const void* _src)
+ {
+ const uint16_t* src = (const uint16_t*)_src;
+ _dst[0] = bx::halfToFloat(src[0]);
+ _dst[1] = bx::halfToFloat(src[1]);
+ }
+
+ // RGBA16
+ void packRgba16(void* _dst, const float* _src)
+ {
+ uint16_t* dst = (uint16_t*)_dst;
+ dst[0] = uint16_t(toUnorm(_src[0], 65535.0f) );
+ dst[1] = uint16_t(toUnorm(_src[1], 65535.0f) );
+ dst[2] = uint16_t(toUnorm(_src[2], 65535.0f) );
+ dst[3] = uint16_t(toUnorm(_src[3], 65535.0f) );
+ }
+
+ void unpackRgba16(float* _dst, const void* _src)
+ {
+ const uint16_t* src = (const uint16_t*)_src;
+ _dst[0] = fromUnorm(src[0], 65535.0f);
+ _dst[1] = fromUnorm(src[1], 65535.0f);
+ _dst[2] = fromUnorm(src[2], 65535.0f);
+ _dst[3] = fromUnorm(src[3], 65535.0f);
+ }
+
+ // RGBA16S
+ void packRgba16S(void* _dst, const float* _src)
+ {
+ int16_t* dst = (int16_t*)_dst;
+ dst[0] = int16_t(toSnorm(_src[0], 32767.0f) );
+ dst[1] = int16_t(toSnorm(_src[1], 32767.0f) );
+ dst[2] = int16_t(toSnorm(_src[2], 32767.0f) );
+ dst[3] = int16_t(toSnorm(_src[3], 32767.0f) );
+ }
+
+ void unpackRgba16S(float* _dst, const void* _src)
+ {
+ const int16_t* src = (const int16_t*)_src;
+ _dst[0] = fromSnorm(src[0], 32767.0f);
+ _dst[1] = fromSnorm(src[1], 32767.0f);
+ _dst[2] = fromSnorm(src[2], 32767.0f);
+ _dst[3] = fromSnorm(src[3], 32767.0f);
+ }
+
+ // RGBA16I
+ void packRgba16I(void* _dst, const float* _src)
+ {
+ int16_t* dst = (int16_t*)_dst;
+ dst[0] = int16_t(_src[0]);
+ dst[1] = int16_t(_src[1]);
+ dst[2] = int16_t(_src[2]);
+ dst[3] = int16_t(_src[3]);
+ }
+
+ void unpackRgba16I(float* _dst, const void* _src)
+ {
+ const int16_t* src = (const int16_t*)_src;
+ _dst[0] = float(src[0]);
+ _dst[1] = float(src[1]);
+ _dst[2] = float(src[2]);
+ _dst[3] = float(src[3]);
+ }
+
+ // RGBA16U
+ void packRgba16U(void* _dst, const float* _src)
+ {
+ uint16_t* dst = (uint16_t*)_dst;
+ dst[0] = uint16_t(_src[0]);
+ dst[1] = uint16_t(_src[1]);
+ dst[2] = uint16_t(_src[2]);
+ dst[3] = uint16_t(_src[3]);
+ }
+
+ void unpackRgba16U(float* _dst, const void* _src)
+ {
+ const uint16_t* src = (const uint16_t*)_src;
+ _dst[0] = float(src[0]);
+ _dst[1] = float(src[1]);
+ _dst[2] = float(src[2]);
+ _dst[3] = float(src[3]);
+ }
+
+ // RGBA16F
+ void packRgba16F(void* _dst, const float* _src)
+ {
+ uint16_t* dst = (uint16_t*)_dst;
+ dst[0] = bx::halfFromFloat(_src[0]);
+ dst[1] = bx::halfFromFloat(_src[1]);
+ dst[2] = bx::halfFromFloat(_src[2]);
+ dst[3] = bx::halfFromFloat(_src[3]);
+ }
+
+ void unpackRgba16F(float* _dst, const void* _src)
+ {
+ const uint16_t* src = (const uint16_t*)_src;
+ _dst[0] = bx::halfToFloat(src[0]);
+ _dst[1] = bx::halfToFloat(src[1]);
+ _dst[2] = bx::halfToFloat(src[2]);
+ _dst[3] = bx::halfToFloat(src[3]);
+ }
+
+ // R32I
+ void packR32I(void* _dst, const float* _src)
+ {
+ memcpy(_dst, _src, 4);
+ }
+
+ void unpackR32I(float* _dst, const void* _src)
+ {
+ memcpy(_dst, _src, 4);
+ }
+
+ // R32U
+ void packR32U(void* _dst, const float* _src)
+ {
+ memcpy(_dst, _src, 4);
+ }
+
+ void unpackR32U(float* _dst, const void* _src)
+ {
+ memcpy(_dst, _src, 4);
+ }
+
+ // R32F
+ void packR32F(void* _dst, const float* _src)
+ {
+ memcpy(_dst, _src, 4);
+ }
+
+ void unpackR32F(float* _dst, const void* _src)
+ {
+ memcpy(_dst, _src, 4);
+ }
+
+ // RG32I
+ void packRg32I(void* _dst, const float* _src)
+ {
+ memcpy(_dst, _src, 8);
+ }
+
+ void unpackRg32I(float* _dst, const void* _src)
+ {
+ memcpy(_dst, _src, 8);
+ }
+
+ // RG32U
+ void packRg32U(void* _dst, const float* _src)
+ {
+ memcpy(_dst, _src, 8);
+ }
+
+ void unpackRg32U(float* _dst, const void* _src)
+ {
+ memcpy(_dst, _src, 8);
+ }
+
+ // RG32F
+ void packRg32F(void* _dst, const float* _src)
+ {
+ memcpy(_dst, _src, 8);
+ }
+
+ void unpackRg32F(float* _dst, const void* _src)
+ {
+ memcpy(_dst, _src, 8);
+ }
+
+ template<int32_t MantissaBits, int32_t ExpBits>
+ void encodeRgbE(float* _dst, const float* _src)
+ {
+ // Reference:
+ // https://www.opengl.org/registry/specs/EXT/texture_shared_exponent.txt
+ const int32_t expMax = (1<<ExpBits) - 1;
+ const int32_t expBias = (1<<(ExpBits - 1) ) - 1;
+ const float sharedExpMax = float(expMax) / float(expMax + 1) * float(1 << (expMax - expBias) );
+
+ const float rr = bx::fclamp(_src[0], 0.0f, sharedExpMax);
+ const float gg = bx::fclamp(_src[1], 0.0f, sharedExpMax);
+ const float bb = bx::fclamp(_src[2], 0.0f, sharedExpMax);
+ const float max = bx::fmax3(rr, gg, bb);
+ union { float ff; uint32_t ui; } cast = { max };
+ int32_t expShared = int32_t(bx::uint32_imax(uint32_t(-expBias-1), ( ( (cast.ui>>23) & 0xff) - 127) ) ) + 1 + expBias;
+ float denom = bx::fpow(2.0f, float(expShared - expBias - MantissaBits) );
+
+ if ( (1<<MantissaBits) == int32_t(bx::fround(max/denom) ) )
+ {
+ denom *= 2.0f;
+ ++expShared;
+ }
+
+ const float invDenom = 1.0f/denom;
+ _dst[0] = bx::fround(rr * invDenom);
+ _dst[1] = bx::fround(gg * invDenom);
+ _dst[2] = bx::fround(bb * invDenom);
+ _dst[3] = float(expShared);
+ }
+
+ template<int32_t MantissaBits, int32_t ExpBits>
+ void decodeRgbE(float* _dst, const float* _src)
+ {
+ const int32_t expBias = (1<<(ExpBits - 1) ) - 1;
+ const float exponent = _src[3]-float(expBias-MantissaBits);
+ const float scale = bx::fpow(2.0f, exponent);
+ _dst[0] = _src[0] * scale;
+ _dst[1] = _src[1] * scale;
+ _dst[2] = _src[2] * scale;
+ }
+
+ // RGB9E5F
+ void packRgb9E5F(void* _dst, const float* _src)
+ {
+ float tmp[4];
+ encodeRgbE<9, 5>(tmp, _src);
+
+ *( (uint32_t*)_dst) = 0
+ | (uint32_t(tmp[0]) )
+ | (uint32_t(tmp[1]) << 9)
+ | (uint32_t(tmp[2]) <<18)
+ | (uint32_t(tmp[3]) <<27)
+ ;
+ }
+
+ void unpackRgb9E5F(float* _dst, const void* _src)
+ {
+ uint32_t packed = *( (const uint32_t*)_src);
+
+ float tmp[4];
+ tmp[0] = float( ( (packed ) & 0x1ff) ) / 511.0f;
+ tmp[1] = float( ( (packed>> 9) & 0x1ff) ) / 511.0f;
+ tmp[2] = float( ( (packed>>18) & 0x1ff) ) / 511.0f;
+ tmp[3] = float( ( (packed>>27) & 0x1f) );
+
+ decodeRgbE<9, 5>(_dst, tmp);
+ }
+
+ // RGBA32I
+ void packRgba32I(void* _dst, const float* _src)
+ {
+ memcpy(_dst, _src, 16);
+ }
+
+ void unpackRgba32I(float* _dst, const void* _src)
+ {
+ memcpy(_dst, _src, 16);
+ }
+
+ // RGBA32U
+ void packRgba32U(void* _dst, const float* _src)
+ {
+ memcpy(_dst, _src, 16);
+ }
+
+ void unpackRgba32U(float* _dst, const void* _src)
+ {
+ memcpy(_dst, _src, 16);
+ }
+
+ // RGBA32F
+ void packRgba32F(void* _dst, const float* _src)
+ {
+ memcpy(_dst, _src, 16);
+ }
+
+ void unpackRgba32F(float* _dst, const void* _src)
+ {
+ memcpy(_dst, _src, 16);
+ }
+
+ // R5G6B5
+ void packR5G6B5(void* _dst, const float* _src)
+ {
+ *( (uint16_t*)_dst) = 0
+ | uint16_t(toUnorm(_src[0], 31.0f) )
+ | uint16_t(toUnorm(_src[1], 63.0f)<< 5)
+ | uint16_t(toUnorm(_src[2], 31.0f)<<11)
+ ;
+ }
+
+ void unpackR5G6B5(float* _dst, const void* _src)
+ {
+ uint16_t packed = *( (const uint16_t*)_src);
+ _dst[0] = float( ( (packed ) & 0x1f) ) / 31.0f;
+ _dst[1] = float( ( (packed>> 5) & 0x3f) ) / 63.0f;
+ _dst[2] = float( ( (packed>>11) & 0x1f) ) / 31.0f;
+ }
+
+ // RGBA4
+ void packRgba4(void* _dst, const float* _src)
+ {
+ *( (uint16_t*)_dst) = 0
+ | uint16_t(toUnorm(_src[0], 15.0f) )
+ | uint16_t(toUnorm(_src[1], 15.0f)<< 4)
+ | uint16_t(toUnorm(_src[2], 15.0f)<< 8)
+ | uint16_t(toUnorm(_src[3], 15.0f)<<12)
+ ;
+ }
+
+ void unpackRgba4(float* _dst, const void* _src)
+ {
+ uint16_t packed = *( (const uint16_t*)_src);
+ _dst[0] = float( ( (packed ) & 0xf) ) / 15.0f;
+ _dst[1] = float( ( (packed>> 4) & 0xf) ) / 15.0f;
+ _dst[2] = float( ( (packed>> 8) & 0xf) ) / 15.0f;
+ _dst[3] = float( ( (packed>>12) & 0xf) ) / 15.0f;
+ }
+
+ // RGB5A1
+ void packRgb5a1(void* _dst, const float* _src)
+ {
+ *( (uint16_t*)_dst) = 0
+ | uint16_t(toUnorm(_src[0], 31.0f) )
+ | uint16_t(toUnorm(_src[1], 31.0f)<< 5)
+ | uint16_t(toUnorm(_src[2], 31.0f)<<10)
+ | uint16_t(toUnorm(_src[3], 1.0f)<<15)
+ ;
+ }
+
+ void unpackRgb5a1(float* _dst, const void* _src)
+ {
+ uint16_t packed = *( (const uint16_t*)_src);
+ _dst[0] = float( ( (packed ) & 0x1f) ) / 31.0f;
+ _dst[1] = float( ( (packed>> 5) & 0x1f) ) / 31.0f;
+ _dst[2] = float( ( (packed>>10) & 0x1f) ) / 31.0f;
+ _dst[3] = float( ( (packed>>14) & 0x1) );
+ }
+
+ // RGB10A2
+ void packRgb10A2(void* _dst, const float* _src)
+ {
+ *( (uint32_t*)_dst) = 0
+ | (toUnorm(_src[0], 1023.0f) )
+ | (toUnorm(_src[1], 1023.0f)<<10)
+ | (toUnorm(_src[2], 1023.0f)<<20)
+ | (toUnorm(_src[3], 3.0f)<<30)
+ ;
+ }
+
+ void unpackRgb10A2(float* _dst, const void* _src)
+ {
+ uint32_t packed = *( (const uint32_t*)_src);
+ _dst[0] = float( ( (packed ) & 0x3ff) ) / 1023.0f;
+ _dst[1] = float( ( (packed>>10) & 0x3ff) ) / 1023.0f;
+ _dst[2] = float( ( (packed>>20) & 0x3ff) ) / 1023.0f;
+ _dst[3] = float( ( (packed>>30) & 0x3) ) / 3.0f;
+ }
+
+ // R11G11B10F
+ void packR11G11B10F(void* _dst, const float* _src)
+ {
+ *( (uint32_t*)_dst) = 0
+ | ( (bx::halfFromFloat(_src[0])>> 4) & 0x7ff)
+ | ( (bx::halfFromFloat(_src[0])<< 7) & 0x3ff800)
+ | ( (bx::halfFromFloat(_src[0])<<17) & 0xffc00000)
+ ;
+ }
+
+ void unpackR11G11B10F(float* _dst, const void* _src)
+ {
+ uint32_t packed = *( (const uint32_t*)_src);
+ _dst[0] = bx::halfToFloat( (packed<< 4) & 0x7ff0);
+ _dst[1] = bx::halfToFloat( (packed>> 7) & 0x7ff0);
+ _dst[2] = bx::halfToFloat( (packed>>17) & 0x7fe0);
+ }
+
+ typedef void (*PackFn)(void*, const float*);
+ typedef void (*UnpackFn)(float*, const void*);
+
+ struct PackUnpack
+ {
+ PackFn pack;
+ UnpackFn unpack;
+ };
+
+ static PackUnpack s_packUnpack[] =
+ {
+ { NULL, NULL }, // BC1
+ { NULL, NULL }, // BC2
+ { NULL, NULL }, // BC3
+ { NULL, NULL }, // BC4
+ { NULL, NULL }, // BC5
+ { NULL, NULL }, // BC6H
+ { NULL, NULL }, // BC7
+ { NULL, NULL }, // ETC1
+ { NULL, NULL }, // ETC2
+ { NULL, NULL }, // ETC2A
+ { NULL, NULL }, // ETC2A1
+ { NULL, NULL }, // PTC12
+ { NULL, NULL }, // PTC14
+ { NULL, NULL }, // PTC12A
+ { NULL, NULL }, // PTC14A
+ { NULL, NULL }, // PTC22
+ { NULL, NULL }, // PTC24
+ { NULL, NULL }, // Unknown
+ { NULL, NULL }, // R1
+ { packR8, unpackR8 }, // A8
+ { packR8, unpackR8 }, // R8
+ { packR8I, unpackR8I }, // R8I
+ { packR8U, unpackR8U }, // R8U
+ { packR8S, unpackR8S }, // R8S
+ { packR16, unpackR16 }, // R16
+ { packR16I, unpackR16I }, // R16I
+ { packR16U, unpackR16U }, // R16U
+ { packR16F, unpackR16F }, // R16F
+ { packR16S, unpackR16S }, // R16S
+ { packR32I, unpackR32I }, // R32I
+ { packR32U, unpackR32U }, // R32U
+ { packR32F, unpackR32F }, // R32F
+ { packRg8, unpackRg8 }, // RG8
+ { packRg8I, unpackRg8I }, // RG8I
+ { packRg8U, unpackRg8U }, // RG8U
+ { packRg8S, unpackRg8S }, // RG8S
+ { packRg16, unpackRg16 }, // RG16
+ { packRg16I, unpackRg16I }, // RG16I
+ { packRg16U, unpackRg16U }, // RG16U
+ { packRg16F, unpackRg16F }, // RG16F
+ { packRg16S, unpackRg16S }, // RG16S
+ { packRg32I, unpackRg32I }, // RG32I
+ { packRg32U, unpackRg32U }, // RG32U
+ { packRg32F, unpackRg32F }, // RG32F
+ { packRgb9E5F, unpackRgb9E5F }, // RGB9E5F
+ { packBgra8, unpackBgra8 }, // BGRA8
+ { packRgba8, unpackRgba8 }, // RGBA8
+ { packRgba8I, unpackRgba8I }, // RGBA8I
+ { packRgba8U, unpackRgba8U }, // RGBA8U
+ { packRgba8S, unpackRgba8S }, // RGBA8S
+ { packRgba16, unpackRgba16 }, // RGBA16
+ { packRgba16I, unpackRgba16I }, // RGBA16I
+ { packRgba16U, unpackRgba16U }, // RGBA16U
+ { packRgba16F, unpackRgba16F }, // RGBA16F
+ { packRgba16S, unpackRgba16S }, // RGBA16S
+ { packRgba32I, unpackRgba32I }, // RGBA32I
+ { packRgba32U, unpackRgba32U }, // RGBA32U
+ { packRgba32F, unpackRgba32F }, // RGBA32F
+ { packR5G6B5, unpackR5G6B5 }, // R5G6B5
+ { packRgba4, unpackRgba4 }, // RGBA4
+ { packRgb5a1, unpackRgb5a1 }, // RGB5A1
+ { packRgb10A2, unpackRgb10A2 }, // RGB10A2
+ { packR11G11B10F, unpackR11G11B10F }, // R11G11B10F
+ { NULL, NULL }, // UnknownDepth
+ { NULL, NULL }, // D16
+ { NULL, NULL }, // D24
+ { NULL, NULL }, // D24S8
+ { NULL, NULL }, // D32
+ { NULL, NULL }, // D16F
+ { NULL, NULL }, // D24F
+ { NULL, NULL }, // D32F
+ { NULL, NULL }, // D0S8
+ };
+ BX_STATIC_ASSERT(TextureFormat::Count == BX_COUNTOF(s_packUnpack) );
+
+ bool imageConvert(void* _dst, TextureFormat::Enum _dstFormat, const void* _src, TextureFormat::Enum _srcFormat, uint32_t _width, uint32_t _height)
+ {
+ UnpackFn unpack = s_packUnpack[_srcFormat].unpack;
+ PackFn pack = s_packUnpack[_dstFormat].pack;
+ if (NULL == pack
+ || NULL == unpack)
+ {
+ return false;
+ }
+
+ const uint8_t* src = (uint8_t*)_src;
+ uint8_t* dst = (uint8_t*)_dst;
+
+ const uint32_t srcBpp = s_imageBlockInfo[_srcFormat].bitsPerPixel;
+ const uint32_t dstBpp = s_imageBlockInfo[_dstFormat].bitsPerPixel;
+ const uint32_t srcPitch = _width * srcBpp / 8;
+ const uint32_t dstPitch = _width * dstBpp / 8;
+
+ for (uint32_t yy = 0; yy < _height; ++yy, src += srcPitch, dst += dstPitch)
+ {
+ for (uint32_t xx = 0; xx < _width; ++xx)
+ {
+ float rgba[4];
+ unpack(rgba, &src[xx*srcBpp/8]);
+ pack(&dst[xx*dstBpp/8], rgba);
+ }
+ }
+
+ return true;
}
uint8_t bitRangeConvert(uint32_t _in, uint32_t _from, uint32_t _to)
@@ -1324,6 +2211,34 @@ namespace bgfx
}
}
+ const Memory* imageAlloc(ImageContainer& _imageContainer, TextureFormat::Enum _format, uint16_t _width, uint16_t _height, uint16_t _depth, bool _cubeMap, bool _mips)
+ {
+ const uint8_t numMips = _mips ? imageGetNumMips(_format, _width, _height) : 1;
+ uint32_t size = imageGetSize(_format, _width, _height, 0, false, numMips);
+ const Memory* image = alloc(size);
+
+ _imageContainer.m_data = image->data;
+ _imageContainer.m_format = _format;
+ _imageContainer.m_size = image->size;
+ _imageContainer.m_offset = 0;
+ _imageContainer.m_width = _width;
+ _imageContainer.m_height = _height;
+ _imageContainer.m_depth = _depth;
+ _imageContainer.m_numMips = numMips;
+ _imageContainer.m_hasAlpha = false;
+ _imageContainer.m_cubeMap = _cubeMap;
+ _imageContainer.m_ktx = false;
+ _imageContainer.m_ktxLE = false;
+ _imageContainer.m_srgb = false;
+
+ return image;
+ }
+
+ void imageFree(const Memory* _memory)
+ {
+ release(_memory);
+ }
+
// DDS
#define DDS_MAGIC BX_MAKEFOURCC('D', 'D', 'S', ' ')
#define DDS_HEADER_SIZE 124
@@ -1670,7 +2585,7 @@ namespace bgfx
_imageContainer.m_width = width;
_imageContainer.m_height = height;
_imageContainer.m_depth = depth;
- _imageContainer.m_format = uint8_t(format);
+ _imageContainer.m_format = format;
_imageContainer.m_numMips = uint8_t( (caps[0] & DDSCAPS_MIPMAP) ? mips : 1);
_imageContainer.m_hasAlpha = hasAlpha;
_imageContainer.m_cubeMap = cubeMap;
@@ -1852,7 +2767,7 @@ namespace bgfx
{ KTX_RG32UI, KTX_ZERO, KTX_RG, KTX_UNSIGNED_INT, }, // RG32U
{ KTX_RG32F, KTX_ZERO, KTX_RG, KTX_FLOAT, }, // RG32F
{ KTX_RGB9_E5, KTX_ZERO, KTX_RGB, KTX_UNSIGNED_INT_5_9_9_9_REV, }, // RGB9E5F
- { KTX_RGBA8, KTX_SRGB8_ALPHA8, KTX_BGRA, KTX_UNSIGNED_BYTE, }, // BGRA8
+ { KTX_BGRA, KTX_SRGB8_ALPHA8, KTX_BGRA, KTX_UNSIGNED_BYTE, }, // BGRA8
{ KTX_RGBA8, KTX_SRGB8_ALPHA8, KTX_RGBA, KTX_UNSIGNED_BYTE, }, // RGBA8
{ KTX_RGBA8I, KTX_ZERO, KTX_RGBA, KTX_BYTE, }, // RGBA8I
{ KTX_RGBA8UI, KTX_ZERO, KTX_RGBA, KTX_UNSIGNED_BYTE, }, // RGBA8U
@@ -1946,7 +2861,7 @@ namespace bgfx
_imageContainer.m_width = width;
_imageContainer.m_height = height;
_imageContainer.m_depth = depth;
- _imageContainer.m_format = uint8_t(format);
+ _imageContainer.m_format = format;
_imageContainer.m_numMips = uint8_t(numMips);
_imageContainer.m_hasAlpha = hasAlpha;
_imageContainer.m_cubeMap = numFaces > 1;
@@ -2094,7 +3009,7 @@ namespace bgfx
_imageContainer.m_width = width;
_imageContainer.m_height = height;
_imageContainer.m_depth = depth;
- _imageContainer.m_format = uint8_t(format);
+ _imageContainer.m_format = format;
_imageContainer.m_numMips = uint8_t(numMips);
_imageContainer.m_hasAlpha = hasAlpha;
_imageContainer.m_cubeMap = numFaces > 1;
@@ -2161,16 +3076,17 @@ namespace bgfx
return imageParse(_imageContainer, &reader);
}
- void imageDecodeToBgra8(uint8_t* _dst, const uint8_t* _src, uint32_t _width, uint32_t _height, uint32_t _pitch, uint8_t _type)
+ void imageDecodeToBgra8(void* _dst, const void* _src, uint32_t _width, uint32_t _height, uint32_t _pitch, TextureFormat::Enum _format)
{
- const uint8_t* src = _src;
+ const uint8_t* src = (const uint8_t*)_src;
+ uint8_t* dst = (uint8_t*)_dst;
uint32_t width = _width/4;
uint32_t height = _height/4;
uint8_t temp[16*4];
- switch (_type)
+ switch (_format)
{
case TextureFormat::BC1:
for (uint32_t yy = 0; yy < height; ++yy)
@@ -2180,11 +3096,11 @@ namespace bgfx
decodeBlockDxt1(temp, src);
src += 8;
- uint8_t* dst = &_dst[(yy*_pitch+xx*4)*4];
- memcpy(&dst[0*_pitch], &temp[ 0], 16);
- memcpy(&dst[1*_pitch], &temp[16], 16);
- memcpy(&dst[2*_pitch], &temp[32], 16);
- memcpy(&dst[3*_pitch], &temp[48], 16);
+ uint8_t* block = &dst[(yy*_pitch+xx*4)*4];
+ memcpy(&block[0*_pitch], &temp[ 0], 16);
+ memcpy(&block[1*_pitch], &temp[16], 16);
+ memcpy(&block[2*_pitch], &temp[32], 16);
+ memcpy(&block[3*_pitch], &temp[48], 16);
}
}
break;
@@ -2199,11 +3115,11 @@ namespace bgfx
decodeBlockDxt(temp, src);
src += 8;
- uint8_t* dst = &_dst[(yy*_pitch+xx*4)*4];
- memcpy(&dst[0*_pitch], &temp[ 0], 16);
- memcpy(&dst[1*_pitch], &temp[16], 16);
- memcpy(&dst[2*_pitch], &temp[32], 16);
- memcpy(&dst[3*_pitch], &temp[48], 16);
+ uint8_t* block = &dst[(yy*_pitch+xx*4)*4];
+ memcpy(&block[0*_pitch], &temp[ 0], 16);
+ memcpy(&block[1*_pitch], &temp[16], 16);
+ memcpy(&block[2*_pitch], &temp[32], 16);
+ memcpy(&block[3*_pitch], &temp[48], 16);
}
}
break;
@@ -2218,11 +3134,11 @@ namespace bgfx
decodeBlockDxt(temp, src);
src += 8;
- uint8_t* dst = &_dst[(yy*_pitch+xx*4)*4];
- memcpy(&dst[0*_pitch], &temp[ 0], 16);
- memcpy(&dst[1*_pitch], &temp[16], 16);
- memcpy(&dst[2*_pitch], &temp[32], 16);
- memcpy(&dst[3*_pitch], &temp[48], 16);
+ uint8_t* block = &dst[(yy*_pitch+xx*4)*4];
+ memcpy(&block[0*_pitch], &temp[ 0], 16);
+ memcpy(&block[1*_pitch], &temp[16], 16);
+ memcpy(&block[2*_pitch], &temp[32], 16);
+ memcpy(&block[3*_pitch], &temp[48], 16);
}
}
break;
@@ -2235,11 +3151,11 @@ namespace bgfx
decodeBlockDxt45A(temp, src);
src += 8;
- uint8_t* dst = &_dst[(yy*_pitch+xx*4)*4];
- memcpy(&dst[0*_pitch], &temp[ 0], 16);
- memcpy(&dst[1*_pitch], &temp[16], 16);
- memcpy(&dst[2*_pitch], &temp[32], 16);
- memcpy(&dst[3*_pitch], &temp[48], 16);
+ uint8_t* block = &dst[(yy*_pitch+xx*4)*4];
+ memcpy(&block[0*_pitch], &temp[ 0], 16);
+ memcpy(&block[1*_pitch], &temp[16], 16);
+ memcpy(&block[2*_pitch], &temp[32], 16);
+ memcpy(&block[3*_pitch], &temp[48], 16);
}
}
break;
@@ -2249,25 +3165,25 @@ namespace bgfx
{
for (uint32_t xx = 0; xx < width; ++xx)
{
- decodeBlockDxt45A(temp+1, src);
- src += 8;
decodeBlockDxt45A(temp+2, src);
src += 8;
+ decodeBlockDxt45A(temp+1, src);
+ src += 8;
for (uint32_t ii = 0; ii < 16; ++ii)
{
float nx = temp[ii*4+2]*2.0f/255.0f - 1.0f;
float ny = temp[ii*4+1]*2.0f/255.0f - 1.0f;
- float nz = sqrtf(1.0f - nx*nx - ny*ny);
+ float nz = bx::fsqrt(1.0f - nx*nx - ny*ny);
temp[ii*4+0] = uint8_t( (nz + 1.0f)*255.0f/2.0f);
temp[ii*4+3] = 0;
}
- uint8_t* dst = &_dst[(yy*_pitch+xx*4)*4];
- memcpy(&dst[0*_pitch], &temp[ 0], 16);
- memcpy(&dst[1*_pitch], &temp[16], 16);
- memcpy(&dst[2*_pitch], &temp[32], 16);
- memcpy(&dst[3*_pitch], &temp[48], 16);
+ uint8_t* block = &dst[(yy*_pitch+xx*4)*4];
+ memcpy(&block[0*_pitch], &temp[ 0], 16);
+ memcpy(&block[1*_pitch], &temp[16], 16);
+ memcpy(&block[2*_pitch], &temp[32], 16);
+ memcpy(&block[3*_pitch], &temp[48], 16);
}
}
break;
@@ -2281,11 +3197,11 @@ namespace bgfx
decodeBlockEtc12(temp, src);
src += 8;
- uint8_t* dst = &_dst[(yy*_pitch+xx*4)*4];
- memcpy(&dst[0*_pitch], &temp[ 0], 16);
- memcpy(&dst[1*_pitch], &temp[16], 16);
- memcpy(&dst[2*_pitch], &temp[32], 16);
- memcpy(&dst[3*_pitch], &temp[48], 16);
+ uint8_t* block = &dst[(yy*_pitch+xx*4)*4];
+ memcpy(&block[0*_pitch], &temp[ 0], 16);
+ memcpy(&block[1*_pitch], &temp[16], 16);
+ memcpy(&block[2*_pitch], &temp[32], 16);
+ memcpy(&block[3*_pitch], &temp[48], 16);
}
}
break;
@@ -2317,11 +3233,11 @@ namespace bgfx
{
decodeBlockPtc14(temp, src, xx, yy, width, height);
- uint8_t* dst = &_dst[(yy*_pitch+xx*4)*4];
- memcpy(&dst[0*_pitch], &temp[ 0], 16);
- memcpy(&dst[1*_pitch], &temp[16], 16);
- memcpy(&dst[2*_pitch], &temp[32], 16);
- memcpy(&dst[3*_pitch], &temp[48], 16);
+ uint8_t* block = &dst[(yy*_pitch+xx*4)*4];
+ memcpy(&block[0*_pitch], &temp[ 0], 16);
+ memcpy(&block[1*_pitch], &temp[16], 16);
+ memcpy(&block[2*_pitch], &temp[32], 16);
+ memcpy(&block[3*_pitch], &temp[48], 16);
}
}
break;
@@ -2333,11 +3249,11 @@ namespace bgfx
{
decodeBlockPtc14A(temp, src, xx, yy, width, height);
- uint8_t* dst = &_dst[(yy*_pitch+xx*4)*4];
- memcpy(&dst[0*_pitch], &temp[ 0], 16);
- memcpy(&dst[1*_pitch], &temp[16], 16);
- memcpy(&dst[2*_pitch], &temp[32], 16);
- memcpy(&dst[3*_pitch], &temp[48], 16);
+ uint8_t* block = &dst[(yy*_pitch+xx*4)*4];
+ memcpy(&block[0*_pitch], &temp[ 0], 16);
+ memcpy(&block[1*_pitch], &temp[16], 16);
+ memcpy(&block[2*_pitch], &temp[32], 16);
+ memcpy(&block[3*_pitch], &temp[48], 16);
}
}
break;
@@ -2367,9 +3283,9 @@ namespace bgfx
}
}
- void imageDecodeToRgba8(uint8_t* _dst, const uint8_t* _src, uint32_t _width, uint32_t _height, uint32_t _pitch, uint8_t _type)
+ void imageDecodeToRgba8(void* _dst, const void* _src, uint32_t _width, uint32_t _height, uint32_t _pitch, TextureFormat::Enum _format)
{
- switch (_type)
+ switch (_format)
{
case TextureFormat::RGBA8:
memcpy(_dst, _src, _pitch*_height);
@@ -2380,12 +3296,136 @@ namespace bgfx
break;
default:
- imageDecodeToBgra8(_dst, _src, _width, _height, _pitch, _type);
+ imageDecodeToBgra8(_dst, _src, _width, _height, _pitch, _format);
imageSwizzleBgra8(_width, _height, _pitch, _dst, _dst);
break;
}
}
+ void imageRgba8ToRgba32fRef(void* _dst, uint32_t _width, uint32_t _height, uint32_t _pitch, const void* _src)
+ {
+ const uint32_t dstwidth = _width;
+ const uint32_t dstheight = _height;
+
+ if (0 == dstwidth
+ || 0 == dstheight)
+ {
+ return;
+ }
+
+ float* dst = (float*)_dst;
+ const uint8_t* src = (const uint8_t*)_src;
+
+ for (uint32_t yy = 0, ystep = _pitch; yy < dstheight; ++yy, src += ystep)
+ {
+ const uint8_t* rgba = src;
+ for (uint32_t xx = 0; xx < dstwidth; ++xx, rgba += 4, dst += 4)
+ {
+ dst[0] = bx::fpow(rgba[0], 2.2f);
+ dst[1] = bx::fpow(rgba[1], 2.2f);
+ dst[2] = bx::fpow(rgba[2], 2.2f);
+ dst[3] = rgba[3];
+ }
+ }
+ }
+
+ void imageRgba8ToRgba32f(void* _dst, uint32_t _width, uint32_t _height, uint32_t _pitch, const void* _src)
+ {
+ const uint32_t dstwidth = _width;
+ const uint32_t dstheight = _height;
+
+ if (0 == dstwidth
+ || 0 == dstheight)
+ {
+ return;
+ }
+
+ float* dst = (float*)_dst;
+ const uint8_t* src = (const uint8_t*)_src;
+
+ using namespace bx;
+ const float4_t unpack = float4_ld(1.0f, 1.0f/256.0f, 1.0f/65536.0f, 1.0f/16777216.0f);
+ const float4_t umask = float4_ild(0xff, 0xff00, 0xff0000, 0xff000000);
+ const float4_t wflip = float4_ild(0, 0, 0, 0x80000000);
+ const float4_t wadd = float4_ld(0.0f, 0.0f, 0.0f, 32768.0f*65536.0f);
+
+ for (uint32_t yy = 0, ystep = _pitch; yy < dstheight; ++yy, src += ystep)
+ {
+ const uint8_t* rgba = src;
+ for (uint32_t xx = 0; xx < dstwidth; ++xx, rgba += 4, dst += 4)
+ {
+ const float4_t abgr0 = float4_splat(rgba);
+ const float4_t abgr0m = float4_and(abgr0, umask);
+ const float4_t abgr0x = float4_xor(abgr0m, wflip);
+ const float4_t abgr0f = float4_itof(abgr0x);
+ const float4_t abgr0c = float4_add(abgr0f, wadd);
+ const float4_t abgr0n = float4_mul(abgr0c, unpack);
+
+ float4_st(dst, abgr0n);
+ }
+ }
+ }
+
+ void imageDecodeToRgba32f(bx::AllocatorI* _allocator, void* _dst, const void* _src, uint32_t _width, uint32_t _height, uint32_t _pitch, TextureFormat::Enum _format)
+ {
+ const uint8_t* src = (const uint8_t*)_src;
+ uint8_t* dst = (uint8_t*)_dst;
+
+ switch (_format)
+ {
+ case TextureFormat::BC5:
+ {
+ uint32_t width = _width/4;
+ uint32_t height = _height/4;
+
+ for (uint32_t yy = 0; yy < height; ++yy)
+ {
+ for (uint32_t xx = 0; xx < width; ++xx)
+ {
+ uint8_t temp[16*4];
+
+ decodeBlockDxt45A(temp+2, src);
+ src += 8;
+ decodeBlockDxt45A(temp+1, src);
+ src += 8;
+
+ for (uint32_t ii = 0; ii < 16; ++ii)
+ {
+ float nx = temp[ii*4+2]*2.0f/255.0f - 1.0f;
+ float ny = temp[ii*4+1]*2.0f/255.0f - 1.0f;
+ float nz = bx::fsqrt(1.0f - nx*nx - ny*ny);
+
+ const uint32_t offset = (yy*4 + ii/4)*_width*16 + (xx*4 + ii%4)*16;
+ float* block = (float*)&dst[offset];
+ block[0] = nx;
+ block[1] = ny;
+ block[2] = nz;
+ block[3] = 0.0f;
+ }
+ }
+ }
+ }
+ break;
+
+ case TextureFormat::RGBA32F:
+ memcpy(_dst, _src, _pitch*_height);
+ break;
+
+ case TextureFormat::RGBA8:
+ imageRgba8ToRgba32f(_dst, _width, _height, _pitch, _src);
+ break;
+
+ default:
+ {
+ void* temp = BX_ALLOC(_allocator, imageGetSize(_format, uint16_t(_pitch/4), uint16_t(_height) ) );
+ imageDecodeToRgba8(temp, _src, _width, _height, _pitch, _format);
+ imageRgba8ToRgba32f(_dst, _width, _height, _pitch, temp);
+ BX_FREE(_allocator, temp);
+ }
+ break;
+ }
+ }
+
bool imageGetRawData(const ImageContainer& _imageContainer, uint8_t _side, uint8_t _lod, const void* _data, uint32_t _size, ImageMip& _mip)
{
uint32_t offset = _imageContainer.m_offset;
@@ -2443,7 +3483,7 @@ namespace bgfx
_mip.m_size = size;
_mip.m_data = &data[offset];
_mip.m_bpp = bpp;
- _mip.m_format = uint8_t(format);
+ _mip.m_format = format;
_mip.m_hasAlpha = hasAlpha;
return true;
}
@@ -2484,7 +3524,7 @@ namespace bgfx
_mip.m_size = size;
_mip.m_data = &data[offset];
_mip.m_bpp = bpp;
- _mip.m_format = uint8_t(format);
+ _mip.m_format = format;
_mip.m_hasAlpha = hasAlpha;
return true;
}
@@ -2504,7 +3544,7 @@ namespace bgfx
return false;
}
- void imageWriteTga(bx::WriterI* _writer, uint32_t _width, uint32_t _height, uint32_t _srcPitch, const void* _src, bool _grayscale, bool _yflip)
+ void imageWriteTga(bx::WriterI* _writer, uint32_t _width, uint32_t _height, uint32_t _pitch, const void* _src, bool _grayscale, bool _yflip)
{
uint8_t type = _grayscale ? 3 : 2;
uint8_t bpp = _grayscale ? 8 : 32;
@@ -2523,16 +3563,16 @@ namespace bgfx
uint32_t dstPitch = _width*bpp/8;
if (_yflip)
{
- uint8_t* data = (uint8_t*)_src + _srcPitch*_height - _srcPitch;
+ uint8_t* data = (uint8_t*)_src + _pitch*_height - _pitch;
for (uint32_t yy = 0; yy < _height; ++yy)
{
bx::write(_writer, data, dstPitch);
- data -= _srcPitch;
+ data -= _pitch;
}
}
- else if (_srcPitch == dstPitch)
+ else if (_pitch == dstPitch)
{
- bx::write(_writer, _src, _height*_srcPitch);
+ bx::write(_writer, _src, _height*_pitch);
}
else
{
@@ -2540,7 +3580,7 @@ namespace bgfx
for (uint32_t yy = 0; yy < _height; ++yy)
{
bx::write(_writer, data, dstPitch);
- data += _srcPitch;
+ data += _pitch;
}
}
}