ufo-scale-task.c 7.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250
  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-scale-task.h"
  18. struct _UfoScaleTaskPrivate {
  19. cl_kernel kernel;
  20. gfloat scale;
  21. };
  22. static void ufo_task_interface_init (UfoTaskIface *iface);
  23. static void ufo_gpu_task_interface_init (UfoGpuTaskIface *iface);
  24. G_DEFINE_TYPE_WITH_CODE (UfoScaleTask, ufo_scale_task, UFO_TYPE_TASK_NODE,
  25. G_IMPLEMENT_INTERFACE (UFO_TYPE_TASK,
  26. ufo_task_interface_init)
  27. G_IMPLEMENT_INTERFACE (UFO_TYPE_GPU_TASK,
  28. ufo_gpu_task_interface_init))
  29. #define UFO_SCALE_TASK_GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE((obj), UFO_TYPE_SCALE_TASK, UfoScaleTaskPrivate))
  30. enum {
  31. PROP_0,
  32. PROP_SCALE,
  33. N_PROPERTIES
  34. };
  35. static GParamSpec *properties[N_PROPERTIES] = { NULL, };
  36. UfoNode *
  37. ufo_scale_task_new (void)
  38. {
  39. return UFO_NODE (g_object_new (UFO_TYPE_SCALE_TASK, NULL));
  40. }
  41. static gboolean
  42. ufo_scale_task_process (UfoGpuTask *task,
  43. UfoBuffer **inputs,
  44. UfoBuffer *output,
  45. UfoRequisition *requisition)
  46. {
  47. UfoScaleTaskPrivate *priv;
  48. UfoGpuNode *node;
  49. cl_command_queue cmd_queue;
  50. cl_mem in_mem;
  51. cl_mem out_mem;
  52. priv = UFO_SCALE_TASK (task)->priv;
  53. node = UFO_GPU_NODE (ufo_task_node_get_proc_node (UFO_TASK_NODE (task)));
  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_PROCESSOR;
  75. *n_inputs = 1;
  76. *in_params = g_new0 (UfoInputParam, 1);
  77. (*in_params)[0].n_dims = 2;
  78. }
  79. static void
  80. ufo_scale_task_setup (UfoTask *task,
  81. UfoResources *resources,
  82. GError **error)
  83. {
  84. UfoScaleTaskPrivate *priv;
  85. priv = UFO_SCALE_TASK_GET_PRIVATE (task);
  86. priv->kernel = ufo_resources_get_kernel (resources,
  87. "scale.cl",
  88. "scale",
  89. error);
  90. if (priv->kernel != NULL)
  91. UFO_RESOURCES_CHECK_CLERR (clRetainKernel (priv->kernel));
  92. }
  93. static void
  94. ufo_scale_task_get_requisition (UfoTask *task,
  95. UfoBuffer **inputs,
  96. UfoRequisition *requisition)
  97. {
  98. UfoScaleTaskPrivate *priv;
  99. priv = UFO_SCALE_TASK_GET_PRIVATE (task);
  100. ufo_buffer_get_requisition (inputs[0], requisition);
  101. }
  102. static UfoNode *
  103. ufo_scale_task_copy_real (UfoNode *node,
  104. GError **error)
  105. {
  106. UfoScaleTask *orig;
  107. UfoScaleTask *copy;
  108. orig = UFO_SCALE_TASK (node);
  109. copy = UFO_SCALE_TASK (ufo_scale_task_new ());
  110. g_object_set (G_OBJECT (copy),
  111. "scale", orig->priv->scale,
  112. NULL);
  113. return UFO_NODE (copy);
  114. }
  115. static gboolean
  116. ufo_scale_task_equal_real (UfoNode *n1,
  117. UfoNode *n2)
  118. {
  119. g_return_val_if_fail (UFO_IS_SCALE_TASK (n1) && UFO_IS_SCALE_TASK (n2), FALSE);
  120. return TRUE;
  121. }
  122. static void
  123. ufo_scale_task_finalize (GObject *object)
  124. {
  125. UfoScaleTaskPrivate *priv;
  126. priv = UFO_SCALE_TASK_GET_PRIVATE (object);
  127. if (priv->kernel) {
  128. clReleaseKernel (priv->kernel);
  129. priv->kernel = NULL;
  130. }
  131. G_OBJECT_CLASS (ufo_scale_task_parent_class)->finalize (object);
  132. }
  133. static void
  134. ufo_task_interface_init (UfoTaskIface *iface)
  135. {
  136. iface->setup = ufo_scale_task_setup;
  137. iface->get_requisition = ufo_scale_task_get_requisition;
  138. iface->get_structure = ufo_scale_task_get_structure;
  139. }
  140. static void
  141. ufo_gpu_task_interface_init (UfoGpuTaskIface *iface)
  142. {
  143. iface->process = ufo_scale_task_process;
  144. }
  145. static void
  146. ufo_scale_task_set_property (GObject *object,
  147. guint property_id,
  148. const GValue *value,
  149. GParamSpec *pspec)
  150. {
  151. UfoScaleTaskPrivate *priv = UFO_SCALE_TASK_GET_PRIVATE (object);
  152. switch (property_id) {
  153. case PROP_SCALE:
  154. priv->scale = g_value_get_float (value);
  155. break;
  156. default:
  157. G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
  158. break;
  159. }
  160. }
  161. static void
  162. ufo_scale_task_get_property (GObject *object,
  163. guint property_id,
  164. GValue *value,
  165. GParamSpec *pspec)
  166. {
  167. UfoScaleTaskPrivate *priv = UFO_SCALE_TASK_GET_PRIVATE (object);
  168. switch (property_id) {
  169. case PROP_SCALE:
  170. g_value_set_float (value, priv->scale);
  171. break;
  172. default:
  173. G_OBJECT_WARN_INVALID_PROPERTY_ID(object, property_id, pspec);
  174. break;
  175. }
  176. }
  177. static void
  178. ufo_scale_task_class_init (UfoScaleTaskClass *klass)
  179. {
  180. GObjectClass *oclass;
  181. UfoNodeClass *node_class;
  182. oclass = G_OBJECT_CLASS (klass);
  183. node_class = UFO_NODE_CLASS (klass);
  184. oclass->finalize = ufo_scale_task_finalize;
  185. oclass->set_property = ufo_scale_task_set_property;
  186. oclass->get_property = ufo_scale_task_get_property;
  187. properties[PROP_SCALE] =
  188. g_param_spec_float ("scale",
  189. "Scale",
  190. "Scale for each pixel",
  191. -5.0, 10.0, 1.0,
  192. G_PARAM_READWRITE);
  193. for (guint i = PROP_0 + 1; i < N_PROPERTIES; i++)
  194. g_object_class_install_property (oclass, i, properties[i]);
  195. node_class->copy = ufo_scale_task_copy_real;
  196. node_class->equal = ufo_scale_task_equal_real;
  197. g_type_class_add_private(klass, sizeof(UfoScaleTaskPrivate));
  198. }
  199. static void
  200. ufo_scale_task_init (UfoScaleTask *self)
  201. {
  202. UfoScaleTaskPrivate *priv;
  203. self->priv = priv = UFO_SCALE_TASK_GET_PRIVATE (self);
  204. priv->kernel = NULL;
  205. }