Restructuring of bilinear kernels in prep for 2-pass change.

#pragma OPENCL EXTENSION cl_khr_byte_addressable_store : enable
#pragma OPENCL EXTENSION cl_amd_printf : enable

__constant int bilinear_filters[8][2] = {
    { 128, 0},
    { 112, 16},
    { 96, 32},
    { 80, 48},
    { 64, 64},
    { 48, 80},
    { 32, 96},
    { 16, 112}
};

__constant short sub_pel_filters[8][8] = {
    //These were originally 8x6, but are padded for vector ops
    { 0, 0, 128, 0, 0, 0, 0, 0}, /* note that 1/8 pel positions are just as per alpha -0.5 bicubic */
    { 0, -6, 123, 12, -1, 0, 0, 0},
    { 2, -11, 108, 36, -8, 1, 0, 0}, /* New 1/4 pel 6 tap filter */
    { 0, -9, 93, 50, -6, 0, 0, 0},
    { 3, -16, 77, 77, -16, 3, 0, 0}, /* New 1/2 pel 6 tap filter */
    { 0, -6, 50, 93, -9, 0, 0, 0},
    { 1, -8, 36, 108, -11, 2, 0, 0}, /* New 1/4 pel 6 tap filter */
    { 0, -1, 12, 123, -6, 0, 0, 0},
};

kernel void vp8_filter_block2d_first_pass_kernel(
    __global unsigned char *src_base,
    int src_offset,
    __global int *output_ptr,
    unsigned int src_pixels_per_line,
    unsigned int pixel_step,
    unsigned int output_height,
    unsigned int output_width,
    int filter_offset
){
    uint tid = get_global_id(0);
    uint i = tid;

    global unsigned char *src_ptr = &src_base[src_offset];
    //Note that src_offset will be reset later, which is why we capture it now

    int Temp;
    int PS2 = 2*(int)pixel_step;
    int PS3 = 3*(int)pixel_step;

    __constant short *vp8_filter = sub_pel_filters[filter_offset];

    if (tid < (output_width*output_height)){
            src_offset = i + (i/output_width * (src_pixels_per_line - output_width)) + PS2;

                Temp = (int)(src_ptr[src_offset - PS2]      * vp8_filter[0]) +
                   (int)(src_ptr[src_offset - (int)pixel_step] * vp8_filter[1]) +
                   (int)(src_ptr[src_offset]                * vp8_filter[2]) +
                   (int)(src_ptr[src_offset + pixel_step]   * vp8_filter[3]) +
                   (int)(src_ptr[src_offset + PS2]          * vp8_filter[4]) +
                   (int)(src_ptr[src_offset + PS3]          * vp8_filter[5]) +
                   (VP8_FILTER_WEIGHT >> 1);      /* Rounding */

            /* Normalize back to 0-255 */
            Temp = Temp >> VP8_FILTER_SHIFT;

            //Temp = (int)src_ptr[2];
            if (Temp < 0)
                Temp = 0;
            else if ( Temp > 255 )
                Temp = 255;

            output_ptr[i] = Temp;
    }

}

kernel void vp8_filter_block2d_second_pass_kernel
(
    __global int *src_base,
    int src_offset,
    __global unsigned char *output_base,
    int output_offset,
    int output_pitch,
    unsigned int src_pixels_per_line,
    unsigned int pixel_step,
    unsigned int output_height,
    unsigned int output_width,
    int filter_offset
) {

    global int *src_ptr = &src_base[src_offset];
    global unsigned char *output_ptr = &output_base[output_offset];

    int out_offset; //Not same as output_offset...
    int Temp;
    int PS2 = 2*(int)pixel_step;
    int PS3 = 3*(int)pixel_step;

    unsigned int src_increment = src_pixels_per_line - output_width;

    uint i = get_global_id(0);

    __constant short *vp8_filter = sub_pel_filters[filter_offset];

    if (i < (output_width * output_height)){
        out_offset = i/output_width;
        src_offset = out_offset;

        src_offset = i + (src_offset * src_increment);
        out_offset = i%output_width + (out_offset * output_pitch);

        /* Apply filter */
        Temp = ((int)src_ptr[src_offset - PS2] * vp8_filter[0]) +
           ((int)src_ptr[src_offset -(int)pixel_step] * vp8_filter[1]) +
           ((int)src_ptr[src_offset]                  * vp8_filter[2]) +
           ((int)src_ptr[src_offset + pixel_step]     * vp8_filter[3]) +
           ((int)src_ptr[src_offset + PS2]       * vp8_filter[4]) +
           ((int)src_ptr[src_offset + PS3]       * vp8_filter[5]) +
           (VP8_FILTER_WEIGHT >> 1);   /* Rounding */

        /* Normalize back to 0-255 */
        Temp = Temp >> VP8_FILTER_SHIFT;
        if (Temp < 0)
            Temp = 0;
        else if (Temp > 255)
            Temp = 255;

        output_ptr[out_offset] = (unsigned char)Temp;
    }
}

void vp8_filter_block2d_bil_first_pass(
    __global unsigned char *src_base,
    int src_offset,
    __global int *output_ptr,
    unsigned int src_pixels_per_line,
    unsigned int pixel_step,
    unsigned int output_height,
    unsigned int output_width,
    int filter_offset
){
    uint tid = get_global_id(0);

    global unsigned char *src_ptr = &src_base[src_offset];

    unsigned int i, j;
    __constant int *vp8_filter = bilinear_filters[filter_offset];

    unsigned int out_row,out_offset;
    int src_increment = src_pixels_per_line - output_width;

    if (tid < output_width * output_height){
        for (i = 0; i < output_height; i++)
        {
            src_offset = i*(output_width+src_increment);
            out_row = output_width * i;
            for (j = 0; j < output_width; j++)
            {
                out_offset = out_row + j;

                /* Apply bilinear filter */
                output_ptr[out_offset] = (((int)src_ptr[src_offset]   * vp8_filter[0]) +
                                 ((int)src_ptr[src_offset+pixel_step] * vp8_filter[1]) +
                                 (VP8_FILTER_WEIGHT / 2)) >> VP8_FILTER_SHIFT;
                src_offset++;
            }
        }
    }
}

void vp8_filter_block2d_bil_second_pass
(
    __global int *src_ptr,
    __global unsigned char *output_base,
    int output_offset,
    int output_pitch,
    unsigned int src_pixels_per_line,
    unsigned int pixel_step,
    unsigned int output_height,
    unsigned int output_width,
    int filter_offset
) {
    uint tid = get_global_id(0);

    global unsigned char *output_ptr = &output_base[output_offset];

    unsigned int i, j;
    int Temp;
    __constant int *vp8_filter = bilinear_filters[filter_offset];

    int out_offset;
    int src_offset;
    int src_increment = src_pixels_per_line - output_width;

    if (tid < output_width*output_height){
        for (i = 0; i < output_height; i++)
        {
            src_offset = i*(output_width+src_increment);
            out_offset = i*output_pitch;
            for (j = 0; j < output_width; j++)
            {
                /* Apply filter */
                Temp = ((int)src_ptr[src_offset]         * vp8_filter[0]) +
                       ((int)src_ptr[src_offset+pixel_step] * vp8_filter[1]) +
                       (VP8_FILTER_WEIGHT / 2);
                output_ptr[out_offset++] = (unsigned int)(Temp >> VP8_FILTER_SHIFT);

                src_offset++;
            }
        }
    }
}

void vp8_filter_block2d_bil
(
    __global unsigned char *src_base,
    int src_offset,
    __global unsigned char *output_ptr,
    int output_offset,
    unsigned int src_pixels_per_line,
    unsigned int dst_pitch,
    int xoffset,
    int yoffset,
    int Width,
    int Height,
    __global int *int_mem
)
{
    /* First filter 1-D horizontally... */
    vp8_filter_block2d_bil_first_pass(src_base, src_offset, int_mem, src_pixels_per_line, 1, Height + 1, Width, xoffset);

    /* then 1-D vertically... */
    vp8_filter_block2d_bil_second_pass(int_mem, output_ptr, output_offset, dst_pitch, Width, Width, Height, Width, yoffset);
}

__kernel void vp8_bilinear_predict4x4_kernel
(
        __global unsigned char *src_ptr,
        int src_pixels_per_line,
        int xoffset,
        int yoffset,
        __global unsigned char *dst_base,
        int dst_offset,
        int dst_pitch,
        __global int *FData
 ) {

    vp8_filter_block2d_bil(src_ptr, 0, dst_base, dst_offset, src_pixels_per_line, dst_pitch, xoffset, yoffset, 4, 4, FData);
}

__kernel void vp8_bilinear_predict8x8_kernel
(
        __global unsigned char *src_ptr,
        int src_pixels_per_line,
        int xoffset,
        int yoffset,
        __global unsigned char *dst_base,
        int dst_offset,
        int dst_pitch,
        __global int *FData
        ) {

    vp8_filter_block2d_bil(src_ptr, 0, dst_base, dst_offset, src_pixels_per_line, dst_pitch, xoffset, yoffset, 8, 8, FData);

}

__kernel void vp8_bilinear_predict8x4_kernel
(
        __global unsigned char *src_ptr,
        int src_pixels_per_line,
        int xoffset,
        int yoffset,
        __global unsigned char *dst_base,
        int dst_offset,
        int dst_pitch,
        __global int *FData
        ) {

    vp8_filter_block2d_bil(src_ptr, 0, dst_base, dst_offset, src_pixels_per_line, dst_pitch, xoffset, yoffset, 8, 4, FData);
}

__kernel void vp8_bilinear_predict16x16_kernel
(
        __global unsigned char *src_ptr,
        int src_pixels_per_line,
        int xoffset,
        int yoffset,
        __global unsigned char *dst_base,
        int dst_offset,
        int dst_pitch,
        __global int *FData
        ) {

    vp8_filter_block2d_bil(src_ptr, 0, dst_base, dst_offset, src_pixels_per_line, dst_pitch, xoffset, yoffset, 16, 16, FData);
}

//Called from reconinter_cl.c
kernel void vp8_memcpy_kernel(
    global unsigned char *src,
    int src_stride,
    global unsigned char *dst,
    int dst_stride,
    int num_bytes,
    int num_iter
){

    int i,r;
    int src_offset, dst_offset;

    r = get_global_id(1);
    if (r < get_global_size(1)){
        i = get_global_id(0);
        if (i < get_global_size(0)){
            src_offset = r*src_stride + i;
            dst_offset = r*dst_stride + i;
            dst[dst_offset] = src[src_offset];
        }
    }
}

//Not used currently.
void vp8_memset_short(
    global short *mem,
    int offset,
    short newval,
    size_t size
)
{
    int tid = get_global_id(0);

    if (tid < (size/2)){
        mem[offset+tid/2] = newval;
    }
}

//Here to EOF is old code that should be removed at end of project.
#if 0

void vp8_filter_block2d_first_pass(
    __global unsigned char *src_base,
    int src_offset,
    __private int *output_ptr,
    unsigned int src_pixels_per_line,
    unsigned int pixel_step,
    unsigned int output_height,
    unsigned int output_width,
    int filter_offset
){
    uint tid = get_global_id(0);
    uint i = tid;

    global unsigned char *src_ptr = &src_base[src_offset];
    //Note that src_offset will be reset later, which is why we capture it now
    src_offset = 0;

    int Temp;
    int PS2 = 2*(int)pixel_step;
    int PS3 = 3*(int)pixel_step;

    __constant short *vp8_filter = sub_pel_filters[filter_offset];

    if (tid < (output_width*output_height)){
        for (i=0; i < output_width*output_height; i++){
            src_offset = i + (i/output_width * (src_pixels_per_line - output_width)) + PS2;

                Temp = (int)(src_ptr[src_offset - PS2]      * vp8_filter[0]) +
                   (int)(src_ptr[src_offset - (int)pixel_step] * vp8_filter[1]) +
                   (int)(src_ptr[src_offset]                * vp8_filter[2]) +
                   (int)(src_ptr[src_offset + pixel_step]   * vp8_filter[3]) +
                   (int)(src_ptr[src_offset + PS2]          * vp8_filter[4]) +
                   (int)(src_ptr[src_offset + PS3]          * vp8_filter[5]) +
                   (VP8_FILTER_WEIGHT >> 1);      /* Rounding */

            /* Normalize back to 0-255 */
            Temp = Temp >> VP8_FILTER_SHIFT;

            //Temp = (int)src_ptr[2];
            if (Temp < 0)
                Temp = 0;
            else if ( Temp > 255 )
                Temp = 255;

            output_ptr[i] = Temp;
        }
    }

    //Add a fence so that no 2nd pass stuff starts before 1st pass writes are done.
    write_mem_fence(CLK_GLOBAL_MEM_FENCE);
}

void vp8_filter_block2d_second_pass
(
    __private int *src_ptr,
    __global unsigned char *output_base,
    int output_offset,
    int output_pitch,
    unsigned int src_pixels_per_line,
    unsigned int pixel_step,
    unsigned int output_height,
    unsigned int output_width,
    int filter_offset
) {

    global unsigned char *output_ptr = &output_base[output_offset];

    int out_offset; //Not same as output_offset...
    int src_offset;
    int Temp;
    int PS2 = 2*(int)pixel_step;
    int PS3 = 3*(int)pixel_step;

    unsigned int src_increment = src_pixels_per_line - output_width;

    uint i = get_global_id(0);

    __constant short *vp8_filter = sub_pel_filters[filter_offset];

    if (i < (output_width * output_height)){
        out_offset = i/output_width;
        src_offset = out_offset;

        src_offset = i + (src_offset * src_increment);
        out_offset = i%output_width + (out_offset * output_pitch);

        /* Apply filter */
        Temp = ((int)src_ptr[src_offset - PS2] * vp8_filter[0]) +
           ((int)src_ptr[src_offset -(int)pixel_step] * vp8_filter[1]) +
           ((int)src_ptr[src_offset]                  * vp8_filter[2]) +
           ((int)src_ptr[src_offset + pixel_step]     * vp8_filter[3]) +
           ((int)src_ptr[src_offset + PS2]       * vp8_filter[4]) +
           ((int)src_ptr[src_offset + PS3]       * vp8_filter[5]) +
           (VP8_FILTER_WEIGHT >> 1);   /* Rounding */

        /* Normalize back to 0-255 */
        Temp = Temp >> VP8_FILTER_SHIFT;
        if (Temp < 0)
            Temp = 0;
        else if (Temp > 255)
            Temp = 255;

        output_ptr[out_offset] = (unsigned char)Temp;
    }
}

//Used?
__kernel void vp8_block_variation_kernel
(
    __global unsigned char  *src_ptr,
    int   src_pixels_per_line,
    __global int *HVar,
    __global int *VVar
)
{
    int i, j;
    __global unsigned char *Ptr = src_ptr;

    for (i = 0; i < 4; i++)
    {
        for (j = 0; j < 4; j++)
        {
            *HVar += abs((int)Ptr[j] - (int)Ptr[j+1]);
            *VVar += abs((int)Ptr[j] - (int)Ptr[j+src_pixels_per_line]);
        }

        Ptr += src_pixels_per_line;
    }
}

__kernel void vp8_sixtap_predict_kernel
(
    __global unsigned char  *src_ptr,
    int src_offset,
    int  src_pixels_per_line,
    int  xoffset,
    int  yoffset,
    __global unsigned char *dst_ptr,
    int dst_offset,
    int  dst_pitch,
    __global int *int_data
        ) {

    /* First filter 1-D horizontally... */
    vp8_filter_block2d_first_pass_kernel(src_ptr, src_offset, int_data, src_pixels_per_line, 1, 9, 4, xoffset);

    /* then filter verticaly... */
    vp8_filter_block2d_second_pass_kernel(int_data, 8, dst_ptr, dst_offset, dst_pitch, 4, 4, 4, 4, yoffset);
}

__kernel void vp8_sixtap_predict8x8_kernel
(
    __global unsigned char  *src_ptr,
    int src_offset,
    int  src_pixels_per_line,
    int  xoffset,
    int  yoffset,
    __global unsigned char *dst_ptr,
    int dst_offset,
    int  dst_pitch
)
{
    __private int FData[13*16];   /* Temp data bufffer used in filtering */

    /* First filter 1-D horizontally... */
    vp8_filter_block2d_first_pass(src_ptr, src_offset, FData, src_pixels_per_line, 1, 13, 8, xoffset);

    /* then filter verticaly... */
    vp8_filter_block2d_second_pass(&FData[16], dst_ptr, dst_offset, dst_pitch, 8, 8, 8, 8, yoffset);

}

__kernel void vp8_sixtap_predict8x4_kernel
(
    __global unsigned char  *src_ptr,
    int src_offset,
    int  src_pixels_per_line,
    int  xoffset,
    int  yoffset,
    __global unsigned char *dst_ptr,
    int dst_offset,
    int  dst_pitch
)
{
    __private int FData[13*16];   /* Temp data buffer used in filtering */

    /* First filter 1-D horizontally... */
    vp8_filter_block2d_first_pass(src_ptr, src_offset, FData, src_pixels_per_line, 1, 9, 8, xoffset);

    /* then filter verticaly... */
    vp8_filter_block2d_second_pass(&FData[16], dst_ptr, dst_offset, dst_pitch, 8, 8, 4, 8, yoffset);
}

__kernel void vp8_sixtap_predict16x16_kernel
(
    __global unsigned char  *src_ptr,
    int src_offset,
    int  src_pixels_per_line,
    int  xoffset,
    int  yoffset,
    __global unsigned char *dst_ptr,
    int dst_offset,
    int  dst_pitch
)
{
    __private int FData[21*24];   /* Temp data buffer used in filtering */

    /* First filter 1-D horizontally... */
    vp8_filter_block2d_first_pass(src_ptr, src_offset, FData, src_pixels_per_line, 1, 21, 16, xoffset);

    /* then filter verticaly... */
    vp8_filter_block2d_second_pass(&FData[32], dst_ptr, dst_offset, dst_pitch, 16, 16, 16, 16, yoffset);

    return;
}
#endif

#pragma OPENCL EXTENSION cl_khr_byte_addressable_store : enable
#pragma OPENCL EXTENSION cl_amd_printf : enable

__constant int bilinear_filters[8][2] = {
    { 128, 0},
    { 112, 16},
    { 96, 32},
    { 80, 48},
    { 64, 64},
    { 48, 80},
    { 32, 96},
    { 16, 112}
};

__constant short sub_pel_filters[8][8] = {
    //These were originally 8x6, but are padded for vector ops
    { 0, 0, 128, 0, 0, 0, 0, 0}, /* note that 1/8 pel positions are just as per alpha -0.5 bicubic */
    { 0, -6, 123, 12, -1, 0, 0, 0},
    { 2, -11, 108, 36, -8, 1, 0, 0}, /* New 1/4 pel 6 tap filter */
    { 0, -9, 93, 50, -6, 0, 0, 0},
    { 3, -16, 77, 77, -16, 3, 0, 0}, /* New 1/2 pel 6 tap filter */
    { 0, -6, 50, 93, -9, 0, 0, 0},
    { 1, -8, 36, 108, -11, 2, 0, 0}, /* New 1/4 pel 6 tap filter */
    { 0, -1, 12, 123, -6, 0, 0, 0},
};

kernel void vp8_filter_block2d_first_pass_kernel(
    __global unsigned char *src_base,
    int src_offset,
    __global int *output_ptr,
    unsigned int src_pixels_per_line,
    unsigned int pixel_step,
    unsigned int output_height,
    unsigned int output_width,
    int filter_offset
){
    uint tid = get_global_id(0);
    uint i = tid;

    global unsigned char *src_ptr = &src_base[src_offset];
    //Note that src_offset will be reset later, which is why we capture it now

    int Temp;
    int PS2 = 2*(int)pixel_step;
    int PS3 = 3*(int)pixel_step;

    __constant short *vp8_filter = sub_pel_filters[filter_offset];

    if (tid < (output_width*output_height)){
            src_offset = i + (i/output_width * (src_pixels_per_line - output_width)) + PS2;

                Temp = (int)(src_ptr[src_offset - PS2]      * vp8_filter[0]) +
                   (int)(src_ptr[src_offset - (int)pixel_step] * vp8_filter[1]) +
                   (int)(src_ptr[src_offset]                * vp8_filter[2]) +
                   (int)(src_ptr[src_offset + pixel_step]   * vp8_filter[3]) +
                   (int)(src_ptr[src_offset + PS2]          * vp8_filter[4]) +
                   (int)(src_ptr[src_offset + PS3]          * vp8_filter[5]) +
                   (VP8_FILTER_WEIGHT >> 1);      /* Rounding */

            /* Normalize back to 0-255 */
            Temp = Temp >> VP8_FILTER_SHIFT;

            //Temp = (int)src_ptr[2];
            if (Temp < 0)
                Temp = 0;
            else if ( Temp > 255 )
                Temp = 255;

            output_ptr[i] = Temp;
    }

}

kernel void vp8_filter_block2d_second_pass_kernel
(
    __global int *src_base,
    int src_offset,
    __global unsigned char *output_base,
    int output_offset,
    int output_pitch,
    unsigned int src_pixels_per_line,
    unsigned int pixel_step,
    unsigned int output_height,
    unsigned int output_width,
    int filter_offset
) {

    global int *src_ptr = &src_base[src_offset];
    global unsigned char *output_ptr = &output_base[output_offset];

    int out_offset; //Not same as output_offset...
    int Temp;
    int PS2 = 2*(int)pixel_step;
    int PS3 = 3*(int)pixel_step;

    unsigned int src_increment = src_pixels_per_line - output_width;

    uint i = get_global_id(0);

    __constant short *vp8_filter = sub_pel_filters[filter_offset];

    if (i < (output_width * output_height)){
        out_offset = i/output_width;
        src_offset = out_offset;

        src_offset = i + (src_offset * src_increment);
        out_offset = i%output_width + (out_offset * output_pitch);

        /* Apply filter */
        Temp = ((int)src_ptr[src_offset - PS2] * vp8_filter[0]) +
           ((int)src_ptr[src_offset -(int)pixel_step] * vp8_filter[1]) +
           ((int)src_ptr[src_offset]                  * vp8_filter[2]) +
           ((int)src_ptr[src_offset + pixel_step]     * vp8_filter[3]) +
           ((int)src_ptr[src_offset + PS2]       * vp8_filter[4]) +
           ((int)src_ptr[src_offset + PS3]       * vp8_filter[5]) +
           (VP8_FILTER_WEIGHT >> 1);   /* Rounding */

        /* Normalize back to 0-255 */
        Temp = Temp >> VP8_FILTER_SHIFT;
        if (Temp < 0)
            Temp = 0;
        else if (Temp > 255)
            Temp = 255;

        output_ptr[out_offset] = (unsigned char)Temp;
    }
}

void vp8_filter_block2d_bil_first_pass(
    __global unsigned char *src_ptr,
    __global int *output_ptr,
    unsigned int src_pixels_per_line,
    unsigned int pixel_step,
    unsigned int output_height,
    unsigned int output_width,
    int filter_offset
){
    uint tid = get_global_id(0);

    unsigned int i, j;
    __constant int *vp8_filter = bilinear_filters[filter_offset];

    unsigned int out_row,out_offset;
    unsigned int src_offset;
    int src_increment = src_pixels_per_line - output_width;

    for (i = 0; i < output_height; i++)
    {
        src_offset = i*(output_width+src_increment);
        out_row = output_width * i;
        for (j = 0; j < output_width; j++)
        {
            out_offset = out_row + j;

            /* Apply bilinear filter */
            output_ptr[out_offset] = (((int)src_ptr[src_offset]          * vp8_filter[0]) +
                             ((int)src_ptr[src_offset+pixel_step] * vp8_filter[1]) +
                             (VP8_FILTER_WEIGHT / 2)) >> VP8_FILTER_SHIFT;
            //src_ptr++;
            src_offset++;
        }

        /* Next row... */
        //src_ptr    += src_pixels_per_line - output_width;
        //output_ptr += output_width;
    }

    //write_mem_fence(CLK_GLOBAL_MEM_FENCE);
    //barrier(CLK_GLOBAL_MEM_FENCE);
}

void vp8_filter_block2d_bil_second_pass
(
    __global int *src_ptr,
    __global unsigned char *output_base,
    int output_offset,
    int output_pitch,
    unsigned int src_pixels_per_line,
    unsigned int pixel_step,
    unsigned int output_height,
    unsigned int output_width,
    int filter_offset
) {
    uint tid = get_global_id(0);

    global unsigned char *output_ptr = &output_base[output_offset];

    unsigned int i, j;
    int Temp;
    __constant int *vp8_filter = bilinear_filters[filter_offset];

    int out_offset;
    int src_offset;
    int src_increment = src_pixels_per_line - output_width;

    if (tid < output_width*output_height){
        for (i = 0; i < output_height; i++)
        {
            src_offset = i*(output_width+src_increment);
            out_offset = i*output_pitch;
            for (j = 0; j < output_width; j++)
            {
                /* Apply filter */
                Temp = ((int)src_ptr[src_offset]         * vp8_filter[0]) +
                       ((int)src_ptr[src_offset+pixel_step] * vp8_filter[1]) +
                       (VP8_FILTER_WEIGHT / 2);
                output_ptr[out_offset++] = (unsigned int)(Temp >> VP8_FILTER_SHIFT);
                //printf("output[%d]=%d\n",out_offset-1, Temp>>VP8_FILTER_SHIFT);
                src_offset++;
            }
        }
    }
}

void vp8_filter_block2d_bil
(
    __global unsigned char *src_ptr,
    __global unsigned char *output_ptr,
    int output_offset,
    unsigned int   src_pixels_per_line,
    unsigned int   dst_pitch,
    int      xoffset,
    int      yoffset,
    int            Width,
    int            Height,
    __global int *FData
)
{

    //__private unsigned short FData[17*16];    /* Temp data buffer used in filtering */

    /* First filter 1-D horizontally... */
    vp8_filter_block2d_bil_first_pass(src_ptr, FData, src_pixels_per_line, 1, Height + 1, Width, xoffset);

    /* then 1-D vertically... */
    vp8_filter_block2d_bil_second_pass(FData, output_ptr, output_offset, dst_pitch, Width, Width, Height, Width, yoffset);
}

__kernel void vp8_bilinear_predict4x4_kernel
(
        __global unsigned char *src_ptr,
        int src_pixels_per_line,
        int xoffset,
        int yoffset,
        __global unsigned char *dst_base,
        int dst_offset,
        int dst_pitch,
        __global int *FData
 ) {

    vp8_filter_block2d_bil(src_ptr, dst_base, dst_offset, src_pixels_per_line, dst_pitch, xoffset, yoffset, 4, 4, FData);
}

__kernel void vp8_bilinear_predict8x8_kernel
(
        __global unsigned char *src_ptr,
        int src_pixels_per_line,
        int xoffset,
        int yoffset,
        __global unsigned char *dst_base,
        int dst_offset,
        int dst_pitch,
        __global int *FData
        ) {

    vp8_filter_block2d_bil(src_ptr, dst_base, dst_offset, src_pixels_per_line, dst_pitch, xoffset, yoffset, 8, 8, FData);

}

__kernel void vp8_bilinear_predict8x4_kernel
(
        __global unsigned char *src_ptr,
        int src_pixels_per_line,
        int xoffset,
        int yoffset,
        __global unsigned char *dst_base,
        int dst_offset,
        int dst_pitch,
        __global int *FData
        ) {

    vp8_filter_block2d_bil(src_ptr, dst_base, dst_offset, src_pixels_per_line, dst_pitch, xoffset, yoffset, 8, 4, FData);
}

__kernel void vp8_bilinear_predict16x16_kernel
(
        __global unsigned char *src_ptr,
        int src_pixels_per_line,
        int xoffset,
        int yoffset,
        __global unsigned char *dst_base,
        int dst_offset,
        int dst_pitch,
        __global int *FData
        ) {

    vp8_filter_block2d_bil(src_ptr, dst_base, dst_offset, src_pixels_per_line, dst_pitch, xoffset, yoffset, 16, 16, FData);
}

//Called from reconinter_cl.c
kernel void vp8_memcpy_kernel(
    global unsigned char *src,
    int src_stride,
    global unsigned char *dst,
    int dst_stride,
    int num_bytes,
    int num_iter
){

    int i,r;
    int src_offset, dst_offset;

    r = get_global_id(1);
    if (r < get_global_size(1)){
        i = get_global_id(0);
        if (i < get_global_size(0)){
            src_offset = r*src_stride + i;
            dst_offset = r*dst_stride + i;
            dst[dst_offset] = src[src_offset];
        }
    }
}

//Not used currently.
void vp8_memset_short(
    global short *mem,
    int offset,
    short newval,
    size_t size
)
{
    int tid = get_global_id(0);

    if (tid < (size/2)){
        mem[offset+tid/2] = newval;
    }
}

//Here to EOF is old code that should be removed at end of project.
#if 0

void vp8_filter_block2d_first_pass(
    __global unsigned char *src_base,
    int src_offset,
    __private int *output_ptr,
    unsigned int src_pixels_per_line,
    unsigned int pixel_step,
    unsigned int output_height,
    unsigned int output_width,
    int filter_offset
){
    uint tid = get_global_id(0);
    uint i = tid;

    global unsigned char *src_ptr = &src_base[src_offset];
    //Note that src_offset will be reset later, which is why we capture it now
    src_offset = 0;

    int Temp;
    int PS2 = 2*(int)pixel_step;
    int PS3 = 3*(int)pixel_step;

    __constant short *vp8_filter = sub_pel_filters[filter_offset];

    if (tid < (output_width*output_height)){
        for (i=0; i < output_width*output_height; i++){
            src_offset = i + (i/output_width * (src_pixels_per_line - output_width)) + PS2;

                Temp = (int)(src_ptr[src_offset - PS2]      * vp8_filter[0]) +
                   (int)(src_ptr[src_offset - (int)pixel_step] * vp8_filter[1]) +
                   (int)(src_ptr[src_offset]                * vp8_filter[2]) +
                   (int)(src_ptr[src_offset + pixel_step]   * vp8_filter[3]) +
                   (int)(src_ptr[src_offset + PS2]          * vp8_filter[4]) +
                   (int)(src_ptr[src_offset + PS3]          * vp8_filter[5]) +
                   (VP8_FILTER_WEIGHT >> 1);      /* Rounding */

            /* Normalize back to 0-255 */
            Temp = Temp >> VP8_FILTER_SHIFT;

            //Temp = (int)src_ptr[2];
            if (Temp < 0)
                Temp = 0;
            else if ( Temp > 255 )
                Temp = 255;

            output_ptr[i] = Temp;
        }
    }

    //Add a fence so that no 2nd pass stuff starts before 1st pass writes are done.
    write_mem_fence(CLK_GLOBAL_MEM_FENCE);
}

void vp8_filter_block2d_second_pass
(
    __private int *src_ptr,
    __global unsigned char *output_base,
    int output_offset,
    int output_pitch,
    unsigned int src_pixels_per_line,
    unsigned int pixel_step,
    unsigned int output_height,
    unsigned int output_width,
    int filter_offset
) {

    global unsigned char *output_ptr = &output_base[output_offset];

    int out_offset; //Not same as output_offset...
    int src_offset;
    int Temp;
    int PS2 = 2*(int)pixel_step;
    int PS3 = 3*(int)pixel_step;

    unsigned int src_increment = src_pixels_per_line - output_width;

    uint i = get_global_id(0);

    __constant short *vp8_filter = sub_pel_filters[filter_offset];

    if (i < (output_width * output_height)){
        out_offset = i/output_width;
        src_offset = out_offset;

        src_offset = i + (src_offset * src_increment);
        out_offset = i%output_width + (out_offset * output_pitch);

        /* Apply filter */
        Temp = ((int)src_ptr[src_offset - PS2] * vp8_filter[0]) +
           ((int)src_ptr[src_offset -(int)pixel_step] * vp8_filter[1]) +
           ((int)src_ptr[src_offset]                  * vp8_filter[2]) +
           ((int)src_ptr[src_offset + pixel_step]     * vp8_filter[3]) +
           ((int)src_ptr[src_offset + PS2]       * vp8_filter[4]) +
           ((int)src_ptr[src_offset + PS3]       * vp8_filter[5]) +
           (VP8_FILTER_WEIGHT >> 1);   /* Rounding */

        /* Normalize back to 0-255 */
        Temp = Temp >> VP8_FILTER_SHIFT;
        if (Temp < 0)
            Temp = 0;
        else if (Temp > 255)
            Temp = 255;

        output_ptr[out_offset] = (unsigned char)Temp;
    }
}

//Used?
__kernel void vp8_block_variation_kernel
(
    __global unsigned char  *src_ptr,
    int   src_pixels_per_line,
    __global int *HVar,
    __global int *VVar
)
{
    int i, j;
    __global unsigned char *Ptr = src_ptr;

    for (i = 0; i < 4; i++)
    {
        for (j = 0; j < 4; j++)
        {
            *HVar += abs((int)Ptr[j] - (int)Ptr[j+1]);
            *VVar += abs((int)Ptr[j] - (int)Ptr[j+src_pixels_per_line]);
        }

        Ptr += src_pixels_per_line;
    }
}

__kernel void vp8_sixtap_predict_kernel
(
    __global unsigned char  *src_ptr,
    int src_offset,
    int  src_pixels_per_line,
    int  xoffset,
    int  yoffset,
    __global unsigned char *dst_ptr,
    int dst_offset,
    int  dst_pitch,
    __global int *int_data
        ) {

    /* First filter 1-D horizontally... */
    vp8_filter_block2d_first_pass_kernel(src_ptr, src_offset, int_data, src_pixels_per_line, 1, 9, 4, xoffset);

    /* then filter verticaly... */
    vp8_filter_block2d_second_pass_kernel(int_data, 8, dst_ptr, dst_offset, dst_pitch, 4, 4, 4, 4, yoffset);
}

__kernel void vp8_sixtap_predict8x8_kernel
(
    __global unsigned char  *src_ptr,
    int src_offset,
    int  src_pixels_per_line,
    int  xoffset,
    int  yoffset,
    __global unsigned char *dst_ptr,
    int dst_offset,
    int  dst_pitch
)
{
    __private int FData[13*16];   /* Temp data bufffer used in filtering */

    /* First filter 1-D horizontally... */
    vp8_filter_block2d_first_pass(src_ptr, src_offset, FData, src_pixels_per_line, 1, 13, 8, xoffset);

    /* then filter verticaly... */
    vp8_filter_block2d_second_pass(&FData[16], dst_ptr, dst_offset, dst_pitch, 8, 8, 8, 8, yoffset);

}

__kernel void vp8_sixtap_predict8x4_kernel
(
    __global unsigned char  *src_ptr,
    int src_offset,
    int  src_pixels_per_line,
    int  xoffset,
    int  yoffset,
    __global unsigned char *dst_ptr,
    int dst_offset,
    int  dst_pitch
)
{
    __private int FData[13*16];   /* Temp data buffer used in filtering */

    /* First filter 1-D horizontally... */
    vp8_filter_block2d_first_pass(src_ptr, src_offset, FData, src_pixels_per_line, 1, 9, 8, xoffset);

    /* then filter verticaly... */
    vp8_filter_block2d_second_pass(&FData[16], dst_ptr, dst_offset, dst_pitch, 8, 8, 4, 8, yoffset);
}

__kernel void vp8_sixtap_predict16x16_kernel
(
    __global unsigned char  *src_ptr,
    int src_offset,
    int  src_pixels_per_line,
    int  xoffset,
    int  yoffset,
    __global unsigned char *dst_ptr,
    int dst_offset,
    int  dst_pitch
)
{
    __private int FData[21*24];   /* Temp data buffer used in filtering */

    /* First filter 1-D horizontally... */
    vp8_filter_block2d_first_pass(src_ptr, src_offset, FData, src_pixels_per_line, 1, 21, 16, xoffset);

    /* then filter verticaly... */
    vp8_filter_block2d_second_pass(&FData[32], dst_ptr, dst_offset, dst_pitch, 16, 16, 16, 16, yoffset);

    return;
}
#endif


trim xor

trim xor


Kernel double -> float

Kernel double -> float

/*
 * Radiosity OpenCL kernels
 * Authors: Martin Simon      <xsimon14@stud.fit.vutbr.cz>
 *          Lukas Brzobohaty  <xbrzob06@stud.fit.vutbr.cz>
 */

/*
 * Sort patches (their indices) into indices array - parallel
 */
//#pragma OPENCL EXTENSION cl_khr_fp64: enable

float formFactor(float4 RecvPos, float4 ShootPos, float4 RecvNormal, float4 ShootNormal, float ShootDArea)
{
    float pi = 3.14159265358979323846f;

    // a normalized vector from shooter to receiver
    if (ShootPos.x == RecvPos.x &&
        ShootPos.y == RecvPos.y &&
        ShootPos.z == RecvPos.z)
    {
        return 0.0;
    }

    float4 r = ShootPos - RecvPos;

    float distance2 = dot(r, r);
    r = normalize(r);

    // the angles of the receiver and the shooter from r
    float cosi = dot(RecvNormal, r);
    float cosj = -dot(ShootNormal, r);

    // retrun computed disc approximation form factor
    return (max(cosi * cosj, 0.0f) / (pi * distance2)) * ShootDArea;
}

__kernel void sort(__global float* energies, uint patchesCount, __global uint* indices, __global uint* indicesCount, uint n, float limit, __global float* maximalEnergy)
{

    int count = 0; //real count
    uint pos = 0; //position of maximal energy
    uint maxPos = patchesCount; //sentinel
    float max = 0.0f; //maximal energy
    float lastMax = 10000000.0f; //last maximal energy
    float lastMaxOld = lastMax;

    for (int i = 0; i < n; i++)
    {
        max = 0.0;
        int j;
        for (j = 0; j < maxPos; j++)
        {
            float energy = energies[j];
            if (energy >= max && energy < lastMax)
            {
                pos = j;
                max = energy;
            }
        }

        if (i == 0)
        {
            maximalEnergy[0] = max;
        }

        if (max == 0.0 || max < limit)
        {
            if (j == maxPos)
            {
                break;
            }

            lastMax = lastMaxOld;
            maxPos = patchesCount;
            continue;
        }

        indices[i] = pos;
        count++;
        maxPos = pos;
        lastMaxOld = max;
    }

    indicesCount[0] = count;
}

/*
 * Compute radiosity step - energy distribution of N most energized patches
 */
__kernel void radiosity(__global float16* patchesGeo, __global float4* patchesInfo, uint patchesCount, __global uint* indices, __global uint* indicesCount, __global float* energies/* array of textures, uint textureSize, __local bit* visited */)
{
    int i = get_global_id(0); //position in indices array
    //int texI = i * textureSize;

    if (i >= indicesCount[0])
    {
        return;
    }

    float16 lightGeo = patchesGeo[indices[i]];
    float4 lightInfo = patchesInfo[indices[i]];
    float lightEnergy = energies[indices[i]];

    float x, y, z;

    /* Center of light patch */
    x = (lightGeo.s0 + lightGeo.s3 + lightGeo.s6 + lightGeo.s9) / 4.0;
    y = (lightGeo.s1 + lightGeo.s4 + lightGeo.s7 + lightGeo.sA) / 4.0;
    z = (lightGeo.s2 + lightGeo.s5 + lightGeo.s8 + lightGeo.sB) / 4.0;
    float4 ShootPos = {x,y,z,0};

    /* Normal of light patch */
    x = lightGeo.sC;
    y = lightGeo.sD;
    z = lightGeo.sE;
    float4 ShootNormal = {x,y,z,0};

    /* Area of light patch */
    float ShootDArea = lightGeo.sF;

    //go through all the texture
    //every point convert to index and if visited[index]==0 -> compute form factor and set to correct index
    //otherwise continue

    for(int j = 0; j < patchesCount; j++) {

        float16 patchGeo = patchesGeo[j];
        //float4 patchInfo = patchesInfo[j];

        /* Center of patch */
        x = (patchGeo.s0 + patchGeo.s3 + patchGeo.s6 + patchGeo.s9) / 4.0;
        y = (patchGeo.s1 + patchGeo.s4 + patchGeo.s7 + patchGeo.sA) / 4.0;
        z = (patchGeo.s2 + patchGeo.s5 + patchGeo.s8 + patchGeo.sB) / 4.0;
        float4 RecvPos = {x,y,z,0};

        /* Normal of patch */
        x = patchGeo.sC;
        y = patchGeo.sD;
        z = patchGeo.sE;
        float4 RecvNormal = {x,y,z,0};

        /* Compute form factor */
        float delta = formFactor(RecvPos, ShootPos, RecvNormal, ShootNormal, ShootDArea);

        /* Distribute energy */
        energies[j] += lightEnergy * 0.5 * delta;

        /* Distribute color */
        patchesInfo[j].s0 += lightInfo.s0 * 0.5 * delta;
        patchesInfo[j].s1 += lightInfo.s1 * 0.5 * delta;
        patchesInfo[j].s2 += lightInfo.s2 * 0.5 * delta;
    }

    /* Erase energy */
    energies[indices[i]] = 0;
}

/*
 * Radiosity OpenCL kernels
 * Authors: Martin Simon      <xsimon14@stud.fit.vutbr.cz>
 *          Lukas Brzobohaty  <xbrzob06@stud.fit.vutbr.cz>
 */

/*
 * Sort patches (their indices) into indices array - parallel
 */
double formFactor(float4 RecvPos, float4 ShootPos, float4 RecvNormal, float4 ShootNormal, float ShootDArea)
{
    double pi = 3.14159265358979323846;

    // a normalized vector from shooter to receiver
    if (ShootPos.x == RecvPos.x &&
        ShootPos.y == RecvPos.y &&
        ShootPos.z == RecvPos.z)
    {
        return 0.0;
    }

    float4 r = ShootPos - RecvPos;

    float distance2 = dot(r, r);
    r = normalize(r);

    // the angles of the receiver and the shooter from r
    double cosi = dot(RecvNormal, r);
    double cosj = -dot(ShootNormal, r);

    // retrun computed disc approximation form factor
    return (max(cosi * cosj, (double) 0) / (pi * distance2)) * ShootDArea;
}

__kernel void sort(__global double* energies, uint patchesCount, __global uint* indices, __global uint* indicesCount, uint n, double limit, __global double* maximalEnergy)
{

    int count = 0; //real count
    uint pos = 0; //position of maximal energy
    uint maxPos = patchesCount; //sentinel
    double max = 0.0; //maximal energy
    double lastMax = 10000000.0f; //last maximal energy
    double lastMaxOld = lastMax;

    for (int i = 0; i < n; i++)
    {
        max = 0.0;
        int j;
        for (j = 0; j < maxPos; j++)
        {
            double energy = energies[j];
            if (energy >= max && energy < lastMax)
            {
                pos = j;
                max = energy;
            }
        }

        if (i == 0)
        {
            maximalEnergy[0] = max;
        }

        if (max == 0.0 || max < limit)
        {
            if (j == maxPos)
            {
                break;
            }

            lastMax = lastMaxOld;
            maxPos = patchesCount;
            continue;
        }

        indices[i] = pos;
        count++;
        maxPos = pos;
        lastMaxOld = max;
    }

    indicesCount[0] = count;
}

/*
 * Compute radiosity step - energy distribution of N most energized patches
 */
__kernel void radiosity(__global float16* patchesGeo, __global float4* patchesInfo, uint patchesCount, __global uint* indices, __global uint* indicesCount, __global double* energies/* array of textures, uint textureSize, __local bit* visited */)
{
    int i = get_global_id(0); //position in indices array
    //int texI = i * textureSize;

    if (i >= indicesCount[0])
    {
        return;
    }

    float16 lightGeo = patchesGeo[indices[i]];
    float4 lightInfo = patchesInfo[indices[i]];
    double lightEnergy = energies[indices[i]];

    float x, y, z;

    /* Center of light patch */
    x = (lightGeo.s0 + lightGeo.s3 + lightGeo.s6 + lightGeo.s9) / 4.0;
    y = (lightGeo.s1 + lightGeo.s4 + lightGeo.s7 + lightGeo.sA) / 4.0;
    z = (lightGeo.s2 + lightGeo.s5 + lightGeo.s8 + lightGeo.sB) / 4.0;
    float4 ShootPos = {x,y,z,0};

    /* Normal of light patch */
    x = lightGeo.sC;
    y = lightGeo.sD;
    z = lightGeo.sE;
    float4 ShootNormal = {x,y,z,0};

    /* Area of light patch */
    float ShootDArea = lightGeo.sF;

    //go through all the texture
    //every point convert to index and if visited[index]==0 -> compute form factor and set to correct index
    //otherwise continue

    for(int j = 0; j < patchesCount; j++) {

        float16 patchGeo = patchesGeo[j];
        //float4 patchInfo = patchesInfo[j];

        /* Center of patch */
        x = (patchGeo.s0 + patchGeo.s3 + patchGeo.s6 + patchGeo.s9) / 4.0;
        y = (patchGeo.s1 + patchGeo.s4 + patchGeo.s7 + patchGeo.sA) / 4.0;
        z = (patchGeo.s2 + patchGeo.s5 + patchGeo.s8 + patchGeo.sB) / 4.0;
        float4 RecvPos = {x,y,z,0};

        /* Normal of patch */
        x = patchGeo.sC;
        y = patchGeo.sD;
        z = patchGeo.sE;
        float4 RecvNormal = {x,y,z,0};

        /* Compute form factor */
        double delta = formFactor(RecvPos, ShootPos, RecvNormal, ShootNormal, ShootDArea);

        /* Distribute energy */
        energies[j] += lightEnergy * 0.5 * delta;

        /* Distribute color */
        patchesInfo[j].s0 += lightInfo.s0 * 0.5 * delta;
        patchesInfo[j].s1 += lightInfo.s1 * 0.5 * delta;
        patchesInfo[j].s2 += lightInfo.s2 * 0.5 * delta;
    }

    /* Erase energy */
    energies[indices[i]] = 0;
}