ufo-scale-task.c 7.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251
  1. /**
  2. * SECTION:ufo-filter-task
  3. * @Short_description: Process arbitrary Filter kernels
  4. * @Title: filter
  5. *
  6. * This module is used to load an arbitrary #UfoScaleTask:kernel from
  7. * #UfoScaleTask:filename and execute it on each input. The kernel must have
  8. * only two global float array parameters, the first represents the input, the
  9. * second one the output. #UfoScaleTask:num-dims must be changed, if the kernel
  10. * accesses either one or three dimensional index spaces.
  11. */
  12. #ifdef __APPLE__
  13. #include <Filter/cl.h>
  14. #else
  15. #include <CL/cl.h>
  16. #endif
  17. #include <ufo-gpu-task-iface.h>
  18. #include "ufo-scale-task.h"
  19. struct _UfoScaleTaskPrivate {
  20. cl_kernel kernel;
  21. gfloat scale;
  22. };
  23. static void ufo_task_interface_init (UfoTaskIface *iface);
  24. static void ufo_gpu_task_interface_init (UfoGpuTaskIface *iface);
  25. G_DEFINE_TYPE_WITH_CODE (UfoScaleTask, ufo_scale_task, UFO_TYPE_TASK_NODE,
  26. G_IMPLEMENT_INTERFACE (UFO_TYPE_TASK,
  27. ufo_task_interface_init)
  28. G_IMPLEMENT_INTERFACE (UFO_TYPE_GPU_TASK,
  29. ufo_gpu_task_interface_init))
  30. #define UFO_SCALE_TASK_GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE((obj), UFO_TYPE_SCALE_TASK, UfoScaleTaskPrivate))
  31. enum {
  32. PROP_0,
  33. PROP_SCALE,
  34. N_PROPERTIES
  35. };
  36. static GParamSpec *properties[N_PROPERTIES] = { NULL, };
  37. UfoNode *
  38. ufo_scale_task_new (void)
  39. {
  40. return UFO_NODE (g_object_new (UFO_TYPE_SCALE_TASK, NULL));
  41. }
  42. static gboolean
  43. ufo_scale_task_process (UfoGpuTask *task,
  44. UfoBuffer **inputs,
  45. UfoBuffer *output,
  46. UfoRequisition *requisition,
  47. UfoGpuNode *node)
  48. {
  49. UfoScaleTaskPrivate *priv;
  50. cl_command_queue cmd_queue;
  51. cl_mem in_mem;
  52. cl_mem out_mem;
  53. priv = UFO_SCALE_TASK (task)->priv;
  54. cmd_queue = ufo_gpu_node_get_cmd_queue (node);
  55. in_mem = ufo_buffer_get_device_array (inputs[0], cmd_queue);
  56. out_mem = ufo_buffer_get_device_array (output, cmd_queue);
  57. UFO_RESOURCES_CHECK_CLERR (clSetKernelArg (priv->kernel, 0, sizeof (cl_mem), &in_mem));
  58. UFO_RESOURCES_CHECK_CLERR (clSetKernelArg (priv->kernel, 1, sizeof (cl_mem), &out_mem));
  59. UFO_RESOURCES_CHECK_CLERR (clSetKernelArg (priv->kernel, 2, sizeof (cl_float), &priv->scale));
  60. UFO_RESOURCES_CHECK_CLERR (clEnqueueNDRangeKernel (cmd_queue,
  61. priv->kernel,
  62. 2, NULL, requisition->dims, NULL,
  63. 0, NULL, NULL));
  64. return TRUE;
  65. }
  66. static void
  67. ufo_scale_task_get_structure (UfoTask *task,
  68. guint *n_inputs,
  69. UfoInputParam **in_params,
  70. UfoTaskMode *mode)
  71. {
  72. UfoScaleTaskPrivate *priv;
  73. priv = UFO_SCALE_TASK_GET_PRIVATE (task);
  74. *mode = UFO_TASK_MODE_SINGLE;
  75. *n_inputs = 1;
  76. *in_params = g_new0 (UfoInputParam, 1);
  77. (*in_params)[0].n_dims = 2;
  78. (*in_params)[0].n_expected = -1;
  79. }
  80. static void
  81. ufo_scale_task_setup (UfoTask *task,
  82. UfoResources *resources,
  83. GError **error)
  84. {
  85. UfoScaleTaskPrivate *priv;
  86. priv = UFO_SCALE_TASK_GET_PRIVATE (task);
  87. priv->kernel = ufo_resources_get_kernel (resources,
  88. "scale.cl",
  89. "scale",
  90. error);
  91. if (priv->kernel != NULL)
  92. UFO_RESOURCES_CHECK_CLERR (clRetainKernel (priv->kernel));
  93. }
  94. static void
  95. ufo_scale_task_get_requisition (UfoTask *task,
  96. UfoBuffer **inputs,
  97. UfoRequisition *requisition)
  98. {
  99. UfoScaleTaskPrivate *priv;
  100. priv = UFO_SCALE_TASK_GET_PRIVATE (task);
  101. ufo_buffer_get_requisition (inputs[0], requisition);
  102. }
  103. static UfoNode *
  104. ufo_scale_task_copy_real (UfoNode *node,
  105. GError **error)
  106. {
  107. UfoScaleTask *orig;
  108. UfoScaleTask *copy;
  109. orig = UFO_SCALE_TASK (node);
  110. copy = UFO_SCALE_TASK (ufo_scale_task_new ());
  111. g_object_set (G_OBJECT (copy),
  112. "scale", orig->priv->scale,
  113. NULL);
  114. return UFO_NODE (copy);
  115. }
  116. static gboolean
  117. ufo_scale_task_equal_real (UfoNode *n1,
  118. UfoNode *n2)
  119. {
  120. g_return_val_if_fail (UFO_IS_SCALE_TASK (n1) && UFO_IS_SCALE_TASK (n2), FALSE);
  121. return TRUE;
  122. }
  123. static void
  124. ufo_scale_task_finalize (GObject *object)
  125. {
  126. UfoScaleTaskPrivate *priv;
  127. priv = UFO_SCALE_TASK_GET_PRIVATE (object);
  128. if (priv->kernel) {
  129. clReleaseKernel (priv->kernel);
  130. priv->kernel = NULL;
  131. }
  132. G_OBJECT_CLASS (ufo_scale_task_parent_class)->finalize (object);
  133. }
  134. static void
  135. ufo_task_interface_init (UfoTaskIface *iface)
  136. {
  137. iface->setup = ufo_scale_task_setup;
  138. iface->get_requisition = ufo_scale_task_get_requisition;
  139. iface->get_structure = ufo_scale_task_get_structure;
  140. }
  141. static void
  142. ufo_gpu_task_interface_init (UfoGpuTaskIface *iface)
  143. {
  144. iface->process = ufo_scale_task_process;
  145. }
  146. static void
  147. ufo_scale_task_set_property (GObject *object,
  148. guint property_id,
  149. const GValue *value,
  150. GParamSpec *pspec)
  151. {
  152. UfoScaleTaskPrivate *priv = UFO_SCALE_TASK_GET_PRIVATE (object);
  153. switch (property_id) {
  154. case PROP_SCALE:
  155. priv->scale = g_value_get_float (value);
  156. break;
  157. default:
  158. G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
  159. break;
  160. }
  161. }
  162. static void
  163. ufo_scale_task_get_property (GObject *object,
  164. guint property_id,
  165. GValue *value,
  166. GParamSpec *pspec)
  167. {
  168. UfoScaleTaskPrivate *priv = UFO_SCALE_TASK_GET_PRIVATE (object);
  169. switch (property_id) {
  170. case PROP_SCALE:
  171. g_value_set_float (value, priv->scale);
  172. break;
  173. default:
  174. G_OBJECT_WARN_INVALID_PROPERTY_ID(object, property_id, pspec);
  175. break;
  176. }
  177. }
  178. static void
  179. ufo_scale_task_class_init (UfoScaleTaskClass *klass)
  180. {
  181. GObjectClass *oclass;
  182. UfoNodeClass *node_class;
  183. oclass = G_OBJECT_CLASS (klass);
  184. node_class = UFO_NODE_CLASS (klass);
  185. oclass->finalize = ufo_scale_task_finalize;
  186. oclass->set_property = ufo_scale_task_set_property;
  187. oclass->get_property = ufo_scale_task_get_property;
  188. properties[PROP_SCALE] =
  189. g_param_spec_float ("scale",
  190. "Scale",
  191. "Scale for each pixel",
  192. -5.0, 10.0, 1.0,
  193. G_PARAM_READWRITE);
  194. for (guint i = PROP_0 + 1; i < N_PROPERTIES; i++)
  195. g_object_class_install_property (oclass, i, properties[i]);
  196. node_class->copy = ufo_scale_task_copy_real;
  197. node_class->equal = ufo_scale_task_equal_real;
  198. g_type_class_add_private(klass, sizeof(UfoScaleTaskPrivate));
  199. }
  200. static void
  201. ufo_scale_task_init (UfoScaleTask *self)
  202. {
  203. UfoScaleTaskPrivate *priv;
  204. self->priv = priv = UFO_SCALE_TASK_GET_PRIVATE (self);
  205. priv->kernel = NULL;
  206. }