FreeRDP/libfreerdp/primitives/test/TestPrimitives16to32bpp.c
2014-09-04 15:46:20 -04:00

210 lines
6.2 KiB
C

/* test_colors.c
* vi:ts=4 sw=4
*
* (c) Copyright 2014 Hewlett-Packard Development Company, L.P.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include <assert.h>
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include <winpr/sysinfo.h>
#include "prim_test.h"
static const int RGB_TRIAL_ITERATIONS = 1000;
static const float TEST_TIME = 4.0;
extern BOOL g_TestPrimitivesPerformance;
extern pstatus_t general_RGB565ToARGB_16u32u_C3C4(
const UINT16* pSrc, INT32 srcStep,
UINT32* pDst, INT32 dstStep,
UINT32 width, UINT32 height,
BOOL alpha, BOOL invert);
extern pstatus_t sse3_RGB565ToARGB_16u32u_C3C4(
const UINT16* pSrc, INT32 srcStep,
UINT32* pDst, INT32 dstStep,
UINT32 width, UINT32 height,
BOOL alpha, BOOL invert);
/* ------------------------------------------------------------------------- */
static BOOL try_16To32(
const UINT16 *data16,
int sOffset,
int dOffset,
int width, int height)
{
BOOL success;
const char *sAligned = "sAlign";
const char *sUnaligned = "s!Align";
const char *dAligned = "dAlign";
const char *dUnaligned = "d!Align";
const char *sAlignStr, *dAlignStr;
const UINT16 *src;
UINT32 ALIGN(outNN1[4096+3]), ALIGN(outAN1[4096+3]),
ALIGN(outNI1[4096+3]), ALIGN(outAI1[4096+3]);
UINT32 ALIGN(outNN2[4096+3]), ALIGN(outAN2[4096+3]),
ALIGN(outNI2[4096+3]), ALIGN(outAI2[4096+3]);
assert(sOffset < 4);
assert(dOffset < 4);
assert(width*height <= 4096);
success = TRUE;
src = data16 + sOffset;
sAlignStr = (sOffset == 0) ? sAligned : sUnaligned;
dAlignStr = (dOffset == 0) ? dAligned : dUnaligned;
general_RGB565ToARGB_16u32u_C3C4(src, width*sizeof(UINT16),
outNN1+dOffset, width*sizeof(UINT32), width, height, FALSE, FALSE);
general_RGB565ToARGB_16u32u_C3C4(src, width*sizeof(UINT16),
outAN1+dOffset, width*sizeof(UINT32), width, height, TRUE, FALSE);
general_RGB565ToARGB_16u32u_C3C4(src, width*sizeof(UINT16),
outNI1+dOffset, width*sizeof(UINT32), width, height, FALSE, TRUE);
general_RGB565ToARGB_16u32u_C3C4(src, width*sizeof(UINT16),
outAI1+dOffset, width*sizeof(UINT32), width, height, TRUE, TRUE);
#ifdef WITH_SSE2
printf(" Testing 16-to-32bpp SSE3 version (%s, %s, %dx%d)\n",
sAlignStr, dAlignStr, width, height);
if (IsProcessorFeaturePresent(PF_SSE3_INSTRUCTIONS_AVAILABLE))
{
int i;
sse3_RGB565ToARGB_16u32u_C3C4(src, width*sizeof(UINT16),
outNN2+dOffset, width*sizeof(UINT32), width, height, FALSE, FALSE);
sse3_RGB565ToARGB_16u32u_C3C4(src, width*sizeof(UINT16),
outAN2+dOffset, width*sizeof(UINT32), width, height, TRUE, FALSE);
sse3_RGB565ToARGB_16u32u_C3C4(src, width*sizeof(UINT16),
outNI2+dOffset, width*sizeof(UINT32), width, height, FALSE, TRUE);
sse3_RGB565ToARGB_16u32u_C3C4(src, width*sizeof(UINT16),
outAI2+dOffset, width*sizeof(UINT32), width, height, TRUE, TRUE);
for (i=0; i<width * height; i++)
{
int s = i + sOffset;
int d = i + dOffset;
if (outNN1[d] != outNN2[d])
{
printf("16To32bpp-SSE FAIL (%s, %s, !alpha, !invert)"
" 0x%04x -> 0x%08x rather than 0x%08x\n",
sAlignStr, dAlignStr, data16[s], outNN2[d], outNN1[d]);
success = FALSE;
}
if (outAN1[d] != outAN2[d])
{
printf("16To32bpp-SSE FAIL (%s, %s, alpha, !invert)"
" 0x%04x -> 0x%08x rather than 0x%08x\n",
sAlignStr, dAlignStr, data16[s], outAN2[d], outAN1[d]);
success = FALSE;
}
if (outNI1[d] != outNI2[d])
{
printf("16To32bpp-SSE FAIL (%s, %s, !alpha, invert)"
" 0x%04x -> 0x%08x rather than 0x%08x\n",
sAlignStr, dAlignStr, data16[s], outNI2[d], outNI1[d]);
success = FALSE;
}
if (outAI1[d] != outAI2[d])
{
printf("16To32bpp-SSE FAIL (%s, %s, alpha, invert)"
" 0x%04x -> 0x%08x rather than 0x%08x\n",
sAlignStr, dAlignStr, data16[s], outAI2[d], outNI1[d]);
success = FALSE;
}
}
}
#endif /* WITH_SSE2 */
return success;
}
/* ------------------------------------------------------------------------- */
int test_RGB565ToARGB_16u32u_C3C4_func(void)
{
UINT16 ALIGN(data16[4096+3]);
BOOL success;
success = TRUE;
get_random_data(data16, sizeof(data16));
/* Source aligned, dest aligned, 64x64 */
success &= try_16To32(data16, 0, 0, 64, 64);
/* Source !aligned, dest aligned, 64x64 */
success &= try_16To32(data16, 1, 0, 64, 64);
/* Source aligned, dest !aligned, 64x64 */
success &= try_16To32(data16, 0, 1, 64, 64);
/* Source !aligned, dest !aligned, 64x64 */
success &= try_16To32(data16, 1, 1, 64, 64);
/* Odd size */
success &= try_16To32(data16, 0, 0, 17, 53);
if (success) printf("All RGB565ToARGB_16u32u_C3C4 tests passed.\n");
return success ? SUCCESS : FAILURE;
}
/* ------------------------------------------------------------------------- */
STD_SPEED_TEST(
test16to32_speed, UINT16, UINT32, PRIM_NOP,
TRUE, general_RGB565ToARGB_16u32u_C3C4(
(const UINT16 *) src1, 64*2, (UINT32 *) dst, 64*4,
64,64, TRUE, TRUE),
#ifdef WITH_SSE2
TRUE, sse3_RGB565ToARGB_16u32u_C3C4(
(const UINT16 *) src1, 64*2, (UINT32 *) dst, 64*4,
64,64, TRUE, TRUE),
PF_SSE3_INSTRUCTIONS_AVAILABLE, FALSE,
#else
FALSE, PRIM_NOP, 0, FALSE,
#endif
FALSE, PRIM_NOP);
/* ------------------------------------------------------------------------- */
int test_RGB565ToARGB_16u32u_C3C4_speed(void)
{
UINT16 ALIGN(src[4096]);
UINT32 ALIGN(dst[4096]);
int size_array[] = { 64 };
get_random_data(src, sizeof(src));
test16to32_speed("16-to-32bpp", "aligned",
(const UINT16 *) src, 0, 0, (UINT32 *) dst,
size_array, 1, RGB_TRIAL_ITERATIONS, TEST_TIME);
return SUCCESS;
}
int TestPrimitives16to32bpp(int argc, char* argv[])
{
int status;
status = test_RGB565ToARGB_16u32u_C3C4_func();
if (status != SUCCESS)
return 1;
if (g_TestPrimitivesPerformance)
{
status = test_RGB565ToARGB_16u32u_C3C4_speed();
if (status != SUCCESS)
return 1;
}
return 0;
}