Ejemplo n.º 1
0
MagickExport MagickBooleanType AccelerateConvolveImage(const Image *image,
  const KernelInfo *kernel,Image *convolve_image,ExceptionInfo *exception)
{
  assert(image != (Image *) NULL);
  assert(image->signature == MagickSignature);
  if (image->debug != MagickFalse)
    (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
  assert(kernel != (KernelInfo *) NULL);
  assert(kernel->signature == MagickSignature);
  assert(convolve_image != (Image *) NULL);
  assert(convolve_image->signature == MagickSignature);
  assert(exception != (ExceptionInfo *) NULL);
  assert(exception->signature == MagickSignature);
  if ((image->storage_class != DirectClass) || 
      (image->colorspace == CMYKColorspace))
  if ((GetImageVirtualPixelMethod(image) != UndefinedVirtualPixelMethod) &&
      (GetImageVirtualPixelMethod(image) != EdgeVirtualPixelMethod))
    return(MagickFalse);
#if !defined(MAGICKCORE_OPENCL_SUPPORT)
  return(MagickFalse);
#else
  {
    const void
      *pixels;

    ConvolveInfo
      *convolve_info;

    MagickBooleanType
      status;

    MagickSizeType
      length;

    void
      *convolve_pixels;

    convolve_info=GetConvolveInfo(image,"Convolve",ConvolveKernel,exception);
    if (convolve_info == (ConvolveInfo *) NULL)
      return(MagickFalse);
    pixels=AcquirePixelCachePixels(image,&length,exception);
    if (pixels == (const void *) NULL)
      {
        (void) ThrowMagickException(exception,GetMagickModule(),CacheError,
          "UnableToReadPixelCache","`%s'",image->filename);
        convolve_info=DestroyConvolveInfo(convolve_info);
        return(MagickFalse);
      }
    convolve_pixels=GetPixelCachePixels(convolve_image,&length,exception);
    if (convolve_pixels == (void *) NULL)
      {
        (void) ThrowMagickException(exception,GetMagickModule(),CacheError,
          "UnableToReadPixelCache","`%s'",image->filename);
        convolve_info=DestroyConvolveInfo(convolve_info);
        return(MagickFalse);
      }
    status=BindConvolveParameters(convolve_info,image,pixels,kernel->values,
      kernel->width,kernel->height,convolve_pixels);
    if (status == MagickFalse)
      {
        DestroyConvolveBuffers(convolve_info);
        convolve_info=DestroyConvolveInfo(convolve_info);
        return(MagickFalse);
      }
    status=EnqueueConvolveKernel(convolve_info,image,pixels,kernel->values,
      kernel->width,kernel->height,convolve_pixels);
    if (status == MagickFalse)
      {
        DestroyConvolveBuffers(convolve_info);
        convolve_info=DestroyConvolveInfo(convolve_info);
        return(MagickFalse);
      }
    DestroyConvolveBuffers(convolve_info);
    convolve_info=DestroyConvolveInfo(convolve_info);
    return(MagickTrue);
  }
#endif
}
MagickExport MagickBooleanType AccelerateConvolveImage(const Image *image,
  const KernelInfo *kernel,Image *convolve_image,ExceptionInfo *exception)
{
  assert(image != (Image *) NULL);
  assert(image->signature == MagickSignature);
  if (image->debug != MagickFalse)
    (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
  assert(kernel != (KernelInfo *) NULL);
  assert(kernel->signature == MagickSignature);
  assert(convolve_image != (Image *) NULL);
  assert(convolve_image->signature == MagickSignature);
  assert(exception != (ExceptionInfo *) NULL);
  assert(exception->signature == MagickSignature);
  if ((image->storage_class != DirectClass) ||
      (image->colorspace == CMYKColorspace))
    return(MagickFalse);
  if ((GetImageVirtualPixelMethod(image) != UndefinedVirtualPixelMethod) &&
      (GetImageVirtualPixelMethod(image) != EdgeVirtualPixelMethod))
    return(MagickFalse);
  if (GetPixelChannels(image) != 4)
    return(MagickFalse);
#if !defined(MAGICKCORE_OPENCL_SUPPORT)
  return(MagickFalse);
#else
  {
    const void
      *pixels;

    float
      *filter;

    ConvolveInfo
      *convolve_info;

    MagickBooleanType
      status;

    MagickSizeType
      length;

    register ssize_t
      i;

    void
      *convolve_pixels;

    convolve_info=GetConvolveInfo(image,"Convolve",ConvolveKernel,exception);
    if (convolve_info == (ConvolveInfo *) NULL)
      return(MagickFalse);
    pixels=AcquirePixelCachePixels(image,&length,exception);
    if (pixels == (const void *) NULL)
      {
        convolve_info=DestroyConvolveInfo(convolve_info);
        (void) ThrowMagickException(exception,GetMagickModule(),CacheError,
          "UnableToReadPixelCache","'%s'",image->filename);
        return(MagickFalse);
      }
    convolve_pixels=GetPixelCachePixels(convolve_image,&length,exception);
    if (convolve_pixels == (void *) NULL)
      {
        convolve_info=DestroyConvolveInfo(convolve_info);
        (void) ThrowMagickException(exception,GetMagickModule(),CacheError,
          "UnableToReadPixelCache","'%s'",image->filename);
        return(MagickFalse);
      }
    filter=(float *) AcquireQuantumMemory(kernel->width,kernel->height*
      sizeof(*filter));
    if (filter == (float *) NULL)
      {
        DestroyConvolveBuffers(convolve_info);
        convolve_info=DestroyConvolveInfo(convolve_info);
        (void) ThrowMagickException(exception,GetMagickModule(),
          ResourceLimitError,"MemoryAllocationFailed","'%s'",image->filename);
        return(MagickFalse);
      }
    for (i=0; i < (ssize_t) (kernel->width*kernel->height); i++)
      filter[i]=(float) kernel->values[i];
    status=BindConvolveParameters(convolve_info,image,pixels,filter,
      kernel->width,kernel->height,convolve_pixels);
    if (status == MagickFalse)
      {
        filter=(float *) RelinquishMagickMemory(filter);
        DestroyConvolveBuffers(convolve_info);
        convolve_info=DestroyConvolveInfo(convolve_info);
        return(MagickFalse);
      }
    status=EnqueueConvolveKernel(convolve_info,image,pixels,filter,
      kernel->width,kernel->height,convolve_pixels);
    filter=(float *) RelinquishMagickMemory(filter);
    if (status == MagickFalse)
      {
        DestroyConvolveBuffers(convolve_info);
        convolve_info=DestroyConvolveInfo(convolve_info);
        return(MagickFalse);
      }
    DestroyConvolveBuffers(convolve_info);
    convolve_info=DestroyConvolveInfo(convolve_info);
    return(MagickTrue);
  }
#endif
}
Ejemplo n.º 3
0
static ConvolveInfo *GetConvolveInfo(const Image *image,const char *name,
  const char *source,ExceptionInfo *exception)
{
  char
    options[MaxTextExtent];

  cl_int
    status;

  ConvolveInfo
    *convolve_info;

  size_t
    length,
    lengths[] = { strlen(source) };

  /*
    Create OpenCL info.
  */
  convolve_info=(ConvolveInfo *) AcquireAlignedMemory(1,sizeof(*convolve_info));
  if (convolve_info == (ConvolveInfo *) NULL)
    {
      (void) ThrowMagickException(exception,GetMagickModule(),
        ResourceLimitError,"MemoryAllocationFailed","`%s'",image->filename);
      return((ConvolveInfo *) NULL);
    }
  (void) ResetMagickMemory(convolve_info,0,sizeof(*convolve_info));
  /*
    Create OpenCL context.
  */
  convolve_info->context=clCreateContextFromType((cl_context_properties *)
    NULL,(cl_device_type) CL_DEVICE_TYPE_GPU,ConvolveNotify,exception,&status);
  if ((convolve_info->context == (cl_context) NULL) || (status != CL_SUCCESS))
    convolve_info->context=clCreateContextFromType((cl_context_properties *)
      NULL,(cl_device_type) CL_DEVICE_TYPE_CPU,ConvolveNotify,exception,
      &status);
  if ((convolve_info->context == (cl_context) NULL) || (status != CL_SUCCESS))
    convolve_info->context=clCreateContextFromType((cl_context_properties *)
      NULL,(cl_device_type) CL_DEVICE_TYPE_DEFAULT,ConvolveNotify,exception,
      &status);
  if ((convolve_info->context == (cl_context) NULL) || (status != CL_SUCCESS))
    {
      (void) ThrowMagickException(exception,GetMagickModule(),DelegateWarning,
        "failed to create OpenCL context","`%s' (%d)",image->filename,status);
      convolve_info=DestroyConvolveInfo(convolve_info);
      return((ConvolveInfo *) NULL);
    }
  /*
    Detect OpenCL devices.
  */
  status=clGetContextInfo(convolve_info->context,CL_CONTEXT_DEVICES,0,NULL,
    &length);
  if ((status != CL_SUCCESS) || (length == 0))
    {
      convolve_info=DestroyConvolveInfo(convolve_info);
      return((ConvolveInfo *) NULL);
    }
  convolve_info->devices=(cl_device_id *) AcquireMagickMemory(length);
  if (convolve_info->devices == (cl_device_id *) NULL)
    {
      (void) ThrowMagickException(exception,GetMagickModule(),
        ResourceLimitError,"MemoryAllocationFailed","`%s'",image->filename);
      convolve_info=DestroyConvolveInfo(convolve_info);
      return((ConvolveInfo *) NULL);
    }
  status=clGetContextInfo(convolve_info->context,CL_CONTEXT_DEVICES,length,
    convolve_info->devices,NULL);
  if (status != CL_SUCCESS)
    {
      convolve_info=DestroyConvolveInfo(convolve_info);
      return((ConvolveInfo *) NULL);
    }
  /*
    Create OpenCL command queue.
  */
  convolve_info->command_queue=clCreateCommandQueue(convolve_info->context,
    convolve_info->devices[0],0,&status);
  if ((convolve_info->command_queue == (cl_command_queue) NULL) ||
      (status != CL_SUCCESS))
    {
      convolve_info=DestroyConvolveInfo(convolve_info);
      return((ConvolveInfo *) NULL);
    }
  /*
    Build OpenCL program.
  */
  convolve_info->program=clCreateProgramWithSource(convolve_info->context,1,
    &source,lengths,&status);
  if ((convolve_info->program == (cl_program) NULL) || (status != CL_SUCCESS))
    {
      convolve_info=DestroyConvolveInfo(convolve_info);
      return((ConvolveInfo *) NULL);
    }
  (void) FormatMagickString(options,MaxTextExtent,CLOptions,(double)
    QuantumRange,MagickEpsilon);
  status=clBuildProgram(convolve_info->program,1,convolve_info->devices,options,
    NULL,NULL);
  if ((convolve_info->program == (cl_program) NULL) || (status != CL_SUCCESS))
    {
      char
        *log;

      status=clGetProgramBuildInfo(convolve_info->program,
        convolve_info->devices[0],CL_PROGRAM_BUILD_LOG,0,NULL,&length);
      log=(char *) AcquireMagickMemory(length);
      if (log == (char *) NULL)
        {
          convolve_info=DestroyConvolveInfo(convolve_info);
          return((ConvolveInfo *) NULL);
        }
      status=clGetProgramBuildInfo(convolve_info->program,
        convolve_info->devices[0],CL_PROGRAM_BUILD_LOG,length,log,&length);
      (void) ThrowMagickException(exception,GetMagickModule(),DelegateWarning,
        "failed to build OpenCL program","`%s' (%s)",image->filename,log);
      log=DestroyString(log);
      convolve_info=DestroyConvolveInfo(convolve_info);
      return((ConvolveInfo *) NULL);
    }
  /*
    Get a kernel object.
  */
  convolve_info->kernel=clCreateKernel(convolve_info->program,name,&status);
  if ((convolve_info->kernel == (cl_kernel) NULL) || (status != CL_SUCCESS))
    {
      convolve_info=DestroyConvolveInfo(convolve_info);
      return((ConvolveInfo *) NULL);
    }
  return(convolve_info);
}
static ConvolveInfo *GetConvolveInfo(const Image *image,const char *name,
  const char *source,ExceptionInfo *exception)
{
  char
    options[MaxTextExtent];

  cl_context_properties
    context_properties[3];

  cl_int
    status;

  cl_platform_id
    platforms[1];

  cl_uint
    number_platforms;

  ConvolveInfo
    *convolve_info;

  size_t
    length,
    lengths[] = { strlen(source) };

  /*
    Create OpenCL info.
  */
  convolve_info=(ConvolveInfo *) AcquireMagickMemory(sizeof(*convolve_info));
  if (convolve_info == (ConvolveInfo *) NULL)
    {
      (void) ThrowMagickException(exception,GetMagickModule(),
        ResourceLimitError,"MemoryAllocationFailed","'%s'",image->filename);
      return((ConvolveInfo *) NULL);
    }
  (void) ResetMagickMemory(convolve_info,0,sizeof(*convolve_info));
  /*
    Create OpenCL context.
  */
  status=clGetPlatformIDs(0,(cl_platform_id *) NULL,&number_platforms);
  if ((status == CL_SUCCESS) && (number_platforms > 0))
    status=clGetPlatformIDs(1,platforms,NULL);
  if (status != CL_SUCCESS)
    {
      (void) ThrowMagickException(exception,GetMagickModule(),DelegateWarning,
        "failed to create OpenCL context","'%s' (%d)",image->filename,status);
      convolve_info=DestroyConvolveInfo(convolve_info);
      return((ConvolveInfo *) NULL);
    }
  context_properties[0]=CL_CONTEXT_PLATFORM;
  context_properties[1]=(cl_context_properties) platforms[0];
  context_properties[2]=0;
  convolve_info->context=clCreateContextFromType(context_properties,
    (cl_device_type) CL_DEVICE_TYPE_GPU,ConvolveNotify,exception,&status);
  if ((convolve_info->context == (cl_context) NULL) || (status != CL_SUCCESS))
    convolve_info->context=clCreateContextFromType(context_properties,
      (cl_device_type) CL_DEVICE_TYPE_CPU,ConvolveNotify,exception,&status);
  if ((convolve_info->context == (cl_context) NULL) || (status != CL_SUCCESS))
    convolve_info->context=clCreateContextFromType(context_properties,
      (cl_device_type) CL_DEVICE_TYPE_DEFAULT,ConvolveNotify,exception,&status);
  if ((convolve_info->context == (cl_context) NULL) || (status != CL_SUCCESS))
    {
      (void) ThrowMagickException(exception,GetMagickModule(),DelegateWarning,
        "failed to create OpenCL context","'%s' (%d)",image->filename,status);
      convolve_info=DestroyConvolveInfo(convolve_info);
      return((ConvolveInfo *) NULL);
    }
  /*
    Detect OpenCL devices.
  */
  status=clGetContextInfo(convolve_info->context,CL_CONTEXT_DEVICES,0,NULL,
    &length);
  if ((status != CL_SUCCESS) || (length == 0))
    {
      convolve_info=DestroyConvolveInfo(convolve_info);
      return((ConvolveInfo *) NULL);
    }
  convolve_info->devices=(cl_device_id *) AcquireMagickMemory(length);
  if (convolve_info->devices == (cl_device_id *) NULL)
    {
      (void) ThrowMagickException(exception,GetMagickModule(),
        ResourceLimitError,"MemoryAllocationFailed","'%s'",image->filename);
      convolve_info=DestroyConvolveInfo(convolve_info);
      return((ConvolveInfo *) NULL);
    }
  status=clGetContextInfo(convolve_info->context,CL_CONTEXT_DEVICES,length,
    convolve_info->devices,NULL);
  if (status != CL_SUCCESS)
    {
      convolve_info=DestroyConvolveInfo(convolve_info);
      return((ConvolveInfo *) NULL);
    }
  if (image->debug != MagickFalse)
    {
      char
        attribute[MaxTextExtent];

      size_t
        length;

      clGetDeviceInfo(convolve_info->devices[0],CL_DEVICE_NAME,
        sizeof(attribute),attribute,&length);
      (void) LogMagickEvent(AccelerateEvent,GetMagickModule(),"Name: %s",
        attribute);
      clGetDeviceInfo(convolve_info->devices[0],CL_DEVICE_VENDOR,
        sizeof(attribute),attribute,&length);
      (void) LogMagickEvent(AccelerateEvent,GetMagickModule(),"Vendor: %s",
        attribute);
      clGetDeviceInfo(convolve_info->devices[0],CL_DEVICE_VERSION,
        sizeof(attribute),attribute,&length);
      (void) LogMagickEvent(AccelerateEvent,GetMagickModule(),
        "Driver Version: %s",attribute);
      clGetDeviceInfo(convolve_info->devices[0],CL_DEVICE_PROFILE,
        sizeof(attribute),attribute,&length);
      (void) LogMagickEvent(AccelerateEvent,GetMagickModule(),"Profile: %s",
        attribute);
      clGetDeviceInfo(convolve_info->devices[0],CL_DRIVER_VERSION,
        sizeof(attribute),attribute,&length);
      (void) LogMagickEvent(AccelerateEvent,GetMagickModule(),"Driver: %s",
        attribute);
      clGetDeviceInfo(convolve_info->devices[0],CL_DEVICE_EXTENSIONS,
        sizeof(attribute),attribute,&length);
      (void) LogMagickEvent(AccelerateEvent,GetMagickModule(),"Extensions: %s",
        attribute);
    }
  /*
    Create OpenCL command queue.
  */
  convolve_info->command_queue=clCreateCommandQueue(convolve_info->context,
    convolve_info->devices[0],0,&status);
  if ((convolve_info->command_queue == (cl_command_queue) NULL) ||
      (status != CL_SUCCESS))
    {
      convolve_info=DestroyConvolveInfo(convolve_info);
      return((ConvolveInfo *) NULL);
    }
  /*
    Build OpenCL program.
  */
  convolve_info->program=clCreateProgramWithSource(convolve_info->context,1,
    &source,lengths,&status);
  if ((convolve_info->program == (cl_program) NULL) || (status != CL_SUCCESS))
    {
      convolve_info=DestroyConvolveInfo(convolve_info);
      return((ConvolveInfo *) NULL);
    }
  (void) FormatLocaleString(options,MaxTextExtent,CLOptions,(float)
    QuantumRange,MagickEpsilon);
  status=clBuildProgram(convolve_info->program,1,convolve_info->devices,options,
    NULL,NULL);
  if ((convolve_info->program == (cl_program) NULL) || (status != CL_SUCCESS))
    {
      char
        *log;

      status=clGetProgramBuildInfo(convolve_info->program,
        convolve_info->devices[0],CL_PROGRAM_BUILD_LOG,0,NULL,&length);
      log=(char *) AcquireMagickMemory(length);
      if (log == (char *) NULL)
        {
          convolve_info=DestroyConvolveInfo(convolve_info);
          return((ConvolveInfo *) NULL);
        }
      status=clGetProgramBuildInfo(convolve_info->program,
        convolve_info->devices[0],CL_PROGRAM_BUILD_LOG,length,log,&length);
      (void) ThrowMagickException(exception,GetMagickModule(),DelegateWarning,
        "failed to build OpenCL program","'%s' (%s)",image->filename,log);
      log=DestroyString(log);
      convolve_info=DestroyConvolveInfo(convolve_info);
      return((ConvolveInfo *) NULL);
    }
  /*
    Get a kernel object.
  */
  convolve_info->kernel=clCreateKernel(convolve_info->program,name,&status);
  if ((convolve_info->kernel == (cl_kernel) NULL) || (status != CL_SUCCESS))
    {
      convolve_info=DestroyConvolveInfo(convolve_info);
      return((ConvolveInfo *) NULL);
    }
  return(convolve_info);
}