Add a dot-product option for first pass sixtap filtering. Seems to work and also improve performance slightly.  If the performance improvement holds on Nvidia as well (only tested on AMD/Windows), then the sub_pel_filters array/function will be converted to return float8 to remove an unnecessary conversion.

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

#define BILINEAR_ROW_SIZE 2
constant int bilinear_filters[8*2] = {
    128, 0,
    112, 16,
    96, 32,
    80, 48,
    64, 64,
    48, 80,
    32, 96,
    16, 112
};

#define SIXTAP_ROW_SIZE 8
constant short8 sub_pel_filters[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}
};

__inline short8 sub_pel_filter_values(int offset, constant short8 *sub_pel_filters){
#if 0
    return sub_pel_filters[offset]; //doesn't work on AMD in Windows...?
#else
    short8 result = 0;
    switch (offset){
        case 0:
            result.s2 = 128;
            break;
        case 1:
            result.s1 = -6;
            result.s2 = 123;
            result.s3 = 12;
            result.s4 = -1;
            break;
        case 2:
            result.s0 = 2;
            result.s1 = -11;
            result.s2 = 108;
            result.s3 = 36;
            result.s4 = -8;
            result.s5 = 1;
            break;
        case 3:
            result.s1 = -9;
            result.s2 = 93;
            result.s3 = 50;
            result.s4 = -6;
            break;
        case 4:
             result.s0 = 3;
             result.s1 = -16;
             result.s2 = 77;
             result.s3 = 77;
             result.s4 = -16;
             result.s5 = 3;
             break;
        case 5:
            result.s1 = -6;
            result.s2 = 50;
            result.s3 = 93;
            result.s4 = -9;
            break;
        case 6:
            result.s0 = 1;
            result.s1 = -8;
            result.s2 = 36;
            result.s3 = 108;
            result.s4 = -11;
            result.s5 = 2;
            break;
        case 7:
            result.s1 = -1;
            result.s2 = 12;
            result.s3 = 123;
            result.s4 = -6;
            break;
        default:
            break;
    }
    return result;
#endif
}

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 output_height,
    unsigned int output_width,
    int filter_offset
){
    uint tid = get_global_id(0);

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

    int Temp;

    short8 vp8_filter = sub_pel_filter_values(filter_offset, sub_pel_filters);

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

        Temp = (int)(src_ptr[src_offset - 2] * vp8_filter.s0) +
           (int)(src_ptr[src_offset - 1] * vp8_filter.s1) +
           (int)(src_ptr[src_offset]     * vp8_filter.s2) +
           (int)(src_ptr[src_offset + 1] * vp8_filter.s3) +
           (int)(src_ptr[src_offset + 2] * vp8_filter.s4) +
           (int)(src_ptr[src_offset + 3] * vp8_filter.s5) +
           (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[tid] = 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
) {

    uint i = get_global_id(0);

    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;

    short8 vp8_filter = sub_pel_filter_values(filter_offset, sub_pel_filters);

    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.s0 +
           ((int)src_ptr[src_offset -(int)pixel_step] * vp8_filter.s1) +
           ((int)src_ptr[src_offset]                  * vp8_filter.s2) +
           ((int)src_ptr[src_offset + pixel_step]     * vp8_filter.s3) +
           ((int)src_ptr[src_offset + PS2]       * vp8_filter.s4) +
           ((int)src_ptr[src_offset + PS3]       * vp8_filter.s5) +
           (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;
    }
}

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

    if (tid < output_width * output_height){
        global unsigned char *src_ptr = &src_base[src_offset];

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

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

        i = tid / output_width;
        j = tid % output_width;

        src_offset = i*(output_width+src_increment) + j;
        out_row = output_width * i;

        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+1] * vp8_filter[1]) +
                 (VP8_FILTER_WEIGHT / 2)) >> VP8_FILTER_SHIFT;
    }
}

kernel void vp8_filter_block2d_bil_second_pass_kernel
(
    __global int *src_ptr,
    __global unsigned char *output_base,
    int output_offset,
    int output_pitch,
    unsigned int output_height,
    unsigned int output_width,
    int filter_offset
)
{

    uint tid = get_global_id(0);

    if (tid < output_width * output_height){
        global unsigned char *output_ptr = &output_base[output_offset];

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

        int out_offset;
        int src_offset;

        i = tid / output_width;
        j = tid % output_width;

        src_offset = i*(output_width) + j;
        out_offset = i*output_pitch + j;

        /* Apply filter */
        Temp = ((int)src_ptr[src_offset]         * vp8_filter[0]) +
               ((int)src_ptr[src_offset+output_width] * vp8_filter[1]) +
               (VP8_FILTER_WEIGHT / 2);

        output_ptr[out_offset++] = (unsigned int)(Temp >> VP8_FILTER_SHIFT);
    }
}

//Called from reconinter_cl.c
kernel void vp8_memcpy_kernel(
    global unsigned char *src_base,
    int src_offset,
    int src_stride,
    global unsigned char *dst_base,
    int dst_offset,
    int dst_stride,
    int num_bytes,
    int num_iter
){

    int i,r;
    global unsigned char *src = &src_base[src_offset];
    global unsigned char *dst = &dst_base[dst_offset];
    src_offset = dst_offset = 0;

    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,
    unsigned int size
)
{
    int tid = get_global_id(0);

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

__kernel void vp8_bilinear_predict4x4_kernel
(
        __global unsigned char *src_base,
        int src_offset,
        int src_pixels_per_line,
        int xoffset,
        int yoffset,
        __global unsigned char *dst_base,
        int dst_offset,
        int dst_pitch,
        __global int *int_mem
)
{
    int Height = 4, Width = 4;

    /* First filter 1-D horizontally... */
    vp8_filter_block2d_bil_first_pass_kernel(src_base, src_offset, int_mem, src_pixels_per_line, Height + 1, Width, xoffset);

    /* then 1-D vertically... */
    vp8_filter_block2d_bil_second_pass_kernel(int_mem, dst_base, dst_offset, dst_pitch, Height, Width, yoffset);
}

__kernel void vp8_bilinear_predict8x8_kernel
(
    __global unsigned char *src_base,
    int src_offset,
    int src_pixels_per_line,
    int xoffset,
    int yoffset,
    __global unsigned char *dst_base,
    int dst_offset,
    int dst_pitch,
    __global int *int_mem
)
{
    int Height = 8, Width = 8;

    /* First filter 1-D horizontally... */
    vp8_filter_block2d_bil_first_pass_kernel(src_base, src_offset, int_mem, src_pixels_per_line, Height + 1, Width, xoffset);

    /* then 1-D vertically... */
    vp8_filter_block2d_bil_second_pass_kernel(int_mem, dst_base, dst_offset, dst_pitch, Height, Width, yoffset);

}

__kernel void vp8_bilinear_predict8x4_kernel
(
    __global unsigned char *src_base,
    int src_offset,
    int src_pixels_per_line,
    int xoffset,
    int yoffset,
    __global unsigned char *dst_base,
    int dst_offset,
    int dst_pitch,
    __global int *int_mem
)
{
    int Height = 4, Width = 8;

    /* First filter 1-D horizontally... */
    vp8_filter_block2d_bil_first_pass_kernel(src_base, src_offset, int_mem, src_pixels_per_line, Height + 1, Width, xoffset);

    /* then 1-D vertically... */
    vp8_filter_block2d_bil_second_pass_kernel(int_mem, dst_base, dst_offset, dst_pitch, Height, Width, yoffset);
}

__kernel void vp8_bilinear_predict16x16_kernel
(
    __global unsigned char *src_base,
    int src_offset,
    int src_pixels_per_line,
    int xoffset,
    int yoffset,
    __global unsigned char *dst_base,
    int dst_offset,
    int dst_pitch,
    __global int *int_mem
)
{

    int Height = 16, Width = 16;

    /* First filter 1-D horizontally... */
    vp8_filter_block2d_bil_first_pass_kernel(src_base, src_offset, int_mem, src_pixels_per_line, Height + 1, Width, xoffset);

    /* then 1-D vertically... */
    vp8_filter_block2d_bil_second_pass_kernel(int_mem, dst_base, dst_offset, dst_pitch, Height, Width, yoffset);

}

void vp8_filter_block2d_first_pass(
    global unsigned char *src_base,
    int src_offset,
    local 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;

    int nthreads = get_global_size(0);
    int ngroups = get_num_groups(0);
    int lsize = get_local_size(0);

    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;

    if (tid < (output_width*output_height)){
        short8 filter = sub_pel_filter_values(filter_offset, sub_pel_filters);

        if (ngroups > 1){
            //This is generally only true on Apple CPU-CL, which gives a group
            //size of 1, regardless of the CPU core count.
            for (int iter=0; iter < ngroups; iter++){
                i = iter * lsize + get_local_id(0);
                src_offset = i + (i/output_width * (src_pixels_per_line - output_width));

#define USE_DOT_FILTERING 0
#if USE_DOT_FILTERING
            float8 src_data;
            float8 tmpfilter = convert_float8(filter);
            src_data.s0 = src_ptr[src_offset-2];
            src_data.s1 = src_ptr[src_offset-1];
            src_data.s2 = src_ptr[src_offset];
            src_data.s3 = src_ptr[src_offset+1];
            src_data.s4 = src_ptr[src_offset+2];
            src_data.s5 = src_ptr[src_offset+3];
            Temp = dot(src_data.s0123, tmpfilter.s0123) + dot(src_data.s01, tmpfilter.s45);
            Temp += (VP8_FILTER_WEIGHT >> 1);
#else
                Temp = (int)(src_ptr[src_offset - 2] * filter.s0) +
                       (int)(src_ptr[src_offset - 1] * filter.s1) +
                       (int)(src_ptr[src_offset]     * filter.s2) +
                       (int)(src_ptr[src_offset + 1] * filter.s3) +
                       (int)(src_ptr[src_offset + 2] * filter.s4) +
                       (int)(src_ptr[src_offset + 3] * filter.s5) +
                       (VP8_FILTER_WEIGHT >> 1);      /* Rounding */
#endif

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

                Temp = clamp(Temp, 0, 255);

                output_ptr[i] = Temp;
            }
        } else {
            src_offset = i + (i/output_width * (src_pixels_per_line - output_width));

#if USE_DOT_FILTERING
            float8 src_data;
            float8 tmpfilter = convert_float8(filter);
            src_data.s0 = src_ptr[src_offset-2];
            src_data.s1 = src_ptr[src_offset-1];
            src_data.s2 = src_ptr[src_offset];
            src_data.s3 = src_ptr[src_offset+1];
            src_data.s4 = src_ptr[src_offset+2];
            src_data.s5 = src_ptr[src_offset+3];
            Temp = dot(src_data.s0123, tmpfilter.s0123) + dot(src_data.s01, tmpfilter.s45);
            Temp += (VP8_FILTER_WEIGHT >> 1);
#else
            Temp = (int)(src_ptr[src_offset - 2] * filter.s0) +
                   (int)(src_ptr[src_offset - 1] * filter.s1) +
                   (int)(src_ptr[src_offset]     * filter.s2) +
                   (int)(src_ptr[src_offset + 1] * filter.s3) +
                   (int)(src_ptr[src_offset + 2] * filter.s4) +
                   (int)(src_ptr[src_offset + 3] * filter.s5) +
                   (VP8_FILTER_WEIGHT >> 1);      /* Rounding */
#endif
            /* Normalize back to 0-255 */
            Temp >>= VP8_FILTER_SHIFT;

            Temp = clamp(Temp, 0, 255);

            output_ptr[i] = Temp;
        }
    }

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

void vp8_filter_block2d_second_pass
(
    local 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);

    short8 vp8_filter = sub_pel_filter_values(filter_offset, sub_pel_filters);

    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.s0) +
           ((int)src_ptr[src_offset -(int)pixel_step] * vp8_filter.s1) +
           ((int)src_ptr[src_offset]                  * vp8_filter.s2) +
           ((int)src_ptr[src_offset + pixel_step]     * vp8_filter.s3) +
           ((int)src_ptr[src_offset + PS2]            * vp8_filter.s4) +
           ((int)src_ptr[src_offset + PS3]       * vp8_filter.s5) +
           (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;
    }
}

__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
)
{

    local int FData[9*4];

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

    /* then filter vertically... */
    vp8_filter_block2d_second_pass(&FData[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
)
{
    local 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 vertically... */
    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
)
{
    local 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
)
{
    local 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;
}

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

#define BILINEAR_ROW_SIZE 2
constant int bilinear_filters[8*2] = {
    128, 0,
    112, 16,
    96, 32,
    80, 48,
    64, 64,
    48, 80,
    32, 96,
    16, 112
};

#define SIXTAP_ROW_SIZE 8
constant short8 sub_pel_filters[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}
};

__inline short8 sub_pel_filter_values(int offset, constant short8 *sub_pel_filters){
#if 0
    return sub_pel_filters[offset]; //doesn't work on AMD in Windows...?
#else
    short8 result = 0;
    switch (offset){
        case 0:
            result.s2 = 128;
            break;
        case 1:
            result.s1 = -6;
            result.s2 = 123;
            result.s3 = 12;
            result.s4 = -1;
            break;
        case 2:
            result.s0 = 2;
            result.s1 = -11;
            result.s2 = 108;
            result.s3 = 36;
            result.s4 = -8;
            result.s5 = 1;
            break;
        case 3:
            result.s1 = -9;
            result.s2 = 93;
            result.s3 = 50;
            result.s4 = -6;
            break;
        case 4:
             result.s0 = 3;
             result.s1 = -16;
             result.s2 = 77;
             result.s3 = 77;
             result.s4 = -16;
             result.s5 = 3;
             break;
        case 5:
            result.s1 = -6;
            result.s2 = 50;
            result.s3 = 93;
            result.s4 = -9;
            break;
        case 6:
            result.s0 = 1;
            result.s1 = -8;
            result.s2 = 36;
            result.s3 = 108;
            result.s4 = -11;
            result.s5 = 2;
            break;
        case 7:
            result.s1 = -1;
            result.s2 = 12;
            result.s3 = 123;
            result.s4 = -6;
            break;
        default:
            break;
    }
    return result;
#endif
}

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 output_height,
    unsigned int output_width,
    int filter_offset
){
    uint tid = get_global_id(0);

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

    int Temp;

    short8 vp8_filter = sub_pel_filter_values(filter_offset, sub_pel_filters);

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

        Temp = (int)(src_ptr[src_offset - 2] * vp8_filter.s0) +
           (int)(src_ptr[src_offset - 1] * vp8_filter.s1) +
           (int)(src_ptr[src_offset]     * vp8_filter.s2) +
           (int)(src_ptr[src_offset + 1] * vp8_filter.s3) +
           (int)(src_ptr[src_offset + 2] * vp8_filter.s4) +
           (int)(src_ptr[src_offset + 3] * vp8_filter.s5) +
           (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[tid] = 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
) {

    uint i = get_global_id(0);

    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;

    short8 vp8_filter = sub_pel_filter_values(filter_offset, sub_pel_filters);

    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.s0 +
           ((int)src_ptr[src_offset -(int)pixel_step] * vp8_filter.s1) +
           ((int)src_ptr[src_offset]                  * vp8_filter.s2) +
           ((int)src_ptr[src_offset + pixel_step]     * vp8_filter.s3) +
           ((int)src_ptr[src_offset + PS2]       * vp8_filter.s4) +
           ((int)src_ptr[src_offset + PS3]       * vp8_filter.s5) +
           (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;
    }
}

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

    if (tid < output_width * output_height){
        global unsigned char *src_ptr = &src_base[src_offset];

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

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

        i = tid / output_width;
        j = tid % output_width;

        src_offset = i*(output_width+src_increment) + j;
        out_row = output_width * i;

        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+1] * vp8_filter[1]) +
                 (VP8_FILTER_WEIGHT / 2)) >> VP8_FILTER_SHIFT;
    }
}

kernel void vp8_filter_block2d_bil_second_pass_kernel
(
    __global int *src_ptr,
    __global unsigned char *output_base,
    int output_offset,
    int output_pitch,
    unsigned int output_height,
    unsigned int output_width,
    int filter_offset
)
{

    uint tid = get_global_id(0);

    if (tid < output_width * output_height){
        global unsigned char *output_ptr = &output_base[output_offset];

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

        int out_offset;
        int src_offset;

        i = tid / output_width;
        j = tid % output_width;

        src_offset = i*(output_width) + j;
        out_offset = i*output_pitch + j;

        /* Apply filter */
        Temp = ((int)src_ptr[src_offset]         * vp8_filter[0]) +
               ((int)src_ptr[src_offset+output_width] * vp8_filter[1]) +
               (VP8_FILTER_WEIGHT / 2);

        output_ptr[out_offset++] = (unsigned int)(Temp >> VP8_FILTER_SHIFT);
    }
}

//Called from reconinter_cl.c
kernel void vp8_memcpy_kernel(
    global unsigned char *src_base,
    int src_offset,
    int src_stride,
    global unsigned char *dst_base,
    int dst_offset,
    int dst_stride,
    int num_bytes,
    int num_iter
){

    int i,r;
    global unsigned char *src = &src_base[src_offset];
    global unsigned char *dst = &dst_base[dst_offset];
    src_offset = dst_offset = 0;

    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,
    unsigned int size
)
{
    int tid = get_global_id(0);

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

__kernel void vp8_bilinear_predict4x4_kernel
(
        __global unsigned char *src_base,
        int src_offset,
        int src_pixels_per_line,
        int xoffset,
        int yoffset,
        __global unsigned char *dst_base,
        int dst_offset,
        int dst_pitch,
        __global int *int_mem
)
{
    int Height = 4, Width = 4;

    /* First filter 1-D horizontally... */
    vp8_filter_block2d_bil_first_pass_kernel(src_base, src_offset, int_mem, src_pixels_per_line, Height + 1, Width, xoffset);

    /* then 1-D vertically... */
    vp8_filter_block2d_bil_second_pass_kernel(int_mem, dst_base, dst_offset, dst_pitch, Height, Width, yoffset);
}

__kernel void vp8_bilinear_predict8x8_kernel
(
    __global unsigned char *src_base,
    int src_offset,
    int src_pixels_per_line,
    int xoffset,
    int yoffset,
    __global unsigned char *dst_base,
    int dst_offset,
    int dst_pitch,
    __global int *int_mem
)
{
    int Height = 8, Width = 8;

    /* First filter 1-D horizontally... */
    vp8_filter_block2d_bil_first_pass_kernel(src_base, src_offset, int_mem, src_pixels_per_line, Height + 1, Width, xoffset);

    /* then 1-D vertically... */
    vp8_filter_block2d_bil_second_pass_kernel(int_mem, dst_base, dst_offset, dst_pitch, Height, Width, yoffset);

}

__kernel void vp8_bilinear_predict8x4_kernel
(
    __global unsigned char *src_base,
    int src_offset,
    int src_pixels_per_line,
    int xoffset,
    int yoffset,
    __global unsigned char *dst_base,
    int dst_offset,
    int dst_pitch,
    __global int *int_mem
)
{
    int Height = 4, Width = 8;

    /* First filter 1-D horizontally... */
    vp8_filter_block2d_bil_first_pass_kernel(src_base, src_offset, int_mem, src_pixels_per_line, Height + 1, Width, xoffset);

    /* then 1-D vertically... */
    vp8_filter_block2d_bil_second_pass_kernel(int_mem, dst_base, dst_offset, dst_pitch, Height, Width, yoffset);
}

__kernel void vp8_bilinear_predict16x16_kernel
(
    __global unsigned char *src_base,
    int src_offset,
    int src_pixels_per_line,
    int xoffset,
    int yoffset,
    __global unsigned char *dst_base,
    int dst_offset,
    int dst_pitch,
    __global int *int_mem
)
{

    int Height = 16, Width = 16;

    /* First filter 1-D horizontally... */
    vp8_filter_block2d_bil_first_pass_kernel(src_base, src_offset, int_mem, src_pixels_per_line, Height + 1, Width, xoffset);

    /* then 1-D vertically... */
    vp8_filter_block2d_bil_second_pass_kernel(int_mem, dst_base, dst_offset, dst_pitch, Height, Width, yoffset);

}

void vp8_filter_block2d_first_pass(
    global unsigned char *src_base,
    int src_offset,
    local 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;

    int nthreads = get_global_size(0);
    int ngroups = get_num_groups(0);
    int lsize = get_local_size(0);

    //printf("global_size = %d, ngroups = %d, lsize = %d\n", nthreads, ngroups, lsize);

    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;

    //__constant short *vp8_filter = &sub_pel_filters[filter_offset*SIXTAP_ROW_SIZE];
    //printf("offset = %d\n", filter_offset*SIXTAP_ROW_SIZE);
    if (tid < (output_width*output_height)){
        short8 filter = sub_pel_filter_values(filter_offset, sub_pel_filters);

        //printf("filter_offset = %d, filters = {%d, %d, %d, %d, %d, %d}\n", filter_offset, filter0, filter1, filter2, filter3, filter4, filter5);
        //printf("sub_pel_filters[0][2] = %d\n", sub_pel_filters[2]);

        if (ngroups > 1){
            //This is generally only true on Apple CPU-CL, which gives a group
            //size of 1, regardless of the CPU core count.
            for (int iter=0; iter < ngroups; iter++){
                i = iter * lsize + get_local_id(0);
                src_offset = i + (i/output_width * (src_pixels_per_line - output_width));

                //printf("src_offset = %d\n", src_offset);

                Temp = (int)(src_ptr[src_offset - 2] * filter.s0) +
                       (int)(src_ptr[src_offset - 1] * filter.s1) +
                       (int)(src_ptr[src_offset]     * filter.s2) +
                       (int)(src_ptr[src_offset + 1] * filter.s3) +
                       (int)(src_ptr[src_offset + 2] * filter.s4) +
                       (int)(src_ptr[src_offset + 3] * filter.s5) +
                       (VP8_FILTER_WEIGHT >> 1);      /* Rounding */

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

                if (Temp < 0)
                    Temp = 0;
                else if ( Temp > 255 )
                    Temp = 255;

                output_ptr[i] = Temp;
                //if (get_group_id(0) == 0 && iter ==1 && get_local_id(0)==1){
                    //printf("short size = %d, filter_offset = %d, sub_pel_filters - vp8_filter = %d\n", sizeof(short), filter_offset, sub_pel_filters[0] - vp8_filter);
                //    printf("Input values = {%d, %d, %d, %d, %d, %d}, filters = {%d, %d, %d, %d, %d, %d}\n",
                //            src_ptr[src_offset-2], src_ptr[src_offset-1], src_ptr[src_offset],
                //            src_ptr[src_offset+1], src_ptr[src_offset+2], src_ptr[src_offset+3],
                //            filter.s0, filter.s1, filter.s2, filter.s3, filter.s4, filter.s5);
                    //printf("Wrote %d to index %d\n", Temp, i);
                //}
            }
        } else {
            src_offset = i + (i/output_width * (src_pixels_per_line - output_width));

            Temp = (int)(src_ptr[src_offset - 2] * filter.s0) +
                   (int)(src_ptr[src_offset - 1] * filter.s1) +
                   (int)(src_ptr[src_offset]     * filter.s2) +
                   (int)(src_ptr[src_offset + 1] * filter.s3) +
                   (int)(src_ptr[src_offset + 2] * filter.s4) +
                   (int)(src_ptr[src_offset + 3] * filter.s5) +
                   (VP8_FILTER_WEIGHT >> 1);      /* Rounding */

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

            if (Temp < 0)
                Temp = 0;
            else if ( Temp > 255 )
                Temp = 255;

            output_ptr[i] = Temp;
            //if (i == 5 && )
        }
    }

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

void vp8_filter_block2d_second_pass
(
    local 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);

    short8 vp8_filter = sub_pel_filter_values(filter_offset, sub_pel_filters);

    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.s0) +
           ((int)src_ptr[src_offset -(int)pixel_step] * vp8_filter.s1) +
           ((int)src_ptr[src_offset]                  * vp8_filter.s2) +
           ((int)src_ptr[src_offset + pixel_step]     * vp8_filter.s3) +
           ((int)src_ptr[src_offset + PS2]            * vp8_filter.s4) +
           ((int)src_ptr[src_offset + PS3]       * vp8_filter.s5) +
           (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;
    }
}

__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
)
{

    local int FData[9*4];

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

    /* then filter vertically... */
    vp8_filter_block2d_second_pass(&FData[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
)
{
    local 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 vertically... */
    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
)
{
    local 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
)
{
    local 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;
}


Update q_iraf_all.cl

Update q_iraf_all.cl

Cleaned up the input and output file names - the output TRANSPAR files now reflect whether the input spectral data were from Target A or B

####FIRST: Please check the contents and comments of GEOMAP.PARAM!!!###
####You'll need to make sure IRAF and the GEOMAP parameters are setup nicely
#################################PART 1: Run GEOMAP##########################

##### Run these commands inside of IRAF after adjusting parameters of geomap :)
#First command - for the standard star (1):

geomap GEOTRAN_STD01.DAT TRANSPARA01 1 320 1 240

#Explanation:
## The GEOTRAN...DAT files were generated by q_transtable2 commands, which themselve were generated by WL_CAL_A_B.f
## TRANSPARA is the output file
## The last four parameters give the (X,Y) pixel range of the image - in this case, NL Low Res spectroscopic data
#Run the object commands (32):
geomap GEOTRAN_OBJ01.DAT TRANSPARA01 1 320 1 240
geomap GEOTRAN_OBJ02.DAT TRANSPARA02 1 320 1 240
geomap GEOTRAN_OBJ03.DAT TRANSPARA03 1 320 1 240
geomap GEOTRAN_OBJ04.DAT TRANSPARA04 1 320 1 240
geomap GEOTRAN_OBJ05.DAT TRANSPARA05 1 320 1 240
geomap GEOTRAN_OBJ06.DAT TRANSPARA06 1 320 1 240
geomap GEOTRAN_OBJ07.DAT TRANSPARA07 1 320 1 240
geomap GEOTRAN_OBJ08.DAT TRANSPARA08 1 320 1 240
geomap GEOTRAN_OBJ09.DAT TRANSPARA09 1 320 1 240
geomap GEOTRAN_OBJ010.DAT TRANSPARA10 1 320 1 240
geomap GEOTRAN_OBJ011.DAT TRANSPARA11 1 320 1 240
geomap GEOTRAN_OBJ012.DAT TRANSPARA12 1 320 1 240
geomap GEOTRAN_OBJ013.DAT TRANSPARA13 1 320 1 240
geomap GEOTRAN_OBJ014.DAT TRANSPARA14 1 320 1 240
geomap GEOTRAN_OBJ015.DAT TRANSPARA15 1 320 1 240
geomap GEOTRAN_OBJ016.DAT TRANSPARA16 1 320 1 240
geomap GEOTRAN_OBJ017.DAT TRANSPARB01 1 320 1 240
geomap GEOTRAN_OBJ018.DAT TRANSPARB02 1 320 1 240
geomap GEOTRAN_OBJ019.DAT TRANSPARB03 1 320 1 240
geomap GEOTRAN_OBJ020.DAT TRANSPARB04 1 320 1 240
geomap GEOTRAN_OBJ021.DAT TRANSPARB05 1 320 1 240
geomap GEOTRAN_OBJ022.DAT TRANSPARB06 1 320 1 240
geomap GEOTRAN_OBJ023.DAT TRANSPARB07 1 320 1 240
geomap GEOTRAN_OBJ024.DAT TRANSPARB08 1 320 1 240
geomap GEOTRAN_OBJ025.DAT TRANSPARB09 1 320 1 240
geomap GEOTRAN_OBJ026.DAT TRANSPARB10 1 320 1 240
geomap GEOTRAN_OBJ027.DAT TRANSPARB11 1 320 1 240
geomap GEOTRAN_OBJ028.DAT TRANSPARB12 1 320 1 240
geomap GEOTRAN_OBJ029.DAT TRANSPARB13 1 320 1 240
geomap GEOTRAN_OBJ030.DAT TRANSPARB14 1 320 1 240
geomap GEOTRAN_OBJ031.DAT TRANSPARB15 1 320 1 240
geomap GEOTRAN_OBJ032.DAT TRANSPARB16 1 320 1 240

####FIRST: Please check the contents and comments of GEOMAP.PARAM!!!###
####You'll need to make sure IRAF and the GEOMAP parameters are setup nicely
#################################PART 1: Run GEOMAP##########################

##### Run these commands inside of IRAF after adjusting parameters of geomap :)
#First command - for the standard star (1):

geomap GEOTRAN_STD01.DAT TRANSPARA01 1 320 1 240

#Explanation:
## The GEOTRAN...DAT files were generated by q_transtable2 commands, which themselve were generated by WL_CAL_A_B.f
## TRANSPARA is the output file
## The last four parameters give the (X,Y) pixel range of the image - in this case, NL Low Res spectroscopic data
#Run the object commands (32):
geomap GEOTRAN_OBJ01.DAT TRANSPARA01 1 320 1 240
geomap GEOTRAN_OBJ02.DAT TRANSPARA02 1 320 1 240
geomap GEOTRAN_OBJ03.DAT TRANSPARA03 1 320 1 240
geomap GEOTRAN_OBJ04.DAT TRANSPARA04 1 320 1 240
geomap GEOTRAN_OBJ05.DAT TRANSPARA05 1 320 1 240
geomap GEOTRAN_OBJ06.DAT TRANSPARA06 1 320 1 240
geomap GEOTRAN_OBJ07.DAT TRANSPARA07 1 320 1 240
geomap GEOTRAN_OBJ08.DAT TRANSPARA08 1 320 1 240
geomap GEOTRAN_OBJ09.DAT TRANSPARA09 1 320 1 240
geomap GEOTRAN_OBJ10.DAT TRANSPARA10 1 320 1 240
geomap GEOTRAN_OBJ11.DAT TRANSPARA11 1 320 1 240
geomap GEOTRAN_OBJ12.DAT TRANSPARA12 1 320 1 240
geomap GEOTRAN_OBJ13.DAT TRANSPARA13 1 320 1 240
geomap GEOTRAN_OBJ14.DAT TRANSPARA14 1 320 1 240
geomap GEOTRAN_OBJ15.DAT TRANSPARA15 1 320 1 240
geomap GEOTRAN_OBJ16.DAT TRANSPARA16 1 320 1 240
geomap GEOTRAN_OBJ17.DAT TRANSPARA17 1 320 1 240
geomap GEOTRAN_OBJ18.DAT TRANSPARA18 1 320 1 240
geomap GEOTRAN_OBJ19.DAT TRANSPARA19 1 320 1 240
geomap GEOTRAN_OBJ20.DAT TRANSPARA20 1 320 1 240
geomap GEOTRAN_OBJ21.DAT TRANSPARA21 1 320 1 240
geomap GEOTRAN_OBJ22.DAT TRANSPARA22 1 320 1 240
geomap GEOTRAN_OBJ23.DAT TRANSPARA23 1 320 1 240
geomap GEOTRAN_OBJ24.DAT TRANSPARA24 1 320 1 240
geomap GEOTRAN_OBJ25.DAT TRANSPARA25 1 320 1 240
geomap GEOTRAN_OBJ26.DAT TRANSPARA26 1 320 1 240
geomap GEOTRAN_OBJ27.DAT TRANSPARA27 1 320 1 240
geomap GEOTRAN_OBJ28.DAT TRANSPARA28 1 320 1 240
geomap GEOTRAN_OBJ29.DAT TRANSPARA29 1 320 1 240
geomap GEOTRAN_OBJ30.DAT TRANSPARA30 1 320 1 240
geomap GEOTRAN_OBJ31.DAT TRANSPARA31 1 320 1 240
geomap GEOTRAN_OBJ32.DAT TRANSPARA32 1 320 1 240


Fixed color distribution in kernel

Fixed color distribution in kernel

/*
 * 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_global_int32_extended_atomics: enable
//#pragma OPENCL EXTENSION cl_khr_global_int32_base_atomics: enable

float formFactor(float4 RecvPos, float4 ShootPos, float4 RecvNormal, float4 ShootNormal, float ShootDArea)
{
    float pi = (float)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]];
    energies[indices[i]] = 0;

    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
 */
//#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;
}


remove vars from thclapply.cl

remove vars from thclapply.cl

// OpenCL kernels....

// expected templated values:
// dims (vector of unique dimension values)
// operation
// dim1
// dim2
// dim3
// ... dimD
// num_input_tensors
// include_scalar_input
//
// maybe should add:
// IndexType (hardcoded to int for now)
// MAX_CUTORCH_DIMS (hardcoded to 25 for now)

// (Ported from cutorch's THCApply.cuh)

// Maximum number of dimensions allowed for cutorch
// #define MAX_CUTORCH_DIMS 25

// Enum that indicates whether tensor arguments are read/write or
// read-only
//enum TensorArgType { ReadWrite, ReadOnly };

{%
 local total_opsize = num_tensors
 if include_scalar_input then
      total_opsize = total_opsize + 1
   end
 %}

inline void op( global float *out
  {% for t=1,(num_tensors-1) do %}
  , global float *in{{t}}
  {% end %}
  {% for s=1,(num_scalars) do %}
  , float val{{s}}
  {% end %}
   {% for pt=1,num_point_tensors do %}
   , global float *pointTensor{{pt}}
   {% end %}
) {
    {{operation}};
}

kernel void
THClTensor_pointwiseApplyD(
   {% for t=1,num_tensors do %}
    int offset_{{t}},
    {% local thisdims = loadstring('return dims' .. t)() %}
    {% for d=1,thisdims do %}
      int size_{{t}}_{{d}},
      int stride_{{t}}_{{d}},
    {% end %}
    global float*data_{{t}},
   {% end %}
   {% for i=1,num_scalars do %}
   float val{{i}},
   {% end %}
   {% for i=1,num_point_tensors do %}
   global float *pointTensor{{i}},
   {% end %}
   int totalElements) {
   int linearIndex = get_global_id(0);
   if(linearIndex < totalElements ) {
      int thisLinearId;
    {% for t=1,num_tensors do %}
      {% local thisdims = loadstring('return dims' .. t)() %}
      {% if thisdims == -2 then %}
         int derived_offset_{{t}} = linearIndex + offset_{{t}};
      {% else %}
         {{IndexType}} derived_offset_{{t}} = offset_{{t}};
         thisLinearId = linearIndex;
        {% for d=thisdims,1,-1 do %}  // bake this in....
          derived_offset_{{t}} += (thisLinearId % size_{{t}}_{{d}}) * stride_{{t}}_{{d}};
          {% if d > 0 then %}
            thisLinearId /= size_{{t}}_{{d}};
          {% end %}
        {% end %}

      {% end %}
    {% end %}

    op(
      {% for t=1,num_tensors do %}
         {% if t > 1 then %} , {% end %}
         &(data_{{t}}[derived_offset_{{t}}])
      {% end %}

      {% for s=1,num_scalars do %}
      , val{{s}}
      {% end %}

       {% for pt=1,num_point_tensors do %}
       , pointTensor{{pt}}
       {% end %}
    );
  }
}

// OpenCL kernels....

// expected templated values:
// dims (vector of unique dimension values)
// operation
// dim1
// dim2
// dim3
// ... dimD
// num_input_tensors
// include_scalar_input
//
// maybe should add:
// IndexType (hardcoded to int for now)
// MAX_CUTORCH_DIMS (hardcoded to 25 for now)

// (Ported from cutorch's THCApply.cuh)

// Maximum number of dimensions allowed for cutorch
// #define MAX_CUTORCH_DIMS 25

// Enum that indicates whether tensor arguments are read/write or
// read-only
//enum TensorArgType { ReadWrite, ReadOnly };

{%
 local total_opsize = num_tensors
 if include_scalar_input then
      total_opsize = total_opsize + 1
   end
 %}

inline void op( global float *out
  {% for t=1,(num_tensors-1) do %}
  , global float *in{{t}}
  {% end %}
  {% for s=1,(num_scalars) do %}
  , float val{{s}}
  {% end %}
   {% for pt=1,num_point_tensors do %}
   , global float *pointTensor{{pt}}
   {% end %}
) {
    {{operation}};
}

kernel void
THClTensor_pointwiseApplyD(
   {% for t=1,num_tensors do %}
    int offset_{{t}},
    {% local thisdims = loadstring('return dims' .. t)() %}
    {% for d=1,thisdims do %}
      int size_{{t}}_{{d}},
      int stride_{{t}}_{{d}},
    {% end %}
    global float*data_{{t}},
   {% end %}
   {% for i=1,num_scalars do %}
   float val{{i}},
   {% end %}
   {% for i=1,num_point_tensors do %}
   global float *pointTensor{{i}},
   {% end %}
   int totalElements) {
   int linearIndex = get_global_id(0);
   if(linearIndex < totalElements ) {
      {{IndexType}} curDimIndex;
      {{IndexType}} curDimOffset;
      int thisLinearId;
    {% for t=1,num_tensors do %}
      {% local thisdims = loadstring('return dims' .. t)() %}
      {% if thisdims == -2 then %}
         int derived_offset_{{t}} = linearIndex + offset_{{t}};
      {% else %}
         {{IndexType}} derived_offset_{{t}} = offset_{{t}};
         thisLinearId = linearIndex;
        {% for d=thisdims,1,-1 do %}  // bake this in....
          curDimIndex = thisLinearId % size_{{t}}_{{d}};
          curDimOffset = curDimIndex * stride_{{t}}_{{d}};
          derived_offset_{{t}} += curDimOffset;
          {% if d > 0 then %}
            thisLinearId /= size_{{t}}_{{d}};
          {% end %}
        {% end %}

      {% end %}
    {% end %}

    op(
      {% for t=1,num_tensors do %}
         {% if t > 1 then %} , {% end %}
         &(data_{{t}}[derived_offset_{{t}}])
      {% end %}

      {% for s=1,num_scalars do %}
      , val{{s}}
      {% end %}

       {% for pt=1,num_point_tensors do %}
       , pointTensor{{pt}}
       {% end %}
    );
  }
}


fixed bug in init kernel

fixed bug in init kernel

__constant sampler_t sampler = CLK_NORMALIZED_COORDS_FALSE | CLK_ADDRESS_CLAMP | CLK_FILTER_NEAREST;

__kernel void GVF2DInit(__read_only image2d_t volume, __write_only image2d_t vector_field ) {
    // Calculate gradient using a 1D central difference for each dimension, with spacing 1
    int2 writePos = {get_global_id(0), get_global_id(1)};

    int2 size = {get_global_size(0), get_global_size(1)};
    int2 pos = writePos;
    pos = select(pos, (int2)(2,2), pos == (int2)(0,0));
    pos = select(pos, size-3, pos >= size-1);

    float f10 = read_imagef(volume, sampler, pos + (int2)(1,0)).x;
    float f_10 = read_imagef(volume, sampler, pos - (int2)(1,0)).x;
    float f01 = read_imagef(volume, sampler, pos + (int2)(0,1)).x;
    float f0_1 = read_imagef(volume, sampler, pos - (int2)(0,1)).x;

    float4 gradient = {
        0.5f*(f10-f_10),
        0.5f*(f01-f0_1),
        0,
        0
    };

    write_imagef(vector_field, writePos, gradient);
}

__kernel __attribute__((reqd_work_group_size(16,16,1))) void GVF2DIteration(__read_only image2d_t init_vector_field, __read_only image2d_t read_vector_field, __write_only image2d_t write_vector_field, __private float mu) {

    int2 writePos = {
        get_global_id(0),
        get_global_id(1)
    };
    // Enforce mirror boundary conditions
    int2 size = {get_image_width(init_vector_field), get_image_height(init_vector_field)};
    int2 pos = writePos;
    pos = select(pos, (int2)(2,2), pos == (int2)(0,0));
    pos = select(pos, size-3, pos >= size-1);

    float2 v = read_imagef(read_vector_field, sampler, pos).xy;

        // Load data from shared memory and do calculations
        float2 init_vector = read_imagef(init_vector_field, sampler, pos).xy;

        float2 fx1, fx_1, fy1, fy_1;
        fx1 = read_imagef(read_vector_field, sampler, pos + (int2)(1,0)).xy;
        fy1 = read_imagef(read_vector_field, sampler, pos + (int2)(0,1)).xy;
        fx_1 = read_imagef(read_vector_field, sampler, pos - (int2)(1,0)).xy;
        fy_1 = read_imagef(read_vector_field, sampler, pos - (int2)(0,1)).xy;

        // Update the vector field: Calculate Laplacian using a 3D central difference scheme
        float2 laplacian = -4*v + fx1 + fx_1 + fy1 + fy_1;

        v += mu * laplacian - (v - init_vector)*(init_vector.x*init_vector.x+init_vector.y*init_vector.y);

        write_imagef(write_vector_field, writePos, (float4)(v.x,v.y,0,0));
}

__kernel void GVF2DResult(__write_only image2d_t result, __read_only image2d_t vectorField, __write_only image2d_t vectorFieldFinal) {
    int2 pos = {get_global_id(0), get_global_id(1)};
    float4 vector = read_imagef(vectorField, sampler, pos);
    vector.z = 0;
    vector.w = 0;
    write_imagef(vectorFieldFinal, pos, vector);
    write_imagef(result, pos, length(vector));
}

__constant sampler_t sampler = CLK_NORMALIZED_COORDS_FALSE | CLK_ADDRESS_CLAMP | CLK_FILTER_NEAREST;

__kernel void GVF2DInit(__read_only image2d_t volume, __write_only image2d_t vector_field ) {
    // Calculate gradient using a 1D central difference for each dimension, with spacing 1
    int2 pos = {get_global_id(0), get_global_id(1)};

    float f10 = read_imagef(volume, sampler, pos + (int2)(1,0)).x;
    float f_10 = read_imagef(volume, sampler, pos - (int2)(1,0)).x;
    float f01 = read_imagef(volume, sampler, pos + (int2)(0,1)).x;
    float f0_1 = read_imagef(volume, sampler, pos - (int2)(0,1)).x;

    float4 gradient = {
        0.5f*(f10-f_10),
        0.5f*(f01-f0_1),
        0,
        0
    };

    write_imagef(vector_field, pos, gradient);
}

__kernel __attribute__((reqd_work_group_size(16,16,1))) void GVF2DIteration(__read_only image2d_t init_vector_field, __read_only image2d_t read_vector_field, __write_only image2d_t write_vector_field, __private float mu) {

    int2 writePos = {
        get_global_id(0),
        get_global_id(1)
    };
    // Enforce mirror boundary conditions
    int2 size = {get_image_width(init_vector_field), get_image_height(init_vector_field)};
    int2 pos = writePos;
    pos = select(pos, (int2)(2,2), pos == (int2)(0,0));
    pos = select(pos, size-3, pos >= size-1);

    float2 v = read_imagef(read_vector_field, sampler, pos).xy;

        // Load data from shared memory and do calculations
        float2 init_vector = read_imagef(init_vector_field, sampler, pos).xy;

        float2 fx1, fx_1, fy1, fy_1;
        fx1 = read_imagef(read_vector_field, sampler, pos + (int2)(1,0)).xy;
        fy1 = read_imagef(read_vector_field, sampler, pos + (int2)(0,1)).xy;
        fx_1 = read_imagef(read_vector_field, sampler, pos - (int2)(1,0)).xy;
        fy_1 = read_imagef(read_vector_field, sampler, pos - (int2)(0,1)).xy;

        // Update the vector field: Calculate Laplacian using a 3D central difference scheme
        float2 laplacian = -4*v + fx1 + fx_1 + fy1 + fy_1;

        v += mu * laplacian - (v - init_vector)*(init_vector.x*init_vector.x+init_vector.y*init_vector.y);

        write_imagef(write_vector_field, writePos, (float4)(v.x,v.y,0,0));
}

__kernel void GVF2DResult(__write_only image2d_t result, __read_only image2d_t vectorField, __write_only image2d_t vectorFieldFinal) {
    int2 pos = {get_global_id(0), get_global_id(1)};
    float4 vector = read_imagef(vectorField, sampler, pos);
    vector.z = 0;
    vector.w = 0;
    write_imagef(vectorFieldFinal, pos, vector);
    write_imagef(result, pos, length(vector));
}