blob: 6f50f05da0d081a5a92315bc49cf5c86857c41d3 [file] [log] [blame]
/*
* Copyright 2008 Sony Corporation of America
*
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
#include <math.h>
#include <spu_intrinsics.h>
#include <spu_mfcio.h>
#include <mars/task.h>
#include "mpu_grayscale.h"
#define DISABLE_SIMD 0
#if DISABLE_SIMD
static float rconst = 0.29891f;
static float gconst = 0.58661f;
static float bconst = 0.11448f;
#else
static vector float vec_rconst = {0.29891f, 0.29891f, 0.29891f, 0.29891f};
static vector float vec_gconst = {0.58661f, 0.58661f, 0.58661f, 0.58661f};
static vector float vec_bconst = {0.11448f, 0.11448f, 0.11448f, 0.11448f};
static vector float vec_fzero = {0.0f, 0.0f, 0.0f, 0.0f};
static vector unsigned int vec_max = {0xff, 0xff, 0xff, 0xff};
static vector unsigned char vec_zero = (vector unsigned char) {
0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00
};
static vector unsigned char vec_patr = (vector unsigned char) {
0x80, 0x80, 0x80, 0x01,
0x80, 0x80, 0x80, 0x05,
0x80, 0x80, 0x80, 0x09,
0x80, 0x80, 0x80, 0x0d
};
static vector unsigned char vec_patg = (vector unsigned char) {
0x80, 0x80, 0x80, 0x02,
0x80, 0x80, 0x80, 0x06,
0x80, 0x80, 0x80, 0x0a,
0x80, 0x80, 0x80, 0x0e
};
static vector unsigned char vec_patb = (vector unsigned char) {
0x80, 0x80, 0x80, 0x03,
0x80, 0x80, 0x80, 0x07,
0x80, 0x80, 0x80, 0x0b,
0x80, 0x80, 0x80, 0x0f
};
static vector unsigned char vec_paty = (vector unsigned char) {
0x80, 0x03, 0x03, 0x03,
0x80, 0x07, 0x07, 0x07,
0x80, 0x0b, 0x0b, 0x0b,
0x80, 0x0f, 0x0f, 0x0f
};
#endif
static unsigned char mandelbrot_buffer[4200] __attribute__((aligned(128)));
static unsigned char grayscale_buffer[4200] __attribute__((aligned(128)));
int mars_task_main(const struct mars_task_args *task_args)
{
struct grayscale_params params;
mfc_get(&params, task_args->type.u64[0], sizeof(struct grayscale_params), 0,0,0);
mfc_write_tag_mask(1 << 0);
mfc_read_tag_status_all();
int line;
unsigned char *src = mandelbrot_buffer;
unsigned char *dst = grayscale_buffer;
for (line = 0; line < params.line_count; line++) {
mfc_get(src, params.src_buffer_ea, params.buffer_w * sizeof(unsigned int), 0,0,0);
mfc_write_tag_mask(1 << 0);
mfc_read_tag_status_all();
#if DISABLE_SIMD
float r, g, b, y;
int i;
for (i = 0; i < params.buffer_w; i++) {
r = (float)src[i * 4 + 1];
g = (float)src[i * 4 + 2];
b = (float)src[i * 4 + 3];
y = r * rconst + g * gconst + b * bconst;
y = y < 0xff ? y : 0xff;
dst[i * 4 + 1] = dst[i * 4 + 2] = dst[i * 4 + 3] = (unsigned char)y;
}
#else
vector unsigned char *vec_src = (vector unsigned char *)src;
vector unsigned char *vec_dst = (vector unsigned char *)dst;
int i;
for (i = 0; i < params.buffer_w / 4; i++) {
vector unsigned int vec_r = (vector unsigned int)spu_shuffle(vec_src[i], vec_zero, vec_patr);
vector unsigned int vec_g = (vector unsigned int)spu_shuffle(vec_src[i], vec_zero, vec_patg);
vector unsigned int vec_b = (vector unsigned int)spu_shuffle(vec_src[i], vec_zero, vec_patb);
vector unsigned int vec_y;
vector unsigned int vec_pat;
vector float vec_fr = spu_convtf(vec_r, 0);
vector float vec_fg = spu_convtf(vec_g, 0);
vector float vec_fb = spu_convtf(vec_b, 0);
vector float vec_fy;
vec_fy = spu_madd(vec_fr, vec_rconst, vec_fzero);
vec_fy = spu_madd(vec_fg, vec_gconst, vec_fy);
vec_fy = spu_madd(vec_fb, vec_bconst, vec_fy);
vec_y = spu_convtu(vec_fy, 0);
vec_pat = spu_cmpgt(vec_y, vec_max);
vec_y = spu_sel(vec_y, vec_max, vec_pat);
vec_dst[i] = (vector unsigned char)spu_shuffle(vec_y, (vector unsigned int)vec_zero, vec_paty);
}
#endif
mfc_put(dst, params.dst_buffer_ea, params.buffer_w * sizeof(unsigned int), 0,0,0);
mfc_write_tag_mask(1 << 0);
mfc_read_tag_status_all();
params.src_buffer_ea += params.buffer_w * sizeof(unsigned int);
params.dst_buffer_ea += params.buffer_w * sizeof(unsigned int);
}
return 0;
}