APPBROWSER-375: Rewrite the transpose.cs with the new common code

Change-Id: I373e349ac35ff52ebcc895723d8aa61b754519d4
Reviewed-on: https://eu-gerrit-1.euhpc.arm.com/115283
Tested-by: Jenkins <bsgcomp@arm.com>
Reviewed-by: Pablo Tello <pablo.tello@arm.com>
Reviewed-by: Joel Liang <joel.liang@arm.com>
diff --git a/src/core/GLES_COMPUTE/cs_shaders/transpose.cs b/src/core/GLES_COMPUTE/cs_shaders/transpose.cs
old mode 100644
new mode 100755
index f8ad303..89bf9fb
--- a/src/core/GLES_COMPUTE/cs_shaders/transpose.cs
+++ b/src/core/GLES_COMPUTE/cs_shaders/transpose.cs
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2017 ARM Limited.
+ * Copyright (c) 2017, 2018 ARM Limited.
  *
  * SPDX-License-Identifier: MIT
  *
@@ -22,7 +22,12 @@
  * SOFTWARE.
  */
 layout(local_size_x = LOCAL_SIZE_X, local_size_y = LOCAL_SIZE_Y, local_size_z = LOCAL_SIZE_Z) in;
-#include "helpers.h"
+
+#include "helpers_cs.h"
+
+#if defined(DATA_TYPE_FP16)
+precision mediump float;
+#endif // DATA_TYPE_FP16
 
 #define SWAP_ROW_func(u0, l0) \
     {                         \
@@ -59,144 +64,90 @@
  * @note The data type must be passed at compile time using "#define DATA_TYPE_NAME". e.g. "#define DATA_TYPE_FP32"
  * @note Optimization name must be passed using "#define OPTIMIZATION_NAME" for F16. e.g. "#define TRANSPOSE_8X8"
  *
- * @param[in]  src_ptr                           Pointer to the source matrix. Supported data types: F32/F16
- * @param[in]  src_stride_x                      Stride of the source matrix in X dimension (in bytes)
- * @param[in]  src_step_x                        src_stride_x * number of elements along X processed per workitem(in bytes)
- * @param[in]  src_stride_y                      Stride of the source matrix in Y dimension (in bytes)
- * @param[in]  src_step_y                        src_stride_y * number of elements along Y processed per workitem(in bytes)
- * @param[in]  src_offset_first_element_in_bytes The offset of the first element in the source matrix
- * @param[out] dst_ptr                           Pointer to the destination matrix Supported data type: same as src_ptr
- * @param[in]  dst_stride_x                      Stride of the destination matrix in X dimension (in bytes)
- * @param[in]  dst_step_x                        dst_gx_stride_x * number of elements along X processed per workitem(in bytes)
- * @param[in]  dst_stride_y                      Stride of the destination matrix in Y dimension (in bytes)
- * @param[in]  dst_step_y                        dst_gx_stride_y * number of elements along Y processed per workitem(in bytes)
- * @param[in]  dst_offset_first_element_in_bytes The offset of the first element in the destination matrix
+ * @param[in]  src_ptr   Pointer to the source matrix. Supported data types: F32/F16
+ * @param[in]  src_attrs The attributes of the source matrix
+ * @param[out] dst_ptr   Pointer to the destination matrix Supported data type: same as src_ptr
+ * @param[in]  dst_attrs The attributes of the destination matrix
  */
-
-layout(std140) uniform shader_params
+SHADER_PARAMS_DECLARATION
 {
-    IMAGE_PARAM_DECLARATION(src);
-    IMAGE_PARAM_DECLARATION(dst);
+    ImageAttributes src_attrs;
+    ImageAttributes dst_attrs;
 };
 
 #ifdef DATA_TYPE_FP32
-precision highp float;
-
-BUFFER_DECLARATION(src, 1, float, readonly);
-BUFFER_DECLARATION(dst, 2, float, writeonly);
-
-#define LOAD16(r, name, offset)              \
-    {                                        \
-        r.x = LOAD4(name, offset);           \
-        r.y = LOAD4(name, offset + uint(1)); \
-        r.z = LOAD4(name, offset + uint(2)); \
-        r.w = LOAD4(name, offset + uint(3)); \
-    }
-
-#define STORE16(name, offset, r)             \
-    {                                        \
-        STORE4(name, offset, r.x);           \
-        STORE4(name, offset + uint(1), r.y); \
-        STORE4(name, offset + uint(2), r.z); \
-        STORE4(name, offset + uint(3), r.w); \
-    }
+TENSOR_DECLARATION(1, srcBuffer, float, src_ptr, src_shift, 2, readonly);
+TENSOR_DECLARATION(2, dstBuffer, float, dst_ptr, dst_shift, 2, writeonly);
 
 void main(void)
 {
     // compute source address
-    Image src = CONVERT_TO_IMAGE_STRUCT(src);
-    Image dst = CONVERT_TO_IMAGE_STRUCT(dst);
+    ImageIterator src_iter = CONVERT_TO_IMAGE_ITERATOR(src_attrs, src_shift);
+    ImageIterator dst_iter = CONVERT_TO_IMAGE_ITERATOR_NO_STEP(dst_attrs, dst_shift);
 
     // load the NxN block at (x, y)
-    vec4 u0;
-    vec4 u1;
-    vec4 u2;
-    vec4 u3;
-    LOAD16(u0, src, offset(src, 0, 0));
-    LOAD16(u1, src, offset(src, 0, 1));
-    LOAD16(u2, src, offset(src, 0, 2));
-    LOAD16(u3, src, offset(src, 0, 3));
+    vec4 u0 = VLOAD4(vec4, src_ptr, IMAGE_OFFSET(src_iter, 0, 0));
+    vec4 u1 = VLOAD4(vec4, src_ptr, IMAGE_OFFSET(src_iter, 0, 1));
+    vec4 u2 = VLOAD4(vec4, src_ptr, IMAGE_OFFSET(src_iter, 0, 2));
+    vec4 u3 = VLOAD4(vec4, src_ptr, IMAGE_OFFSET(src_iter, 0, 3));
 
     // transpose the block
     TRANSPOSE_4x4_func(u0, u1, u2, u3);
 
     // store the block at (y, x)
-    uint dst_offset_in_bytes = uint(16) * uint(gl_GlobalInvocationID.y) + uint(4) * uint(gl_GlobalInvocationID.x) * (dst.stride_y) + (dst.offset_first_element_in_bytes);
+    TENSOR_ITERATOR_ADVANCE_IN_BYTES(dst_iter, uint(16) * uint(gl_GlobalInvocationID.y) + uint(4) * uint(gl_GlobalInvocationID.x) * (dst_attrs.stride_y));
 
-    STORE16(dst, uint((dst_offset_in_bytes + uint(0) * dst.stride_y) >> 2), u0);
-    STORE16(dst, uint((dst_offset_in_bytes + uint(1) * dst.stride_y) >> 2), u1);
-    STORE16(dst, uint((dst_offset_in_bytes + uint(2) * dst.stride_y) >> 2), u2);
-    STORE16(dst, uint((dst_offset_in_bytes + uint(3) * dst.stride_y) >> 2), u3);
+    VSTORE4(dst_ptr, IMAGE_OFFSET(dst_iter, 0, 0), u0);
+    VSTORE4(dst_ptr, IMAGE_OFFSET(dst_iter, 0, 1), u1);
+    VSTORE4(dst_ptr, IMAGE_OFFSET(dst_iter, 0, 2), u2);
+    VSTORE4(dst_ptr, IMAGE_OFFSET(dst_iter, 0, 3), u3);
 }
 
-#elif defined(DATA_TYPE_FP16) /* DATA_TYPE_FP32 */
-precision mediump float;
+#elif defined(DATA_TYPE_FP16) /* DATA_TYPE_FP16 */
 
 #if defined(TRANSPOSE_4X4)
-
-BUFFER_DECLARATION(src, 1, uvec2, readonly);
-BUFFER_DECLARATION(dst, 2, uvec2, writeonly);
+TENSOR_DECLARATION(1, srcBuffer, uvec2, src_ptr, src_shift, 3, readonly);
+TENSOR_DECLARATION(2, dstBuffer, uvec2, dst_ptr, dst_shift, 3, writeonly);
 
 void main(void)
 {
     // compute source address
-    Image src = GC_CONVERT_TO_IMAGE_STRUCT(src);
-    Image dst = GC_CONVERT_TO_IMAGE_STRUCT(dst);
+    ImageIterator src_iter = CONVERT_TO_IMAGE_ITERATOR(src_attrs, src_shift);
+    ImageIterator dst_iter = CONVERT_TO_IMAGE_ITERATOR_NO_STEP(dst_attrs, dst_shift);
 
     // load the NxN block at (x, y)
-    vec4  u0;
-    vec4  u1;
-    vec4  u2;
-    vec4  u3;
-    uvec2 packed_s[4];
-
-    GC_LOAD1_2D_OFFSET(packed_s[0], src, 0, 0);
-    GC_LOAD1_2D_OFFSET(packed_s[1], src, 0, 1);
-    GC_LOAD1_2D_OFFSET(packed_s[2], src, 0, 2);
-    GC_LOAD1_2D_OFFSET(packed_s[3], src, 0, 3);
-
-    u0 = vec4(unpackHalf2x16(packed_s[0].x), unpackHalf2x16(packed_s[0].y));
-    u1 = vec4(unpackHalf2x16(packed_s[1].x), unpackHalf2x16(packed_s[1].y));
-    u2 = vec4(unpackHalf2x16(packed_s[2].x), unpackHalf2x16(packed_s[2].y));
-    u3 = vec4(unpackHalf2x16(packed_s[3].x), unpackHalf2x16(packed_s[3].y));
+    vec4 u0 = LOAD_UNPACK4_HALF(src_ptr, IMAGE_OFFSET(src_iter, 0, 0));
+    vec4 u1 = LOAD_UNPACK4_HALF(src_ptr, IMAGE_OFFSET(src_iter, 0, 1));
+    vec4 u2 = LOAD_UNPACK4_HALF(src_ptr, IMAGE_OFFSET(src_iter, 0, 2));
+    vec4 u3 = LOAD_UNPACK4_HALF(src_ptr, IMAGE_OFFSET(src_iter, 0, 3));
 
     // transpose the block
     TRANSPOSE_4x4_func(u0, u1, u2, u3);
 
     // store the block at (y, x)
-    uint dst_offset_in_bytes = uint(8) * uint(gl_GlobalInvocationID.y) + uint(gl_GlobalInvocationID.x) * (dst_step_y) + (dst.offset_first_element_in_bytes);
-    dst.current_offset       = dst_offset_in_bytes;
+    TENSOR_ITERATOR_ADVANCE_IN_BYTES(dst_iter, uint(8) * uint(gl_GlobalInvocationID.y) + uint(gl_GlobalInvocationID.x) * (dst_attrs.step_y));
 
-    packed_s[0] = uvec2(packHalf2x16(u0.xy), packHalf2x16(u0.zw));
-    packed_s[1] = uvec2(packHalf2x16(u1.xy), packHalf2x16(u1.zw));
-    packed_s[2] = uvec2(packHalf2x16(u2.xy), packHalf2x16(u2.zw));
-    packed_s[3] = uvec2(packHalf2x16(u3.xy), packHalf2x16(u3.zw));
-
-    GC_STORE1_2D_OFFSET(packed_s[0], dst, 0, 0);
-    GC_STORE1_2D_OFFSET(packed_s[1], dst, 0, 1);
-    GC_STORE1_2D_OFFSET(packed_s[2], dst, 0, 2);
-    GC_STORE1_2D_OFFSET(packed_s[3], dst, 0, 3);
+    STORE_PACK4_HALF(dst_ptr, IMAGE_OFFSET(dst_iter, 0, 0), u0);
+    STORE_PACK4_HALF(dst_ptr, IMAGE_OFFSET(dst_iter, 0, 1), u1);
+    STORE_PACK4_HALF(dst_ptr, IMAGE_OFFSET(dst_iter, 0, 2), u2);
+    STORE_PACK4_HALF(dst_ptr, IMAGE_OFFSET(dst_iter, 0, 3), u3);
 }
 
-#elif defined(TRANSPOSE_8X8) /* TRANSPOSE_4X4 */
-
-BUFFER_DECLARATION(src, 1, uvec4, readonly);
-BUFFER_DECLARATION(dst, 2, uvec4, writeonly);
+#elif defined(TRANSPOSE_8X8) /* TRANSPOSE_8X8 */
+TENSOR_DECLARATION(1, srcBuffer, uvec4, src_ptr, src_shift, 4, readonly);
+TENSOR_DECLARATION(2, dstBuffer, uvec4, dst_ptr, dst_shift, 4, writeonly);
 
 void main(void)
 {
     // compute source address
-    Image src = GC_CONVERT_TO_IMAGE_STRUCT(src);
-    Image dst = GC_CONVERT_TO_IMAGE_STRUCT(dst);
+    ImageIterator src_iter = CONVERT_TO_IMAGE_ITERATOR(src_attrs, src_shift);
+    ImageIterator dst_iter = CONVERT_TO_IMAGE_ITERATOR_NO_STEP(dst_attrs, dst_shift);
 
-    vec4  u[8][2];
-    uvec4 packed_s[8];
+    vec4 u[8][2];
 
     for(int i = 0; i < 8; i++)
     {
-        GC_LOAD1_2D_OFFSET(packed_s[i], src, 0, i);
-        u[i][0] = vec4(unpackHalf2x16(packed_s[i].x), unpackHalf2x16(packed_s[i].y));
-        u[i][1] = vec4(unpackHalf2x16(packed_s[i].z), unpackHalf2x16(packed_s[i].w));
+        u[i] = LOAD_UNPACK8_HALF(src_ptr, IMAGE_OFFSET(src_iter, 0, i));
     }
 
     // transpose the block
@@ -207,41 +158,36 @@
     SWAP_4x4_func(u[0][1], u[1][1], u[2][1], u[3][1], u[4][0], u[5][0], u[6][0], u[7][0]);
 
     // store the block at (y, x)
-    uint dst_offset_in_bytes = uint(16) * uint(gl_GlobalInvocationID.y) + uint(gl_GlobalInvocationID.x) * (dst_step_y) + (dst.offset_first_element_in_bytes);
-    dst.current_offset       = dst_offset_in_bytes;
+    TENSOR_ITERATOR_ADVANCE_IN_BYTES(dst_iter, uint(16) * uint(gl_GlobalInvocationID.y) + uint(gl_GlobalInvocationID.x) * (dst_attrs.step_y));
 
     for(int i = 0; i < 8; i++)
     {
-        packed_s[i] = uvec4(packHalf2x16(u[i][0].xy), packHalf2x16(u[i][0].zw), packHalf2x16(u[i][1].xy), packHalf2x16(u[i][1].zw));
-        GC_STORE1_2D_OFFSET(packed_s[i], dst, 0, i);
+        STORE_PACK8_HALF(dst_ptr, IMAGE_OFFSET(dst_iter, 0, i), u[i]);
     }
 }
 
-#elif defined(TRANSPOSE_8X8_SQUARE) /* TRANSPOSE_4X4 */
-
-BUFFER_DECLARATION(src, 1, uvec4, readonly);
-BUFFER_DECLARATION(dst, 2, uvec4, writeonly);
+#elif defined(TRANSPOSE_8X8_SQUARE) /* TRANSPOSE_8x8_SQUARE */
+TENSOR_DECLARATION(1, srcBuffer, uvec4, src_ptr, src_shift, 4, readonly);
+TENSOR_DECLARATION(2, dstBuffer, uvec4, dst_ptr, dst_shift, 4, writeonly);
 
 void main(void)
 {
-    Image src = GC_CONVERT_TO_IMAGE_STRUCT(src);
-    Image dst = GC_CONVERT_TO_IMAGE_STRUCT(dst);
+    ImageIterator src_iter = CONVERT_TO_IMAGE_ITERATOR(src_attrs, src_shift);
+    ImageIterator dst_iter = CONVERT_TO_IMAGE_ITERATOR_NO_STEP(dst_attrs, dst_shift);
 
     if(gl_GlobalInvocationID.x <= gl_GlobalInvocationID.y)
     {
-        uint blk1_offset_in_bytes = src.current_offset;
-        uint blk2_offset_in_bytes = uint(16) * uint(gl_GlobalInvocationID.y) + uint(gl_GlobalInvocationID.x) * (dst_step_y) + (dst.offset_first_element_in_bytes);
+        uint blk1_offset_in_bytes = CURRENT_ITEM_OFFSET_IN_BYTES(src_iter);
+        TENSOR_ITERATOR_ADVANCE_IN_BYTES(dst_iter, uint(16) * uint(gl_GlobalInvocationID.y) + uint(gl_GlobalInvocationID.x) * (dst_attrs.step_y));
+        uint blk2_offset_in_bytes = CURRENT_ITEM_OFFSET_IN_BYTES(dst_iter);
 
         // load block1
-        vec4  u1[8][2];
-        uvec4 packed_s[8];
+        vec4 u1[8][2];
 
-        src.current_offset = blk1_offset_in_bytes;
+        SET_TENSOR_ITERATOR_OFFSET_IN_BYTES(src_iter, blk1_offset_in_bytes);
         for(int i = 0; i < 8; i++)
         {
-            GC_LOAD1_2D_OFFSET(packed_s[i], src, 0, i);
-            u1[i][0] = vec4(unpackHalf2x16(packed_s[i].x), unpackHalf2x16(packed_s[i].y));
-            u1[i][1] = vec4(unpackHalf2x16(packed_s[i].z), unpackHalf2x16(packed_s[i].w));
+            u1[i] = LOAD_UNPACK8_HALF(src_ptr, IMAGE_OFFSET(src_iter, 0, i));
         }
 
         // transpose block1
@@ -252,22 +198,19 @@
         SWAP_4x4_func(u1[0][1], u1[1][1], u1[2][1], u1[3][1], u1[4][0], u1[5][0], u1[6][0], u1[7][0]);
 
         // write to block2
-        dst.current_offset = blk2_offset_in_bytes;
+        SET_TENSOR_ITERATOR_OFFSET_IN_BYTES(dst_iter, blk2_offset_in_bytes);
         for(int i = 0; i < 8; i++)
         {
-            packed_s[i] = uvec4(packHalf2x16(u1[i][0].xy), packHalf2x16(u1[i][0].zw), packHalf2x16(u1[i][1].xy), packHalf2x16(u1[i][1].zw));
-            GC_STORE1_2D_OFFSET(packed_s[i], dst, 0, i);
+            STORE_PACK8_HALF(dst_ptr, IMAGE_OFFSET(dst_iter, 0, i), u1[i]);
         }
 
         // load block2
         vec4 u2[8][2];
 
-        src.current_offset = blk2_offset_in_bytes;
+        SET_TENSOR_ITERATOR_OFFSET_IN_BYTES(src_iter, blk2_offset_in_bytes);
         for(int i = 0; i < 8; i++)
         {
-            GC_LOAD1_2D_OFFSET(packed_s[i], src, 0, i);
-            u2[i][0] = vec4(unpackHalf2x16(packed_s[i].x), unpackHalf2x16(packed_s[i].y));
-            u2[i][1] = vec4(unpackHalf2x16(packed_s[i].z), unpackHalf2x16(packed_s[i].w));
+            u2[i] = LOAD_UNPACK8_HALF(src_ptr, IMAGE_OFFSET(src_iter, 0, i));
         }
 
         // transpose block2
@@ -278,11 +221,10 @@
         SWAP_4x4_func(u2[0][1], u2[1][1], u2[2][1], u2[3][1], u2[4][0], u2[5][0], u2[6][0], u2[7][0]);
 
         // write to block1
-        dst.current_offset = blk1_offset_in_bytes;
+        SET_TENSOR_ITERATOR_OFFSET_IN_BYTES(dst_iter, blk1_offset_in_bytes);
         for(int i = 0; i < 8; i++)
         {
-            packed_s[i] = uvec4(packHalf2x16(u2[i][0].xy), packHalf2x16(u2[i][0].zw), packHalf2x16(u2[i][1].xy), packHalf2x16(u2[i][1].zw));
-            GC_STORE1_2D_OFFSET(packed_s[i], dst, 0, i);
+            STORE_PACK8_HALF(dst_ptr, IMAGE_OFFSET(dst_iter, 0, i), u2[i]);
         }
     }
 }