Browse Source

Use input from its current location in backproject

Tomas Farago 9 years ago
parent
commit
3317b6752d
1 changed files with 74 additions and 25 deletions
  1. 74 25
      src/ufo-anka-backproject-task.c

+ 74 - 25
src/ufo-anka-backproject-task.c

@@ -265,6 +265,67 @@ set_region (GValueArray *src, GValueArray **dst)
     }
 }
 
+static void
+copy_to_image (UfoBuffer *input,
+               cl_mem output_image,
+               cl_command_queue cmd_queue,
+               size_t origin[3],
+               size_t region[3],
+               gint in_width)
+{
+    const UfoBufferLocation location = ufo_buffer_get_location (input);
+    cl_mem input_data;
+    gfloat *input_data_host;
+    size_t src_offset;
+
+    switch (location) {
+        case UFO_BUFFER_LOCATION_HOST:
+            input_data_host = ufo_buffer_get_host_array (input, NULL);
+            src_offset = origin[1] * in_width + origin[0];
+            UFO_RESOURCES_CHECK_CLERR (clEnqueueWriteImage (cmd_queue,
+                                                            output_image,
+                                                            CL_TRUE,
+                                                            origin,
+                                                            region,
+                                                            0,
+                                                            0,
+                                                            input_data_host + src_offset,
+                                                            0,
+                                                            NULL,
+                                                            NULL));
+            break;
+        case UFO_BUFFER_LOCATION_DEVICE:
+            input_data = ufo_buffer_get_device_array (input, cmd_queue);
+            src_offset = (origin[1] * in_width + origin[0]) * sizeof (cl_float);
+            UFO_RESOURCES_CHECK_CLERR (clEnqueueCopyBufferToImage (cmd_queue,
+                                                                   input_data,
+                                                                   output_image,
+                                                                   src_offset,
+                                                                   origin,
+                                                                   region,
+                                                                   0,
+                                                                   NULL,
+                                                                   NULL));
+            break;
+        case UFO_BUFFER_LOCATION_DEVICE_IMAGE:
+            input_data = ufo_buffer_get_device_image (input, cmd_queue);
+            UFO_RESOURCES_CHECK_CLERR (clEnqueueCopyImage (cmd_queue,
+                                                           input_data,
+                                                           output_image,
+                                                           origin,
+                                                           origin,
+                                                           region,
+                                                           0,
+                                                           NULL,
+                                                           NULL));
+            break;
+        default:
+            g_warning ("Invalid input buffer location");
+            break;
+    }
+}
+
+
 UfoNode *
 ufo_anka_backproject_task_new (void)
 {
@@ -376,6 +437,7 @@ ufo_anka_backproject_task_process (UfoTask *task,
                                    UfoRequisition *requisition)
 {
     UfoAnkaBackprojectTaskPrivate *priv;
+    UfoRequisition in_req;
     UfoGpuNode *node;
     UfoProfiler *profiler;
     gfloat tomo_angle, *sines, *cosines;
@@ -388,11 +450,9 @@ ufo_anka_backproject_task_process (UfoTask *task,
     gint x_copy_region[2], y_copy_region[2];
     cl_kernel kernel;
     cl_command_queue cmd_queue;
-    cl_mem image;
     cl_mem out_mem;
     cl_int cl_error;
     /* image creation and copying */
-    size_t im_width, im_height;
     cl_image_format image_fmt;
     size_t origin[3];
     size_t region[3];
@@ -416,9 +476,7 @@ ufo_anka_backproject_task_process (UfoTask *task,
     node = UFO_GPU_NODE (ufo_task_node_get_proc_node (UFO_TASK_NODE (task)));
     cmd_queue = ufo_gpu_node_get_cmd_queue (node);
     out_mem = ufo_buffer_get_device_array (output, cmd_queue);
-    /* TODO: Get host/buffer/image depending on where the data *currently* resides. */
-    /* This Must be made available in UFO core first. */
-    image = ufo_buffer_get_device_image (inputs[0], cmd_queue); 
+    ufo_buffer_get_requisition (inputs[0], &in_req);
 
     index = priv->count % BURST;
     tomo_angle = priv->tomo_angle > -G_MAXFLOAT ? priv->tomo_angle :
@@ -437,18 +495,14 @@ ufo_anka_backproject_task_process (UfoTask *task,
     cos_lamino = cosf (priv->lamino_angle);
     scalar = priv->count >= priv->num_projections / BURST * BURST ? 1 : 0;
 
-    /* copy the image for further usage once BURST images arrived */
-    clGetImageInfo (image, CL_IMAGE_WIDTH, sizeof (size_t), &im_width, NULL);
-    clGetImageInfo (image, CL_IMAGE_HEIGHT, sizeof (size_t), &im_height, NULL);
-
     /* If COPY_PROJECTION_REGION is True we copy only the part necessary  */
     /* for a given tomographic and laminographic angle */
     if (COPY_PROJECTION_REGION) {
         determine_x_region (x_copy_region, priv->x_region, priv->y_region, tomo_angle,
-                            EXTRACT_FLOAT (priv->center, 0), im_width);
+                            EXTRACT_FLOAT (priv->center, 0), in_req.dims[0]);
         determine_y_region (y_copy_region, priv->x_region, priv->y_region, priv->z_region,
                             tomo_angle, priv->lamino_angle, EXTRACT_FLOAT (priv->center, 1),
-                            im_height);
+                            in_req.dims[1]);
         origin[0] = x_copy_region[0];
         origin[1] = y_copy_region[0];
         origin[2] = 0;
@@ -456,33 +510,28 @@ ufo_anka_backproject_task_process (UfoTask *task,
         region[1] = y_copy_region[1] - y_copy_region[0];
     } else {
         origin[0] = origin[1] = origin[2] = 0;
-        region[0] = im_width;
-        region[1] = im_height;
+        region[0] = in_req.dims[0];
+        region[1] = in_req.dims[1];
     }
     region[2] = 1;
 
     if (priv->images[index] == NULL) {
-        clGetImageInfo (image, CL_IMAGE_FORMAT, sizeof (cl_image_format), &image_fmt, NULL);
+        /* TODO: dangerous, don't rely on the ufo-buffer */
+        image_fmt.image_channel_order = CL_R;
+        image_fmt.image_channel_data_type = CL_FLOAT;
         /* TODO: what with the "other" API? */
         priv->images[index] = clCreateImage2D (priv->context,
                                                CL_MEM_READ_ONLY,
                                                &image_fmt,
-                                               im_width,
-                                               im_height,
+                                               in_req.dims[0],
+                                               in_req.dims[1],
                                                0,
                                                NULL,
                                                &cl_error);
         UFO_RESOURCES_CHECK_CLERR (cl_error);
     }
-    UFO_RESOURCES_CHECK_CLERR (clEnqueueCopyImage (cmd_queue,
-                               image,
-                               priv->images[index],
-                               origin,
-                               origin,
-                               region,
-                               0,
-                               NULL,
-                               NULL));
+
+    copy_to_image (inputs[0], priv->images[index], cmd_queue, origin, region, in_req.dims[0]);
 
     if (scalar) {
         kernel = priv->scalar_kernel;