Fixed texture update when requested texture format doesn't match internal texture format, and simplified texture creation.
This commit is contained in:
parent
82256fc34d
commit
488483a945
13 changed files with 697 additions and 1027 deletions
|
@ -319,7 +319,6 @@ namespace bgfx
|
|||
PTC24, // PVRTC2 RGBA 4BPP
|
||||
Unknown,
|
||||
L8,
|
||||
BGRX8,
|
||||
BGRA8,
|
||||
RGBA16,
|
||||
RGBA16F,
|
||||
|
@ -749,12 +748,37 @@ namespace bgfx
|
|||
TextureHandle createTexture(const Memory* _mem, uint32_t _flags = BGFX_TEXTURE_NONE, TextureInfo* _info = NULL);
|
||||
|
||||
/// Create 2D texture.
|
||||
///
|
||||
/// @param _width
|
||||
/// @param _height
|
||||
/// @param _numMips
|
||||
/// @param _format
|
||||
/// @param _flags
|
||||
/// @param _mem
|
||||
///
|
||||
TextureHandle createTexture2D(uint16_t _width, uint16_t _height, uint8_t _numMips, TextureFormat::Enum _format, uint32_t _flags = BGFX_TEXTURE_NONE, const Memory* _mem = NULL);
|
||||
|
||||
/// Create 3D texture.
|
||||
///
|
||||
/// @param _width
|
||||
/// @param _height
|
||||
/// @param _depth
|
||||
/// @param _numMips
|
||||
/// @param _format
|
||||
/// @param _flags
|
||||
/// @param _mem
|
||||
///
|
||||
TextureHandle createTexture3D(uint16_t _width, uint16_t _height, uint16_t _depth, uint8_t _numMips, TextureFormat::Enum _format, uint32_t _flags = BGFX_TEXTURE_NONE, const Memory* _mem = NULL);
|
||||
|
||||
/// Create Cube texture.
|
||||
///
|
||||
/// @param _sides
|
||||
/// @param _width
|
||||
/// @param _numMips
|
||||
/// @param _format
|
||||
/// @param _flags
|
||||
/// @param _mem
|
||||
///
|
||||
TextureHandle createTextureCube(uint16_t _sides, uint16_t _width, uint8_t _numMips, TextureFormat::Enum _format, uint32_t _flags = BGFX_TEXTURE_NONE, const Memory* _mem = NULL);
|
||||
|
||||
/// Update 2D texture.
|
||||
|
|
31
src/bgfx_p.h
31
src/bgfx_p.h
|
@ -16,20 +16,9 @@
|
|||
#include <string.h>
|
||||
#include <alloca.h>
|
||||
|
||||
// clang analyzer annotation
|
||||
#if !defined(__has_feature)
|
||||
# define __has_feature(_a) 0
|
||||
#endif // !defined(__has_feature)
|
||||
|
||||
#if __has_feature(attribute_analyzer_noreturn)
|
||||
# define CLANG_ANALYZER_NO_RETURN __attribute__( (analyzer_noreturn) )
|
||||
#else
|
||||
# define CLANG_ANALYZER_NO_RETURN
|
||||
#endif // __has_feature(attribute_analyzer_noreturn)
|
||||
|
||||
namespace bgfx
|
||||
{
|
||||
void fatal(Fatal::Enum _code, const char* _format, ...) CLANG_ANALYZER_NO_RETURN;
|
||||
void fatal(Fatal::Enum _code, const char* _format, ...);
|
||||
void dbgPrintf(const char* _format, ...);
|
||||
}
|
||||
|
||||
|
@ -2156,7 +2145,7 @@ namespace bgfx
|
|||
, (uint16_t)imageContainer.m_height
|
||||
, (uint16_t)imageContainer.m_depth
|
||||
, imageContainer.m_numMips
|
||||
, imageContainer.m_type
|
||||
, TextureFormat::Enum(imageContainer.m_format)
|
||||
);
|
||||
}
|
||||
else
|
||||
|
@ -2949,6 +2938,22 @@ namespace bgfx
|
|||
|
||||
rendererCreateTexture(handle, mem, flags);
|
||||
|
||||
bx::MemoryReader reader(mem->data, mem->size);
|
||||
|
||||
uint32_t magic;
|
||||
bx::read(&reader, magic);
|
||||
|
||||
if (BGFX_CHUNK_MAGIC_TEX == magic)
|
||||
{
|
||||
TextureCreate tc;
|
||||
bx::read(&reader, tc);
|
||||
|
||||
if (NULL != tc.m_mem)
|
||||
{
|
||||
release(tc.m_mem);
|
||||
}
|
||||
}
|
||||
|
||||
release(mem);
|
||||
}
|
||||
break;
|
||||
|
|
|
@ -91,6 +91,10 @@
|
|||
# define BGFX_CONFIG_DEBUG_PERFHUD 0
|
||||
#endif // BGFX_CONFIG_DEBUG_NVPERFHUD
|
||||
|
||||
#ifndef BGFX_CONFIG_RENDERER_USE_EXTENSIONS
|
||||
# define BGFX_CONFIG_RENDERER_USE_EXTENSIONS 1
|
||||
#endif // BGFX_CONFIG_RENDERER_USE_EXTENSIONS
|
||||
|
||||
/// DX9 PIX markers
|
||||
#ifndef BGFX_CONFIG_DEBUG_PIX
|
||||
# define BGFX_CONFIG_DEBUG_PIX BGFX_CONFIG_DEBUG
|
||||
|
|
412
src/image.cpp
412
src/image.cpp
|
@ -30,7 +30,6 @@ namespace bgfx
|
|||
4, // PTC24
|
||||
0, // Unknown
|
||||
8, // L8
|
||||
32, // BGRX8
|
||||
32, // BGRA8
|
||||
64, // RGBA16
|
||||
64, // RGBA16F
|
||||
|
@ -564,174 +563,6 @@ namespace bgfx
|
|||
}
|
||||
}
|
||||
|
||||
void Mip::decode(uint8_t* _dst)
|
||||
{
|
||||
const uint8_t* src = m_data;
|
||||
|
||||
if (TextureFormat::Unknown > m_type)
|
||||
{
|
||||
uint32_t width = m_width/4;
|
||||
uint32_t height = m_height/4;
|
||||
uint32_t pitch = m_width*4;
|
||||
|
||||
uint8_t temp[16*4];
|
||||
|
||||
switch (m_type)
|
||||
{
|
||||
case TextureFormat::BC1:
|
||||
for (uint32_t yy = 0; yy < height; ++yy)
|
||||
{
|
||||
for (uint32_t xx = 0; xx < width; ++xx)
|
||||
{
|
||||
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);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case TextureFormat::BC2:
|
||||
for (uint32_t yy = 0; yy < height; ++yy)
|
||||
{
|
||||
for (uint32_t xx = 0; xx < width; ++xx)
|
||||
{
|
||||
decodeBlockDxt23A(temp+3, src);
|
||||
src += 8;
|
||||
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);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case TextureFormat::BC3:
|
||||
for (uint32_t yy = 0; yy < height; ++yy)
|
||||
{
|
||||
for (uint32_t xx = 0; xx < width; ++xx)
|
||||
{
|
||||
decodeBlockDxt45A(temp+3, src);
|
||||
src += 8;
|
||||
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);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case TextureFormat::BC4:
|
||||
for (uint32_t yy = 0; yy < height; ++yy)
|
||||
{
|
||||
for (uint32_t xx = 0; xx < width; ++xx)
|
||||
{
|
||||
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);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case TextureFormat::BC5:
|
||||
for (uint32_t yy = 0; yy < height; ++yy)
|
||||
{
|
||||
for (uint32_t xx = 0; xx < width; ++xx)
|
||||
{
|
||||
decodeBlockDxt45A(temp+1, src);
|
||||
src += 8;
|
||||
decodeBlockDxt45A(temp+2, 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);
|
||||
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);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case TextureFormat::ETC1:
|
||||
for (uint32_t yy = 0; yy < height; ++yy)
|
||||
{
|
||||
for (uint32_t xx = 0; xx < width; ++xx)
|
||||
{
|
||||
decodeBlockEtc1(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);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
// Decompression not implemented... Make ugly red-yellow checkerboard texture.
|
||||
imageCheckerboard(m_width, m_height, 16, UINT32_C(0xffff0000), UINT32_C(0xffffff00), _dst);
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
uint32_t width = m_width;
|
||||
uint32_t height = m_height;
|
||||
|
||||
if (m_bpp == 8
|
||||
|| m_bpp == 32
|
||||
|| m_bpp == 64)
|
||||
{
|
||||
uint32_t pitch = m_width*m_bpp/8;
|
||||
memcpy(_dst, src, pitch*height);
|
||||
}
|
||||
else
|
||||
{
|
||||
uint32_t pitch = m_width*4;
|
||||
for (uint32_t yy = 0; yy < height; ++yy)
|
||||
{
|
||||
uint8_t* dst = &_dst[yy*pitch];
|
||||
|
||||
for (uint32_t xx = 0; xx < width; ++xx)
|
||||
{
|
||||
memcpy(dst, src, 3);
|
||||
dst[3] = 255;
|
||||
dst += 4;
|
||||
src += 3;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// DDS
|
||||
#define DDS_MAGIC BX_MAKEFOURCC('D', 'D', 'S', ' ')
|
||||
#define DDS_HEADER_SIZE 124
|
||||
|
@ -803,7 +634,6 @@ namespace bgfx
|
|||
{ DDS_BC5U, TextureFormat::BC5 },
|
||||
{ D3DFMT_A16B16G16R16, TextureFormat::RGBA16 },
|
||||
{ D3DFMT_A16B16G16R16F, TextureFormat::RGBA16F },
|
||||
{ DDPF_RGB, TextureFormat::BGRX8 },
|
||||
{ DDPF_RGB|DDPF_ALPHAPIXELS, TextureFormat::BGRA8 },
|
||||
{ DDPF_INDEXED, TextureFormat::L8 },
|
||||
{ DDPF_LUMINANCE, TextureFormat::L8 },
|
||||
|
@ -889,31 +719,30 @@ namespace bgfx
|
|||
|
||||
uint8_t bpp = 0;
|
||||
uint8_t blockSize = 1;
|
||||
TextureFormat::Enum type = TextureFormat::Unknown;
|
||||
TextureFormat::Enum format = TextureFormat::Unknown;
|
||||
bool hasAlpha = pixelFlags & DDPF_ALPHAPIXELS;
|
||||
|
||||
uint32_t format = pixelFlags & DDPF_FOURCC ? fourcc : pixelFlags;
|
||||
uint32_t ddsFormat = pixelFlags & DDPF_FOURCC ? fourcc : pixelFlags;
|
||||
for (uint32_t ii = 0; ii < BX_COUNTOF(s_translateDdsFormat); ++ii)
|
||||
{
|
||||
if (s_translateDdsFormat[ii].m_format == format)
|
||||
if (s_translateDdsFormat[ii].m_format == ddsFormat)
|
||||
{
|
||||
type = s_translateDdsFormat[ii].m_textureFormat;
|
||||
format = s_translateDdsFormat[ii].m_textureFormat;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
bpp = TextureFormat::BGRX8 == type // special case to force conversion to 32-bpp.
|
||||
? 24
|
||||
: getBitsPerPixel(type)
|
||||
;
|
||||
blockSize = type < TextureFormat::Unknown ? 4*4 : 1;
|
||||
bpp = getBitsPerPixel(format);
|
||||
blockSize = format < TextureFormat::Unknown ? 4*4 : 1;
|
||||
blockSize = blockSize*bpp/8;
|
||||
|
||||
_imageContainer.m_type = type;
|
||||
_imageContainer.m_data = NULL;
|
||||
_imageContainer.m_size = 0;
|
||||
_imageContainer.m_offset = DDS_IMAGE_DATA_OFFSET;
|
||||
_imageContainer.m_width = width;
|
||||
_imageContainer.m_height = height;
|
||||
_imageContainer.m_depth = depth;
|
||||
_imageContainer.m_format = format;
|
||||
_imageContainer.m_blockSize = blockSize;
|
||||
_imageContainer.m_numMips = (caps[0] & DDSCAPS_MIPMAP) ? mips : 1;
|
||||
_imageContainer.m_bpp = bpp;
|
||||
|
@ -921,7 +750,7 @@ namespace bgfx
|
|||
_imageContainer.m_cubeMap = cubeMap;
|
||||
_imageContainer.m_ktx = false;
|
||||
|
||||
return TextureFormat::Unknown != type;
|
||||
return TextureFormat::Unknown != format;
|
||||
}
|
||||
|
||||
// KTX
|
||||
|
@ -1043,30 +872,29 @@ namespace bgfx
|
|||
|
||||
uint8_t bpp = 0;
|
||||
uint8_t blockSize = 1;
|
||||
TextureFormat::Enum type = TextureFormat::Unknown;
|
||||
TextureFormat::Enum format = TextureFormat::Unknown;
|
||||
bool hasAlpha = false;
|
||||
|
||||
for (uint32_t ii = 0; ii < BX_COUNTOF(s_translateKtxFormat); ++ii)
|
||||
{
|
||||
if (s_translateKtxFormat[ii].m_format == glInternalFormat)
|
||||
{
|
||||
type = s_translateKtxFormat[ii].m_textureFormat;
|
||||
format = s_translateKtxFormat[ii].m_textureFormat;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
bpp = TextureFormat::BGRX8 == type // special case to force conversion to 32-bpp.
|
||||
? 24
|
||||
: getBitsPerPixel(type)
|
||||
;
|
||||
blockSize = type < TextureFormat::Unknown ? 4*4 : 1;
|
||||
bpp = getBitsPerPixel(format);
|
||||
blockSize = format < TextureFormat::Unknown ? 4*4 : 1;
|
||||
blockSize = blockSize*bpp/8;
|
||||
|
||||
_imageContainer.m_type = type;
|
||||
_imageContainer.m_data = NULL;
|
||||
_imageContainer.m_size = 0;
|
||||
_imageContainer.m_offset = (uint32_t)offset;
|
||||
_imageContainer.m_width = width;
|
||||
_imageContainer.m_height = height;
|
||||
_imageContainer.m_depth = depth;
|
||||
_imageContainer.m_format = format;
|
||||
_imageContainer.m_blockSize = blockSize;
|
||||
_imageContainer.m_numMips = numMips;
|
||||
_imageContainer.m_bpp = bpp;
|
||||
|
@ -1074,7 +902,7 @@ namespace bgfx
|
|||
_imageContainer.m_cubeMap = numFaces > 1;
|
||||
_imageContainer.m_ktx = true;
|
||||
|
||||
return TextureFormat::Unknown != type;
|
||||
return TextureFormat::Unknown != format;
|
||||
}
|
||||
|
||||
// PVR3
|
||||
|
@ -1164,7 +992,7 @@ namespace bgfx
|
|||
|
||||
uint8_t bpp = 0;
|
||||
uint8_t blockSize = 1;
|
||||
TextureFormat::Enum type = TextureFormat::Unknown;
|
||||
TextureFormat::Enum format = TextureFormat::Unknown;
|
||||
bool hasAlpha = false;
|
||||
|
||||
for (uint32_t ii = 0; ii < BX_COUNTOF(s_translatePvr3Format); ++ii)
|
||||
|
@ -1172,23 +1000,22 @@ namespace bgfx
|
|||
if (s_translatePvr3Format[ii].m_format == pixelFormat
|
||||
&& channelType == (s_translatePvr3Format[ii].m_channelTypeMask & channelType) )
|
||||
{
|
||||
type = s_translatePvr3Format[ii].m_textureFormat;
|
||||
format = s_translatePvr3Format[ii].m_textureFormat;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
bpp = TextureFormat::BGRX8 == type // special case to force conversion to 32-bpp.
|
||||
? 24
|
||||
: getBitsPerPixel(type)
|
||||
;
|
||||
blockSize = type < TextureFormat::Unknown ? 4*4 : 1;
|
||||
bpp = getBitsPerPixel(format);
|
||||
blockSize = format < TextureFormat::Unknown ? 4*4 : 1;
|
||||
blockSize = blockSize*bpp/8;
|
||||
|
||||
_imageContainer.m_type = type;
|
||||
_imageContainer.m_data = NULL;
|
||||
_imageContainer.m_size = 0;
|
||||
_imageContainer.m_offset = (uint32_t)offset;
|
||||
_imageContainer.m_width = width;
|
||||
_imageContainer.m_height = height;
|
||||
_imageContainer.m_depth = depth;
|
||||
_imageContainer.m_format = format;
|
||||
_imageContainer.m_blockSize = blockSize;
|
||||
_imageContainer.m_numMips = numMips;
|
||||
_imageContainer.m_bpp = bpp;
|
||||
|
@ -1196,7 +1023,7 @@ namespace bgfx
|
|||
_imageContainer.m_cubeMap = numFaces > 1;
|
||||
_imageContainer.m_ktx = false;
|
||||
|
||||
return TextureFormat::Unknown != type;
|
||||
return TextureFormat::Unknown != format;
|
||||
}
|
||||
|
||||
bool imageParse(ImageContainer& _imageContainer, bx::ReaderSeekerI* _reader)
|
||||
|
@ -1216,6 +1043,39 @@ namespace bgfx
|
|||
{
|
||||
return imageParsePvr3(_imageContainer, _reader);
|
||||
}
|
||||
else if (BGFX_CHUNK_MAGIC_TEX == magic)
|
||||
{
|
||||
TextureCreate tc;
|
||||
bx::read(_reader, tc);
|
||||
|
||||
uint32_t bpp = getBitsPerPixel(TextureFormat::Enum(tc.m_format) );
|
||||
uint32_t blockSize = tc.m_format < TextureFormat::Unknown ? 4*4 : 1;
|
||||
blockSize = blockSize*bpp/8;
|
||||
|
||||
_imageContainer.m_format = tc.m_format;
|
||||
_imageContainer.m_offset = UINT32_MAX;
|
||||
if (NULL == tc.m_mem)
|
||||
{
|
||||
_imageContainer.m_data = NULL;
|
||||
_imageContainer.m_size = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
_imageContainer.m_data = tc.m_mem->data;
|
||||
_imageContainer.m_size = tc.m_mem->size;
|
||||
}
|
||||
_imageContainer.m_width = tc.m_width;
|
||||
_imageContainer.m_height = tc.m_height;
|
||||
_imageContainer.m_depth = tc.m_depth;
|
||||
_imageContainer.m_blockSize = blockSize;
|
||||
_imageContainer.m_numMips = tc.m_numMips;
|
||||
_imageContainer.m_bpp = getBitsPerPixel(TextureFormat::Enum(tc.m_format) );
|
||||
_imageContainer.m_hasAlpha = false;
|
||||
_imageContainer.m_cubeMap = tc.m_cubeMap;
|
||||
_imageContainer.m_ktx = false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
@ -1226,14 +1086,162 @@ namespace bgfx
|
|||
return imageParse(_imageContainer, &reader);
|
||||
}
|
||||
|
||||
bool imageGetRawData(const ImageContainer& _imageContainer, uint8_t _side, uint8_t _lod, const void* _data, uint32_t _size, Mip& _mip)
|
||||
void imageDecodeToBgra8(uint8_t* _dst, const uint8_t* _src, uint32_t _width, uint32_t _height, uint8_t _type)
|
||||
{
|
||||
const uint8_t* src = _src;
|
||||
|
||||
uint32_t width = _width/4;
|
||||
uint32_t height = _height/4;
|
||||
uint32_t pitch = _width*4;
|
||||
|
||||
uint8_t temp[16*4];
|
||||
|
||||
switch (_type)
|
||||
{
|
||||
case TextureFormat::BC1:
|
||||
for (uint32_t yy = 0; yy < height; ++yy)
|
||||
{
|
||||
for (uint32_t xx = 0; xx < width; ++xx)
|
||||
{
|
||||
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);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case TextureFormat::BC2:
|
||||
for (uint32_t yy = 0; yy < height; ++yy)
|
||||
{
|
||||
for (uint32_t xx = 0; xx < width; ++xx)
|
||||
{
|
||||
decodeBlockDxt23A(temp+3, src);
|
||||
src += 8;
|
||||
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);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case TextureFormat::BC3:
|
||||
for (uint32_t yy = 0; yy < height; ++yy)
|
||||
{
|
||||
for (uint32_t xx = 0; xx < width; ++xx)
|
||||
{
|
||||
decodeBlockDxt45A(temp+3, src);
|
||||
src += 8;
|
||||
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);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case TextureFormat::BC4:
|
||||
for (uint32_t yy = 0; yy < height; ++yy)
|
||||
{
|
||||
for (uint32_t xx = 0; xx < width; ++xx)
|
||||
{
|
||||
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);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case TextureFormat::BC5:
|
||||
for (uint32_t yy = 0; yy < height; ++yy)
|
||||
{
|
||||
for (uint32_t xx = 0; xx < width; ++xx)
|
||||
{
|
||||
decodeBlockDxt45A(temp+1, src);
|
||||
src += 8;
|
||||
decodeBlockDxt45A(temp+2, 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);
|
||||
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);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case TextureFormat::ETC1:
|
||||
for (uint32_t yy = 0; yy < height; ++yy)
|
||||
{
|
||||
for (uint32_t xx = 0; xx < width; ++xx)
|
||||
{
|
||||
decodeBlockEtc1(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);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
// Decompression not implemented... Make ugly red-yellow checkerboard texture.
|
||||
imageCheckerboard(_width, _height, 16, UINT32_C(0xffff0000), UINT32_C(0xffffff00), _dst);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
bool imageGetRawData(const ImageContainer& _imageContainer, uint8_t _side, uint8_t _lod, const void* _data, uint32_t _size, ImageMip& _mip)
|
||||
{
|
||||
const uint32_t blockSize = _imageContainer.m_blockSize;
|
||||
uint32_t offset = _imageContainer.m_offset;
|
||||
const uint8_t bpp = _imageContainer.m_bpp;
|
||||
TextureFormat::Enum type = _imageContainer.m_type;
|
||||
TextureFormat::Enum type = TextureFormat::Enum(_imageContainer.m_format);
|
||||
bool hasAlpha = _imageContainer.m_hasAlpha;
|
||||
|
||||
if (UINT32_MAX == _imageContainer.m_offset)
|
||||
{
|
||||
if (NULL == _imageContainer.m_data)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
offset = 0;
|
||||
_data = _imageContainer.m_data;
|
||||
_size = _imageContainer.m_size;
|
||||
}
|
||||
|
||||
for (uint8_t side = 0, numSides = _imageContainer.m_cubeMap ? 6 : 1; side < numSides; ++side)
|
||||
{
|
||||
uint32_t width = _imageContainer.m_width;
|
||||
|
@ -1269,7 +1277,7 @@ namespace bgfx
|
|||
_mip.m_size = size;
|
||||
_mip.m_data = (const uint8_t*)_data + offset;
|
||||
_mip.m_bpp = bpp;
|
||||
_mip.m_type = type;
|
||||
_mip.m_format = type;
|
||||
_mip.m_hasAlpha = hasAlpha;
|
||||
return true;
|
||||
}
|
||||
|
|
17
src/image.h
17
src/image.h
|
@ -12,11 +12,13 @@ namespace bgfx
|
|||
{
|
||||
struct ImageContainer
|
||||
{
|
||||
TextureFormat::Enum m_type;
|
||||
void* m_data;
|
||||
uint32_t m_size;
|
||||
uint32_t m_offset;
|
||||
uint32_t m_width;
|
||||
uint32_t m_height;
|
||||
uint32_t m_depth;
|
||||
uint8_t m_format;
|
||||
uint8_t m_blockSize;
|
||||
uint8_t m_numMips;
|
||||
uint8_t m_bpp;
|
||||
|
@ -25,18 +27,16 @@ namespace bgfx
|
|||
bool m_ktx;
|
||||
};
|
||||
|
||||
struct Mip
|
||||
struct ImageMip
|
||||
{
|
||||
uint32_t m_width;
|
||||
uint32_t m_height;
|
||||
uint32_t m_blockSize;
|
||||
uint32_t m_size;
|
||||
uint8_t m_bpp;
|
||||
uint8_t m_type;
|
||||
uint8_t m_format;
|
||||
bool m_hasAlpha;
|
||||
const uint8_t* m_data;
|
||||
|
||||
void decode(uint8_t* _dst);
|
||||
};
|
||||
|
||||
///
|
||||
|
@ -61,10 +61,13 @@ namespace bgfx
|
|||
bool imageParse(ImageContainer& _imageContainer, bx::ReaderSeekerI* _reader);
|
||||
|
||||
///
|
||||
bool imageParse(ImageContainer& _dds, const void* _data, uint32_t _size);
|
||||
bool imageParse(ImageContainer& _imageContainer, const void* _data, uint32_t _size);
|
||||
|
||||
///
|
||||
bool imageGetRawData(const ImageContainer& _dds, uint8_t _side, uint8_t _index, const void* _data, uint32_t _size, Mip& _mip);
|
||||
void imageDecodeToBgra8(uint8_t* _dst, const uint8_t* _src, uint32_t _width, uint32_t _height, uint8_t _type);
|
||||
|
||||
///
|
||||
bool imageGetRawData(const ImageContainer& _dds, uint8_t _side, uint8_t _index, const void* _data, uint32_t _size, ImageMip& _mip);
|
||||
|
||||
} // namespace bgfx
|
||||
|
||||
|
|
|
@ -200,7 +200,6 @@ namespace bgfx
|
|||
{ DXGI_FORMAT_UNKNOWN }, // PTC24
|
||||
{ DXGI_FORMAT_UNKNOWN }, // Unknown
|
||||
{ DXGI_FORMAT_R8_UNORM }, // L8
|
||||
{ DXGI_FORMAT_B8G8R8A8_UNORM }, // BGRX8
|
||||
{ DXGI_FORMAT_B8G8R8A8_UNORM }, // BGRA8
|
||||
{ DXGI_FORMAT_R16G16B16A16_UNORM }, // RGBA16
|
||||
{ DXGI_FORMAT_R16G16B16A16_FLOAT }, // RGBA16F
|
||||
|
@ -1643,7 +1642,20 @@ namespace bgfx
|
|||
|
||||
if (imageParse(imageContainer, _mem->data, _mem->size) )
|
||||
{
|
||||
bool decompress = DXGI_FORMAT_UNKNOWN == s_textureFormat[imageContainer.m_type].m_fmt;
|
||||
m_requestedFormat = (uint8_t)imageContainer.m_format;
|
||||
m_textureFormat = (uint8_t)imageContainer.m_format;
|
||||
|
||||
const TextureFormatInfo& tfi = s_textureFormat[m_requestedFormat];
|
||||
const bool convert = DXGI_FORMAT_UNKNOWN == tfi.m_fmt;
|
||||
|
||||
uint8_t bpp = getBitsPerPixel(TextureFormat::Enum(m_textureFormat) );
|
||||
if (convert)
|
||||
{
|
||||
m_textureFormat = (uint8_t)TextureFormat::BGRA8;
|
||||
bpp = 32;
|
||||
}
|
||||
|
||||
DXGI_FORMAT format = s_textureFormat[m_textureFormat].m_fmt;
|
||||
|
||||
if (imageContainer.m_cubeMap)
|
||||
{
|
||||
|
@ -1658,92 +1670,61 @@ namespace bgfx
|
|||
m_type = Texture2D;
|
||||
}
|
||||
|
||||
TextureFormat::Enum textureFormat = decompress ? TextureFormat::BGRA8 : imageContainer.m_type;
|
||||
m_numMips = imageContainer.m_numMips;
|
||||
|
||||
uint32_t numSrd = imageContainer.m_numMips*(imageContainer.m_cubeMap ? 6 : 1);
|
||||
D3D11_SUBRESOURCE_DATA* srd = (D3D11_SUBRESOURCE_DATA*)alloca(numSrd*sizeof(D3D11_SUBRESOURCE_DATA) );
|
||||
|
||||
uint32_t kk = 0;
|
||||
bool convert = false;
|
||||
|
||||
m_numMips = imageContainer.m_numMips;
|
||||
|
||||
if (decompress
|
||||
|| TextureFormat::Unknown < imageContainer.m_type)
|
||||
for (uint8_t side = 0, numSides = imageContainer.m_cubeMap ? 6 : 1; side < numSides; ++side)
|
||||
{
|
||||
uint32_t bpp = getBitsPerPixel(textureFormat);
|
||||
convert = decompress
|
||||
|| TextureFormat::BGRX8 == textureFormat
|
||||
;
|
||||
uint32_t width = imageContainer.m_width;
|
||||
uint32_t height = imageContainer.m_height;
|
||||
uint32_t depth = imageContainer.m_depth;
|
||||
|
||||
for (uint8_t side = 0, numSides = imageContainer.m_cubeMap ? 6 : 1; side < numSides; ++side)
|
||||
for (uint32_t lod = 0, num = m_numMips; lod < num; ++lod)
|
||||
{
|
||||
uint32_t width = imageContainer.m_width;
|
||||
uint32_t height = imageContainer.m_height;
|
||||
uint32_t depth = imageContainer.m_depth;
|
||||
width = bx::uint32_max(1, width);
|
||||
height = bx::uint32_max(1, height);
|
||||
depth = bx::uint32_max(1, depth);
|
||||
|
||||
for (uint32_t lod = 0, num = m_numMips; lod < num; ++lod)
|
||||
ImageMip mip;
|
||||
if (imageGetRawData(imageContainer, side, lod, _mem->data, _mem->size, mip) )
|
||||
{
|
||||
width = bx::uint32_max(1, width);
|
||||
height = bx::uint32_max(1, height);
|
||||
depth = bx::uint32_max(1, depth);
|
||||
srd[kk].pSysMem = mip.m_data;
|
||||
|
||||
Mip mip;
|
||||
if (imageGetRawData(imageContainer, side, lod, _mem->data, _mem->size, mip) )
|
||||
if (convert)
|
||||
{
|
||||
if (convert)
|
||||
{
|
||||
uint8_t* temp = (uint8_t*)g_realloc(NULL, mip.m_width*mip.m_height*bpp/8);
|
||||
mip.decode(temp);
|
||||
uint8_t* temp = (uint8_t*)g_realloc(NULL, mip.m_width*mip.m_height*bpp/8);
|
||||
imageDecodeToBgra8(temp, mip.m_data, mip.m_width, mip.m_height, mip.m_format);
|
||||
|
||||
srd[kk].pSysMem = temp;
|
||||
srd[kk].SysMemPitch = mip.m_width*bpp/8;
|
||||
}
|
||||
else
|
||||
{
|
||||
srd[kk].pSysMem = mip.m_data;
|
||||
srd[kk].SysMemPitch = mip.m_width*mip.m_bpp/8;
|
||||
}
|
||||
|
||||
srd[kk].SysMemSlicePitch = mip.m_height*srd[kk].SysMemPitch;
|
||||
++kk;
|
||||
srd[kk].pSysMem = temp;
|
||||
srd[kk].SysMemPitch = mip.m_width*bpp/8;
|
||||
}
|
||||
else if (TextureFormat::Unknown > m_textureFormat)
|
||||
{
|
||||
srd[kk].SysMemPitch = (mip.m_width/4)*mip.m_blockSize;
|
||||
srd[kk].SysMemSlicePitch = (mip.m_height/4)*srd[kk].SysMemPitch;
|
||||
}
|
||||
else
|
||||
{
|
||||
srd[kk].SysMemPitch = mip.m_width*mip.m_bpp/8;
|
||||
}
|
||||
|
||||
width >>= 1;
|
||||
height >>= 1;
|
||||
depth >>= 1;
|
||||
srd[kk].SysMemSlicePitch = mip.m_height*srd[kk].SysMemPitch;
|
||||
++kk;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for (uint8_t side = 0, numSides = imageContainer.m_cubeMap ? 6 : 1; side < numSides; ++side)
|
||||
{
|
||||
for (uint32_t lod = 0, num = m_numMips; lod < num; ++lod)
|
||||
{
|
||||
Mip mip;
|
||||
if (imageGetRawData(imageContainer, side, lod, _mem->data, _mem->size, mip) )
|
||||
{
|
||||
srd[kk].pSysMem = mip.m_data;
|
||||
if (TextureFormat::Unknown > imageContainer.m_type)
|
||||
{
|
||||
srd[kk].SysMemPitch = (mip.m_width/4)*mip.m_blockSize;
|
||||
srd[kk].SysMemSlicePitch = (mip.m_height/4)*srd[kk].SysMemPitch;
|
||||
}
|
||||
else
|
||||
{
|
||||
srd[kk].SysMemPitch = mip.m_width*mip.m_bpp/8;
|
||||
srd[kk].SysMemSlicePitch = mip.m_height*srd[kk].SysMemPitch;
|
||||
}
|
||||
|
||||
++kk;
|
||||
}
|
||||
}
|
||||
width >>= 1;
|
||||
height >>= 1;
|
||||
depth >>= 1;
|
||||
}
|
||||
}
|
||||
|
||||
D3D11_SHADER_RESOURCE_VIEW_DESC srvd;
|
||||
memset(&srvd, 0, sizeof(srvd) );
|
||||
srvd.Format = s_textureFormat[textureFormat].m_fmt;
|
||||
srvd.Format = format;
|
||||
|
||||
switch (m_type)
|
||||
{
|
||||
|
@ -1757,7 +1738,7 @@ namespace bgfx
|
|||
desc.Format = srvd.Format;
|
||||
desc.SampleDesc.Count = 1;
|
||||
desc.SampleDesc.Quality = 0;
|
||||
desc.Usage = D3D11_USAGE_IMMUTABLE;
|
||||
desc.Usage = kk == 0 ? D3D11_USAGE_DEFAULT : D3D11_USAGE_IMMUTABLE;
|
||||
desc.BindFlags = D3D11_BIND_SHADER_RESOURCE;
|
||||
desc.CPUAccessFlags = 0;
|
||||
|
||||
|
@ -1776,7 +1757,7 @@ namespace bgfx
|
|||
srvd.Texture2D.MipLevels = imageContainer.m_numMips;
|
||||
}
|
||||
|
||||
DX_CHECK(s_renderCtx.m_device->CreateTexture2D(&desc, srd, &m_texture2d) );
|
||||
DX_CHECK(s_renderCtx.m_device->CreateTexture2D(&desc, kk == 0 ? NULL : srd, &m_texture2d) );
|
||||
}
|
||||
break;
|
||||
|
||||
|
@ -1788,7 +1769,7 @@ namespace bgfx
|
|||
desc.Depth = imageContainer.m_depth;
|
||||
desc.MipLevels = imageContainer.m_numMips;
|
||||
desc.Format = srvd.Format;
|
||||
desc.Usage = D3D11_USAGE_IMMUTABLE;
|
||||
desc.Usage = kk == 0 ? D3D11_USAGE_DEFAULT : D3D11_USAGE_IMMUTABLE;
|
||||
desc.BindFlags = D3D11_BIND_SHADER_RESOURCE;
|
||||
desc.CPUAccessFlags = 0;
|
||||
desc.MiscFlags = 0;
|
||||
|
@ -1796,14 +1777,15 @@ namespace bgfx
|
|||
srvd.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE3D;
|
||||
srvd.Texture3D.MipLevels = imageContainer.m_numMips;
|
||||
|
||||
DX_CHECK(s_renderCtx.m_device->CreateTexture3D(&desc, srd, &m_texture3d) );
|
||||
DX_CHECK(s_renderCtx.m_device->CreateTexture3D(&desc, kk == 0 ? NULL : srd, &m_texture3d) );
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
DX_CHECK(s_renderCtx.m_device->CreateShaderResourceView(m_ptr, &srvd, &m_srv) );
|
||||
|
||||
if (convert)
|
||||
if (convert
|
||||
&& 0 != kk)
|
||||
{
|
||||
kk = 0;
|
||||
for (uint8_t side = 0, numSides = imageContainer.m_cubeMap ? 6 : 1; side < numSides; ++side)
|
||||
|
@ -1816,153 +1798,6 @@ namespace bgfx
|
|||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
bx::MemoryReader reader(_mem->data, _mem->size);
|
||||
|
||||
uint32_t magic;
|
||||
bx::read(&reader, magic);
|
||||
|
||||
if (BGFX_CHUNK_MAGIC_TEX == magic)
|
||||
{
|
||||
TextureCreate tc;
|
||||
bx::read(&reader, tc);
|
||||
|
||||
if (tc.m_cubeMap)
|
||||
{
|
||||
m_type = TextureCube;
|
||||
}
|
||||
else if (tc.m_depth > 1)
|
||||
{
|
||||
m_type = Texture3D;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_type = Texture2D;
|
||||
}
|
||||
|
||||
m_numMips = tc.m_numMips;
|
||||
|
||||
D3D11_SHADER_RESOURCE_VIEW_DESC srvd;
|
||||
memset(&srvd, 0, sizeof(srvd) );
|
||||
srvd.Format = s_textureFormat[tc.m_format].m_fmt;
|
||||
|
||||
if (NULL != tc.m_mem)
|
||||
{
|
||||
D3D11_TEXTURE2D_DESC desc;
|
||||
desc.Width = tc.m_width;
|
||||
desc.Height = tc.m_height;
|
||||
desc.MipLevels = tc.m_numMips;
|
||||
desc.ArraySize = 1;
|
||||
desc.Format = srvd.Format;
|
||||
desc.SampleDesc.Count = 1;
|
||||
desc.SampleDesc.Quality = 0;
|
||||
desc.Usage = D3D11_USAGE_IMMUTABLE;
|
||||
desc.BindFlags = D3D11_BIND_SHADER_RESOURCE;
|
||||
desc.CPUAccessFlags = 0;
|
||||
desc.MiscFlags = 0;
|
||||
|
||||
srvd.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2D;
|
||||
srvd.Texture2D.MipLevels = tc.m_numMips;
|
||||
|
||||
D3D11_SUBRESOURCE_DATA* srd = (D3D11_SUBRESOURCE_DATA*)alloca(tc.m_numMips*sizeof(D3D11_SUBRESOURCE_DATA) );
|
||||
uint32_t bpp = getBitsPerPixel(TextureFormat::Enum(tc.m_format) );
|
||||
uint8_t* data = tc.m_mem->data;
|
||||
|
||||
for (uint8_t side = 0, numSides = tc.m_cubeMap ? 6 : 1; side < numSides; ++side)
|
||||
{
|
||||
uint32_t width = tc.m_width;
|
||||
uint32_t height = tc.m_height;
|
||||
uint32_t depth = tc.m_depth;
|
||||
|
||||
for (uint32_t lod = 0, num = tc.m_numMips; lod < num; ++lod)
|
||||
{
|
||||
width = bx::uint32_max(1, width);
|
||||
height = bx::uint32_max(1, height);
|
||||
depth = bx::uint32_max(1, depth);
|
||||
|
||||
srd[lod].pSysMem = data;
|
||||
srd[lod].SysMemPitch = width*bpp/8;
|
||||
srd[lod].SysMemSlicePitch = 0;
|
||||
|
||||
data += width*height*bpp/8;
|
||||
|
||||
width >>= 1;
|
||||
height >>= 1;
|
||||
depth >>= 1;
|
||||
}
|
||||
}
|
||||
|
||||
DX_CHECK(s_renderCtx.m_device->CreateTexture2D(&desc, srd, &m_texture2d) );
|
||||
|
||||
release(tc.m_mem);
|
||||
}
|
||||
else
|
||||
{
|
||||
switch (m_type)
|
||||
{
|
||||
case Texture2D:
|
||||
case TextureCube:
|
||||
{
|
||||
D3D11_TEXTURE2D_DESC desc;
|
||||
desc.Width = tc.m_width;
|
||||
desc.Height = tc.m_height;
|
||||
desc.MipLevels = tc.m_numMips;
|
||||
desc.Format = srvd.Format;
|
||||
desc.SampleDesc.Count = 1;
|
||||
desc.SampleDesc.Quality = 0;
|
||||
desc.Usage = D3D11_USAGE_DEFAULT;
|
||||
desc.BindFlags = D3D11_BIND_SHADER_RESOURCE;
|
||||
desc.CPUAccessFlags = 0;
|
||||
|
||||
if (TextureCube == m_type)
|
||||
{
|
||||
desc.ArraySize = 6;
|
||||
desc.MiscFlags = D3D11_RESOURCE_MISC_TEXTURECUBE;
|
||||
srvd.ViewDimension = D3D11_SRV_DIMENSION_TEXTURECUBE;
|
||||
srvd.TextureCube.MipLevels = m_numMips;
|
||||
}
|
||||
else
|
||||
{
|
||||
desc.ArraySize = 1;
|
||||
desc.MiscFlags = 0;
|
||||
srvd.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2D;
|
||||
srvd.Texture2D.MipLevels = m_numMips;
|
||||
}
|
||||
|
||||
DX_CHECK(s_renderCtx.m_device->CreateTexture2D(&desc, NULL, &m_texture2d) );
|
||||
}
|
||||
break;
|
||||
|
||||
case Texture3D:
|
||||
{
|
||||
D3D11_TEXTURE3D_DESC desc;
|
||||
desc.Width = tc.m_width;
|
||||
desc.Height = tc.m_height;
|
||||
desc.Depth = tc.m_depth;
|
||||
desc.MipLevels = tc.m_numMips;
|
||||
desc.Format = srvd.Format;
|
||||
desc.Usage = D3D11_USAGE_DEFAULT;
|
||||
desc.BindFlags = D3D11_BIND_SHADER_RESOURCE;
|
||||
desc.CPUAccessFlags = 0;
|
||||
desc.MiscFlags = 0;
|
||||
|
||||
srvd.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE3D;
|
||||
srvd.Texture3D.MipLevels = m_numMips;
|
||||
|
||||
DX_CHECK(s_renderCtx.m_device->CreateTexture3D(&desc, NULL, &m_texture3d) );
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
DX_CHECK(s_renderCtx.m_device->CreateShaderResourceView(m_ptr, &srvd, &m_srv) );
|
||||
}
|
||||
else
|
||||
{
|
||||
//
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Texture::destroy()
|
||||
|
@ -1994,23 +1829,28 @@ namespace bgfx
|
|||
box.back = box.front + _depth;
|
||||
|
||||
uint32_t subres = _mip + (_side * m_numMips);
|
||||
#if 0
|
||||
D3D11_MAPPED_SUBRESOURCE mapped;
|
||||
DX_CHECK(deviceCtx->Map(m_ptr, 0, D3D11_MAP_WRITE, D3D11_MAP_FLAG_DO_NOT_WAIT, &mapped) );
|
||||
memcpy( (uint8_t*)mapped.pData + subres*mapped.DepthPitch, _mem->data, _mem->size);
|
||||
deviceCtx->Unmap(m_ptr, 0);
|
||||
|
||||
deviceCtx->CopySubresourceRegion(m_ptr
|
||||
, subres
|
||||
, _rect.m_x
|
||||
, _rect.m_y
|
||||
, _rect.m_z
|
||||
, staging // D3D11_USAGE_STAGING
|
||||
, ...
|
||||
);
|
||||
#else
|
||||
deviceCtx->UpdateSubresource(m_ptr, subres, &box, _mem->data, _rect.m_width*4, 0);
|
||||
#endif // 0
|
||||
uint32_t bpp = getBitsPerPixel(TextureFormat::Enum(m_textureFormat) );
|
||||
uint32_t srcpitch = _rect.m_width*bpp/8;
|
||||
|
||||
const bool convert = m_textureFormat != m_requestedFormat;
|
||||
|
||||
uint8_t* data = _mem->data;
|
||||
uint8_t* temp = NULL;
|
||||
|
||||
if (convert)
|
||||
{
|
||||
uint8_t* temp = (uint8_t*)g_realloc(NULL, srcpitch*_rect.m_height);
|
||||
imageDecodeToBgra8(temp, data, _rect.m_width, _rect.m_height, m_requestedFormat);
|
||||
data = temp;
|
||||
}
|
||||
|
||||
deviceCtx->UpdateSubresource(m_ptr, subres, &box, data, srcpitch, 0);
|
||||
|
||||
if (NULL != temp)
|
||||
{
|
||||
g_free(temp);
|
||||
}
|
||||
}
|
||||
|
||||
void RenderTarget::create(uint16_t _width, uint16_t _height, uint32_t _flags, uint32_t _textureFlags)
|
||||
|
|
|
@ -255,7 +255,9 @@ namespace bgfx
|
|||
|
||||
ID3D11ShaderResourceView* m_srv;
|
||||
ID3D11SamplerState* m_sampler;
|
||||
Enum m_type;
|
||||
uint8_t m_type;
|
||||
uint8_t m_requestedFormat;
|
||||
uint8_t m_textureFormat;
|
||||
uint8_t m_numMips;
|
||||
};
|
||||
|
||||
|
|
|
@ -183,36 +183,34 @@ namespace bgfx
|
|||
struct TextureFormatInfo
|
||||
{
|
||||
D3DFORMAT m_fmt;
|
||||
uint8_t m_bpp;
|
||||
};
|
||||
|
||||
static const TextureFormatInfo s_textureFormat[TextureFormat::Count] =
|
||||
static TextureFormatInfo s_textureFormat[TextureFormat::Count] =
|
||||
{
|
||||
{ D3DFMT_DXT1, 4 }, // BC1
|
||||
{ D3DFMT_DXT3, 8 }, // BC2
|
||||
{ D3DFMT_DXT5, 8 }, // BC3
|
||||
{ D3DFMT_ATI1, 4 }, // BC4
|
||||
{ D3DFMT_ATI2, 8 }, // BC5
|
||||
{ D3DFMT_UNKNOWN, 0 }, // ETC1
|
||||
{ D3DFMT_UNKNOWN, 0 }, // ETC2
|
||||
{ D3DFMT_UNKNOWN, 0 }, // ETC2A
|
||||
{ D3DFMT_UNKNOWN, 0 }, // ETC2A1
|
||||
{ D3DFMT_UNKNOWN, 0 }, // PTC12
|
||||
{ D3DFMT_UNKNOWN, 0 }, // PTC14
|
||||
{ D3DFMT_UNKNOWN, 0 }, // PTC12A
|
||||
{ D3DFMT_UNKNOWN, 0 }, // PTC14A
|
||||
{ D3DFMT_UNKNOWN, 0 }, // PTC22
|
||||
{ D3DFMT_UNKNOWN, 0 }, // PTC24
|
||||
{ D3DFMT_UNKNOWN, 0 }, // Unknown
|
||||
{ D3DFMT_L8, 8 }, // L8
|
||||
{ D3DFMT_X8R8G8B8, 32 }, // BGRX8
|
||||
{ D3DFMT_A8R8G8B8, 32 }, // BGRA8
|
||||
{ D3DFMT_A16B16G16R16, 64 }, // RGBA16
|
||||
{ D3DFMT_A16B16G16R16F, 64 }, // RGBA16F
|
||||
{ D3DFMT_R5G6B5, 16 }, // R5G6B5
|
||||
{ D3DFMT_A4R4G4B4, 16 }, // RGBA4
|
||||
{ D3DFMT_A1R5G5B5, 16 }, // RGB5A1
|
||||
{ D3DFMT_A2B10G10R10, 32 }, // RGB10A2
|
||||
{ D3DFMT_DXT1 }, // BC1
|
||||
{ D3DFMT_DXT3 }, // BC2
|
||||
{ D3DFMT_DXT5 }, // BC3
|
||||
{ D3DFMT_UNKNOWN }, // BC4
|
||||
{ D3DFMT_UNKNOWN }, // BC5
|
||||
{ D3DFMT_UNKNOWN }, // ETC1
|
||||
{ D3DFMT_UNKNOWN }, // ETC2
|
||||
{ D3DFMT_UNKNOWN }, // ETC2A
|
||||
{ D3DFMT_UNKNOWN }, // ETC2A1
|
||||
{ D3DFMT_UNKNOWN }, // PTC12
|
||||
{ D3DFMT_UNKNOWN }, // PTC14
|
||||
{ D3DFMT_UNKNOWN }, // PTC12A
|
||||
{ D3DFMT_UNKNOWN }, // PTC14A
|
||||
{ D3DFMT_UNKNOWN }, // PTC22
|
||||
{ D3DFMT_UNKNOWN }, // PTC24
|
||||
{ D3DFMT_UNKNOWN }, // Unknown
|
||||
{ D3DFMT_L8 }, // L8
|
||||
{ D3DFMT_A8R8G8B8 }, // BGRA8
|
||||
{ D3DFMT_A16B16G16R16 }, // RGBA16
|
||||
{ D3DFMT_A16B16G16R16F }, // RGBA16F
|
||||
{ D3DFMT_R5G6B5 }, // R5G6B5
|
||||
{ D3DFMT_A4R4G4B4 }, // RGBA4
|
||||
{ D3DFMT_A1R5G5B5 }, // RGB5A1
|
||||
{ D3DFMT_A2B10G10R10 }, // RGB10A2
|
||||
};
|
||||
|
||||
static ExtendedFormat s_extendedFormats[ExtendedFormat::Count] =
|
||||
|
@ -404,6 +402,7 @@ namespace bgfx
|
|||
BX_TRACE("Max fragment shader 2.0 instr. slots: %d", m_caps.PS20Caps.NumInstructionSlots);
|
||||
BX_TRACE("Max fragment shader 3.0 instr. slots: %d", m_caps.MaxPixelShader30InstructionSlots);
|
||||
|
||||
#if BGFX_CONFIG_RENDERER_USE_EXTENSIONS
|
||||
BX_TRACE("Extended formats:");
|
||||
for (uint32_t ii = 0; ii < ExtendedFormat::Count; ++ii)
|
||||
{
|
||||
|
@ -426,6 +425,10 @@ namespace bgfx
|
|||
m_device->SetRenderState(D3DRS_POINTSIZE, D3DFMT_INST);
|
||||
}
|
||||
|
||||
s_textureFormat[TextureFormat::BC4].m_fmt = s_extendedFormats[ExtendedFormat::Ati1].m_supported ? D3DFMT_ATI1 : D3DFMT_UNKNOWN;
|
||||
s_textureFormat[TextureFormat::BC5].m_fmt = s_extendedFormats[ExtendedFormat::Ati2].m_supported ? D3DFMT_ATI2 : D3DFMT_UNKNOWN;
|
||||
#endif // BGFX_CONFIG_RENDERER_USE_EXTENSIONS
|
||||
|
||||
uint32_t index = 1;
|
||||
for (const D3DFORMAT* fmt = &s_checkColorFormats[index]; *fmt != D3DFMT_UNKNOWN; ++fmt, ++index)
|
||||
{
|
||||
|
@ -1518,17 +1521,20 @@ namespace bgfx
|
|||
|
||||
if (imageParse(imageContainer, _mem->data, _mem->size) )
|
||||
{
|
||||
m_format = imageContainer.m_type;
|
||||
const TextureFormatInfo& tfi = s_textureFormat[imageContainer.m_type];
|
||||
m_requestedFormat = (uint8_t)imageContainer.m_format;
|
||||
m_textureFormat = (uint8_t)imageContainer.m_format;
|
||||
|
||||
bool decompress = false
|
||||
|| (TextureFormat::BC4 == imageContainer.m_type && !s_extendedFormats[ExtendedFormat::Ati1].m_supported)
|
||||
|| (TextureFormat::BC5 == imageContainer.m_type && !s_extendedFormats[ExtendedFormat::Ati2].m_supported)
|
||||
|| (D3DFMT_UNKNOWN == tfi.m_fmt)
|
||||
;
|
||||
const TextureFormatInfo& tfi = s_textureFormat[m_requestedFormat];
|
||||
const bool convert = D3DFMT_UNKNOWN == tfi.m_fmt;
|
||||
|
||||
D3DFORMAT format = decompress ? D3DFMT_A8R8G8B8 : tfi.m_fmt;
|
||||
uint8_t bpp = decompress ? 32 : tfi.m_bpp;
|
||||
uint8_t bpp = getBitsPerPixel(TextureFormat::Enum(m_textureFormat) );
|
||||
if (convert)
|
||||
{
|
||||
m_textureFormat = (uint8_t)TextureFormat::BGRA8;
|
||||
bpp = 32;
|
||||
}
|
||||
|
||||
D3DFORMAT format = s_textureFormat[m_textureFormat].m_fmt;
|
||||
|
||||
if (imageContainer.m_cubeMap)
|
||||
{
|
||||
|
@ -1543,167 +1549,82 @@ namespace bgfx
|
|||
createTexture(imageContainer.m_width, imageContainer.m_height, imageContainer.m_numMips, format);
|
||||
}
|
||||
|
||||
if (decompress
|
||||
|| TextureFormat::Unknown < imageContainer.m_type)
|
||||
// For BC4 and B5 in DX9 LockRect returns wrong number of
|
||||
// bytes. If actual mip size is used it causes memory corruption.
|
||||
// http://www.aras-p.info/texts/D3D9GPUHacks.html#3dc
|
||||
const bool useMipSize = true
|
||||
&& imageContainer.m_format != TextureFormat::BC4
|
||||
&& imageContainer.m_format != TextureFormat::BC5
|
||||
;
|
||||
|
||||
const bool compressed = TextureFormat::Unknown > m_requestedFormat;
|
||||
const uint32_t min = compressed ? 4 : 1;
|
||||
|
||||
for (uint8_t side = 0, numSides = imageContainer.m_cubeMap ? 6 : 1; side < numSides; ++side)
|
||||
{
|
||||
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 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)
|
||||
{
|
||||
uint32_t width = imageContainer.m_width;
|
||||
uint32_t height = imageContainer.m_height;
|
||||
uint32_t depth = imageContainer.m_depth;
|
||||
width = bx::uint32_max(1, width);
|
||||
height = bx::uint32_max(1, height);
|
||||
depth = bx::uint32_max(1, depth);
|
||||
mipWidth = bx::uint32_max(min, mipWidth);
|
||||
mipHeight = bx::uint32_max(min, mipHeight);
|
||||
uint32_t mipSize = width*height*depth*bpp/8;
|
||||
|
||||
for (uint32_t lod = 0, num = imageContainer.m_numMips; lod < num; ++lod)
|
||||
ImageMip mip;
|
||||
if (imageGetRawData(imageContainer, 0, lod, _mem->data, _mem->size, mip) )
|
||||
{
|
||||
width = bx::uint32_max(1, width);
|
||||
height = bx::uint32_max(1, height);
|
||||
depth = bx::uint32_max(1, depth);
|
||||
uint32_t pitch;
|
||||
uint32_t slicePitch;
|
||||
uint8_t* bits = lock(side, lod, pitch, slicePitch);
|
||||
|
||||
Mip mip;
|
||||
if (imageGetRawData(imageContainer, side, lod, _mem->data, _mem->size, mip) )
|
||||
if (convert)
|
||||
{
|
||||
uint32_t pitch;
|
||||
uint32_t slicePitch;
|
||||
uint8_t* bits = lock(side, lod, pitch, slicePitch);
|
||||
|
||||
if (width != mip.m_width
|
||||
|| height != mip.m_height)
|
||||
if (width != mipWidth
|
||||
|| height != mipHeight)
|
||||
{
|
||||
uint32_t srcpitch = mip.m_width*bpp/8;
|
||||
uint32_t srcpitch = mipWidth*bpp/8;
|
||||
|
||||
uint8_t* temp = (uint8_t*)g_realloc(NULL, srcpitch*mip.m_height);
|
||||
mip.decode(temp);
|
||||
uint8_t* temp = (uint8_t*)g_realloc(NULL, srcpitch*mipHeight);
|
||||
imageDecodeToBgra8(temp, mip.m_data, mip.m_width, mip.m_height, mip.m_format);
|
||||
|
||||
uint32_t dstpitch = pitch;
|
||||
for (uint32_t yy = 0; yy < height; ++yy)
|
||||
{
|
||||
uint8_t* src = &temp[yy*srcpitch];
|
||||
uint8_t* dst = &bits[yy*dstpitch];
|
||||
memcpy(dst, src, srcpitch);
|
||||
memcpy(dst, src, dstpitch);
|
||||
}
|
||||
|
||||
g_free(temp);
|
||||
}
|
||||
else
|
||||
{
|
||||
mip.decode(bits);
|
||||
imageDecodeToBgra8(bits, mip.m_data, mip.m_width, mip.m_height, mip.m_format);
|
||||
}
|
||||
|
||||
unlock(side, lod);
|
||||
}
|
||||
|
||||
width >>= 1;
|
||||
height >>= 1;
|
||||
depth >>= 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// For BC4 and B5 in DX9 LockRect returns wrong number of
|
||||
// bytes. If actual mip size is used it causes memory corruption.
|
||||
// http://www.aras-p.info/texts/D3D9GPUHacks.html#3dc
|
||||
bool useMipSize = true
|
||||
&& imageContainer.m_type != TextureFormat::BC4
|
||||
&& imageContainer.m_type != TextureFormat::BC5
|
||||
;
|
||||
|
||||
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 depth = imageContainer.m_depth;
|
||||
|
||||
for (uint32_t lod = 0, num = imageContainer.m_numMips; lod < num; ++lod)
|
||||
{
|
||||
width = bx::uint32_max(1, width);
|
||||
height = bx::uint32_max(1, height);
|
||||
depth = bx::uint32_max(1, depth);
|
||||
|
||||
Mip mip;
|
||||
if (imageGetRawData(imageContainer, 0, lod, _mem->data, _mem->size, mip) )
|
||||
else
|
||||
{
|
||||
uint32_t pitch;
|
||||
uint32_t slicePitch;
|
||||
uint8_t* dst = lock(side, lod, pitch, slicePitch);
|
||||
|
||||
uint32_t size = useMipSize ? mip.m_size : width*height*depth*bpp/8;
|
||||
|
||||
memcpy(dst, mip.m_data, size);
|
||||
|
||||
unlock(side, lod);
|
||||
uint32_t size = useMipSize ? mip.m_size : mipSize;
|
||||
memcpy(bits, mip.m_data, size);
|
||||
}
|
||||
|
||||
width >>= 1;
|
||||
height >>= 1;
|
||||
depth >>= 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
bx::MemoryReader reader(_mem->data, _mem->size);
|
||||
|
||||
uint32_t magic;
|
||||
bx::read(&reader, magic);
|
||||
|
||||
if (BGFX_CHUNK_MAGIC_TEX == magic)
|
||||
{
|
||||
TextureCreate tc;
|
||||
bx::read(&reader, tc);
|
||||
m_format = (TextureFormat::Enum)tc.m_format;
|
||||
|
||||
if (tc.m_cubeMap)
|
||||
{
|
||||
createCubeTexture(tc.m_width, tc.m_numMips, s_textureFormat[tc.m_format].m_fmt);
|
||||
}
|
||||
else if (tc.m_depth > 1)
|
||||
{
|
||||
createVolumeTexture(tc.m_width, tc.m_height, tc.m_depth, tc.m_numMips, s_textureFormat[tc.m_format].m_fmt);
|
||||
}
|
||||
else
|
||||
{
|
||||
createTexture(tc.m_width, tc.m_height, tc.m_numMips, s_textureFormat[tc.m_format].m_fmt);
|
||||
}
|
||||
|
||||
if (NULL != tc.m_mem)
|
||||
{
|
||||
uint32_t bpp = s_textureFormat[tc.m_format].m_bpp;
|
||||
uint8_t* data = tc.m_mem->data;
|
||||
|
||||
for (uint8_t side = 0, numSides = tc.m_cubeMap ? 6 : 1; side < numSides; ++side)
|
||||
{
|
||||
uint32_t width = tc.m_width;
|
||||
uint32_t height = tc.m_height;
|
||||
uint32_t depth = tc.m_depth;
|
||||
|
||||
for (uint32_t lod = 0, num = tc.m_numMips; lod < num; ++lod)
|
||||
{
|
||||
width = bx::uint32_max(1, width);
|
||||
height = bx::uint32_max(1, height);
|
||||
depth = bx::uint32_max(1, depth);
|
||||
|
||||
uint32_t pitch;
|
||||
uint32_t slicePitch;
|
||||
uint8_t* dst = lock(side, lod, pitch, slicePitch);
|
||||
uint32_t len = width*height*bpp/8;
|
||||
memcpy(dst, data, len);
|
||||
data += len;
|
||||
unlock(side, lod);
|
||||
|
||||
width >>= 1;
|
||||
height >>= 1;
|
||||
depth >>= 1;
|
||||
}
|
||||
unlock(side, lod);
|
||||
}
|
||||
|
||||
release(tc.m_mem);
|
||||
width >>= 1;
|
||||
height >>= 1;
|
||||
depth >>= 1;
|
||||
mipWidth >>= 1;
|
||||
mipHeight >>= 1;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
//
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1717,25 +1638,42 @@ namespace bgfx
|
|||
|
||||
void Texture::update(uint8_t _side, uint8_t _mip, const Rect& _rect, uint16_t _z, uint16_t _depth, const Memory* _mem)
|
||||
{
|
||||
uint32_t bpp = s_textureFormat[m_format].m_bpp;
|
||||
uint32_t bpp = getBitsPerPixel(TextureFormat::Enum(m_textureFormat) );
|
||||
uint32_t srcpitch = _rect.m_width*bpp/8;
|
||||
uint32_t dstpitch = s_renderCtx.m_updateTexturePitch;
|
||||
uint8_t* bits = s_renderCtx.m_updateTextureBits + _rect.m_y*dstpitch + _rect.m_x*bpp/8;
|
||||
|
||||
const bool convert = m_textureFormat != m_requestedFormat;
|
||||
|
||||
uint8_t* data = _mem->data;
|
||||
uint8_t* temp = NULL;
|
||||
|
||||
if (convert)
|
||||
{
|
||||
uint8_t* temp = (uint8_t*)g_realloc(NULL, srcpitch*_rect.m_height);
|
||||
imageDecodeToBgra8(temp, data, _rect.m_width, _rect.m_height, m_requestedFormat);
|
||||
data = temp;
|
||||
}
|
||||
|
||||
if (srcpitch == dstpitch)
|
||||
{
|
||||
memcpy(bits, _mem->data, srcpitch*_rect.m_height);
|
||||
memcpy(bits, data, srcpitch*_rect.m_height);
|
||||
}
|
||||
else
|
||||
{
|
||||
for (uint32_t yy = 0, height = _rect.m_height; yy < height; ++yy)
|
||||
{
|
||||
uint8_t* src = &_mem->data[yy*srcpitch];
|
||||
uint8_t* src = &data[yy*srcpitch];
|
||||
uint8_t* dst = &bits[yy*dstpitch];
|
||||
memcpy(dst, src, srcpitch);
|
||||
}
|
||||
}
|
||||
|
||||
if (NULL != temp)
|
||||
{
|
||||
g_free(temp);
|
||||
}
|
||||
|
||||
if (0 == _mip)
|
||||
{
|
||||
dirty(_side, _rect, _z, _depth);
|
||||
|
|
|
@ -320,8 +320,9 @@ namespace bgfx
|
|||
};
|
||||
|
||||
uint32_t m_flags;
|
||||
TextureFormat::Enum m_format;
|
||||
Enum m_type;
|
||||
uint8_t m_type;
|
||||
uint8_t m_requestedFormat;
|
||||
uint8_t m_textureFormat;
|
||||
};
|
||||
|
||||
struct RenderTarget
|
||||
|
|
|
@ -194,31 +194,30 @@ namespace bgfx
|
|||
|
||||
static TextureFormatInfo s_textureFormat[TextureFormat::Count] =
|
||||
{
|
||||
{ GL_COMPRESSED_RGBA_S3TC_DXT1_EXT, GL_COMPRESSED_RGBA_S3TC_DXT1_EXT, GL_ZERO, false },
|
||||
{ GL_COMPRESSED_RGBA_S3TC_DXT3_EXT, GL_COMPRESSED_RGBA_S3TC_DXT3_EXT, GL_ZERO, false },
|
||||
{ GL_COMPRESSED_RGBA_S3TC_DXT5_EXT, GL_COMPRESSED_RGBA_S3TC_DXT5_EXT, GL_ZERO, false },
|
||||
{ GL_COMPRESSED_LUMINANCE_LATC1_EXT, GL_COMPRESSED_LUMINANCE_LATC1_EXT, GL_ZERO, false },
|
||||
{ GL_COMPRESSED_LUMINANCE_ALPHA_LATC2_EXT, GL_COMPRESSED_LUMINANCE_ALPHA_LATC2_EXT, GL_ZERO, false },
|
||||
{ GL_ETC1_RGB8_OES, GL_ETC1_RGB8_OES, GL_ZERO, false },
|
||||
{ GL_COMPRESSED_RGB8_ETC2, GL_COMPRESSED_RGB8_ETC2, GL_ZERO, false },
|
||||
{ GL_COMPRESSED_RGBA8_ETC2_EAC, GL_COMPRESSED_RGBA8_ETC2_EAC, GL_ZERO, false },
|
||||
{ GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2, GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2, GL_ZERO, false },
|
||||
{ GL_COMPRESSED_RGB_PVRTC_2BPPV1_IMG, GL_COMPRESSED_RGB_PVRTC_2BPPV1_IMG, GL_ZERO, false },
|
||||
{ GL_COMPRESSED_RGB_PVRTC_4BPPV1_IMG, GL_COMPRESSED_RGB_PVRTC_4BPPV1_IMG, GL_ZERO, false },
|
||||
{ GL_COMPRESSED_RGBA_PVRTC_2BPPV1_IMG, GL_COMPRESSED_RGBA_PVRTC_2BPPV1_IMG, GL_ZERO, false },
|
||||
{ GL_COMPRESSED_RGBA_PVRTC_4BPPV1_IMG, GL_COMPRESSED_RGBA_PVRTC_4BPPV1_IMG, GL_ZERO, false },
|
||||
{ GL_COMPRESSED_RGBA_PVRTC_2BPPV2_IMG, GL_COMPRESSED_RGBA_PVRTC_2BPPV2_IMG, GL_ZERO, false },
|
||||
{ GL_COMPRESSED_RGBA_PVRTC_4BPPV2_IMG, GL_COMPRESSED_RGBA_PVRTC_4BPPV2_IMG, GL_ZERO, false },
|
||||
{ GL_ZERO, GL_ZERO, GL_ZERO, true },
|
||||
{ GL_LUMINANCE, GL_LUMINANCE, GL_UNSIGNED_BYTE, true },
|
||||
{ GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE, true },
|
||||
{ GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE, true },
|
||||
{ GL_RGBA16, GL_RGBA, GL_UNSIGNED_BYTE, true },
|
||||
{ GL_RGBA16F, GL_RGBA, GL_HALF_FLOAT, true },
|
||||
{ GL_RGB565, GL_RGB, GL_UNSIGNED_SHORT_5_6_5, true },
|
||||
{ GL_RGBA4, GL_RGBA, GL_UNSIGNED_SHORT_4_4_4_4, true },
|
||||
{ GL_RGB5_A1, GL_RGBA, GL_UNSIGNED_SHORT_5_5_5_1, true },
|
||||
{ GL_RGB10_A2, GL_RGBA, GL_UNSIGNED_INT_2_10_10_10_REV, true },
|
||||
{ GL_COMPRESSED_RGBA_S3TC_DXT1_EXT, GL_COMPRESSED_RGBA_S3TC_DXT1_EXT, GL_ZERO, false }, // BC1
|
||||
{ GL_COMPRESSED_RGBA_S3TC_DXT3_EXT, GL_COMPRESSED_RGBA_S3TC_DXT3_EXT, GL_ZERO, false }, // BC2
|
||||
{ GL_COMPRESSED_RGBA_S3TC_DXT5_EXT, GL_COMPRESSED_RGBA_S3TC_DXT5_EXT, GL_ZERO, false }, // BC3
|
||||
{ GL_COMPRESSED_LUMINANCE_LATC1_EXT, GL_COMPRESSED_LUMINANCE_LATC1_EXT, GL_ZERO, false }, // BC4
|
||||
{ GL_COMPRESSED_LUMINANCE_ALPHA_LATC2_EXT, GL_COMPRESSED_LUMINANCE_ALPHA_LATC2_EXT, GL_ZERO, false }, // BC5
|
||||
{ GL_ETC1_RGB8_OES, GL_ETC1_RGB8_OES, GL_ZERO, false }, // ETC1
|
||||
{ GL_COMPRESSED_RGB8_ETC2, GL_COMPRESSED_RGB8_ETC2, GL_ZERO, false }, // ETC2
|
||||
{ GL_COMPRESSED_RGBA8_ETC2_EAC, GL_COMPRESSED_RGBA8_ETC2_EAC, GL_ZERO, false }, // ETC2A
|
||||
{ GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2, GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2, GL_ZERO, false }, // ETC2A1
|
||||
{ GL_COMPRESSED_RGB_PVRTC_2BPPV1_IMG, GL_COMPRESSED_RGB_PVRTC_2BPPV1_IMG, GL_ZERO, false }, // PTC12
|
||||
{ GL_COMPRESSED_RGB_PVRTC_4BPPV1_IMG, GL_COMPRESSED_RGB_PVRTC_4BPPV1_IMG, GL_ZERO, false }, // PTC14
|
||||
{ GL_COMPRESSED_RGBA_PVRTC_2BPPV1_IMG, GL_COMPRESSED_RGBA_PVRTC_2BPPV1_IMG, GL_ZERO, false }, // PTC12A
|
||||
{ GL_COMPRESSED_RGBA_PVRTC_4BPPV1_IMG, GL_COMPRESSED_RGBA_PVRTC_4BPPV1_IMG, GL_ZERO, false }, // PTC14A
|
||||
{ GL_COMPRESSED_RGBA_PVRTC_2BPPV2_IMG, GL_COMPRESSED_RGBA_PVRTC_2BPPV2_IMG, GL_ZERO, false }, // PTC22
|
||||
{ GL_COMPRESSED_RGBA_PVRTC_4BPPV2_IMG, GL_COMPRESSED_RGBA_PVRTC_4BPPV2_IMG, GL_ZERO, false }, // PTC24
|
||||
{ GL_ZERO, GL_ZERO, GL_ZERO, true }, // Unknown
|
||||
{ GL_LUMINANCE, GL_LUMINANCE, GL_UNSIGNED_BYTE, true }, // L8
|
||||
{ GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE, true }, // BGRA8
|
||||
{ GL_RGBA16, GL_RGBA, GL_UNSIGNED_BYTE, true }, // RGBA16
|
||||
{ GL_RGBA16F, GL_RGBA, GL_HALF_FLOAT, true }, // RGBA16F
|
||||
{ GL_RGB565, GL_RGB, GL_UNSIGNED_SHORT_5_6_5, true }, // R5G6B5
|
||||
{ GL_RGBA4, GL_RGBA, GL_UNSIGNED_SHORT_4_4_4_4, true }, // RGBA4
|
||||
{ GL_RGB5_A1, GL_RGBA, GL_UNSIGNED_SHORT_5_5_5_1, true }, // RGB5A1
|
||||
{ GL_RGB10_A2, GL_RGBA, GL_UNSIGNED_INT_2_10_10_10_REV, true }, // RGB10A2
|
||||
};
|
||||
|
||||
struct Extension
|
||||
|
@ -595,9 +594,7 @@ namespace bgfx
|
|||
GL_CHECK(glBindFramebuffer(GL_FRAMEBUFFER, m_msaaBackBufferFbo) );
|
||||
}
|
||||
#else
|
||||
BX_UNUSED(_width);
|
||||
BX_UNUSED(_height);
|
||||
BX_UNUSED(_msaa);
|
||||
BX_UNUSED(_width, _height, _msaa);
|
||||
#endif // BGFX_CONFIG_RENDERER_OPENGL|BGFX_CONFIG_RENDERER_OPENGLES3
|
||||
}
|
||||
|
||||
|
@ -1323,37 +1320,33 @@ namespace bgfx
|
|||
m_vcref.invalidate(s_renderCtx.m_vaoStateCache);
|
||||
}
|
||||
|
||||
static void texImage(GLenum _target, GLint _level, GLint _internalFormat, GLsizei _width, GLsizei _height, GLsizei _depth, GLint _border, GLenum _format, GLenum _type, const GLvoid* _pixels)
|
||||
static void texImage(GLenum _target, GLint _level, GLint _internalFormat, GLsizei _width, GLsizei _height, GLsizei _depth, GLint _border, GLenum _format, GLenum _type, const GLvoid* _data)
|
||||
{
|
||||
#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
|
||||
) );
|
||||
GL_CHECK(glTexImage3D(_target, _level, _internalFormat, _width, _height, _depth, _border, _format, _type, _data) );
|
||||
}
|
||||
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
|
||||
) );
|
||||
GL_CHECK(glTexImage2D(_target, _level, _internalFormat, _width, _height, _border, _format, _type, _data) );
|
||||
}
|
||||
}
|
||||
|
||||
static void texSubImage(GLenum _target, GLint _level, GLint _xoffset, GLint _yoffset, GLint _zoffset, GLsizei _width, GLsizei _height, GLsizei _depth, GLenum _format, GLenum _type, const GLvoid* _data)
|
||||
{
|
||||
#if BGFX_CONFIG_RENDERER_OPENGL|BGFX_CONFIG_RENDERER_OPENGLES3
|
||||
if (_target == GL_TEXTURE_3D)
|
||||
{
|
||||
GL_CHECK(glTexSubImage3D(_target, _level, _xoffset, _yoffset, _zoffset, _width, _height, _depth, _format, _type, _data) );
|
||||
}
|
||||
else
|
||||
#endif // BGFX_CONFIG_RENDERER_OPENGL|BGFX_CONFIG_RENDERER_OPENGLES3
|
||||
{
|
||||
BX_UNUSED(_zoffset, _depth);
|
||||
GL_CHECK(glTexSubImage2D(_target, _level, _xoffset, _yoffset, _width, _height, _format, _type, _data) );
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1362,45 +1355,69 @@ namespace bgfx
|
|||
#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
|
||||
) );
|
||||
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
|
||||
) );
|
||||
GL_CHECK(glCompressedTexImage2D(_target, _level, _internalformat, _width, _height, _border, _imageSize, _data) );
|
||||
}
|
||||
}
|
||||
|
||||
void Texture::init(GLenum _target, uint8_t _numMips, uint32_t _flags)
|
||||
static void compressedTexSubImage(GLenum _target, GLint _level, GLint _xoffset, GLint _yoffset, GLint _zoffset, GLsizei _width, GLsizei _height, GLsizei _depth, GLenum _format, GLsizei _imageSize, const GLvoid* _data)
|
||||
{
|
||||
#if BGFX_CONFIG_RENDERER_OPENGL|BGFX_CONFIG_RENDERER_OPENGLES3
|
||||
if (_target == GL_TEXTURE_3D)
|
||||
{
|
||||
GL_CHECK(glCompressedTexSubImage3D(_target, _level, _xoffset, _yoffset, _zoffset, _width, _height, _depth, _format, _imageSize, _data) );
|
||||
}
|
||||
else
|
||||
#endif // BGFX_CONFIG_RENDERER_OPENGL|BGFX_CONFIG_RENDERER_OPENGLES3
|
||||
{
|
||||
BX_UNUSED(_zoffset, _depth);
|
||||
GL_CHECK(glCompressedTexSubImage2D(_target, _level, _xoffset, _yoffset, _width, _height, _format, _imageSize, _data) );
|
||||
}
|
||||
}
|
||||
|
||||
void Texture::init(GLenum _target, uint8_t _format, uint8_t _numMips, uint32_t _flags)
|
||||
{
|
||||
m_target = _target;
|
||||
m_numMips = _numMips;
|
||||
m_flags = _flags;
|
||||
m_currentFlags = UINT32_MAX;
|
||||
m_requestedFormat = _format;
|
||||
m_textureFormat = _format;
|
||||
|
||||
GL_CHECK(glGenTextures(1, &m_id) );
|
||||
BX_CHECK(0 != m_id, "Failed to generate texture id.");
|
||||
GL_CHECK(glBindTexture(_target, m_id) );
|
||||
|
||||
setSamplerState(_flags);
|
||||
|
||||
const TextureFormatInfo& tfi = s_textureFormat[_format];
|
||||
m_fmt = tfi.m_fmt;
|
||||
m_type = tfi.m_type;
|
||||
|
||||
const bool compressed = TextureFormat::Unknown > _format;
|
||||
const bool decompress = !tfi.m_supported && compressed;
|
||||
|
||||
if (decompress)
|
||||
{
|
||||
m_textureFormat = (uint8_t)TextureFormat::BGRA8;
|
||||
const TextureFormatInfo& tfi = s_textureFormat[TextureFormat::BGRA8];
|
||||
m_fmt = tfi.m_fmt;
|
||||
m_type = tfi.m_type;
|
||||
}
|
||||
|
||||
#if BGFX_CONFIG_RENDERER_OPENGL
|
||||
if (GL_RGBA == m_fmt
|
||||
&& s_renderCtx.m_textureSwizzleSupport)
|
||||
{
|
||||
GLint swizzleMask[] = { GL_BLUE, GL_GREEN, GL_RED, GL_ALPHA };
|
||||
GL_CHECK(glTexParameteriv(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_RGBA, swizzleMask) );
|
||||
}
|
||||
#endif // BGFX_CONFIG_RENDERER_OPENGL
|
||||
}
|
||||
|
||||
void Texture::create(const Memory* _mem, uint32_t _flags)
|
||||
|
@ -1411,127 +1428,58 @@ namespace bgfx
|
|||
{
|
||||
uint8_t numMips = imageContainer.m_numMips;
|
||||
|
||||
GLenum target = GL_TEXTURE_2D;
|
||||
if (imageContainer.m_cubeMap)
|
||||
{
|
||||
init(GL_TEXTURE_CUBE_MAP, numMips, _flags);
|
||||
target = GL_TEXTURE_CUBE_MAP;
|
||||
}
|
||||
#if BGFX_CONFIG_RENDERER_OPENGL|BGFX_CONFIG_RENDERER_OPENGLES3
|
||||
else if (imageContainer.m_depth > 1)
|
||||
{
|
||||
init(GL_TEXTURE_3D, numMips, _flags);
|
||||
target = GL_TEXTURE_3D;
|
||||
}
|
||||
#endif // BGFX_CONFIG_RENDERER_OPENGL|BGFX_CONFIG_RENDERER_OPENGLES3
|
||||
else
|
||||
|
||||
init(target
|
||||
, imageContainer.m_format
|
||||
, numMips
|
||||
, _flags
|
||||
);
|
||||
|
||||
target = GL_TEXTURE_CUBE_MAP == m_target ? GL_TEXTURE_CUBE_MAP_POSITIVE_X : m_target;
|
||||
|
||||
const GLenum internalFmt = s_textureFormat[m_textureFormat].m_internalFmt;
|
||||
|
||||
const bool swizzle = GL_RGBA == internalFmt;
|
||||
const bool convert = m_textureFormat != m_requestedFormat;
|
||||
const bool compressed = TextureFormat::Unknown > m_textureFormat;
|
||||
const uint32_t min = convert && compressed ? 4 : 1;
|
||||
|
||||
uint8_t* temp = NULL;
|
||||
if (convert || swizzle)
|
||||
{
|
||||
init(GL_TEXTURE_2D, numMips, _flags);
|
||||
temp = (uint8_t*)g_realloc(NULL, imageContainer.m_width*imageContainer.m_height*4);
|
||||
}
|
||||
|
||||
const TextureFormatInfo& tfi = s_textureFormat[imageContainer.m_type];
|
||||
GLenum internalFmt = tfi.m_internalFmt;
|
||||
m_fmt = tfi.m_fmt;
|
||||
m_type = tfi.m_type;
|
||||
|
||||
GLenum target = m_target;
|
||||
if (imageContainer.m_cubeMap)
|
||||
for (uint8_t side = 0, numSides = imageContainer.m_cubeMap ? 6 : 1; side < numSides; ++side)
|
||||
{
|
||||
target = GL_TEXTURE_CUBE_MAP_POSITIVE_X;
|
||||
}
|
||||
uint32_t width = imageContainer.m_width;
|
||||
uint32_t height = imageContainer.m_height;
|
||||
uint32_t depth = imageContainer.m_depth;
|
||||
|
||||
if (!tfi.m_supported
|
||||
|| TextureFormat::Unknown < imageContainer.m_type)
|
||||
{
|
||||
TextureFormat::Enum textureFormat = imageContainer.m_type;
|
||||
bool decompress = TextureFormat::Unknown > textureFormat;
|
||||
uint32_t bpp = getBitsPerPixel(imageContainer.m_type);
|
||||
|
||||
if (decompress)
|
||||
for (uint32_t lod = 0, num = numMips; lod < num; ++lod)
|
||||
{
|
||||
textureFormat = TextureFormat::BGRA8;
|
||||
const TextureFormatInfo& tfi = s_textureFormat[textureFormat];
|
||||
internalFmt = tfi.m_internalFmt;
|
||||
m_fmt = tfi.m_fmt;
|
||||
m_type = tfi.m_type;
|
||||
bpp = getBitsPerPixel(textureFormat);
|
||||
}
|
||||
width = bx::uint32_max(min, width);
|
||||
height = bx::uint32_max(min, height);
|
||||
depth = bx::uint32_max(1, depth);
|
||||
|
||||
bool swizzle = GL_RGBA == m_fmt;
|
||||
|
||||
#if BGFX_CONFIG_RENDERER_OPENGL
|
||||
if (swizzle
|
||||
&& s_renderCtx.m_textureSwizzleSupport)
|
||||
{
|
||||
swizzle = false;
|
||||
GLint swizzleMask[] = { GL_BLUE, GL_GREEN, GL_RED, GL_ALPHA };
|
||||
GL_CHECK(glTexParameteriv(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_RGBA, swizzleMask) );
|
||||
}
|
||||
#endif // BGFX_CONFIG_RENDERER_OPENGL
|
||||
|
||||
uint8_t* bits = (uint8_t*)g_realloc(NULL, imageContainer.m_width*imageContainer.m_height*bpp/8);
|
||||
|
||||
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 depth = imageContainer.m_depth;
|
||||
|
||||
for (uint32_t lod = 0, num = numMips; lod < num; ++lod)
|
||||
ImageMip mip;
|
||||
if (imageGetRawData(imageContainer, side, lod, _mem->data, _mem->size, mip) )
|
||||
{
|
||||
width = bx::uint32_max(1, width);
|
||||
height = bx::uint32_max(1, height);
|
||||
depth = bx::uint32_max(1, depth);
|
||||
|
||||
Mip mip;
|
||||
if (imageGetRawData(imageContainer, side, lod, _mem->data, _mem->size, mip) )
|
||||
{
|
||||
mip.decode(bits);
|
||||
|
||||
if (swizzle)
|
||||
{
|
||||
imageSwizzleBgra8(width, height, bits, bits);
|
||||
}
|
||||
|
||||
texImage(target+side
|
||||
, lod
|
||||
, internalFmt
|
||||
, width
|
||||
, height
|
||||
, depth
|
||||
, 0
|
||||
, m_fmt
|
||||
, m_type
|
||||
, bits
|
||||
);
|
||||
}
|
||||
|
||||
width >>= 1;
|
||||
height >>= 1;
|
||||
depth >>= 1;
|
||||
}
|
||||
}
|
||||
|
||||
g_free(bits);
|
||||
}
|
||||
else
|
||||
{
|
||||
m_compressed = true;
|
||||
|
||||
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 depth = imageContainer.m_depth;
|
||||
|
||||
for (uint32_t ii = 0, num = numMips; ii < num; ++ii)
|
||||
{
|
||||
width = bx::uint32_max(1, width);
|
||||
height = bx::uint32_max(1, height);
|
||||
depth = bx::uint32_max(1, depth);
|
||||
|
||||
Mip mip;
|
||||
if (imageGetRawData(imageContainer, side, ii, _mem->data, _mem->size, mip) )
|
||||
if (compressed)
|
||||
{
|
||||
compressedTexImage(target+side
|
||||
, ii
|
||||
, lod
|
||||
, internalFmt
|
||||
, width
|
||||
, height
|
||||
|
@ -1541,102 +1489,20 @@ namespace bgfx
|
|||
, mip.m_data
|
||||
);
|
||||
}
|
||||
|
||||
width >>= 1;
|
||||
height >>= 1;
|
||||
depth >>= 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
bx::MemoryReader reader(_mem->data, _mem->size);
|
||||
|
||||
uint32_t magic;
|
||||
bx::read(&reader, magic);
|
||||
|
||||
if (BGFX_CHUNK_MAGIC_TEX == magic)
|
||||
{
|
||||
TextureCreate tc;
|
||||
bx::read(&reader, tc);
|
||||
|
||||
uint8_t numMips = tc.m_numMips;
|
||||
|
||||
if (tc.m_cubeMap)
|
||||
{
|
||||
init(GL_TEXTURE_CUBE_MAP, numMips, _flags);
|
||||
}
|
||||
#if BGFX_CONFIG_RENDERER_OPENGL|BGFX_CONFIG_RENDERER_OPENGLES3
|
||||
else if (tc.m_depth > 1)
|
||||
{
|
||||
init(GL_TEXTURE_3D, numMips, _flags);
|
||||
}
|
||||
#endif // BGFX_CONFIG_RENDERER_OPENGL|BGFX_CONFIG_RENDERER_OPENGLES3
|
||||
else
|
||||
{
|
||||
init(GL_TEXTURE_2D, numMips, _flags);
|
||||
}
|
||||
|
||||
const TextureFormatInfo& tfi = s_textureFormat[tc.m_format];
|
||||
GLenum internalFmt = tfi.m_internalFmt;
|
||||
m_fmt = tfi.m_fmt;
|
||||
m_type = tfi.m_type;
|
||||
m_compressed = tc.m_format < TextureFormat::Unknown;
|
||||
|
||||
GLenum target = m_target;
|
||||
if (tc.m_cubeMap)
|
||||
{
|
||||
target = GL_TEXTURE_CUBE_MAP_POSITIVE_X;
|
||||
}
|
||||
|
||||
uint32_t bpp = getBitsPerPixel(TextureFormat::Enum(tc.m_format) );
|
||||
uint8_t* data = NULL != tc.m_mem ? tc.m_mem->data : NULL;
|
||||
uint32_t min = m_compressed ? 4 : 1;
|
||||
bool swizzle = GL_RGBA == m_fmt;
|
||||
|
||||
#if BGFX_CONFIG_RENDERER_OPENGL
|
||||
if (swizzle
|
||||
&& s_renderCtx.m_textureSwizzleSupport)
|
||||
{
|
||||
swizzle = false;
|
||||
GLint swizzleMask[] = { GL_BLUE, GL_GREEN, GL_RED, GL_ALPHA };
|
||||
GL_CHECK(glTexParameteriv(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_RGBA, swizzleMask) );
|
||||
}
|
||||
#endif // BGFX_CONFIG_RENDERER_OPENGL
|
||||
|
||||
for (uint8_t side = 0, numSides = tc.m_cubeMap ? 6 : 1; side < numSides; ++side)
|
||||
{
|
||||
uint32_t width = tc.m_width;
|
||||
uint32_t height = tc.m_height;
|
||||
uint32_t depth = tc.m_depth;
|
||||
|
||||
for (uint32_t lod = 0, num = numMips; lod < num; ++lod)
|
||||
{
|
||||
width = bx::uint32_max(width, min);
|
||||
height = bx::uint32_max(height, min);
|
||||
depth = bx::uint32_max(1, depth);
|
||||
uint32_t size = width*height*bpp/8;
|
||||
|
||||
if (m_compressed)
|
||||
{
|
||||
compressedTexImage(target+side
|
||||
, lod
|
||||
, internalFmt
|
||||
, width
|
||||
, height
|
||||
, depth
|
||||
, 0
|
||||
, size
|
||||
, data
|
||||
);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (NULL != data
|
||||
&& swizzle)
|
||||
const uint8_t* data = mip.m_data;
|
||||
|
||||
if (convert)
|
||||
{
|
||||
imageSwizzleBgra8(width, height, data, data);
|
||||
imageDecodeToBgra8(temp, mip.m_data, mip.m_width, mip.m_height, mip.m_format);
|
||||
data = temp;
|
||||
}
|
||||
|
||||
if (swizzle)
|
||||
{
|
||||
imageSwizzleBgra8(width, height, data, temp);
|
||||
data = temp;
|
||||
}
|
||||
|
||||
texImage(target+side
|
||||
|
@ -1651,26 +1517,52 @@ namespace bgfx
|
|||
, data
|
||||
);
|
||||
}
|
||||
|
||||
if (NULL != data)
|
||||
{
|
||||
data += size;
|
||||
}
|
||||
|
||||
width >>= 1;
|
||||
height >>= 1;
|
||||
depth >>= 1;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (compressed)
|
||||
{
|
||||
uint32_t size = bx::uint32_max(1, (width + 3)>>2)
|
||||
* bx::uint32_max(1, (height + 3)>>2)
|
||||
* 4*4*getBitsPerPixel(TextureFormat::Enum(m_textureFormat) )/8
|
||||
;
|
||||
|
||||
if (NULL != tc.m_mem)
|
||||
{
|
||||
release(tc.m_mem);
|
||||
compressedTexImage(target+side
|
||||
, lod
|
||||
, internalFmt
|
||||
, width
|
||||
, height
|
||||
, depth
|
||||
, 0
|
||||
, size
|
||||
, NULL
|
||||
);
|
||||
}
|
||||
else
|
||||
{
|
||||
texImage(target+side
|
||||
, lod
|
||||
, internalFmt
|
||||
, width
|
||||
, height
|
||||
, depth
|
||||
, 0
|
||||
, m_fmt
|
||||
, m_type
|
||||
, NULL
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
width >>= 1;
|
||||
height >>= 1;
|
||||
depth >>= 1;
|
||||
}
|
||||
}
|
||||
else
|
||||
|
||||
if (NULL != temp)
|
||||
{
|
||||
//
|
||||
g_free(temp);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1761,106 +1653,74 @@ namespace bgfx
|
|||
|
||||
void Texture::update(uint8_t _side, uint8_t _mip, const Rect& _rect, uint16_t _z, uint16_t _depth, const Memory* _mem)
|
||||
{
|
||||
BX_UNUSED(_z);
|
||||
BX_UNUSED(_depth);
|
||||
BX_UNUSED(_z, _depth);
|
||||
|
||||
GL_CHECK(glBindTexture(m_target, m_id) );
|
||||
GL_CHECK(glPixelStorei(GL_UNPACK_ALIGNMENT, 1) );
|
||||
|
||||
switch (m_target)
|
||||
GLenum target = GL_TEXTURE_CUBE_MAP == m_target ? GL_TEXTURE_CUBE_MAP_POSITIVE_X : m_target;
|
||||
|
||||
const bool swizzle = GL_RGBA == m_fmt;
|
||||
const bool convert = m_textureFormat != m_requestedFormat;
|
||||
const bool compressed = TextureFormat::Unknown > m_textureFormat;
|
||||
|
||||
uint32_t width = _rect.m_width;
|
||||
uint32_t height = _rect.m_height;
|
||||
|
||||
uint8_t* temp = NULL;
|
||||
if (convert || swizzle)
|
||||
{
|
||||
case GL_TEXTURE_2D:
|
||||
if (m_compressed)
|
||||
{
|
||||
GL_CHECK(glCompressedTexSubImage2D(m_target
|
||||
, _mip
|
||||
, _rect.m_x
|
||||
, _rect.m_y
|
||||
, _rect.m_width
|
||||
, _rect.m_height
|
||||
, m_fmt
|
||||
, _mem->size
|
||||
, _mem->data
|
||||
) );
|
||||
}
|
||||
else
|
||||
{
|
||||
GL_CHECK(glTexSubImage2D(m_target
|
||||
, _mip
|
||||
, _rect.m_x
|
||||
, _rect.m_y
|
||||
, _rect.m_width
|
||||
, _rect.m_height
|
||||
, m_fmt
|
||||
, m_type
|
||||
, _mem->data
|
||||
) );
|
||||
}
|
||||
break;
|
||||
temp = (uint8_t*)g_realloc(NULL, width*height*4);
|
||||
}
|
||||
|
||||
case GL_TEXTURE_CUBE_MAP:
|
||||
if (m_compressed)
|
||||
{
|
||||
GL_CHECK(glCompressedTexSubImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X+_side
|
||||
, _mip
|
||||
, _rect.m_x
|
||||
, _rect.m_y
|
||||
, _rect.m_width
|
||||
, _rect.m_height
|
||||
, m_fmt
|
||||
, _mem->size
|
||||
, _mem->data
|
||||
) );
|
||||
}
|
||||
else
|
||||
{
|
||||
GL_CHECK(glTexSubImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X+_side
|
||||
, _mip
|
||||
, _rect.m_x
|
||||
, _rect.m_y
|
||||
, _rect.m_width
|
||||
, _rect.m_height
|
||||
, m_fmt
|
||||
, m_type
|
||||
, _mem->data
|
||||
) );
|
||||
}
|
||||
break;
|
||||
if (compressed)
|
||||
{
|
||||
GL_CHECK(compressedTexSubImage(target+_side
|
||||
, _mip
|
||||
, _rect.m_x
|
||||
, _rect.m_y
|
||||
, _z
|
||||
, _rect.m_width
|
||||
, _rect.m_height
|
||||
, _depth
|
||||
, m_fmt
|
||||
, _mem->size
|
||||
, _mem->data
|
||||
) );
|
||||
}
|
||||
else
|
||||
{
|
||||
const uint8_t* data = _mem->data;
|
||||
|
||||
#if BGFX_CONFIG_RENDERER_OPENGL|BGFX_CONFIG_RENDERER_OPENGLES3
|
||||
case GL_TEXTURE_3D:
|
||||
if (m_compressed)
|
||||
if (convert)
|
||||
{
|
||||
GL_CHECK(glCompressedTexSubImage3D(m_target
|
||||
, _mip
|
||||
, _rect.m_x
|
||||
, _rect.m_y
|
||||
, _z
|
||||
, _rect.m_width
|
||||
, _rect.m_height
|
||||
, _depth
|
||||
, m_fmt
|
||||
, _mem->size
|
||||
, _mem->data
|
||||
) );
|
||||
imageDecodeToBgra8(temp, data, width, height, m_requestedFormat);
|
||||
data = temp;
|
||||
}
|
||||
else
|
||||
|
||||
if (swizzle)
|
||||
{
|
||||
GL_CHECK(glTexSubImage3D(m_target
|
||||
, _mip
|
||||
, _rect.m_x
|
||||
, _rect.m_y
|
||||
, _z
|
||||
, _rect.m_width
|
||||
, _rect.m_height
|
||||
, _depth
|
||||
, m_fmt
|
||||
, m_type
|
||||
, _mem->data
|
||||
) );
|
||||
imageSwizzleBgra8(width, height, data, temp);
|
||||
data = temp;
|
||||
}
|
||||
break;
|
||||
#endif // BGFX_CONFIG_RENDERER_OPENGL|BGFX_CONFIG_RENDERER_OPENGLES3
|
||||
|
||||
GL_CHECK(texSubImage(target+_side
|
||||
, _mip
|
||||
, _rect.m_x
|
||||
, _rect.m_y
|
||||
, _z
|
||||
, _rect.m_width
|
||||
, _rect.m_height
|
||||
, _depth
|
||||
, m_fmt
|
||||
, m_type
|
||||
, data
|
||||
) );
|
||||
}
|
||||
|
||||
if (NULL != temp)
|
||||
{
|
||||
g_free(temp);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2458,6 +2318,7 @@ namespace bgfx
|
|||
^ (uint64_t(getGLStringHash(GL_VERSION ) )<<16)
|
||||
;
|
||||
|
||||
#if BGFX_CONFIG_RENDERER_USE_EXTENSIONS
|
||||
const char* extensions = (const char*)glGetString(GL_EXTENSIONS);
|
||||
glGetError(); // ignore error if glGetString returns NULL.
|
||||
if (NULL != extensions)
|
||||
|
@ -2514,6 +2375,7 @@ namespace bgfx
|
|||
}
|
||||
}
|
||||
}
|
||||
#endif // BGFX_CONFIG_RENDERER_OPENGL_USE_EXTENSIONS
|
||||
|
||||
bool bc123Supported = s_extension[Extension::EXT_texture_compression_s3tc].m_supported;
|
||||
s_textureFormat[TextureFormat::BC1].m_supported = bc123Supported || s_extension[Extension::EXT_texture_compression_dxt1].m_supported;
|
||||
|
@ -2596,7 +2458,6 @@ namespace bgfx
|
|||
s_renderCtx.m_readPixelsFmt = GL_BGRA_EXT;
|
||||
#endif // BGFX_CONFIG_RENDERER_OPENGL
|
||||
|
||||
s_textureFormat[TextureFormat::BGRX8].m_fmt = GL_BGRA_EXT;
|
||||
s_textureFormat[TextureFormat::BGRA8].m_fmt = GL_BGRA_EXT;
|
||||
|
||||
// Mixing GLES and GL extensions here. OpenGL EXT_bgra wants
|
||||
|
@ -2609,7 +2470,6 @@ namespace bgfx
|
|||
// https://www.opengl.org/registry/specs/EXT/bgra.txt
|
||||
if (!s_extension[Extension::EXT_bgra].m_supported)
|
||||
{
|
||||
s_textureFormat[TextureFormat::BGRX8].m_internalFmt = GL_BGRA_EXT;
|
||||
s_textureFormat[TextureFormat::BGRA8].m_internalFmt = GL_BGRA_EXT;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -558,11 +558,10 @@ namespace bgfx
|
|||
, m_flags(0)
|
||||
, m_currentFlags(UINT32_MAX)
|
||||
, m_numMips(0)
|
||||
, m_compressed(false)
|
||||
{
|
||||
}
|
||||
|
||||
void init(GLenum _target, uint8_t _numMips, uint32_t _flags);
|
||||
void init(GLenum _target, uint8_t _format, uint8_t _numMips, uint32_t _flags);
|
||||
void create(const Memory* _mem, uint32_t _flags);
|
||||
void createColor(uint32_t _colorFormat, uint32_t _width, uint32_t _height, GLenum _min, GLenum _mag);
|
||||
void createDepth(uint32_t _width, uint32_t _height);
|
||||
|
@ -578,7 +577,8 @@ namespace bgfx
|
|||
uint32_t m_flags;
|
||||
uint32_t m_currentFlags;
|
||||
uint8_t m_numMips;
|
||||
bool m_compressed;
|
||||
uint8_t m_requestedFormat;
|
||||
uint8_t m_textureFormat;
|
||||
};
|
||||
|
||||
struct Shader
|
||||
|
|
|
@ -105,23 +105,8 @@ namespace bgfx
|
|||
{
|
||||
}
|
||||
|
||||
void Context::rendererCreateTexture(TextureHandle /*_handle*/, Memory* _mem, uint32_t /*_flags*/)
|
||||
void Context::rendererCreateTexture(TextureHandle /*_handle*/, Memory* /*_mem*/, uint32_t /*_flags*/)
|
||||
{
|
||||
bx::MemoryReader reader(_mem->data, _mem->size);
|
||||
|
||||
uint32_t magic;
|
||||
bx::read(&reader, magic);
|
||||
|
||||
if (BGFX_CHUNK_MAGIC_TEX == magic)
|
||||
{
|
||||
TextureCreate tc;
|
||||
bx::read(&reader, tc);
|
||||
|
||||
if (NULL != tc.m_mem)
|
||||
{
|
||||
release(tc.m_mem);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Context::rendererUpdateTextureBegin(TextureHandle /*_handle*/, uint8_t /*_side*/, uint8_t /*_mip*/)
|
||||
|
|
|
@ -108,7 +108,7 @@ int main(int _argc, const char* _argv[])
|
|||
bool decompress = cmdLine.hasArg('d');
|
||||
|
||||
if (decompress
|
||||
|| 0 == imageContainer.m_type)
|
||||
|| 0 == imageContainer.m_format)
|
||||
{
|
||||
for (uint8_t side = 0, numSides = imageContainer.m_cubeMap ? 6 : 1; side < numSides; ++side)
|
||||
{
|
||||
|
@ -120,7 +120,7 @@ int main(int _argc, const char* _argv[])
|
|||
width = bx::uint32_max(1, width);
|
||||
height = bx::uint32_max(1, height);
|
||||
|
||||
Mip mip;
|
||||
ImageMip mip;
|
||||
if (imageGetRawData(imageContainer, side, lod, mem->data, mem->size, mip) )
|
||||
{
|
||||
uint32_t dstpitch = width*4;
|
||||
|
@ -130,7 +130,7 @@ int main(int _argc, const char* _argv[])
|
|||
|| height != mip.m_height)
|
||||
{
|
||||
uint8_t* temp = (uint8_t*)realloc(NULL, mip.m_width*mip.m_height*4);
|
||||
mip.decode(temp);
|
||||
imageDecodeToBgra8(temp, mip.m_data, mip.m_width, mip.m_height, mip.m_format);
|
||||
uint32_t srcpitch = mip.m_width*4;
|
||||
|
||||
for (uint32_t yy = 0; yy < height; ++yy)
|
||||
|
@ -150,7 +150,7 @@ int main(int _argc, const char* _argv[])
|
|||
}
|
||||
else
|
||||
{
|
||||
mip.decode(bits);
|
||||
imageDecodeToBgra8(bits, mip.m_data, mip.m_width, mip.m_height, mip.m_format);
|
||||
}
|
||||
|
||||
char filePath[256];
|
||||
|
@ -169,7 +169,7 @@ int main(int _argc, const char* _argv[])
|
|||
{
|
||||
for (uint32_t lod = 0, num = imageContainer.m_numMips; lod < num; ++lod)
|
||||
{
|
||||
Mip mip;
|
||||
ImageMip mip;
|
||||
if (imageGetRawData(imageContainer, 0, lod, mem->data, mem->size, mip) )
|
||||
{
|
||||
char filePath[256];
|
||||
|
|
Reference in a new issue