@@ -46,20 +46,18 @@ String String::Printf(char const *format, va_list ap) | |||||
String ret; | String ret; | ||||
/* Visual Studio 2010 does not support it va_copy. */ | |||||
#if defined _MSC_VER | |||||
# undef va_copy | |||||
# define va_copy(dst, src) (dst = src) | |||||
#endif | |||||
va_list ap2; | va_list ap2; | ||||
#if !defined _MSC_VER | |||||
/* Visual Studio 2010 does not support va_copy. */ | |||||
va_copy(ap2, ap); | va_copy(ap2, ap); | ||||
#if defined _MSC_VER | |||||
# undef va_copy | |||||
#else | |||||
ap2 = ap; | |||||
#endif | #endif | ||||
/* vsnprintf() tells us how many character we need, and we need to | /* vsnprintf() tells us how many character we need, and we need to | ||||
* add one for the terminating null byte. */ | * add one for the terminating null byte. */ | ||||
size_t needed = vsnprintf(nullptr, 0, format, ap2) + 1; | size_t needed = vsnprintf(nullptr, 0, format, ap2) + 1; | ||||
va_end(ap2); | |||||
((Super &)ret).Reserve(needed); | ((Super &)ret).Reserve(needed); | ||||
ret.m_count = needed; | ret.m_count = needed; | ||||
@@ -250,16 +250,26 @@ void Texture::SetMagFiltering(TextureMagFilter filter) | |||||
// In DirectX, texture filtering is a per-texture-unit state | // In DirectX, texture filtering is a per-texture-unit state | ||||
switch (filter) | switch (filter) | ||||
{ | { | ||||
case TextureMagFilter::NEAREST_TEXEL: m_data->m_mag_filter = D3DTEXF_POINT; break; | |||||
case TextureMagFilter::LINEAR_TEXEL: m_data->m_mag_filter = D3DTEXF_LINEAR; break; | |||||
case TextureMagFilter::LINEAR_TEXEL: | |||||
m_data->m_mag_filter = D3DTEXF_LINEAR; | |||||
break; | |||||
case TextureMagFilter::NEAREST_TEXEL: | |||||
default: | |||||
m_data->m_mag_filter = D3DTEXF_POINT; | |||||
break; | |||||
} | } | ||||
#else | #else | ||||
glBindTexture(GL_TEXTURE_2D, m_data->m_texture); | glBindTexture(GL_TEXTURE_2D, m_data->m_texture); | ||||
GLenum gl_filter; | GLenum gl_filter; | ||||
switch (filter) | switch (filter) | ||||
{ | { | ||||
case TextureMagFilter::NEAREST_TEXEL: gl_filter = GL_NEAREST; break; | |||||
case TextureMagFilter::LINEAR_TEXEL: gl_filter = GL_LINEAR; break; | |||||
case TextureMagFilter::LINEAR_TEXEL: | |||||
gl_filter = GL_LINEAR; | |||||
break; | |||||
case TextureMagFilter::NEAREST_TEXEL: | |||||
default: | |||||
gl_filter = GL_NEAREST; | |||||
break; | |||||
} | } | ||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, gl_filter); | glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, gl_filter); | ||||
#endif | #endif | ||||
@@ -273,12 +283,25 @@ void Texture::SetMinFiltering(TextureMinFilter filter) | |||||
m_data->m_min_filter = x; m_data->m_mip_filter = y; | m_data->m_min_filter = x; m_data->m_mip_filter = y; | ||||
switch (filter) | switch (filter) | ||||
{ | { | ||||
case TextureMinFilter::NEAREST_TEXEL_NO_MIPMAP: F(D3DTEXF_POINT, D3DTEXF_NONE); break; | |||||
case TextureMinFilter::LINEAR_TEXEL_NO_MIPMAP: F(D3DTEXF_POINT, D3DTEXF_NONE); break; | |||||
case TextureMinFilter::NEAREST_TEXEL_NEAREST_MIPMAP: F(D3DTEXF_POINT, D3DTEXF_POINT); break; | |||||
case TextureMinFilter::LINEAR_TEXEL_NEAREST_MIPMAP: F(D3DTEXF_LINEAR, D3DTEXF_POINT); break; | |||||
case TextureMinFilter::NEAREST_TEXEL_LINEAR_MIPMAP: F(D3DTEXF_POINT, D3DTEXF_LINEAR); break; | |||||
case TextureMinFilter::LINEAR_TEXEL_LINEAR_MIPMAP: F(D3DTEXF_LINEAR, D3DTEXF_LINEAR); break; | |||||
case TextureMinFilter::LINEAR_TEXEL_NO_MIPMAP: | |||||
F(D3DTEXF_POINT, D3DTEXF_NONE); | |||||
break; | |||||
case TextureMinFilter::NEAREST_TEXEL_NEAREST_MIPMAP: | |||||
F(D3DTEXF_POINT, D3DTEXF_POINT); | |||||
break; | |||||
case TextureMinFilter::LINEAR_TEXEL_NEAREST_MIPMAP: | |||||
F(D3DTEXF_LINEAR, D3DTEXF_POINT); | |||||
break; | |||||
case TextureMinFilter::NEAREST_TEXEL_LINEAR_MIPMAP: | |||||
F(D3DTEXF_POINT, D3DTEXF_LINEAR); | |||||
break; | |||||
case TextureMinFilter::LINEAR_TEXEL_LINEAR_MIPMAP: | |||||
F(D3DTEXF_LINEAR, D3DTEXF_LINEAR); | |||||
break; | |||||
case TextureMinFilter::NEAREST_TEXEL_NO_MIPMAP: | |||||
default: | |||||
F(D3DTEXF_POINT, D3DTEXF_NONE); | |||||
break; | |||||
} | } | ||||
#undef F | #undef F | ||||
@@ -287,12 +310,25 @@ void Texture::SetMinFiltering(TextureMinFilter filter) | |||||
GLenum gl_filter; | GLenum gl_filter; | ||||
switch (filter) | switch (filter) | ||||
{ | { | ||||
case TextureMinFilter::NEAREST_TEXEL_NO_MIPMAP: gl_filter = GL_NEAREST; break; | |||||
case TextureMinFilter::LINEAR_TEXEL_NO_MIPMAP: gl_filter = GL_LINEAR; break; | |||||
case TextureMinFilter::NEAREST_TEXEL_NEAREST_MIPMAP: gl_filter = GL_NEAREST_MIPMAP_NEAREST; break; | |||||
case TextureMinFilter::NEAREST_TEXEL_LINEAR_MIPMAP: gl_filter = GL_NEAREST_MIPMAP_LINEAR; break; | |||||
case TextureMinFilter::LINEAR_TEXEL_NEAREST_MIPMAP: gl_filter = GL_LINEAR_MIPMAP_NEAREST; break; | |||||
case TextureMinFilter::LINEAR_TEXEL_LINEAR_MIPMAP: gl_filter = GL_LINEAR_MIPMAP_LINEAR; break; | |||||
case TextureMinFilter::LINEAR_TEXEL_NO_MIPMAP: | |||||
gl_filter = GL_LINEAR; | |||||
break; | |||||
case TextureMinFilter::NEAREST_TEXEL_NEAREST_MIPMAP: | |||||
gl_filter = GL_NEAREST_MIPMAP_NEAREST; | |||||
break; | |||||
case TextureMinFilter::NEAREST_TEXEL_LINEAR_MIPMAP: | |||||
gl_filter = GL_NEAREST_MIPMAP_LINEAR; | |||||
break; | |||||
case TextureMinFilter::LINEAR_TEXEL_NEAREST_MIPMAP: | |||||
gl_filter = GL_LINEAR_MIPMAP_NEAREST; | |||||
break; | |||||
case TextureMinFilter::LINEAR_TEXEL_LINEAR_MIPMAP: | |||||
gl_filter = GL_LINEAR_MIPMAP_LINEAR; | |||||
break; | |||||
case TextureMinFilter::NEAREST_TEXEL_NO_MIPMAP: | |||||
default: | |||||
gl_filter = GL_NEAREST; | |||||
break; | |||||
} | } | ||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, gl_filter); | glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, gl_filter); | ||||
#endif | #endif | ||||
@@ -53,11 +53,18 @@ class TimerData | |||||
private: | private: | ||||
TimerData() | TimerData() | ||||
{ | { | ||||
Init(); | |||||
(void)GetSeconds(true); | (void)GetSeconds(true); | ||||
} | } | ||||
#if __linux__ || __native_client__ || __APPLE__ \ | #if __linux__ || __native_client__ || __APPLE__ \ | ||||
|| (HAVE_GETTIMEOFDAY && HAVE_USLEEP) | || (HAVE_GETTIMEOFDAY && HAVE_USLEEP) | ||||
inline void Init() | |||||
{ | |||||
m_tv.tv_usec = 0; | |||||
m_tv.tv_sec = 0; | |||||
} | |||||
float GetSeconds(bool reset) | float GetSeconds(bool reset) | ||||
{ | { | ||||
struct timeval tv, tv0 = m_tv; | struct timeval tv, tv0 = m_tv; | ||||
@@ -76,6 +83,11 @@ private: | |||||
struct timeval m_tv; | struct timeval m_tv; | ||||
#elif _WIN32 | #elif _WIN32 | ||||
inline void Init() | |||||
{ | |||||
m_cycles.QuadPart = 0; | |||||
} | |||||
float GetSeconds(bool reset) | float GetSeconds(bool reset) | ||||
{ | { | ||||
static float secs_per_cycle = GetSecondsPerCycle(); | static float secs_per_cycle = GetSecondsPerCycle(); | ||||
@@ -102,6 +114,11 @@ private: | |||||
LARGE_INTEGER m_cycles; | LARGE_INTEGER m_cycles; | ||||
#elif __CELLOS_LV2__ | #elif __CELLOS_LV2__ | ||||
inline void Init() | |||||
{ | |||||
m_cycles = 0; | |||||
} | |||||
float GetSeconds(bool reset) | float GetSeconds(bool reset) | ||||
{ | { | ||||
static float secs_per_cycle = GetSecondsPerCycle(); | static float secs_per_cycle = GetSecondsPerCycle(); | ||||
@@ -126,6 +143,11 @@ private: | |||||
uint64_t m_cycles; | uint64_t m_cycles; | ||||
#else | #else | ||||
inline void Init() | |||||
{ | |||||
m_ticks = 0; | |||||
} | |||||
float GetSeconds(bool reset) | float GetSeconds(bool reset) | ||||
{ | { | ||||
static bool initialised = Init(); | static bool initialised = Init(); | ||||
@@ -40,26 +40,27 @@ void bench_half(int mode) | |||||
ph[i] = half::makebits(rand<uint16_t>()); | ph[i] = half::makebits(rand<uint16_t>()); | ||||
break; | break; | ||||
case 2: | case 2: | ||||
default: | |||||
for (size_t i = 0; i < HALF_TABLE_SIZE + 1; i++) | for (size_t i = 0; i < HALF_TABLE_SIZE + 1; i++) | ||||
ph[i] = rand(-2.0f, 2.0f); | ph[i] = rand(-2.0f, 2.0f); | ||||
break; | break; | ||||
} | } | ||||
/* Copy float */ | |||||
timer.Get(); | |||||
for (size_t i = 0; i < HALF_TABLE_SIZE; i++) | |||||
pf[i] = pf[i + 1]; | |||||
result[0] += timer.Get(); | |||||
/* Convert half to float (array) */ | /* Convert half to float (array) */ | ||||
timer.Get(); | timer.Get(); | ||||
half::convert(pf, ph, HALF_TABLE_SIZE); | half::convert(pf, ph, HALF_TABLE_SIZE); | ||||
result[1] += timer.Get(); | |||||
result[0] += timer.Get(); | |||||
/* Convert half to float (fast) */ | /* Convert half to float (fast) */ | ||||
timer.Get(); | timer.Get(); | ||||
for (size_t i = 0; i < HALF_TABLE_SIZE; i++) | for (size_t i = 0; i < HALF_TABLE_SIZE; i++) | ||||
pf[i] = (float)ph[i]; | pf[i] = (float)ph[i]; | ||||
result[1] += timer.Get(); | |||||
/* Copy float */ | |||||
timer.Get(); | |||||
for (size_t i = 0; i < HALF_TABLE_SIZE; i++) | |||||
pf[i] = pf[i + 1]; | |||||
result[2] += timer.Get(); | result[2] += timer.Get(); | ||||
/* Add a half to every float */ | /* Add a half to every float */ | ||||
@@ -111,9 +112,9 @@ void bench_half(int mode) | |||||
result[i] *= 1e9f / (HALF_TABLE_SIZE * HALF_RUNS); | result[i] *= 1e9f / (HALF_TABLE_SIZE * HALF_RUNS); | ||||
Log::Info(" ns/elem\n"); | Log::Info(" ns/elem\n"); | ||||
Log::Info("float = float %7.3f\n", result[0]); | |||||
Log::Info("float = half (array) %7.3f\n", result[1]); | |||||
Log::Info("float = half (fast) %7.3f\n", result[2]); | |||||
Log::Info("float = half (array) %7.3f\n", result[0]); | |||||
Log::Info("float = half (fast) %7.3f\n", result[1]); | |||||
Log::Info("float = float %7.3f\n", result[2]); | |||||
Log::Info("float += half %7.3f\n", result[3]); | Log::Info("float += half %7.3f\n", result[3]); | ||||
Log::Info("half = half %7.3f\n", result[4]); | Log::Info("half = half %7.3f\n", result[4]); | ||||
Log::Info("half = -half %7.3f\n", result[5]); | Log::Info("half = -half %7.3f\n", result[5]); | ||||