Added 07-callback example.

This commit is contained in:
bkaradzic
2012-12-30 20:52:47 -08:00
parent ff41632999
commit d4cd0ea4fa
32 changed files with 1152 additions and 206 deletions

View File

@@ -37,14 +37,56 @@ namespace bgfx
# define BGFX_CHECK_RENDER_THREAD()
#endif // BGFX_CONFIG_MULTITHREADED
void fatalStub(Fatal::Enum _code, const char* _str)
struct CallbackStub : public CallbackI
{
BX_TRACE("0x%08x: %s", _code, _str);
BX_UNUSED(_code);
BX_UNUSED(_str);
}
virtual ~CallbackStub()
{
}
void* reallocStub(void* _ptr, size_t _size)
virtual void fatal(Fatal::Enum _code, const char* _str) BX_OVERRIDE
{
BX_TRACE("0x%08x: %s", _code, _str);
BX_UNUSED(_code);
BX_UNUSED(_str);
abort();
}
virtual uint32_t cacheReadSize(uint64_t /*_id*/) BX_OVERRIDE
{
return 0;
}
virtual bool cacheRead(uint64_t /*_id*/, void* /*_data*/, uint32_t /*_size*/) BX_OVERRIDE
{
return false;
}
virtual void cacheWrite(uint64_t /*_id*/, const void* /*_data*/, uint32_t /*_size*/) BX_OVERRIDE
{
}
virtual void screenShot(const char* _filePath, uint32_t _width, uint32_t _height, uint32_t _pitch, const void* _data, uint32_t /*_size*/, bool _yflip) BX_OVERRIDE
{
saveTga(_filePath, _width, _height, _pitch, _data, false, _yflip);
}
virtual void captureBegin(uint32_t /*_width*/, uint32_t /*_height*/, uint32_t /*_pitch*/, bgfx::TextureFormat::Enum /*_format*/, bool /*_yflip*/) BX_OVERRIDE
{
BX_TRACE("Warning: using capture without callback (a.k.a. pointless).");
}
virtual void captureEnd() BX_OVERRIDE
{
}
virtual void captureFrame(const void* /*_data*/, uint32_t /*_size*/) BX_OVERRIDE
{
}
};
static CallbackStub s_callbackStub;
static void* reallocStub(void* _ptr, size_t _size)
{
void* ptr = ::realloc(_ptr, _size);
BX_CHECK(NULL != ptr, "Out of memory!");
@@ -52,21 +94,15 @@ namespace bgfx
return ptr;
}
void freeStub(void* _ptr)
static void freeStub(void* _ptr)
{
// BX_TRACE("free %p", _ptr);
::free(_ptr);
}
void cacheStub(uint64_t /*_id*/, bool /*_store*/, void* /*_data*/, uint32_t& _length)
{
_length = 0;
}
FatalFn g_fatal = fatalStub;
CallbackI* g_callback = &s_callbackStub;
ReallocFn g_realloc = reallocStub;
FreeFn g_free = freeStub;
CacheFn g_cache = cacheStub;
static BX_THREAD uint32_t s_threadIndex = 0;
static Context s_ctx;
@@ -82,7 +118,7 @@ namespace bgfx
temp[sizeof(temp)-1] = '\0';
g_fatal(_code, temp);
g_callback->fatal(_code, temp);
}
inline void vec4MulMtx(float* __restrict _result, const float* __restrict _vec, const float* __restrict _mat)
@@ -150,7 +186,7 @@ namespace bgfx
uint32_t dstPitch = _width*bpp/8;
if (_yflip)
{
uint8_t* data = (uint8_t*)_src + dstPitch*_height - _srcPitch;
uint8_t* data = (uint8_t*)_src + _srcPitch*_height - _srcPitch;
for (uint32_t yy = 0; yy < _height; ++yy)
{
fwrite(data, dstPitch, 1, file);
@@ -520,11 +556,11 @@ namespace bgfx
#endif // BGFX_CONFIG_RENDERER_
}
void init(FatalFn _fatal, ReallocFn _realloc, FreeFn _free, CacheFn _cache)
void init(CallbackI* _callback, ReallocFn _realloc, FreeFn _free)
{
if (NULL != _fatal)
if (NULL != _callback)
{
g_fatal = _fatal;
g_callback = _callback;
}
if (NULL != _realloc
@@ -534,11 +570,6 @@ namespace bgfx
g_free = _free;
}
if (NULL != _cache)
{
g_cache = _cache;
}
s_threadIndex = BGFX_MAIN_THREAD_MAGIC;
// On NaCl renderer is on the main thread.
@@ -551,10 +582,9 @@ namespace bgfx
s_ctx.shutdown();
s_threadIndex = 0;
g_fatal = fatalStub;
g_callback = &s_callbackStub;
g_realloc = reallocStub;
g_free = freeStub;
g_cache = cacheStub;
}
void reset(uint32_t _width, uint32_t _height, uint32_t _flags)

View File

@@ -177,10 +177,9 @@ namespace bgfx
};
extern const uint32_t g_uniformTypeSize[UniformType::Count];
extern FatalFn g_fatal;
extern CallbackI* g_callback;
extern ReallocFn g_realloc;
extern FreeFn g_free;
extern CacheFn g_cache;
void fatal(Fatal::Enum _code, const char* _format, ...);
void release(const Memory* _mem);

View File

@@ -437,7 +437,7 @@ bool parseDds(Dds& _dds, const Memory* _mem)
break;
case D3DFMT_A16B16G16R16F:
type = TextureFormat::ABGR16;
type = TextureFormat::RGBA16;
blockSize = 8;
bpp = 64;
break;
@@ -448,13 +448,13 @@ bool parseDds(Dds& _dds, const Memory* _mem)
switch (pixelFlags)
{
case DDPF_RGB:
type = TextureFormat::XRGB8;
type = TextureFormat::BGRX8;
blockSize = 3;
bpp = 24;
break;
case DDPF_RGB|DDPF_ALPHAPIXELS:
type = TextureFormat::ARGB8;
type = TextureFormat::BGRA8;
blockSize = 4;
bpp = 32;
break;

View File

@@ -18,6 +18,7 @@ GL_IMPORT(false, PFNGLTEXIMAGE2DPROC, glTexImage2D);
GL_IMPORT(false, PFNGLTEXSUBIMAGE2DPROC, glTexSubImage2D);
GL_IMPORT(false, PFNGLPIXELSTOREI, glPixelStorei);
GL_IMPORT(false, PFNGLTEXPARAMETERIPROC, glTexParameteri);
GL_IMPORT(false, PFNGLTEXPARAMETERIVPROC, glTexParameteriv);
GL_IMPORT(false, PFNGLTEXPARAMETERFPROC, glTexParameterf);
GL_IMPORT(false, PFNGLBINDTEXTUREPROC, glBindTexture);
GL_IMPORT(false, PFNGLGENTEXTURESPROC, glGenTextures);

View File

@@ -405,6 +405,8 @@ namespace bgfx
DX_RELEASE(m_backBufferColor, 0);
// invalidateCache();
capturePreReset();
}
void postReset()
@@ -436,6 +438,8 @@ namespace bgfx
m_currentColor = m_backBufferColor;
m_currentDepthStencil = m_backBufferDepthStencil;
capturePostReset();
}
void flip()
@@ -761,6 +765,18 @@ namespace bgfx
commitTextureStage();
}
void capturePreReset()
{
}
void capturePostReset()
{
}
void capture()
{
}
void saveScreenShot(Memory* _mem)
{
ID3D11Texture2D* backBuffer;
@@ -801,7 +817,14 @@ namespace bgfx
D3D11_MAPPED_SUBRESOURCE mapped;
DX_CHECK(m_deviceCtx->Map(texture, 0, D3D11_MAP_READ, 0, &mapped) );
saveTga( (const char*)_mem->data, backBufferDesc.Width, backBufferDesc.Height, mapped.RowPitch, mapped.pData);
g_callback->screenShot( (const char*)_mem->data
, backBufferDesc.Width
, backBufferDesc.Height
, mapped.RowPitch
, mapped.pData
, backBufferDesc.Height*mapped.RowPitch
, false
);
m_deviceCtx->Unmap(texture, 0);
DX_RELEASE(texture, 0);
@@ -1354,7 +1377,7 @@ namespace bgfx
D3D11_SUBRESOURCE_DATA* srd = (D3D11_SUBRESOURCE_DATA*)alloca(numSrd*sizeof(D3D11_SUBRESOURCE_DATA) );
uint32_t kk = 0;
bool convert = TextureFormat::XRGB8 == dds.m_type;
bool convert = false;
m_numMips = dds.m_numMips;
@@ -1362,6 +1385,7 @@ namespace bgfx
|| TextureFormat::Unknown < dds.m_type)
{
uint32_t bpp = s_textureFormat[dds.m_type].m_bpp;
convert = TextureFormat::BGRX8 == dds.m_type;
for (uint8_t side = 0, numSides = dds.m_cubeMap ? 6 : 1; side < numSides; ++side)
{
@@ -1380,7 +1404,7 @@ namespace bgfx
{
if (convert)
{
uint8_t* temp = (uint8_t*)g_realloc(NULL, mip.m_width*bpp*mip.m_height/8);
uint8_t* temp = (uint8_t*)g_realloc(NULL, mip.m_width*mip.m_height*bpp/8);
mip.decode(temp);
srd[kk].pSysMem = temp;

View File

@@ -656,6 +656,8 @@ namespace bgfx
DX_RELEASE(m_backBufferColor, 0);
DX_RELEASE(m_backBufferDepthStencil, 0);
capturePreReset();
for (uint32_t ii = 0; ii < countof(m_indexBuffers); ++ii)
{
m_indexBuffers[ii].preReset();
@@ -677,6 +679,8 @@ namespace bgfx
DX_CHECK(m_device->GetBackBuffer(0, 0, D3DBACKBUFFER_TYPE_MONO, &m_backBufferColor) );
DX_CHECK(m_device->GetDepthStencilSurface(&m_backBufferDepthStencil) );
capturePostReset();
for (uint32_t ii = 0; ii < countof(m_indexBuffers); ++ii)
{
m_indexBuffers[ii].postReset();
@@ -693,6 +697,89 @@ namespace bgfx
}
}
void capturePreReset()
{
if (NULL != m_captureSurface)
{
g_callback->captureEnd();
}
DX_RELEASE(m_captureSurface, 1);
DX_RELEASE(m_captureTexture, 0);
DX_RELEASE(m_captureResolve, 0);
}
void capturePostReset()
{
if (m_flags&BGFX_RESET_CAPTURE)
{
uint32_t width = m_params.BackBufferWidth;
uint32_t height = m_params.BackBufferHeight;
D3DFORMAT fmt = m_params.BackBufferFormat;
DX_CHECK(m_device->CreateTexture(width
, height
, 1
, 0
, fmt
, D3DPOOL_SYSTEMMEM
, &m_captureTexture
, NULL
) );
DX_CHECK(m_captureTexture->GetSurfaceLevel(0
, &m_captureSurface
) );
if (m_params.MultiSampleType != D3DMULTISAMPLE_NONE)
{
DX_CHECK(m_device->CreateRenderTarget(width
, height
, fmt
, D3DMULTISAMPLE_NONE
, 0
, false
, &m_captureResolve
, NULL
) );
}
g_callback->captureBegin(width, height, width*4, TextureFormat::BGRA8, false);
}
}
void capture()
{
if (NULL != m_captureSurface)
{
IDirect3DSurface9* resolve = m_backBufferColor;
if (NULL != m_captureResolve)
{
resolve = m_captureResolve;
DX_CHECK(m_device->StretchRect(m_backBufferColor
, 0
, m_captureResolve
, NULL
, D3DTEXF_NONE
) );
}
HRESULT hr = m_device->GetRenderTargetData(resolve, m_captureSurface);
if (SUCCEEDED(hr) )
{
D3DLOCKED_RECT rect;
DX_CHECK(m_captureSurface->LockRect(&rect
, NULL
, D3DLOCK_NO_DIRTY_UPDATE|D3DLOCK_NOSYSLOCK|D3DLOCK_READONLY
) );
g_callback->captureFrame(rect.pBits, m_params.BackBufferHeight*rect.Pitch);
DX_CHECK(m_captureSurface->UnlockRect() );
}
}
}
void saveScreenShot(Memory* _mem)
{
#if BX_PLATFORM_WINDOWS
@@ -727,7 +814,15 @@ namespace bgfx
ClientToScreen(g_bgfxHwnd, &point);
uint8_t* data = (uint8_t*)rect.pBits;
uint32_t bytesPerPixel = rect.Pitch/dm.Width;
saveTga( (const char*)_mem->data, m_params.BackBufferWidth, m_params.BackBufferHeight, rect.Pitch, &data[point.y*rect.Pitch+point.x*bytesPerPixel]);
g_callback->screenShot( (const char*)_mem->data
, m_params.BackBufferWidth
, m_params.BackBufferHeight
, rect.Pitch
, &data[point.y*rect.Pitch+point.x*bytesPerPixel]
, m_params.BackBufferHeight*rect.Pitch
, false
);
DX_CHECK(surface->UnlockRect() );
DX_RELEASE(surface, 0);
@@ -752,6 +847,11 @@ namespace bgfx
IDirect3DSurface9* m_backBufferColor;
IDirect3DSurface9* m_backBufferDepthStencil;
IDirect3DTexture9* m_captureTexture;
IDirect3DSurface9* m_captureSurface;
IDirect3DSurface9* m_captureResolve;
IDirect3DVertexDeclaration9* m_instanceDataDecls[BGFX_CONFIG_MAX_INSTANCE_DATA_COUNT];
HMODULE m_d3d9dll;
@@ -2490,6 +2590,10 @@ namespace bgfx
int64_t now = bx::getHPCounter();
elapsed += now;
int64_t captureElapsed = -bx::getHPCounter();
s_renderCtx.capture();
captureElapsed += bx::getHPCounter();
static int64_t last = now;
int64_t frameTime = now - last;
last = now;
@@ -2513,7 +2617,6 @@ namespace bgfx
double freq = double(bx::getHPFrequency() );
double toMs = 1000.0/freq;
double elapsedCpuMs = double(elapsed)*toMs;
tvm.clear();
uint16_t pos = 10;
@@ -2524,6 +2627,8 @@ namespace bgfx
, double(max)*toMs
, freq/frameTime
);
double elapsedCpuMs = double(elapsed)*toMs;
tvm.printf(10, pos++, 0x8e, " Draw calls: %4d / CPU %3.4f [ms]"
, m_render->m_num
, elapsedCpuMs
@@ -2533,6 +2638,9 @@ namespace bgfx
, statsNumInstances
, statsNumPrimsSubmitted
);
double captureMs = double(captureElapsed)*toMs;
tvm.printf(10, pos++, 0x8e, " Capture: %3.4f [ms]", captureMs);
tvm.printf(10, pos++, 0x8e, " Indices: %7d", statsNumIndices);
tvm.printf(10, pos++, 0x8e, " DVB size: %7d", m_render->m_vboffset);
tvm.printf(10, pos++, 0x8e, " DIB size: %7d", m_render->m_iboffset);

View File

@@ -26,6 +26,97 @@
namespace bgfx
{
struct Extension
{
enum Enum
{
EXT_texture_filter_anisotropic,
EXT_texture_format_BGRA8888,
EXT_texture_compression_s3tc,
EXT_texture_compression_dxt1,
CHROMIUM_texture_compression_dxt3,
CHROMIUM_texture_compression_dxt5,
ARB_texture_float,
OES_texture_float,
OES_texture_float_linear,
OES_texture_half_float,
OES_texture_half_float_linear,
EXT_texture_type_2_10_10_10_REV,
EXT_texture_sRGB,
ARB_texture_swizzle,
EXT_texture_swizzle,
OES_standard_derivatives,
ARB_get_program_binary,
OES_get_program_binary,
EXT_framebuffer_blit,
ARB_timer_query,
EXT_timer_query,
ARB_framebuffer_sRGB,
EXT_framebuffer_sRGB,
ARB_multisample,
CHROMIUM_framebuffer_multisample,
ANGLE_translated_shader_source,
ARB_instanced_arrays,
ANGLE_instanced_arrays,
ARB_half_float_vertex,
OES_vertex_half_float,
ARB_vertex_type_2_10_10_10_rev,
OES_vertex_type_10_10_10_2,
EXT_occlusion_query_boolean,
ARB_vertex_array_object,
ATI_meminfo,
NVX_gpu_memory_info,
Count
};
const char* m_name;
bool m_supported;
bool m_initialize;
};
static Extension s_extension[Extension::Count] =
{
{ "GL_EXT_texture_filter_anisotropic", false, true },
// Nvidia BGRA on Linux bug:
// https://groups.google.com/a/chromium.org/forum/?fromgroups#!topic/chromium-reviews/yFfbUdyeUCQ
{ "GL_EXT_texture_format_BGRA8888", false, !BX_PLATFORM_LINUX },
{ "GL_EXT_texture_compression_s3tc", false, true },
{ "GL_EXT_texture_compression_dxt1", false, true },
{ "GL_CHROMIUM_texture_compression_dxt3", false, true },
{ "GL_CHROMIUM_texture_compression_dxt5", false, true },
{ "GL_ARB_texture_float", false, true },
{ "GL_OES_texture_float", false, true },
{ "GL_OES_texture_float_linear", false, true },
{ "GL_OES_texture_half_float", false, true },
{ "GL_OES_texture_half_float_linear", false, true },
{ "GL_EXT_texture_type_2_10_10_10_REV", false, true },
{ "GL_EXT_texture_sRGB", false, true },
{ "GL_ARB_texture_swizzle", false, true },
{ "GL_EXT_texture_swizzle", false, true },
{ "GL_OES_standard_derivatives", false, true },
{ "GL_ARB_get_program_binary", false, true },
{ "GL_OES_get_program_binary", false, false },
{ "GL_EXT_framebuffer_blit", false, true },
{ "GL_ARB_timer_query", false, true },
{ "GL_EXT_timer_query", false, true },
{ "GL_ARB_framebuffer_sRGB", false, true },
{ "GL_EXT_framebuffer_sRGB", false, true },
{ "GL_ARB_multisample", false, true },
{ "GL_CHROMIUM_framebuffer_multisample", false, true },
{ "GL_ANGLE_translated_shader_source", false, true },
{ "GL_ARB_instanced_arrays", false, true },
{ "GL_ANGLE_instanced_arrays", false, true },
{ "GL_ARB_half_float_vertex", false, true },
{ "GL_OES_vertex_half_float", false, true },
{ "GL_ARB_vertex_type_2_10_10_10_rev", false, true },
{ "GL_OES_vertex_type_10_10_10_2", false, true },
{ "GL_EXT_occlusion_query_boolean", false, true },
{ "GL_ARB_vertex_array_object", false, true },
{ "GL_ATI_meminfo", false, true },
{ "GL_NVX_gpu_memory_info", false, true },
};
#if BGFX_USE_WGL
PFNWGLGETPROCADDRESSPROC wglGetProcAddress;
PFNWGLMAKECURRENTPROC wglMakeCurrent;
@@ -74,10 +165,29 @@ namespace bgfx
};
#endif // BX_PLATFORM_NACL
static void rgbaToBgra(uint8_t* _data, uint32_t _width, uint32_t _height)
{
uint32_t dstpitch = _width*4;
for (uint32_t yy = 0; yy < _height; ++yy)
{
uint8_t* dst = &_data[yy*dstpitch];
for (uint32_t xx = 0; xx < _width; ++xx)
{
uint8_t tmp = dst[0];
dst[0] = dst[2];
dst[2] = tmp;
dst += 4;
}
}
}
struct RendererContext
{
RendererContext()
: m_maxAnisotropy(0.0f)
: m_capture(NULL)
, m_captureSize(0)
, m_maxAnisotropy(0.0f)
, m_dxtSupport(false)
, m_programBinarySupport(false)
, m_flip(false)
@@ -116,6 +226,7 @@ namespace bgfx
m_resolution = _resolution;
setRenderContextSize(_resolution.m_width, _resolution.m_height);
updateCapture();
}
}
@@ -198,6 +309,19 @@ namespace bgfx
DescribePixelFormat(m_hdc, pixelFormat, sizeof(PIXELFORMATDESCRIPTOR), &pfd);
BX_TRACE("Pixel format:\n"
"\tiPixelType %d\n"
"\tcColorBits %d\n"
"\tcAlphaBits %d\n"
"\tcDepthBits %d\n"
"\tcStencilBits %d\n"
, pfd.iPixelType
, pfd.cColorBits
, pfd.cAlphaBits
, pfd.cDepthBits
, pfd.cStencilBits
);
int result;
result = SetPixelFormat(m_hdc, pixelFormat, &pfd);
BGFX_FATAL(0 != result, Fatal::UnableToInitialize, "SetPixelFormat failed!");
@@ -464,21 +588,75 @@ namespace bgfx
}
}
void updateCapture()
{
if (m_resolution.m_flags&BGFX_RESET_CAPTURE)
{
m_captureSize = m_resolution.m_width*m_resolution.m_height*4;
m_capture = g_realloc(m_capture, m_captureSize);
g_callback->captureBegin(m_resolution.m_width, m_resolution.m_height, m_resolution.m_width*4, TextureFormat::BGRA8, true);
}
else
{
if (NULL != m_capture)
{
g_callback->captureEnd();
g_free(m_capture);
m_capture = NULL;
m_captureSize = 0;
}
}
}
void capture()
{
if (NULL != m_capture)
{
GLint fmt = s_extension[Extension::EXT_texture_format_BGRA8888].m_supported ? GL_BGRA_EXT : GL_RGBA;
GL_CHECK(glReadPixels(0
, 0
, m_resolution.m_width
, m_resolution.m_height
, fmt
, GL_UNSIGNED_BYTE
, m_capture
) );
g_callback->captureFrame(m_capture, m_captureSize);
}
}
void saveScreenShot(Memory* _mem)
{
void* data = g_realloc(NULL, m_resolution.m_width*m_resolution.m_height*4);
glReadPixels(0, 0, m_resolution.m_width, m_resolution.m_height, GL_RGBA, GL_UNSIGNED_BYTE, data);
uint32_t length = m_resolution.m_width*m_resolution.m_height*4;
uint8_t* data = (uint8_t*)g_realloc(NULL, length);
GLint fmt = s_extension[Extension::EXT_texture_format_BGRA8888].m_supported ? GL_BGRA_EXT : GL_RGBA;
uint8_t* rgba = (uint8_t*)data;
for (uint32_t ii = 0, num = m_resolution.m_width*m_resolution.m_height; ii < num; ++ii)
uint32_t width = m_resolution.m_width;
uint32_t height = m_resolution.m_height;
GL_CHECK(glReadPixels(0
, 0
, width
, height
, fmt
, GL_UNSIGNED_BYTE
, data
) );
if (GL_RGBA == fmt)
{
uint8_t temp = rgba[0];
rgba[0] = rgba[2];
rgba[2] = temp;
rgba += 4;
rgbaToBgra(data, width, height);
}
saveTga( (const char*)_mem->data, m_resolution.m_width, m_resolution.m_height, m_resolution.m_width*4, data, false, true);
g_callback->screenShot( (const char*)_mem->data
, width
, height
, width*4
, data
, length
, true
);
g_free(data);
}
@@ -531,6 +709,8 @@ namespace bgfx
TextVideoMem m_textVideoMem;
Resolution m_resolution;
void* m_capture;
uint32_t m_captureSize;
float m_maxAnisotropy;
bool m_dxtSupport;
bool m_programBinarySupport;
@@ -613,93 +793,6 @@ namespace bgfx
}
#endif // BX_PLATFORM_
struct Extension
{
enum Enum
{
EXT_texture_filter_anisotropic,
EXT_texture_format_BGRA8888,
EXT_texture_compression_s3tc,
EXT_texture_compression_dxt1,
CHROMIUM_texture_compression_dxt3,
CHROMIUM_texture_compression_dxt5,
ARB_texture_float,
OES_texture_float,
OES_texture_float_linear,
OES_texture_half_float,
OES_texture_half_float_linear,
EXT_texture_type_2_10_10_10_REV,
EXT_texture_sRGB,
OES_standard_derivatives,
ARB_get_program_binary,
OES_get_program_binary,
EXT_framebuffer_blit,
ARB_timer_query,
EXT_timer_query,
ARB_framebuffer_sRGB,
EXT_framebuffer_sRGB,
ARB_multisample,
CHROMIUM_framebuffer_multisample,
ANGLE_translated_shader_source,
ARB_instanced_arrays,
ANGLE_instanced_arrays,
ARB_half_float_vertex,
OES_vertex_half_float,
ARB_vertex_type_2_10_10_10_rev,
OES_vertex_type_10_10_10_2,
EXT_occlusion_query_boolean,
ARB_vertex_array_object,
ATI_meminfo,
NVX_gpu_memory_info,
Count
};
const char* m_name;
bool m_supported;
bool m_initialize;
};
static Extension s_extension[Extension::Count] =
{
{ "GL_EXT_texture_filter_anisotropic", false, true },
// Nvidia BGRA on Linux bug:
// https://groups.google.com/a/chromium.org/forum/?fromgroups#!topic/chromium-reviews/yFfbUdyeUCQ
{ "GL_EXT_texture_format_BGRA8888", false, !BX_PLATFORM_LINUX },
{ "GL_EXT_texture_compression_s3tc", false, true },
{ "GL_EXT_texture_compression_dxt1", false, true },
{ "GL_CHROMIUM_texture_compression_dxt3", false, true },
{ "GL_CHROMIUM_texture_compression_dxt5", false, true },
{ "GL_ARB_texture_float", false, true },
{ "GL_OES_texture_float", false, true },
{ "GL_OES_texture_float_linear", false, true },
{ "GL_OES_texture_half_float", false, true },
{ "GL_OES_texture_half_float_linear", false, true },
{ "GL_EXT_texture_type_2_10_10_10_REV", false, true },
{ "GL_EXT_texture_sRGB", false, true },
{ "GL_OES_standard_derivatives", false, true },
{ "GL_ARB_get_program_binary", false, true },
{ "GL_OES_get_program_binary", false, false },
{ "GL_EXT_framebuffer_blit", false, true },
{ "GL_ARB_timer_query", false, true },
{ "GL_EXT_timer_query", false, true },
{ "GL_ARB_framebuffer_sRGB", false, true },
{ "GL_EXT_framebuffer_sRGB", false, true },
{ "GL_ARB_multisample", false, true },
{ "GL_CHROMIUM_framebuffer_multisample", false, true },
{ "GL_ANGLE_translated_shader_source", false, true },
{ "GL_ARB_instanced_arrays", false, true },
{ "GL_ANGLE_instanced_arrays", false, true },
{ "GL_ARB_half_float_vertex", false, true },
{ "GL_OES_vertex_half_float", false, true },
{ "GL_ARB_vertex_type_2_10_10_10_rev", false, true },
{ "GL_OES_vertex_type_10_10_10_2", false, true },
{ "GL_EXT_occlusion_query_boolean", false, true },
{ "GL_ARB_vertex_array_object", false, true },
{ "GL_ATI_meminfo", false, true },
{ "GL_NVX_gpu_memory_info", false, true },
};
static const GLenum s_primType[] =
{
GL_TRIANGLES,
@@ -966,21 +1059,21 @@ namespace bgfx
if (s_renderCtx.m_programBinarySupport)
{
uint32_t length;
g_cache(id, false, NULL, length);
uint32_t length = g_callback->cacheReadSize(id);
cached = length > 0;
if (cached)
{
void* data = g_realloc(NULL, length);
g_cache(id, false, data, length);
if (g_callback->cacheRead(id, data, length) )
{
bx::MemoryReader reader(data, length);
bx::MemoryReader reader(data, length);
GLenum format;
bx::read(&reader, format);
GLenum format;
bx::read(&reader, format);
GL_CHECK(glProgramBinary(m_id, format, reader.getDataPtr(), (GLsizei)reader.remaining() ) );
GL_CHECK(glProgramBinary(m_id, format, reader.getDataPtr(), (GLsizei)reader.remaining() ) );
}
g_free(data);
}
@@ -1022,7 +1115,7 @@ namespace bgfx
GL_CHECK(glGetProgramBinary(m_id, programLength, NULL, &format, &data[4]) );
*(uint32_t*)data = format;
g_cache(id, true, data, length);
g_callback->cacheWrite(id, data, length);
g_free(data);
}
@@ -1344,16 +1437,30 @@ namespace bgfx
if (GL_RGBA == internalFmt
|| decompress)
{
internalFmt = GL_RGBA;
m_fmt = s_extension[Extension::EXT_texture_format_BGRA8888].m_supported ? GL_BGRA_EXT : GL_RGBA;
}
bool swizzle = GL_RGBA == m_fmt;
#if BGFX_CONFIG_RENDERER_OPENGL
if (swizzle
&& (s_extension[Extension::ARB_texture_swizzle].m_supported || s_extension[Extension::EXT_texture_swizzle].m_supported) )
{
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
m_type = tfi.m_type;
if (decompress)
{
m_type = GL_UNSIGNED_BYTE;
}
uint8_t* bits = (uint8_t*)g_realloc(NULL, dds.m_width*dds.m_height*tfi.m_bpp/8);
uint8_t* bits = (uint8_t*)g_realloc(NULL, dds.m_width*dds.m_height*4);
for (uint8_t side = 0, numSides = dds.m_cubeMap ? 6 : 1; side < numSides; ++side)
{
@@ -1372,21 +1479,9 @@ namespace bgfx
{
mip.decode(bits);
if (GL_RGBA == internalFmt)
if (swizzle)
{
uint32_t dstpitch = width*4;
for (uint32_t yy = 0; yy < height; ++yy)
{
uint8_t* dst = &bits[yy*dstpitch];
for (uint32_t xx = 0; xx < width; ++xx)
{
uint8_t tmp = dst[0];
dst[0] = dst[2];
dst[2] = tmp;
dst += 4;
}
}
rgbaToBgra(bits, width, height);
}
texImage(target+side
@@ -2881,6 +2976,10 @@ namespace bgfx
int64_t now = bx::getHPCounter();
elapsed += now;
int64_t captureElapsed = -bx::getHPCounter();
s_renderCtx.capture();
captureElapsed += bx::getHPCounter();
static int64_t last = now;
int64_t frameTime = now - last;
last = now;
@@ -2908,7 +3007,6 @@ namespace bgfx
next = now + bx::getHPFrequency();
double freq = double(bx::getHPFrequency() );
double toMs = 1000.0/freq;
double elapsedCpuMs = double(elapsed)*toMs;
tvm.clear();
uint16_t pos = 10;
@@ -2919,6 +3017,8 @@ namespace bgfx
, double(max)*toMs
, freq/frameTime
);
double elapsedCpuMs = double(elapsed)*toMs;
tvm.printf(10, pos++, 0x8e, " Draw calls: %4d / CPU %3.4f [ms] %c GPU %3.4f [ms]"
, m_render->m_num
, elapsedCpuMs
@@ -2930,6 +3030,10 @@ namespace bgfx
, statsNumInstances
, statsNumPrimsSubmitted
);
double captureMs = double(captureElapsed)*toMs;
tvm.printf(10, pos++, 0x8e, " Capture: %3.4f [ms]", captureMs);
tvm.printf(10, pos++, 0x8e, " Indices: %7d", statsNumIndices);
tvm.printf(10, pos++, 0x8e, " DVB size: %7d", m_render->m_vboffset);
tvm.printf(10, pos++, 0x8e, " DIB size: %7d", m_render->m_iboffset);

View File

@@ -158,6 +158,7 @@ typedef void (APIENTRYP PFNGLREADPIXELSPROC) (GLint x, GLint y, GLsizei width, G
typedef void (APIENTRYP PFNGLTEXIMAGE2DPROC) (GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, const GLvoid *pixels);
typedef void (APIENTRYP PFNGLTEXSUBIMAGE2DPROC) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid *pixels);
typedef void (APIENTRYP PFNGLTEXPARAMETERIPROC) (GLenum target, GLenum pname, GLint param);
typedef void (APIENTRYP PFNGLTEXPARAMETERIVPROC) (GLenum target, GLenum pname, const GLint *params);
typedef void (APIENTRYP PFNGLTEXPARAMETERFPROC) (GLenum target, GLenum pname, GLfloat param);
typedef void (APIENTRYP PFNGLPIXELSTOREI) (GLenum pname, GLint param);
typedef void (APIENTRYP PFNGLBINDTEXTUREPROC) (GLenum target, GLuint texture);