--- OpenCL/gengetinfo 2012/04/19 14:34:56 1.8 +++ OpenCL/gengetinfo 2012/05/05 15:43:02 1.19 @@ -20,10 +20,12 @@ program_build Program kernel Kernel kernel_work_group Kernel + kernel_arg_info Kernel command_queue Queue ); my %typemap = ( + # getinfo.txt c type, constructor, pod cl_bool => ['cl_bool', 'value [i] ? &PL_sv_yes : &PL_sv_no', 'boolean'], #char => ['char', 'newSVpvn (value, size)', 'string'], char => ['char', 'newSVpv (value, 0)', 'string'], # all these are 0-terminated strings, and the driver often appends a \0 @@ -37,8 +39,23 @@ Program => ['cl_program', 'OpenCL::Program', 'program'], CommandQueue => ['cl_command_queue', 'OpenCL::Queue', 'queue'], cl_context_properties => ['cl_context_properties', 'newSVuv ((UV)value [i])', 'property_int'], + cl_program_binary_type => ['cl_program_binary_type', 'newSVuv ((UV)value [i])', 'binary_type'], ); + +# try to re-use types with same representation in C - if we +# ever overload bitfields etc. then we need to remove all +# typesimplify code. +my %typesimplify; +{ + open my $h, ") { + $typesimplify{$2} = $1 + if /typedef\s+(cl_\S+)\s+(cl_\S+);/; + } +} + { my %tmap = ( T_IV => "newSViv (value [i])", @@ -79,7 +96,7 @@ rename "$file~", $file; } -for my $CLASS (qw(platform device context command_queue mem image sampler program program_build kernel kernel_work_group event profiling gl_texture)) { +for my $CLASS (qw(platform device context command_queue mem image sampler program program_build kernel kernel_work_group kernel_arg event profiling gl_texture)) { open my $fh, ") { chomp; - my ($class, $name, $ctype) = split /,\s*/, $_, 3; + my ($class, $name, $ctype) = split /\s*,\s*/, $_, 3; next unless $class eq "cl_$CLASS\_info"; next if $name eq "CL_IMAGE_FORMAT"; # struct next if $name eq "CL_PROGRAM_BINARIES"; # needs multiple calls @@ -99,7 +116,7 @@ my $cbase = $class; $cbase =~ s/_(.)/\U$1/g; - $cbase =~ s/_Gl_/_GL/g; + $cbase =~ s/Gl(?=[A-Z])/GL/g; $cbase =~ s/^cl//; $cbase =~ s/Info$//; $cbase = "MemObject" if $cbase eq "Mem"; @@ -108,6 +125,7 @@ my $real_class = $CLASS; $real_class = "program" if $real_class eq "program_build"; $real_class = "kernel" if $real_class eq "kernel_work_group"; + $real_class = "kernel" if $real_class eq "kernel_arg"; $real_class = "event" if $real_class eq "profiling"; my $perl_name = lc $name; @@ -125,6 +143,12 @@ $extra_xs_args = ', OpenCL::Device device'; } + if ($CLASS eq "kernel_arg") { + $extra_args = ', idx'; + $extra_perl_args = ' ($idx)'; + $extra_xs_args = ', cl_uint idx'; + } + my $dynamic; my $nelem = "size / sizeof (*value)"; @@ -156,7 +180,9 @@ $perltype = "\$$perltype"; } - $POD .= "=item $perltype = \$$real_class->$perl_name$extra_perl_args\n\nCalls C with C<$name> and returns the result.\n\n"; + (my $perlenum = $name) =~ s/^CL_/OpenCL::/ or die; + + $POD .= "=item $perltype = \$$real_class->$perl_name$extra_perl_args\n\nCalls C with C<$perlenum> and returns the result.\n\n"; # XS1 contains the function before ALIAS, XS2 the function afterwards (the body) # after we generate the bdoy we look for an identical body generated earlier @@ -167,13 +193,16 @@ . "XXXNAMEXXX (OpenCL::$classmap{$real_class} self$extra_xs_args)\n"; $XS2 = " PPCODE:\n"; + my $stype = $type->[0]; # simplified type + $stype = $typesimplify{$stype} while exists $typesimplify{$stype}; + if ($dynamic) { $XS2 .= " size_t size;\n" . " NEED_SUCCESS (Get${cbase}Info, (self$extra_args, ix, 0, 0, &size));\n" - . " $type->[0] *value = tmpbuf (size);\n" + . " $stype *value = tmpbuf (size);\n" . " NEED_SUCCESS (Get${cbase}Info, (self$extra_args, ix, size, value, 0));\n"; } else { - $XS2 .= " $type->[0] value [1];\n" + $XS2 .= " $stype value [1];\n" . " NEED_SUCCESS (Get${cbase}Info, (self$extra_args, ix, sizeof (value), value, 0));\n"; } @@ -191,10 +220,12 @@ $oclass = "MemObject" if $oclass eq "Memory"; $oclass = "CommandQueue" if $oclass eq "Queue"; - $XS2 .= " {\n"; - $XS2 .= " NEED_SUCCESS (Retain$oclass, (value [i]));\n" unless $1 eq "Platform" || $1 eq "Device"; - $XS2 .= " PUSHs (NEW_MORTAL_OBJ (\"$type->[1]\", value [i]));\n"; - $XS2 .= " }\n"; + my $stash = lc $type->[1]; + $stash =~ s/opencl:://; + $stash =~ s/::/_/g; + + $XS2 .= " NEED_SUCCESS (Retain$oclass, (value [i]));\n" unless $oclass eq "Platform" || $oclass eq "Device"; + $XS2 .= " PUSH_CLOBJ (stash_$stash, value [i]);\n"; } else { $XS2 .= " PUSHs (sv_2mortal ($type->[1]));\n"; } @@ -219,7 +250,7 @@ $_->[2] =~ s/\bix\b/$_->[1][0][1]/g; $_->[1] = ""; } else { - $_->[1] = " ALIAS:\n" . join "", map " $_->[0] = $_->[1]\n", @{ $_->[1] }; + $_->[1] = " ALIAS:\n" . join "", sort, map " $_->[0] = $_->[1]\n", @{ $_->[1] }; } $XS .= join "", @$_; }