diff options
Diffstat (limited to 'src/gallium/state_trackers/clover')
69 files changed, 0 insertions, 15449 deletions
diff --git a/src/gallium/state_trackers/clover/Doxyfile b/src/gallium/state_trackers/clover/Doxyfile deleted file mode 100644 index 19337bbd656..00000000000 --- a/src/gallium/state_trackers/clover/Doxyfile +++ /dev/null @@ -1,1716 +0,0 @@ -# Doxyfile 1.7.4 - -# This file describes the settings to be used by the documentation system -# doxygen (www.doxygen.org) for a project. -# -# All text after a hash (#) is considered a comment and will be ignored. -# The format is: -# TAG = value [value, ...] -# For lists items can also be appended using: -# TAG += value [value, ...] -# Values that contain spaces should be placed between quotes (" "). - -#--------------------------------------------------------------------------- -# Project related configuration options -#--------------------------------------------------------------------------- - -# This tag specifies the encoding used for all characters in the config file -# that follow. The default is UTF-8 which is also the encoding used for all -# text before the first occurrence of this tag. Doxygen uses libiconv (or the -# iconv built into libc) for the transcoding. See -# http://www.gnu.org/software/libiconv for the list of possible encodings. - -DOXYFILE_ENCODING = UTF-8 - -# The PROJECT_NAME tag is a single word (or a sequence of words surrounded -# by quotes) that should identify the project. - -PROJECT_NAME = Clover - -# The PROJECT_NUMBER tag can be used to enter a project or revision number. -# This could be handy for archiving the generated documentation or -# if some version control system is used. - -PROJECT_NUMBER = - -# Using the PROJECT_BRIEF tag one can provide an optional one line description -# for a project that appears at the top of each page and should give viewer -# a quick idea about the purpose of the project. Keep the description short. - -PROJECT_BRIEF = - -# With the PROJECT_LOGO tag one can specify an logo or icon that is -# included in the documentation. The maximum height of the logo should not -# exceed 55 pixels and the maximum width should not exceed 200 pixels. -# Doxygen will copy the logo to the output directory. - -PROJECT_LOGO = - -# The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute) -# base path where the generated documentation will be put. -# If a relative path is entered, it will be relative to the location -# where doxygen was started. If left blank the current directory will be used. - -OUTPUT_DIRECTORY = - -# If the CREATE_SUBDIRS tag is set to YES, then doxygen will create -# 4096 sub-directories (in 2 levels) under the output directory of each output -# format and will distribute the generated files over these directories. -# Enabling this option can be useful when feeding doxygen a huge amount of -# source files, where putting all generated files in the same directory would -# otherwise cause performance problems for the file system. - -CREATE_SUBDIRS = NO - -# The OUTPUT_LANGUAGE tag is used to specify the language in which all -# documentation generated by doxygen is written. Doxygen will use this -# information to generate all constant output in the proper language. -# The default language is English, other supported languages are: -# Afrikaans, Arabic, Brazilian, Catalan, Chinese, Chinese-Traditional, -# Croatian, Czech, Danish, Dutch, Esperanto, Farsi, Finnish, French, German, -# Greek, Hungarian, Italian, Japanese, Japanese-en (Japanese with English -# messages), Korean, Korean-en, Lithuanian, Norwegian, Macedonian, Persian, -# Polish, Portuguese, Romanian, Russian, Serbian, Serbian-Cyrillic, Slovak, -# Slovene, Spanish, Swedish, Ukrainian, and Vietnamese. - -OUTPUT_LANGUAGE = English - -# If the BRIEF_MEMBER_DESC tag is set to YES (the default) Doxygen will -# include brief member descriptions after the members that are listed in -# the file and class documentation (similar to JavaDoc). -# Set to NO to disable this. - -BRIEF_MEMBER_DESC = YES - -# If the REPEAT_BRIEF tag is set to YES (the default) Doxygen will prepend -# the brief description of a member or function before the detailed description. -# Note: if both HIDE_UNDOC_MEMBERS and BRIEF_MEMBER_DESC are set to NO, the -# brief descriptions will be completely suppressed. - -REPEAT_BRIEF = YES - -# This tag implements a quasi-intelligent brief description abbreviator -# that is used to form the text in various listings. Each string -# in this list, if found as the leading text of the brief description, will be -# stripped from the text and the result after processing the whole list, is -# used as the annotated text. Otherwise, the brief description is used as-is. -# If left blank, the following values are used ("$name" is automatically -# replaced with the name of the entity): "The $name class" "The $name widget" -# "The $name file" "is" "provides" "specifies" "contains" -# "represents" "a" "an" "the" - -ABBREVIATE_BRIEF = - -# If the ALWAYS_DETAILED_SEC and REPEAT_BRIEF tags are both set to YES then -# Doxygen will generate a detailed section even if there is only a brief -# description. - -ALWAYS_DETAILED_SEC = NO - -# If the INLINE_INHERITED_MEMB tag is set to YES, doxygen will show all -# inherited members of a class in the documentation of that class as if those -# members were ordinary class members. Constructors, destructors and assignment -# operators of the base classes will not be shown. - -INLINE_INHERITED_MEMB = NO - -# If the FULL_PATH_NAMES tag is set to YES then Doxygen will prepend the full -# path before files name in the file list and in the header files. If set -# to NO the shortest path that makes the file name unique will be used. - -FULL_PATH_NAMES = YES - -# If the FULL_PATH_NAMES tag is set to YES then the STRIP_FROM_PATH tag -# can be used to strip a user-defined part of the path. Stripping is -# only done if one of the specified strings matches the left-hand part of -# the path. The tag can be used to show relative paths in the file list. -# If left blank the directory from which doxygen is run is used as the -# path to strip. - -STRIP_FROM_PATH = - -# The STRIP_FROM_INC_PATH tag can be used to strip a user-defined part of -# the path mentioned in the documentation of a class, which tells -# the reader which header file to include in order to use a class. -# If left blank only the name of the header file containing the class -# definition is used. Otherwise one should specify the include paths that -# are normally passed to the compiler using the -I flag. - -STRIP_FROM_INC_PATH = - -# If the SHORT_NAMES tag is set to YES, doxygen will generate much shorter -# (but less readable) file names. This can be useful if your file system -# doesn't support long names like on DOS, Mac, or CD-ROM. - -SHORT_NAMES = NO - -# If the JAVADOC_AUTOBRIEF tag is set to YES then Doxygen -# will interpret the first line (until the first dot) of a JavaDoc-style -# comment as the brief description. If set to NO, the JavaDoc -# comments will behave just like regular Qt-style comments -# (thus requiring an explicit @brief command for a brief description.) - -JAVADOC_AUTOBRIEF = YES - -# If the QT_AUTOBRIEF tag is set to YES then Doxygen will -# interpret the first line (until the first dot) of a Qt-style -# comment as the brief description. If set to NO, the comments -# will behave just like regular Qt-style comments (thus requiring -# an explicit \brief command for a brief description.) - -QT_AUTOBRIEF = NO - -# The MULTILINE_CPP_IS_BRIEF tag can be set to YES to make Doxygen -# treat a multi-line C++ special comment block (i.e. a block of //! or /// -# comments) as a brief description. This used to be the default behaviour. -# The new default is to treat a multi-line C++ comment block as a detailed -# description. Set this tag to YES if you prefer the old behaviour instead. - -MULTILINE_CPP_IS_BRIEF = NO - -# If the INHERIT_DOCS tag is set to YES (the default) then an undocumented -# member inherits the documentation from any documented member that it -# re-implements. - -INHERIT_DOCS = YES - -# If the SEPARATE_MEMBER_PAGES tag is set to YES, then doxygen will produce -# a new page for each member. If set to NO, the documentation of a member will -# be part of the file/class/namespace that contains it. - -SEPARATE_MEMBER_PAGES = NO - -# The TAB_SIZE tag can be used to set the number of spaces in a tab. -# Doxygen uses this value to replace tabs by spaces in code fragments. - -TAB_SIZE = 8 - -# This tag can be used to specify a number of aliases that acts -# as commands in the documentation. An alias has the form "name=value". -# For example adding "sideeffect=\par Side Effects:\n" will allow you to -# put the command \sideeffect (or @sideeffect) in the documentation, which -# will result in a user-defined paragraph with heading "Side Effects:". -# You can put \n's in the value part of an alias to insert newlines. - -ALIASES = - -# Set the OPTIMIZE_OUTPUT_FOR_C tag to YES if your project consists of C -# sources only. Doxygen will then generate output that is more tailored for C. -# For instance, some of the names that are used will be different. The list -# of all members will be omitted, etc. - -OPTIMIZE_OUTPUT_FOR_C = NO - -# Set the OPTIMIZE_OUTPUT_JAVA tag to YES if your project consists of Java -# sources only. Doxygen will then generate output that is more tailored for -# Java. For instance, namespaces will be presented as packages, qualified -# scopes will look different, etc. - -OPTIMIZE_OUTPUT_JAVA = NO - -# Set the OPTIMIZE_FOR_FORTRAN tag to YES if your project consists of Fortran -# sources only. Doxygen will then generate output that is more tailored for -# Fortran. - -OPTIMIZE_FOR_FORTRAN = NO - -# Set the OPTIMIZE_OUTPUT_VHDL tag to YES if your project consists of VHDL -# sources. Doxygen will then generate output that is tailored for -# VHDL. - -OPTIMIZE_OUTPUT_VHDL = NO - -# Doxygen selects the parser to use depending on the extension of the files it -# parses. With this tag you can assign which parser to use for a given extension. -# Doxygen has a built-in mapping, but you can override or extend it using this -# tag. The format is ext=language, where ext is a file extension, and language -# is one of the parsers supported by doxygen: IDL, Java, Javascript, CSharp, C, -# C++, D, PHP, Objective-C, Python, Fortran, VHDL, C, C++. For instance to make -# doxygen treat .inc files as Fortran files (default is PHP), and .f files as C -# (default is Fortran), use: inc=Fortran f=C. Note that for custom extensions -# you also need to set FILE_PATTERNS otherwise the files are not read by doxygen. - -EXTENSION_MAPPING = - -# If you use STL classes (i.e. std::string, std::vector, etc.) but do not want -# to include (a tag file for) the STL sources as input, then you should -# set this tag to YES in order to let doxygen match functions declarations and -# definitions whose arguments contain STL classes (e.g. func(std::string); v.s. -# func(std::string) {}). This also makes the inheritance and collaboration -# diagrams that involve STL classes more complete and accurate. - -BUILTIN_STL_SUPPORT = YES - -# If you use Microsoft's C++/CLI language, you should set this option to YES to -# enable parsing support. - -CPP_CLI_SUPPORT = NO - -# Set the SIP_SUPPORT tag to YES if your project consists of sip sources only. -# Doxygen will parse them like normal C++ but will assume all classes use public -# instead of private inheritance when no explicit protection keyword is present. - -SIP_SUPPORT = NO - -# For Microsoft's IDL there are propget and propput attributes to indicate getter -# and setter methods for a property. Setting this option to YES (the default) -# will make doxygen replace the get and set methods by a property in the -# documentation. This will only work if the methods are indeed getting or -# setting a simple type. If this is not the case, or you want to show the -# methods anyway, you should set this option to NO. - -IDL_PROPERTY_SUPPORT = YES - -# If member grouping is used in the documentation and the DISTRIBUTE_GROUP_DOC -# tag is set to YES, then doxygen will reuse the documentation of the first -# member in the group (if any) for the other members of the group. By default -# all members of a group must be documented explicitly. - -DISTRIBUTE_GROUP_DOC = NO - -# Set the SUBGROUPING tag to YES (the default) to allow class member groups of -# the same type (for instance a group of public functions) to be put as a -# subgroup of that type (e.g. under the Public Functions section). Set it to -# NO to prevent subgrouping. Alternatively, this can be done per class using -# the \nosubgrouping command. - -SUBGROUPING = YES - -# When the INLINE_GROUPED_CLASSES tag is set to YES, classes, structs and -# unions are shown inside the group in which they are included (e.g. using -# @ingroup) instead of on a separate page (for HTML and Man pages) or -# section (for LaTeX and RTF). - -INLINE_GROUPED_CLASSES = NO - -# When TYPEDEF_HIDES_STRUCT is enabled, a typedef of a struct, union, or enum -# is documented as struct, union, or enum with the name of the typedef. So -# typedef struct TypeS {} TypeT, will appear in the documentation as a struct -# with name TypeT. When disabled the typedef will appear as a member of a file, -# namespace, or class. And the struct will be named TypeS. This can typically -# be useful for C code in case the coding convention dictates that all compound -# types are typedef'ed and only the typedef is referenced, never the tag name. - -TYPEDEF_HIDES_STRUCT = NO - -# The SYMBOL_CACHE_SIZE determines the size of the internal cache use to -# determine which symbols to keep in memory and which to flush to disk. -# When the cache is full, less often used symbols will be written to disk. -# For small to medium size projects (<1000 input files) the default value is -# probably good enough. For larger projects a too small cache size can cause -# doxygen to be busy swapping symbols to and from disk most of the time -# causing a significant performance penalty. -# If the system has enough physical memory increasing the cache will improve the -# performance by keeping more symbols in memory. Note that the value works on -# a logarithmic scale so increasing the size by one will roughly double the -# memory usage. The cache size is given by this formula: -# 2^(16+SYMBOL_CACHE_SIZE). The valid range is 0..9, the default is 0, -# corresponding to a cache size of 2^16 = 65536 symbols - -SYMBOL_CACHE_SIZE = 0 - -#--------------------------------------------------------------------------- -# Build related configuration options -#--------------------------------------------------------------------------- - -# If the EXTRACT_ALL tag is set to YES doxygen will assume all entities in -# documentation are documented, even if no documentation was available. -# Private class members and static file members will be hidden unless -# the EXTRACT_PRIVATE and EXTRACT_STATIC tags are set to YES - -EXTRACT_ALL = NO - -# If the EXTRACT_PRIVATE tag is set to YES all private members of a class -# will be included in the documentation. - -EXTRACT_PRIVATE = NO - -# If the EXTRACT_STATIC tag is set to YES all static members of a file -# will be included in the documentation. - -EXTRACT_STATIC = NO - -# If the EXTRACT_LOCAL_CLASSES tag is set to YES classes (and structs) -# defined locally in source files will be included in the documentation. -# If set to NO only classes defined in header files are included. - -EXTRACT_LOCAL_CLASSES = YES - -# This flag is only useful for Objective-C code. When set to YES local -# methods, which are defined in the implementation section but not in -# the interface are included in the documentation. -# If set to NO (the default) only methods in the interface are included. - -EXTRACT_LOCAL_METHODS = NO - -# If this flag is set to YES, the members of anonymous namespaces will be -# extracted and appear in the documentation as a namespace called -# 'anonymous_namespace{file}', where file will be replaced with the base -# name of the file that contains the anonymous namespace. By default -# anonymous namespaces are hidden. - -EXTRACT_ANON_NSPACES = YES - -# If the HIDE_UNDOC_MEMBERS tag is set to YES, Doxygen will hide all -# undocumented members of documented classes, files or namespaces. -# If set to NO (the default) these members will be included in the -# various overviews, but no documentation section is generated. -# This option has no effect if EXTRACT_ALL is enabled. - -HIDE_UNDOC_MEMBERS = NO - -# If the HIDE_UNDOC_CLASSES tag is set to YES, Doxygen will hide all -# undocumented classes that are normally visible in the class hierarchy. -# If set to NO (the default) these classes will be included in the various -# overviews. This option has no effect if EXTRACT_ALL is enabled. - -HIDE_UNDOC_CLASSES = NO - -# If the HIDE_FRIEND_COMPOUNDS tag is set to YES, Doxygen will hide all -# friend (class|struct|union) declarations. -# If set to NO (the default) these declarations will be included in the -# documentation. - -HIDE_FRIEND_COMPOUNDS = NO - -# If the HIDE_IN_BODY_DOCS tag is set to YES, Doxygen will hide any -# documentation blocks found inside the body of a function. -# If set to NO (the default) these blocks will be appended to the -# function's detailed documentation block. - -HIDE_IN_BODY_DOCS = NO - -# The INTERNAL_DOCS tag determines if documentation -# that is typed after a \internal command is included. If the tag is set -# to NO (the default) then the documentation will be excluded. -# Set it to YES to include the internal documentation. - -INTERNAL_DOCS = NO - -# If the CASE_SENSE_NAMES tag is set to NO then Doxygen will only generate -# file names in lower-case letters. If set to YES upper-case letters are also -# allowed. This is useful if you have classes or files whose names only differ -# in case and if your file system supports case sensitive file names. Windows -# and Mac users are advised to set this option to NO. - -CASE_SENSE_NAMES = YES - -# If the HIDE_SCOPE_NAMES tag is set to NO (the default) then Doxygen -# will show members with their full class and namespace scopes in the -# documentation. If set to YES the scope will be hidden. - -HIDE_SCOPE_NAMES = NO - -# If the SHOW_INCLUDE_FILES tag is set to YES (the default) then Doxygen -# will put a list of the files that are included by a file in the documentation -# of that file. - -SHOW_INCLUDE_FILES = YES - -# If the FORCE_LOCAL_INCLUDES tag is set to YES then Doxygen -# will list include files with double quotes in the documentation -# rather than with sharp brackets. - -FORCE_LOCAL_INCLUDES = NO - -# If the INLINE_INFO tag is set to YES (the default) then a tag [inline] -# is inserted in the documentation for inline members. - -INLINE_INFO = YES - -# If the SORT_MEMBER_DOCS tag is set to YES (the default) then doxygen -# will sort the (detailed) documentation of file and class members -# alphabetically by member name. If set to NO the members will appear in -# declaration order. - -SORT_MEMBER_DOCS = YES - -# If the SORT_BRIEF_DOCS tag is set to YES then doxygen will sort the -# brief documentation of file, namespace and class members alphabetically -# by member name. If set to NO (the default) the members will appear in -# declaration order. - -SORT_BRIEF_DOCS = NO - -# If the SORT_MEMBERS_CTORS_1ST tag is set to YES then doxygen -# will sort the (brief and detailed) documentation of class members so that -# constructors and destructors are listed first. If set to NO (the default) -# the constructors will appear in the respective orders defined by -# SORT_MEMBER_DOCS and SORT_BRIEF_DOCS. -# This tag will be ignored for brief docs if SORT_BRIEF_DOCS is set to NO -# and ignored for detailed docs if SORT_MEMBER_DOCS is set to NO. - -SORT_MEMBERS_CTORS_1ST = NO - -# If the SORT_GROUP_NAMES tag is set to YES then doxygen will sort the -# hierarchy of group names into alphabetical order. If set to NO (the default) -# the group names will appear in their defined order. - -SORT_GROUP_NAMES = NO - -# If the SORT_BY_SCOPE_NAME tag is set to YES, the class list will be -# sorted by fully-qualified names, including namespaces. If set to -# NO (the default), the class list will be sorted only by class name, -# not including the namespace part. -# Note: This option is not very useful if HIDE_SCOPE_NAMES is set to YES. -# Note: This option applies only to the class list, not to the -# alphabetical list. - -SORT_BY_SCOPE_NAME = NO - -# If the STRICT_PROTO_MATCHING option is enabled and doxygen fails to -# do proper type resolution of all parameters of a function it will reject a -# match between the prototype and the implementation of a member function even -# if there is only one candidate or it is obvious which candidate to choose -# by doing a simple string match. By disabling STRICT_PROTO_MATCHING doxygen -# will still accept a match between prototype and implementation in such cases. - -STRICT_PROTO_MATCHING = NO - -# The GENERATE_TODOLIST tag can be used to enable (YES) or -# disable (NO) the todo list. This list is created by putting \todo -# commands in the documentation. - -GENERATE_TODOLIST = YES - -# The GENERATE_TESTLIST tag can be used to enable (YES) or -# disable (NO) the test list. This list is created by putting \test -# commands in the documentation. - -GENERATE_TESTLIST = YES - -# The GENERATE_BUGLIST tag can be used to enable (YES) or -# disable (NO) the bug list. This list is created by putting \bug -# commands in the documentation. - -GENERATE_BUGLIST = YES - -# The GENERATE_DEPRECATEDLIST tag can be used to enable (YES) or -# disable (NO) the deprecated list. This list is created by putting -# \deprecated commands in the documentation. - -GENERATE_DEPRECATEDLIST= YES - -# The ENABLED_SECTIONS tag can be used to enable conditional -# documentation sections, marked by \if sectionname ... \endif. - -ENABLED_SECTIONS = - -# The MAX_INITIALIZER_LINES tag determines the maximum number of lines -# the initial value of a variable or macro consists of for it to appear in -# the documentation. If the initializer consists of more lines than specified -# here it will be hidden. Use a value of 0 to hide initializers completely. -# The appearance of the initializer of individual variables and macros in the -# documentation can be controlled using \showinitializer or \hideinitializer -# command in the documentation regardless of this setting. - -MAX_INITIALIZER_LINES = 30 - -# Set the SHOW_USED_FILES tag to NO to disable the list of files generated -# at the bottom of the documentation of classes and structs. If set to YES the -# list will mention the files that were used to generate the documentation. - -SHOW_USED_FILES = YES - -# If the sources in your project are distributed over multiple directories -# then setting the SHOW_DIRECTORIES tag to YES will show the directory hierarchy -# in the documentation. The default is NO. - -SHOW_DIRECTORIES = NO - -# Set the SHOW_FILES tag to NO to disable the generation of the Files page. -# This will remove the Files entry from the Quick Index and from the -# Folder Tree View (if specified). The default is YES. - -SHOW_FILES = YES - -# Set the SHOW_NAMESPACES tag to NO to disable the generation of the -# Namespaces page. -# This will remove the Namespaces entry from the Quick Index -# and from the Folder Tree View (if specified). The default is YES. - -SHOW_NAMESPACES = YES - -# The FILE_VERSION_FILTER tag can be used to specify a program or script that -# doxygen should invoke to get the current version for each file (typically from -# the version control system). Doxygen will invoke the program by executing (via -# popen()) the command <command> <input-file>, where <command> is the value of -# the FILE_VERSION_FILTER tag, and <input-file> is the name of an input file -# provided by doxygen. Whatever the program writes to standard output -# is used as the file version. See the manual for examples. - -FILE_VERSION_FILTER = - -# The LAYOUT_FILE tag can be used to specify a layout file which will be parsed -# by doxygen. The layout file controls the global structure of the generated -# output files in an output format independent way. The create the layout file -# that represents doxygen's defaults, run doxygen with the -l option. -# You can optionally specify a file name after the option, if omitted -# DoxygenLayout.xml will be used as the name of the layout file. - -LAYOUT_FILE = - -#--------------------------------------------------------------------------- -# configuration options related to warning and progress messages -#--------------------------------------------------------------------------- - -# The QUIET tag can be used to turn on/off the messages that are generated -# by doxygen. Possible values are YES and NO. If left blank NO is used. - -QUIET = NO - -# The WARNINGS tag can be used to turn on/off the warning messages that are -# generated by doxygen. Possible values are YES and NO. If left blank -# NO is used. - -WARNINGS = YES - -# If WARN_IF_UNDOCUMENTED is set to YES, then doxygen will generate warnings -# for undocumented members. If EXTRACT_ALL is set to YES then this flag will -# automatically be disabled. - -WARN_IF_UNDOCUMENTED = NO - -# If WARN_IF_DOC_ERROR is set to YES, doxygen will generate warnings for -# potential errors in the documentation, such as not documenting some -# parameters in a documented function, or documenting parameters that -# don't exist or using markup commands wrongly. - -WARN_IF_DOC_ERROR = YES - -# The WARN_NO_PARAMDOC option can be enabled to get warnings for -# functions that are documented, but have no documentation for their parameters -# or return value. If set to NO (the default) doxygen will only warn about -# wrong or incomplete parameter documentation, but not about the absence of -# documentation. - -WARN_NO_PARAMDOC = NO - -# The WARN_FORMAT tag determines the format of the warning messages that -# doxygen can produce. The string should contain the $file, $line, and $text -# tags, which will be replaced by the file and line number from which the -# warning originated and the warning text. Optionally the format may contain -# $version, which will be replaced by the version of the file (if it could -# be obtained via FILE_VERSION_FILTER) - -WARN_FORMAT = "$file:$line: $text" - -# The WARN_LOGFILE tag can be used to specify a file to which warning -# and error messages should be written. If left blank the output is written -# to stderr. - -WARN_LOGFILE = - -#--------------------------------------------------------------------------- -# configuration options related to the input files -#--------------------------------------------------------------------------- - -# The INPUT tag can be used to specify the files and/or directories that contain -# documented source files. You may enter file names like "myfile.cpp" or -# directories like "/usr/src/myproject". Separate the files or directories -# with spaces. - -INPUT = api/ core/ util/ - -# This tag can be used to specify the character encoding of the source files -# that doxygen parses. Internally doxygen uses the UTF-8 encoding, which is -# also the default input encoding. Doxygen uses libiconv (or the iconv built -# into libc) for the transcoding. See http://www.gnu.org/software/libiconv for -# the list of possible encodings. - -INPUT_ENCODING = UTF-8 - -# If the value of the INPUT tag contains directories, you can use the -# FILE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp -# and *.h) to filter out the source-files in the directories. If left -# blank the following patterns are tested: -# *.c *.cc *.cxx *.cpp *.c++ *.d *.java *.ii *.ixx *.ipp *.i++ *.inl *.h *.hh -# *.hxx *.hpp *.h++ *.idl *.odl *.cs *.php *.php3 *.inc *.m *.mm *.dox *.py -# *.f90 *.f *.for *.vhd *.vhdl - -FILE_PATTERNS = - -# The RECURSIVE tag can be used to turn specify whether or not subdirectories -# should be searched for input files as well. Possible values are YES and NO. -# If left blank NO is used. - -RECURSIVE = NO - -# The EXCLUDE tag can be used to specify files and/or directories that should -# excluded from the INPUT source files. This way you can easily exclude a -# subdirectory from a directory tree whose root is specified with the INPUT tag. - -EXCLUDE = - -# The EXCLUDE_SYMLINKS tag can be used select whether or not files or -# directories that are symbolic links (a Unix file system feature) are excluded -# from the input. - -EXCLUDE_SYMLINKS = NO - -# If the value of the INPUT tag contains directories, you can use the -# EXCLUDE_PATTERNS tag to specify one or more wildcard patterns to exclude -# certain files from those directories. Note that the wildcards are matched -# against the file with absolute path, so to exclude all test directories -# for example use the pattern */test/* - -EXCLUDE_PATTERNS = - -# The EXCLUDE_SYMBOLS tag can be used to specify one or more symbol names -# (namespaces, classes, functions, etc.) that should be excluded from the -# output. The symbol name can be a fully qualified name, a word, or if the -# wildcard * is used, a substring. Examples: ANamespace, AClass, -# AClass::ANamespace, ANamespace::*Test - -EXCLUDE_SYMBOLS = - -# The EXAMPLE_PATH tag can be used to specify one or more files or -# directories that contain example code fragments that are included (see -# the \include command). - -EXAMPLE_PATH = - -# If the value of the EXAMPLE_PATH tag contains directories, you can use the -# EXAMPLE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp -# and *.h) to filter out the source-files in the directories. If left -# blank all files are included. - -EXAMPLE_PATTERNS = - -# If the EXAMPLE_RECURSIVE tag is set to YES then subdirectories will be -# searched for input files to be used with the \include or \dontinclude -# commands irrespective of the value of the RECURSIVE tag. -# Possible values are YES and NO. If left blank NO is used. - -EXAMPLE_RECURSIVE = NO - -# The IMAGE_PATH tag can be used to specify one or more files or -# directories that contain image that are included in the documentation (see -# the \image command). - -IMAGE_PATH = - -# The INPUT_FILTER tag can be used to specify a program that doxygen should -# invoke to filter for each input file. Doxygen will invoke the filter program -# by executing (via popen()) the command <filter> <input-file>, where <filter> -# is the value of the INPUT_FILTER tag, and <input-file> is the name of an -# input file. Doxygen will then use the output that the filter program writes -# to standard output. -# If FILTER_PATTERNS is specified, this tag will be -# ignored. - -INPUT_FILTER = - -# The FILTER_PATTERNS tag can be used to specify filters on a per file pattern -# basis. -# Doxygen will compare the file name with each pattern and apply the -# filter if there is a match. -# The filters are a list of the form: -# pattern=filter (like *.cpp=my_cpp_filter). See INPUT_FILTER for further -# info on how filters are used. If FILTER_PATTERNS is empty or if -# non of the patterns match the file name, INPUT_FILTER is applied. - -FILTER_PATTERNS = - -# If the FILTER_SOURCE_FILES tag is set to YES, the input filter (if set using -# INPUT_FILTER) will be used to filter the input files when producing source -# files to browse (i.e. when SOURCE_BROWSER is set to YES). - -FILTER_SOURCE_FILES = NO - -# The FILTER_SOURCE_PATTERNS tag can be used to specify source filters per file -# pattern. A pattern will override the setting for FILTER_PATTERN (if any) -# and it is also possible to disable source filtering for a specific pattern -# using *.ext= (so without naming a filter). This option only has effect when -# FILTER_SOURCE_FILES is enabled. - -FILTER_SOURCE_PATTERNS = - -#--------------------------------------------------------------------------- -# configuration options related to source browsing -#--------------------------------------------------------------------------- - -# If the SOURCE_BROWSER tag is set to YES then a list of source files will -# be generated. Documented entities will be cross-referenced with these sources. -# Note: To get rid of all source code in the generated output, make sure also -# VERBATIM_HEADERS is set to NO. - -SOURCE_BROWSER = NO - -# Setting the INLINE_SOURCES tag to YES will include the body -# of functions and classes directly in the documentation. - -INLINE_SOURCES = NO - -# Setting the STRIP_CODE_COMMENTS tag to YES (the default) will instruct -# doxygen to hide any special comment blocks from generated source code -# fragments. Normal C and C++ comments will always remain visible. - -STRIP_CODE_COMMENTS = YES - -# If the REFERENCED_BY_RELATION tag is set to YES -# then for each documented function all documented -# functions referencing it will be listed. - -REFERENCED_BY_RELATION = NO - -# If the REFERENCES_RELATION tag is set to YES -# then for each documented function all documented entities -# called/used by that function will be listed. - -REFERENCES_RELATION = NO - -# If the REFERENCES_LINK_SOURCE tag is set to YES (the default) -# and SOURCE_BROWSER tag is set to YES, then the hyperlinks from -# functions in REFERENCES_RELATION and REFERENCED_BY_RELATION lists will -# link to the source code. -# Otherwise they will link to the documentation. - -REFERENCES_LINK_SOURCE = YES - -# If the USE_HTAGS tag is set to YES then the references to source code -# will point to the HTML generated by the htags(1) tool instead of doxygen -# built-in source browser. The htags tool is part of GNU's global source -# tagging system (see http://www.gnu.org/software/global/global.html). You -# will need version 4.8.6 or higher. - -USE_HTAGS = NO - -# If the VERBATIM_HEADERS tag is set to YES (the default) then Doxygen -# will generate a verbatim copy of the header file for each class for -# which an include is specified. Set to NO to disable this. - -VERBATIM_HEADERS = YES - -#--------------------------------------------------------------------------- -# configuration options related to the alphabetical class index -#--------------------------------------------------------------------------- - -# If the ALPHABETICAL_INDEX tag is set to YES, an alphabetical index -# of all compounds will be generated. Enable this if the project -# contains a lot of classes, structs, unions or interfaces. - -ALPHABETICAL_INDEX = YES - -# If the alphabetical index is enabled (see ALPHABETICAL_INDEX) then -# the COLS_IN_ALPHA_INDEX tag can be used to specify the number of columns -# in which this list will be split (can be a number in the range [1..20]) - -COLS_IN_ALPHA_INDEX = 5 - -# In case all classes in a project start with a common prefix, all -# classes will be put under the same header in the alphabetical index. -# The IGNORE_PREFIX tag can be used to specify one or more prefixes that -# should be ignored while generating the index headers. - -IGNORE_PREFIX = - -#--------------------------------------------------------------------------- -# configuration options related to the HTML output -#--------------------------------------------------------------------------- - -# If the GENERATE_HTML tag is set to YES (the default) Doxygen will -# generate HTML output. - -GENERATE_HTML = YES - -# The HTML_OUTPUT tag is used to specify where the HTML docs will be put. -# If a relative path is entered the value of OUTPUT_DIRECTORY will be -# put in front of it. If left blank `html' will be used as the default path. - -HTML_OUTPUT = html - -# The HTML_FILE_EXTENSION tag can be used to specify the file extension for -# each generated HTML page (for example: .htm,.php,.asp). If it is left blank -# doxygen will generate files with .html extension. - -HTML_FILE_EXTENSION = .html - -# The HTML_HEADER tag can be used to specify a personal HTML header for -# each generated HTML page. If it is left blank doxygen will generate a -# standard header. Note that when using a custom header you are responsible -# for the proper inclusion of any scripts and style sheets that doxygen -# needs, which is dependent on the configuration options used. -# It is adviced to generate a default header using "doxygen -w html -# header.html footer.html stylesheet.css YourConfigFile" and then modify -# that header. Note that the header is subject to change so you typically -# have to redo this when upgrading to a newer version of doxygen or when changing the value of configuration settings such as GENERATE_TREEVIEW! - -HTML_HEADER = - -# The HTML_FOOTER tag can be used to specify a personal HTML footer for -# each generated HTML page. If it is left blank doxygen will generate a -# standard footer. - -HTML_FOOTER = - -# The HTML_STYLESHEET tag can be used to specify a user-defined cascading -# style sheet that is used by each HTML page. It can be used to -# fine-tune the look of the HTML output. If the tag is left blank doxygen -# will generate a default style sheet. Note that doxygen will try to copy -# the style sheet file to the HTML output directory, so don't put your own -# stylesheet in the HTML output directory as well, or it will be erased! - -HTML_STYLESHEET = - -# The HTML_EXTRA_FILES tag can be used to specify one or more extra images or -# other source files which should be copied to the HTML output directory. Note -# that these files will be copied to the base HTML output directory. Use the -# $relpath$ marker in the HTML_HEADER and/or HTML_FOOTER files to load these -# files. In the HTML_STYLESHEET file, use the file name only. Also note that -# the files will be copied as-is; there are no commands or markers available. - -HTML_EXTRA_FILES = - -# The HTML_COLORSTYLE_HUE tag controls the color of the HTML output. -# Doxygen will adjust the colors in the stylesheet and background images -# according to this color. Hue is specified as an angle on a colorwheel, -# see http://en.wikipedia.org/wiki/Hue for more information. -# For instance the value 0 represents red, 60 is yellow, 120 is green, -# 180 is cyan, 240 is blue, 300 purple, and 360 is red again. -# The allowed range is 0 to 359. - -HTML_COLORSTYLE_HUE = 220 - -# The HTML_COLORSTYLE_SAT tag controls the purity (or saturation) of -# the colors in the HTML output. For a value of 0 the output will use -# grayscales only. A value of 255 will produce the most vivid colors. - -HTML_COLORSTYLE_SAT = 100 - -# The HTML_COLORSTYLE_GAMMA tag controls the gamma correction applied to -# the luminance component of the colors in the HTML output. Values below -# 100 gradually make the output lighter, whereas values above 100 make -# the output darker. The value divided by 100 is the actual gamma applied, -# so 80 represents a gamma of 0.8, The value 220 represents a gamma of 2.2, -# and 100 does not change the gamma. - -HTML_COLORSTYLE_GAMMA = 80 - -# If the HTML_TIMESTAMP tag is set to YES then the footer of each generated HTML -# page will contain the date and time when the page was generated. Setting -# this to NO can help when comparing the output of multiple runs. - -HTML_TIMESTAMP = YES - -# If the HTML_ALIGN_MEMBERS tag is set to YES, the members of classes, -# files or namespaces will be aligned in HTML using tables. If set to -# NO a bullet list will be used. - -HTML_ALIGN_MEMBERS = YES - -# If the HTML_DYNAMIC_SECTIONS tag is set to YES then the generated HTML -# documentation will contain sections that can be hidden and shown after the -# page has loaded. For this to work a browser that supports -# JavaScript and DHTML is required (for instance Mozilla 1.0+, Firefox -# Netscape 6.0+, Internet explorer 5.0+, Konqueror, or Safari). - -HTML_DYNAMIC_SECTIONS = NO - -# If the GENERATE_DOCSET tag is set to YES, additional index files -# will be generated that can be used as input for Apple's Xcode 3 -# integrated development environment, introduced with OSX 10.5 (Leopard). -# To create a documentation set, doxygen will generate a Makefile in the -# HTML output directory. Running make will produce the docset in that -# directory and running "make install" will install the docset in -# ~/Library/Developer/Shared/Documentation/DocSets so that Xcode will find -# it at startup. -# See http://developer.apple.com/tools/creatingdocsetswithdoxygen.html -# for more information. - -GENERATE_DOCSET = NO - -# When GENERATE_DOCSET tag is set to YES, this tag determines the name of the -# feed. A documentation feed provides an umbrella under which multiple -# documentation sets from a single provider (such as a company or product suite) -# can be grouped. - -DOCSET_FEEDNAME = "Doxygen generated docs" - -# When GENERATE_DOCSET tag is set to YES, this tag specifies a string that -# should uniquely identify the documentation set bundle. This should be a -# reverse domain-name style string, e.g. com.mycompany.MyDocSet. Doxygen -# will append .docset to the name. - -DOCSET_BUNDLE_ID = org.doxygen.Project - -# When GENERATE_PUBLISHER_ID tag specifies a string that should uniquely identify -# the documentation publisher. This should be a reverse domain-name style -# string, e.g. com.mycompany.MyDocSet.documentation. - -DOCSET_PUBLISHER_ID = org.doxygen.Publisher - -# The GENERATE_PUBLISHER_NAME tag identifies the documentation publisher. - -DOCSET_PUBLISHER_NAME = Publisher - -# If the GENERATE_HTMLHELP tag is set to YES, additional index files -# will be generated that can be used as input for tools like the -# Microsoft HTML help workshop to generate a compiled HTML help file (.chm) -# of the generated HTML documentation. - -GENERATE_HTMLHELP = NO - -# If the GENERATE_HTMLHELP tag is set to YES, the CHM_FILE tag can -# be used to specify the file name of the resulting .chm file. You -# can add a path in front of the file if the result should not be -# written to the html output directory. - -CHM_FILE = - -# If the GENERATE_HTMLHELP tag is set to YES, the HHC_LOCATION tag can -# be used to specify the location (absolute path including file name) of -# the HTML help compiler (hhc.exe). If non-empty doxygen will try to run -# the HTML help compiler on the generated index.hhp. - -HHC_LOCATION = - -# If the GENERATE_HTMLHELP tag is set to YES, the GENERATE_CHI flag -# controls if a separate .chi index file is generated (YES) or that -# it should be included in the master .chm file (NO). - -GENERATE_CHI = NO - -# If the GENERATE_HTMLHELP tag is set to YES, the CHM_INDEX_ENCODING -# is used to encode HtmlHelp index (hhk), content (hhc) and project file -# content. - -CHM_INDEX_ENCODING = - -# If the GENERATE_HTMLHELP tag is set to YES, the BINARY_TOC flag -# controls whether a binary table of contents is generated (YES) or a -# normal table of contents (NO) in the .chm file. - -BINARY_TOC = NO - -# The TOC_EXPAND flag can be set to YES to add extra items for group members -# to the contents of the HTML help documentation and to the tree view. - -TOC_EXPAND = NO - -# If the GENERATE_QHP tag is set to YES and both QHP_NAMESPACE and -# QHP_VIRTUAL_FOLDER are set, an additional index file will be generated -# that can be used as input for Qt's qhelpgenerator to generate a -# Qt Compressed Help (.qch) of the generated HTML documentation. - -GENERATE_QHP = NO - -# If the QHG_LOCATION tag is specified, the QCH_FILE tag can -# be used to specify the file name of the resulting .qch file. -# The path specified is relative to the HTML output folder. - -QCH_FILE = - -# The QHP_NAMESPACE tag specifies the namespace to use when generating -# Qt Help Project output. For more information please see -# http://doc.trolltech.com/qthelpproject.html#namespace - -QHP_NAMESPACE = org.doxygen.Project - -# The QHP_VIRTUAL_FOLDER tag specifies the namespace to use when generating -# Qt Help Project output. For more information please see -# http://doc.trolltech.com/qthelpproject.html#virtual-folders - -QHP_VIRTUAL_FOLDER = doc - -# If QHP_CUST_FILTER_NAME is set, it specifies the name of a custom filter to -# add. For more information please see -# http://doc.trolltech.com/qthelpproject.html#custom-filters - -QHP_CUST_FILTER_NAME = - -# The QHP_CUST_FILT_ATTRS tag specifies the list of the attributes of the -# custom filter to add. For more information please see -# <a href="http://doc.trolltech.com/qthelpproject.html#custom-filters"> -# Qt Help Project / Custom Filters</a>. - -QHP_CUST_FILTER_ATTRS = - -# The QHP_SECT_FILTER_ATTRS tag specifies the list of the attributes this -# project's -# filter section matches. -# <a href="http://doc.trolltech.com/qthelpproject.html#filter-attributes"> -# Qt Help Project / Filter Attributes</a>. - -QHP_SECT_FILTER_ATTRS = - -# If the GENERATE_QHP tag is set to YES, the QHG_LOCATION tag can -# be used to specify the location of Qt's qhelpgenerator. -# If non-empty doxygen will try to run qhelpgenerator on the generated -# .qhp file. - -QHG_LOCATION = - -# If the GENERATE_ECLIPSEHELP tag is set to YES, additional index files -# will be generated, which together with the HTML files, form an Eclipse help -# plugin. To install this plugin and make it available under the help contents -# menu in Eclipse, the contents of the directory containing the HTML and XML -# files needs to be copied into the plugins directory of eclipse. The name of -# the directory within the plugins directory should be the same as -# the ECLIPSE_DOC_ID value. After copying Eclipse needs to be restarted before -# the help appears. - -GENERATE_ECLIPSEHELP = NO - -# A unique identifier for the eclipse help plugin. When installing the plugin -# the directory name containing the HTML and XML files should also have -# this name. - -ECLIPSE_DOC_ID = org.doxygen.Project - -# The DISABLE_INDEX tag can be used to turn on/off the condensed index at -# top of each HTML page. The value NO (the default) enables the index and -# the value YES disables it. - -DISABLE_INDEX = NO - -# The ENUM_VALUES_PER_LINE tag can be used to set the number of enum values -# (range [0,1..20]) that doxygen will group on one line in the generated HTML -# documentation. Note that a value of 0 will completely suppress the enum -# values from appearing in the overview section. - -ENUM_VALUES_PER_LINE = 4 - -# The GENERATE_TREEVIEW tag is used to specify whether a tree-like index -# structure should be generated to display hierarchical information. -# If the tag value is set to YES, a side panel will be generated -# containing a tree-like index structure (just like the one that -# is generated for HTML Help). For this to work a browser that supports -# JavaScript, DHTML, CSS and frames is required (i.e. any modern browser). -# Windows users are probably better off using the HTML help feature. - -GENERATE_TREEVIEW = NO - -# By enabling USE_INLINE_TREES, doxygen will generate the Groups, Directories, -# and Class Hierarchy pages using a tree view instead of an ordered list. - -USE_INLINE_TREES = NO - -# If the treeview is enabled (see GENERATE_TREEVIEW) then this tag can be -# used to set the initial width (in pixels) of the frame in which the tree -# is shown. - -TREEVIEW_WIDTH = 250 - -# When the EXT_LINKS_IN_WINDOW option is set to YES doxygen will open -# links to external symbols imported via tag files in a separate window. - -EXT_LINKS_IN_WINDOW = NO - -# Use this tag to change the font size of Latex formulas included -# as images in the HTML documentation. The default is 10. Note that -# when you change the font size after a successful doxygen run you need -# to manually remove any form_*.png images from the HTML output directory -# to force them to be regenerated. - -FORMULA_FONTSIZE = 10 - -# Use the FORMULA_TRANPARENT tag to determine whether or not the images -# generated for formulas are transparent PNGs. Transparent PNGs are -# not supported properly for IE 6.0, but are supported on all modern browsers. -# Note that when changing this option you need to delete any form_*.png files -# in the HTML output before the changes have effect. - -FORMULA_TRANSPARENT = YES - -# Enable the USE_MATHJAX option to render LaTeX formulas using MathJax -# (see http://www.mathjax.org) which uses client side Javascript for the -# rendering instead of using prerendered bitmaps. Use this if you do not -# have LaTeX installed or if you want to formulas look prettier in the HTML -# output. When enabled you also need to install MathJax separately and -# configure the path to it using the MATHJAX_RELPATH option. - -USE_MATHJAX = NO - -# When MathJax is enabled you need to specify the location relative to the -# HTML output directory using the MATHJAX_RELPATH option. The destination -# directory should contain the MathJax.js script. For instance, if the mathjax -# directory is located at the same level as the HTML output directory, then -# MATHJAX_RELPATH should be ../mathjax. The default value points to the -# mathjax.org site, so you can quickly see the result without installing -# MathJax, but it is strongly recommended to install a local copy of MathJax -# before deployment. - -MATHJAX_RELPATH = http://www.mathjax.org/mathjax - -# When the SEARCHENGINE tag is enabled doxygen will generate a search box -# for the HTML output. The underlying search engine uses javascript -# and DHTML and should work on any modern browser. Note that when using -# HTML help (GENERATE_HTMLHELP), Qt help (GENERATE_QHP), or docsets -# (GENERATE_DOCSET) there is already a search function so this one should -# typically be disabled. For large projects the javascript based search engine -# can be slow, then enabling SERVER_BASED_SEARCH may provide a better solution. - -SEARCHENGINE = YES - -# When the SERVER_BASED_SEARCH tag is enabled the search engine will be -# implemented using a PHP enabled web server instead of at the web client -# using Javascript. Doxygen will generate the search PHP script and index -# file to put on the web server. The advantage of the server -# based approach is that it scales better to large projects and allows -# full text search. The disadvantages are that it is more difficult to setup -# and does not have live searching capabilities. - -SERVER_BASED_SEARCH = NO - -#--------------------------------------------------------------------------- -# configuration options related to the LaTeX output -#--------------------------------------------------------------------------- - -# If the GENERATE_LATEX tag is set to YES (the default) Doxygen will -# generate Latex output. - -GENERATE_LATEX = YES - -# The LATEX_OUTPUT tag is used to specify where the LaTeX docs will be put. -# If a relative path is entered the value of OUTPUT_DIRECTORY will be -# put in front of it. If left blank `latex' will be used as the default path. - -LATEX_OUTPUT = latex - -# The LATEX_CMD_NAME tag can be used to specify the LaTeX command name to be -# invoked. If left blank `latex' will be used as the default command name. -# Note that when enabling USE_PDFLATEX this option is only used for -# generating bitmaps for formulas in the HTML output, but not in the -# Makefile that is written to the output directory. - -LATEX_CMD_NAME = latex - -# The MAKEINDEX_CMD_NAME tag can be used to specify the command name to -# generate index for LaTeX. If left blank `makeindex' will be used as the -# default command name. - -MAKEINDEX_CMD_NAME = makeindex - -# If the COMPACT_LATEX tag is set to YES Doxygen generates more compact -# LaTeX documents. This may be useful for small projects and may help to -# save some trees in general. - -COMPACT_LATEX = NO - -# The PAPER_TYPE tag can be used to set the paper type that is used -# by the printer. Possible values are: a4, letter, legal and -# executive. If left blank a4wide will be used. - -PAPER_TYPE = a4 - -# The EXTRA_PACKAGES tag can be to specify one or more names of LaTeX -# packages that should be included in the LaTeX output. - -EXTRA_PACKAGES = - -# The LATEX_HEADER tag can be used to specify a personal LaTeX header for -# the generated latex document. The header should contain everything until -# the first chapter. If it is left blank doxygen will generate a -# standard header. Notice: only use this tag if you know what you are doing! - -LATEX_HEADER = - -# The LATEX_FOOTER tag can be used to specify a personal LaTeX footer for -# the generated latex document. The footer should contain everything after -# the last chapter. If it is left blank doxygen will generate a -# standard footer. Notice: only use this tag if you know what you are doing! - -LATEX_FOOTER = - -# If the PDF_HYPERLINKS tag is set to YES, the LaTeX that is generated -# is prepared for conversion to pdf (using ps2pdf). The pdf file will -# contain links (just like the HTML output) instead of page references -# This makes the output suitable for online browsing using a pdf viewer. - -PDF_HYPERLINKS = YES - -# If the USE_PDFLATEX tag is set to YES, pdflatex will be used instead of -# plain latex in the generated Makefile. Set this option to YES to get a -# higher quality PDF documentation. - -USE_PDFLATEX = YES - -# If the LATEX_BATCHMODE tag is set to YES, doxygen will add the \\batchmode. -# command to the generated LaTeX files. This will instruct LaTeX to keep -# running if errors occur, instead of asking the user for help. -# This option is also used when generating formulas in HTML. - -LATEX_BATCHMODE = NO - -# If LATEX_HIDE_INDICES is set to YES then doxygen will not -# include the index chapters (such as File Index, Compound Index, etc.) -# in the output. - -LATEX_HIDE_INDICES = NO - -# If LATEX_SOURCE_CODE is set to YES then doxygen will include -# source code with syntax highlighting in the LaTeX output. -# Note that which sources are shown also depends on other settings -# such as SOURCE_BROWSER. - -LATEX_SOURCE_CODE = NO - -#--------------------------------------------------------------------------- -# configuration options related to the RTF output -#--------------------------------------------------------------------------- - -# If the GENERATE_RTF tag is set to YES Doxygen will generate RTF output -# The RTF output is optimized for Word 97 and may not look very pretty with -# other RTF readers or editors. - -GENERATE_RTF = NO - -# The RTF_OUTPUT tag is used to specify where the RTF docs will be put. -# If a relative path is entered the value of OUTPUT_DIRECTORY will be -# put in front of it. If left blank `rtf' will be used as the default path. - -RTF_OUTPUT = rtf - -# If the COMPACT_RTF tag is set to YES Doxygen generates more compact -# RTF documents. This may be useful for small projects and may help to -# save some trees in general. - -COMPACT_RTF = NO - -# If the RTF_HYPERLINKS tag is set to YES, the RTF that is generated -# will contain hyperlink fields. The RTF file will -# contain links (just like the HTML output) instead of page references. -# This makes the output suitable for online browsing using WORD or other -# programs which support those fields. -# Note: wordpad (write) and others do not support links. - -RTF_HYPERLINKS = NO - -# Load stylesheet definitions from file. Syntax is similar to doxygen's -# config file, i.e. a series of assignments. You only have to provide -# replacements, missing definitions are set to their default value. - -RTF_STYLESHEET_FILE = - -# Set optional variables used in the generation of an rtf document. -# Syntax is similar to doxygen's config file. - -RTF_EXTENSIONS_FILE = - -#--------------------------------------------------------------------------- -# configuration options related to the man page output -#--------------------------------------------------------------------------- - -# If the GENERATE_MAN tag is set to YES (the default) Doxygen will -# generate man pages - -GENERATE_MAN = NO - -# The MAN_OUTPUT tag is used to specify where the man pages will be put. -# If a relative path is entered the value of OUTPUT_DIRECTORY will be -# put in front of it. If left blank `man' will be used as the default path. - -MAN_OUTPUT = man - -# The MAN_EXTENSION tag determines the extension that is added to -# the generated man pages (default is the subroutine's section .3) - -MAN_EXTENSION = .3 - -# If the MAN_LINKS tag is set to YES and Doxygen generates man output, -# then it will generate one additional man file for each entity -# documented in the real man page(s). These additional files -# only source the real man page, but without them the man command -# would be unable to find the correct page. The default is NO. - -MAN_LINKS = NO - -#--------------------------------------------------------------------------- -# configuration options related to the XML output -#--------------------------------------------------------------------------- - -# If the GENERATE_XML tag is set to YES Doxygen will -# generate an XML file that captures the structure of -# the code including all documentation. - -GENERATE_XML = NO - -# The XML_OUTPUT tag is used to specify where the XML pages will be put. -# If a relative path is entered the value of OUTPUT_DIRECTORY will be -# put in front of it. If left blank `xml' will be used as the default path. - -XML_OUTPUT = xml - -# The XML_SCHEMA tag can be used to specify an XML schema, -# which can be used by a validating XML parser to check the -# syntax of the XML files. - -XML_SCHEMA = - -# The XML_DTD tag can be used to specify an XML DTD, -# which can be used by a validating XML parser to check the -# syntax of the XML files. - -XML_DTD = - -# If the XML_PROGRAMLISTING tag is set to YES Doxygen will -# dump the program listings (including syntax highlighting -# and cross-referencing information) to the XML output. Note that -# enabling this will significantly increase the size of the XML output. - -XML_PROGRAMLISTING = YES - -#--------------------------------------------------------------------------- -# configuration options for the AutoGen Definitions output -#--------------------------------------------------------------------------- - -# If the GENERATE_AUTOGEN_DEF tag is set to YES Doxygen will -# generate an AutoGen Definitions (see autogen.sf.net) file -# that captures the structure of the code including all -# documentation. Note that this feature is still experimental -# and incomplete at the moment. - -GENERATE_AUTOGEN_DEF = NO - -#--------------------------------------------------------------------------- -# configuration options related to the Perl module output -#--------------------------------------------------------------------------- - -# If the GENERATE_PERLMOD tag is set to YES Doxygen will -# generate a Perl module file that captures the structure of -# the code including all documentation. Note that this -# feature is still experimental and incomplete at the -# moment. - -GENERATE_PERLMOD = NO - -# If the PERLMOD_LATEX tag is set to YES Doxygen will generate -# the necessary Makefile rules, Perl scripts and LaTeX code to be able -# to generate PDF and DVI output from the Perl module output. - -PERLMOD_LATEX = NO - -# If the PERLMOD_PRETTY tag is set to YES the Perl module output will be -# nicely formatted so it can be parsed by a human reader. -# This is useful -# if you want to understand what is going on. -# On the other hand, if this -# tag is set to NO the size of the Perl module output will be much smaller -# and Perl will parse it just the same. - -PERLMOD_PRETTY = YES - -# The names of the make variables in the generated doxyrules.make file -# are prefixed with the string contained in PERLMOD_MAKEVAR_PREFIX. -# This is useful so different doxyrules.make files included by the same -# Makefile don't overwrite each other's variables. - -PERLMOD_MAKEVAR_PREFIX = - -#--------------------------------------------------------------------------- -# Configuration options related to the preprocessor -#--------------------------------------------------------------------------- - -# If the ENABLE_PREPROCESSING tag is set to YES (the default) Doxygen will -# evaluate all C-preprocessor directives found in the sources and include -# files. - -ENABLE_PREPROCESSING = YES - -# If the MACRO_EXPANSION tag is set to YES Doxygen will expand all macro -# names in the source code. If set to NO (the default) only conditional -# compilation will be performed. Macro expansion can be done in a controlled -# way by setting EXPAND_ONLY_PREDEF to YES. - -MACRO_EXPANSION = NO - -# If the EXPAND_ONLY_PREDEF and MACRO_EXPANSION tags are both set to YES -# then the macro expansion is limited to the macros specified with the -# PREDEFINED and EXPAND_AS_DEFINED tags. - -EXPAND_ONLY_PREDEF = NO - -# If the SEARCH_INCLUDES tag is set to YES (the default) the includes files -# pointed to by INCLUDE_PATH will be searched when a #include is found. - -SEARCH_INCLUDES = YES - -# The INCLUDE_PATH tag can be used to specify one or more directories that -# contain include files that are not input files but should be processed by -# the preprocessor. - -INCLUDE_PATH = - -# You can use the INCLUDE_FILE_PATTERNS tag to specify one or more wildcard -# patterns (like *.h and *.hpp) to filter out the header-files in the -# directories. If left blank, the patterns specified with FILE_PATTERNS will -# be used. - -INCLUDE_FILE_PATTERNS = - -# The PREDEFINED tag can be used to specify one or more macro names that -# are defined before the preprocessor is started (similar to the -D option of -# gcc). The argument of the tag is a list of macros of the form: name -# or name=definition (no spaces). If the definition and the = are -# omitted =1 is assumed. To prevent a macro definition from being -# undefined via #undef or recursively expanded use the := operator -# instead of the = operator. - -PREDEFINED = - -# If the MACRO_EXPANSION and EXPAND_ONLY_PREDEF tags are set to YES then -# this tag can be used to specify a list of macro names that should be expanded. -# The macro definition that is found in the sources will be used. -# Use the PREDEFINED tag if you want to use a different macro definition that -# overrules the definition found in the source code. - -EXPAND_AS_DEFINED = - -# If the SKIP_FUNCTION_MACROS tag is set to YES (the default) then -# doxygen's preprocessor will remove all references to function-like macros -# that are alone on a line, have an all uppercase name, and do not end with a -# semicolon, because these will confuse the parser if not removed. - -SKIP_FUNCTION_MACROS = YES - -#--------------------------------------------------------------------------- -# Configuration::additions related to external references -#--------------------------------------------------------------------------- - -# The TAGFILES option can be used to specify one or more tagfiles. -# Optionally an initial location of the external documentation -# can be added for each tagfile. The format of a tag file without -# this location is as follows: -# -# TAGFILES = file1 file2 ... -# Adding location for the tag files is done as follows: -# -# TAGFILES = file1=loc1 "file2 = loc2" ... -# where "loc1" and "loc2" can be relative or absolute paths or -# URLs. If a location is present for each tag, the installdox tool -# does not have to be run to correct the links. -# Note that each tag file must have a unique name -# (where the name does NOT include the path) -# If a tag file is not located in the directory in which doxygen -# is run, you must also specify the path to the tagfile here. - -TAGFILES = - -# When a file name is specified after GENERATE_TAGFILE, doxygen will create -# a tag file that is based on the input files it reads. - -GENERATE_TAGFILE = - -# If the ALLEXTERNALS tag is set to YES all external classes will be listed -# in the class index. If set to NO only the inherited external classes -# will be listed. - -ALLEXTERNALS = NO - -# If the EXTERNAL_GROUPS tag is set to YES all external groups will be listed -# in the modules index. If set to NO, only the current project's groups will -# be listed. - -EXTERNAL_GROUPS = YES - -# The PERL_PATH should be the absolute path and name of the perl script -# interpreter (i.e. the result of `which perl'). - -PERL_PATH = /usr/bin/perl - -#--------------------------------------------------------------------------- -# Configuration options related to the dot tool -#--------------------------------------------------------------------------- - -# If the CLASS_DIAGRAMS tag is set to YES (the default) Doxygen will -# generate a inheritance diagram (in HTML, RTF and LaTeX) for classes with base -# or super classes. Setting the tag to NO turns the diagrams off. Note that -# this option also works with HAVE_DOT disabled, but it is recommended to -# install and use dot, since it yields more powerful graphs. - -CLASS_DIAGRAMS = YES - -# You can define message sequence charts within doxygen comments using the \msc -# command. Doxygen will then run the mscgen tool (see -# http://www.mcternan.me.uk/mscgen/) to produce the chart and insert it in the -# documentation. The MSCGEN_PATH tag allows you to specify the directory where -# the mscgen tool resides. If left empty the tool is assumed to be found in the -# default search path. - -MSCGEN_PATH = - -# If set to YES, the inheritance and collaboration graphs will hide -# inheritance and usage relations if the target is undocumented -# or is not a class. - -HIDE_UNDOC_RELATIONS = YES - -# If you set the HAVE_DOT tag to YES then doxygen will assume the dot tool is -# available from the path. This tool is part of Graphviz, a graph visualization -# toolkit from AT&T and Lucent Bell Labs. The other options in this section -# have no effect if this option is set to NO (the default) - -HAVE_DOT = NO - -# The DOT_NUM_THREADS specifies the number of dot invocations doxygen is -# allowed to run in parallel. When set to 0 (the default) doxygen will -# base this on the number of processors available in the system. You can set it -# explicitly to a value larger than 0 to get control over the balance -# between CPU load and processing speed. - -DOT_NUM_THREADS = 0 - -# By default doxygen will write a font called Helvetica to the output -# directory and reference it in all dot files that doxygen generates. -# When you want a differently looking font you can specify the font name -# using DOT_FONTNAME. You need to make sure dot is able to find the font, -# which can be done by putting it in a standard location or by setting the -# DOTFONTPATH environment variable or by setting DOT_FONTPATH to the directory -# containing the font. - -DOT_FONTNAME = Helvetica - -# The DOT_FONTSIZE tag can be used to set the size of the font of dot graphs. -# The default size is 10pt. - -DOT_FONTSIZE = 10 - -# By default doxygen will tell dot to use the output directory to look for the -# FreeSans.ttf font (which doxygen will put there itself). If you specify a -# different font using DOT_FONTNAME you can set the path where dot -# can find it using this tag. - -DOT_FONTPATH = - -# If the CLASS_GRAPH and HAVE_DOT tags are set to YES then doxygen -# will generate a graph for each documented class showing the direct and -# indirect inheritance relations. Setting this tag to YES will force the -# the CLASS_DIAGRAMS tag to NO. - -CLASS_GRAPH = YES - -# If the COLLABORATION_GRAPH and HAVE_DOT tags are set to YES then doxygen -# will generate a graph for each documented class showing the direct and -# indirect implementation dependencies (inheritance, containment, and -# class references variables) of the class with other documented classes. - -COLLABORATION_GRAPH = YES - -# If the GROUP_GRAPHS and HAVE_DOT tags are set to YES then doxygen -# will generate a graph for groups, showing the direct groups dependencies - -GROUP_GRAPHS = YES - -# If the UML_LOOK tag is set to YES doxygen will generate inheritance and -# collaboration diagrams in a style similar to the OMG's Unified Modeling -# Language. - -UML_LOOK = NO - -# If set to YES, the inheritance and collaboration graphs will show the -# relations between templates and their instances. - -TEMPLATE_RELATIONS = NO - -# If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDE_GRAPH, and HAVE_DOT -# tags are set to YES then doxygen will generate a graph for each documented -# file showing the direct and indirect include dependencies of the file with -# other documented files. - -INCLUDE_GRAPH = YES - -# If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDED_BY_GRAPH, and -# HAVE_DOT tags are set to YES then doxygen will generate a graph for each -# documented header file showing the documented files that directly or -# indirectly include this file. - -INCLUDED_BY_GRAPH = YES - -# If the CALL_GRAPH and HAVE_DOT options are set to YES then -# doxygen will generate a call dependency graph for every global function -# or class method. Note that enabling this option will significantly increase -# the time of a run. So in most cases it will be better to enable call graphs -# for selected functions only using the \callgraph command. - -CALL_GRAPH = NO - -# If the CALLER_GRAPH and HAVE_DOT tags are set to YES then -# doxygen will generate a caller dependency graph for every global function -# or class method. Note that enabling this option will significantly increase -# the time of a run. So in most cases it will be better to enable caller -# graphs for selected functions only using the \callergraph command. - -CALLER_GRAPH = NO - -# If the GRAPHICAL_HIERARCHY and HAVE_DOT tags are set to YES then doxygen -# will generate a graphical hierarchy of all classes instead of a textual one. - -GRAPHICAL_HIERARCHY = YES - -# If the DIRECTORY_GRAPH, SHOW_DIRECTORIES and HAVE_DOT tags are set to YES -# then doxygen will show the dependencies a directory has on other directories -# in a graphical way. The dependency relations are determined by the #include -# relations between the files in the directories. - -DIRECTORY_GRAPH = YES - -# The DOT_IMAGE_FORMAT tag can be used to set the image format of the images -# generated by dot. Possible values are svg, png, jpg, or gif. -# If left blank png will be used. - -DOT_IMAGE_FORMAT = png - -# The tag DOT_PATH can be used to specify the path where the dot tool can be -# found. If left blank, it is assumed the dot tool can be found in the path. - -DOT_PATH = - -# The DOTFILE_DIRS tag can be used to specify one or more directories that -# contain dot files that are included in the documentation (see the -# \dotfile command). - -DOTFILE_DIRS = - -# The MSCFILE_DIRS tag can be used to specify one or more directories that -# contain msc files that are included in the documentation (see the -# \mscfile command). - -MSCFILE_DIRS = - -# The DOT_GRAPH_MAX_NODES tag can be used to set the maximum number of -# nodes that will be shown in the graph. If the number of nodes in a graph -# becomes larger than this value, doxygen will truncate the graph, which is -# visualized by representing a node as a red box. Note that doxygen if the -# number of direct children of the root node in a graph is already larger than -# DOT_GRAPH_MAX_NODES then the graph will not be shown at all. Also note -# that the size of a graph can be further restricted by MAX_DOT_GRAPH_DEPTH. - -DOT_GRAPH_MAX_NODES = 50 - -# The MAX_DOT_GRAPH_DEPTH tag can be used to set the maximum depth of the -# graphs generated by dot. A depth value of 3 means that only nodes reachable -# from the root by following a path via at most 3 edges will be shown. Nodes -# that lay further from the root node will be omitted. Note that setting this -# option to 1 or 2 may greatly reduce the computation time needed for large -# code bases. Also note that the size of a graph can be further restricted by -# DOT_GRAPH_MAX_NODES. Using a depth of 0 means no depth restriction. - -MAX_DOT_GRAPH_DEPTH = 0 - -# Set the DOT_TRANSPARENT tag to YES to generate images with a transparent -# background. This is disabled by default, because dot on Windows does not -# seem to support this out of the box. Warning: Depending on the platform used, -# enabling this option may lead to badly anti-aliased labels on the edges of -# a graph (i.e. they become hard to read). - -DOT_TRANSPARENT = NO - -# Set the DOT_MULTI_TARGETS tag to YES allow dot to generate multiple output -# files in one run (i.e. multiple -o and -T options on the command line). This -# makes dot run faster, but since only newer versions of dot (>1.8.10) -# support this, this feature is disabled by default. - -DOT_MULTI_TARGETS = NO - -# If the GENERATE_LEGEND tag is set to YES (the default) Doxygen will -# generate a legend page explaining the meaning of the various boxes and -# arrows in the dot generated graphs. - -GENERATE_LEGEND = YES - -# If the DOT_CLEANUP tag is set to YES (the default) Doxygen will -# remove the intermediate dot files that are used to generate -# the various graphs. - -DOT_CLEANUP = YES diff --git a/src/gallium/state_trackers/clover/Makefile.sources b/src/gallium/state_trackers/clover/Makefile.sources deleted file mode 100644 index 38f94981fb6..00000000000 --- a/src/gallium/state_trackers/clover/Makefile.sources +++ /dev/null @@ -1,68 +0,0 @@ -CPP_SOURCES := \ - api/context.cpp \ - api/device.cpp \ - api/dispatch.cpp \ - api/dispatch.hpp \ - api/event.cpp \ - api/interop.cpp \ - api/kernel.cpp \ - api/memory.cpp \ - api/platform.cpp \ - api/program.cpp \ - api/queue.cpp \ - api/sampler.cpp \ - api/transfer.cpp \ - api/util.hpp \ - core/context.cpp \ - core/context.hpp \ - core/device.cpp \ - core/device.hpp \ - core/error.hpp \ - core/event.cpp \ - core/event.hpp \ - core/format.cpp \ - core/format.hpp \ - core/kernel.cpp \ - core/kernel.hpp \ - core/memory.cpp \ - core/memory.hpp \ - core/module.cpp \ - core/module.hpp \ - core/object.hpp \ - core/platform.cpp \ - core/platform.hpp \ - core/program.cpp \ - core/program.hpp \ - core/property.hpp \ - core/queue.cpp \ - core/queue.hpp \ - core/resource.cpp \ - core/resource.hpp \ - core/sampler.cpp \ - core/sampler.hpp \ - core/timestamp.cpp \ - core/timestamp.hpp \ - util/adaptor.hpp \ - util/algebra.hpp \ - util/algorithm.hpp \ - util/factor.hpp \ - util/functional.hpp \ - util/lazy.hpp \ - util/pointer.hpp \ - util/range.hpp \ - util/tuple.hpp - -LLVM_SOURCES := \ - llvm/codegen/bitcode.cpp \ - llvm/codegen/common.cpp \ - llvm/codegen/native.cpp \ - llvm/codegen.hpp \ - llvm/compat.hpp \ - llvm/invocation.cpp \ - llvm/invocation.hpp \ - llvm/metadata.hpp \ - llvm/util.hpp - -SPIRV_SOURCES := \ - spirv/invocation.cpp \ - spirv/invocation.hpp diff --git a/src/gallium/state_trackers/clover/api/context.cpp b/src/gallium/state_trackers/clover/api/context.cpp deleted file mode 100644 index c0cd2d32b95..00000000000 --- a/src/gallium/state_trackers/clover/api/context.cpp +++ /dev/null @@ -1,144 +0,0 @@ -// -// Copyright 2012 Francisco Jerez -// -// Permission is hereby granted, free of charge, to any person obtaining a -// copy of this software and associated documentation files (the "Software"), -// to deal in the Software without restriction, including without limitation -// the rights to use, copy, modify, merge, publish, distribute, sublicense, -// and/or sell copies of the Software, and to permit persons to whom the -// Software is furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL -// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR -// OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, -// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR -// OTHER DEALINGS IN THE SOFTWARE. -// - -#include "api/util.hpp" -#include "core/context.hpp" -#include "core/platform.hpp" - -using namespace clover; - -CLOVER_API cl_context -clCreateContext(const cl_context_properties *d_props, cl_uint num_devs, - const cl_device_id *d_devs, - void (CL_CALLBACK *pfn_notify)(const char *, const void *, - size_t, void *), - void *user_data, cl_int *r_errcode) try { - auto props = obj<property_list_tag>(d_props); - auto devs = objs(d_devs, num_devs); - - if (!pfn_notify && user_data) - throw error(CL_INVALID_VALUE); - - for (auto &prop : props) { - if (prop.first == CL_CONTEXT_PLATFORM) - obj(prop.second.as<cl_platform_id>()); - else - throw error(CL_INVALID_PROPERTY); - } - - const auto notify = (!pfn_notify ? context::notify_action() : - [=](const char *s) { - pfn_notify(s, NULL, 0, user_data); - }); - - ret_error(r_errcode, CL_SUCCESS); - return desc(new context(props, devs, notify)); - -} catch (error &e) { - ret_error(r_errcode, e); - return NULL; -} - -CLOVER_API cl_context -clCreateContextFromType(const cl_context_properties *d_props, - cl_device_type type, - void (CL_CALLBACK *pfn_notify)( - const char *, const void *, size_t, void *), - void *user_data, cl_int *r_errcode) try { - cl_platform_id d_platform; - cl_uint num_platforms; - cl_int ret; - std::vector<cl_device_id> devs; - cl_uint num_devices; - - ret = clGetPlatformIDs(1, &d_platform, &num_platforms); - if (ret || !num_platforms) - throw error(CL_INVALID_PLATFORM); - - ret = clGetDeviceIDs(d_platform, type, 0, NULL, &num_devices); - if (ret) - throw error(CL_DEVICE_NOT_FOUND); - devs.resize(num_devices); - ret = clGetDeviceIDs(d_platform, type, num_devices, devs.data(), 0); - if (ret) - throw error(CL_DEVICE_NOT_FOUND); - - return clCreateContext(d_props, num_devices, devs.data(), pfn_notify, - user_data, r_errcode); - -} catch (error &e) { - ret_error(r_errcode, e); - return NULL; -} - -CLOVER_API cl_int -clRetainContext(cl_context d_ctx) try { - obj(d_ctx).retain(); - return CL_SUCCESS; - -} catch (error &e) { - return e.get(); -} - -CLOVER_API cl_int -clReleaseContext(cl_context d_ctx) try { - if (obj(d_ctx).release()) - delete pobj(d_ctx); - - return CL_SUCCESS; - -} catch (error &e) { - return e.get(); -} - -CLOVER_API cl_int -clGetContextInfo(cl_context d_ctx, cl_context_info param, - size_t size, void *r_buf, size_t *r_size) try { - property_buffer buf { r_buf, size, r_size }; - auto &ctx = obj(d_ctx); - - switch (param) { - case CL_CONTEXT_REFERENCE_COUNT: - buf.as_scalar<cl_uint>() = ctx.ref_count(); - break; - - case CL_CONTEXT_NUM_DEVICES: - buf.as_scalar<cl_uint>() = ctx.devices().size(); - break; - - case CL_CONTEXT_DEVICES: - buf.as_vector<cl_device_id>() = descs(ctx.devices()); - break; - - case CL_CONTEXT_PROPERTIES: - buf.as_vector<cl_context_properties>() = desc(ctx.properties()); - break; - - default: - throw error(CL_INVALID_VALUE); - } - - return CL_SUCCESS; - -} catch (error &e) { - return e.get(); -} diff --git a/src/gallium/state_trackers/clover/api/device.cpp b/src/gallium/state_trackers/clover/api/device.cpp deleted file mode 100644 index 042f2eda21c..00000000000 --- a/src/gallium/state_trackers/clover/api/device.cpp +++ /dev/null @@ -1,421 +0,0 @@ -// -// Copyright 2012 Francisco Jerez -// -// Permission is hereby granted, free of charge, to any person obtaining a -// copy of this software and associated documentation files (the "Software"), -// to deal in the Software without restriction, including without limitation -// the rights to use, copy, modify, merge, publish, distribute, sublicense, -// and/or sell copies of the Software, and to permit persons to whom the -// Software is furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL -// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR -// OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, -// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR -// OTHER DEALINGS IN THE SOFTWARE. -// - -#include "api/util.hpp" -#include "core/platform.hpp" -#include "core/device.hpp" -#include "git_sha1.h" - -using namespace clover; - -CLOVER_API cl_int -clGetDeviceIDs(cl_platform_id d_platform, cl_device_type device_type, - cl_uint num_entries, cl_device_id *rd_devices, - cl_uint *rnum_devices) try { - auto &platform = obj(d_platform); - std::vector<cl_device_id> d_devs; - - if ((!num_entries && rd_devices) || - (!rnum_devices && !rd_devices)) - throw error(CL_INVALID_VALUE); - - // Collect matching devices - for (device &dev : platform) { - if (((device_type & CL_DEVICE_TYPE_DEFAULT) && - dev == platform.front()) || - (device_type & dev.type())) - d_devs.push_back(desc(dev)); - } - - if (d_devs.empty()) - throw error(CL_DEVICE_NOT_FOUND); - - // ...and return the requested data. - if (rnum_devices) - *rnum_devices = d_devs.size(); - if (rd_devices) - copy(range(d_devs.begin(), - std::min((unsigned)d_devs.size(), num_entries)), - rd_devices); - - return CL_SUCCESS; - -} catch (error &e) { - return e.get(); -} - -CLOVER_API cl_int -clCreateSubDevices(cl_device_id d_dev, - const cl_device_partition_property *props, - cl_uint num_devs, cl_device_id *rd_devs, - cl_uint *rnum_devs) { - // There are no currently supported partitioning schemes. - return CL_INVALID_VALUE; -} - -CLOVER_API cl_int -clRetainDevice(cl_device_id d_dev) try { - obj(d_dev); - - // The reference count doesn't change for root devices. - return CL_SUCCESS; - -} catch (error &e) { - return e.get(); -} - -CLOVER_API cl_int -clReleaseDevice(cl_device_id d_dev) try { - obj(d_dev); - - // The reference count doesn't change for root devices. - return CL_SUCCESS; - -} catch (error &e) { - return e.get(); -} - -CLOVER_API cl_int -clGetDeviceInfo(cl_device_id d_dev, cl_device_info param, - size_t size, void *r_buf, size_t *r_size) try { - property_buffer buf { r_buf, size, r_size }; - auto &dev = obj(d_dev); - - switch (param) { - case CL_DEVICE_TYPE: - buf.as_scalar<cl_device_type>() = dev.type(); - break; - - case CL_DEVICE_VENDOR_ID: - buf.as_scalar<cl_uint>() = dev.vendor_id(); - break; - - case CL_DEVICE_MAX_COMPUTE_UNITS: - buf.as_scalar<cl_uint>() = dev.max_compute_units(); - break; - - case CL_DEVICE_MAX_WORK_ITEM_DIMENSIONS: - buf.as_scalar<cl_uint>() = dev.max_block_size().size(); - break; - - case CL_DEVICE_MAX_WORK_ITEM_SIZES: - buf.as_vector<size_t>() = dev.max_block_size(); - break; - - case CL_DEVICE_MAX_WORK_GROUP_SIZE: - buf.as_scalar<size_t>() = dev.max_threads_per_block(); - break; - - case CL_DEVICE_PREFERRED_VECTOR_WIDTH_CHAR: - buf.as_scalar<cl_uint>() = 16; - break; - - case CL_DEVICE_PREFERRED_VECTOR_WIDTH_SHORT: - buf.as_scalar<cl_uint>() = 8; - break; - - case CL_DEVICE_PREFERRED_VECTOR_WIDTH_INT: - buf.as_scalar<cl_uint>() = 4; - break; - - case CL_DEVICE_PREFERRED_VECTOR_WIDTH_LONG: - buf.as_scalar<cl_uint>() = 2; - break; - - case CL_DEVICE_PREFERRED_VECTOR_WIDTH_FLOAT: - buf.as_scalar<cl_uint>() = 4; - break; - - case CL_DEVICE_PREFERRED_VECTOR_WIDTH_DOUBLE: - buf.as_scalar<cl_uint>() = dev.has_doubles() ? 2 : 0; - break; - - case CL_DEVICE_PREFERRED_VECTOR_WIDTH_HALF: - buf.as_scalar<cl_uint>() = dev.has_halves() ? 8 : 0; - break; - - case CL_DEVICE_MAX_CLOCK_FREQUENCY: - buf.as_scalar<cl_uint>() = dev.max_clock_frequency(); - break; - - case CL_DEVICE_ADDRESS_BITS: - buf.as_scalar<cl_uint>() = dev.address_bits(); - break; - - case CL_DEVICE_MAX_READ_IMAGE_ARGS: - buf.as_scalar<cl_uint>() = dev.max_images_read(); - break; - - case CL_DEVICE_MAX_WRITE_IMAGE_ARGS: - buf.as_scalar<cl_uint>() = dev.max_images_write(); - break; - - case CL_DEVICE_MAX_MEM_ALLOC_SIZE: - buf.as_scalar<cl_ulong>() = dev.max_mem_alloc_size(); - break; - - case CL_DEVICE_IMAGE2D_MAX_WIDTH: - case CL_DEVICE_IMAGE2D_MAX_HEIGHT: - buf.as_scalar<size_t>() = 1 << dev.max_image_levels_2d(); - break; - - case CL_DEVICE_IMAGE3D_MAX_WIDTH: - case CL_DEVICE_IMAGE3D_MAX_HEIGHT: - case CL_DEVICE_IMAGE3D_MAX_DEPTH: - buf.as_scalar<size_t>() = 1 << dev.max_image_levels_3d(); - break; - - case CL_DEVICE_IMAGE_MAX_BUFFER_SIZE: - buf.as_scalar<size_t>() = dev.max_image_buffer_size(); - break; - - case CL_DEVICE_IMAGE_MAX_ARRAY_SIZE: - buf.as_scalar<size_t>() = dev.max_image_array_number(); - break; - - case CL_DEVICE_IMAGE_SUPPORT: - buf.as_scalar<cl_bool>() = dev.image_support(); - break; - - case CL_DEVICE_MAX_PARAMETER_SIZE: - buf.as_scalar<size_t>() = dev.max_mem_input(); - break; - - case CL_DEVICE_MAX_SAMPLERS: - buf.as_scalar<cl_uint>() = dev.max_samplers(); - break; - - case CL_DEVICE_MEM_BASE_ADDR_ALIGN: - buf.as_scalar<cl_uint>() = 8 * - std::max(dev.mem_base_addr_align(), (cl_uint) sizeof(cl_long) * 16); - break; - - case CL_DEVICE_MIN_DATA_TYPE_ALIGN_SIZE: - buf.as_scalar<cl_uint>() = 128; - break; - - case CL_DEVICE_HALF_FP_CONFIG: - // This is the "mandated minimum half precision floating-point - // capability" for OpenCL 1.x. - buf.as_scalar<cl_device_fp_config>() = - CL_FP_INF_NAN | CL_FP_ROUND_TO_NEAREST; - break; - - case CL_DEVICE_SINGLE_FP_CONFIG: - // This is the "mandated minimum single precision floating-point - // capability" for OpenCL 1.1. In OpenCL 1.2, nothing is required for - // custom devices. - buf.as_scalar<cl_device_fp_config>() = - CL_FP_INF_NAN | CL_FP_ROUND_TO_NEAREST; - break; - - case CL_DEVICE_DOUBLE_FP_CONFIG: - if (dev.has_doubles()) - // This is the "mandated minimum double precision floating-point - // capability" - buf.as_scalar<cl_device_fp_config>() = - CL_FP_FMA - | CL_FP_ROUND_TO_NEAREST - | CL_FP_ROUND_TO_ZERO - | CL_FP_ROUND_TO_INF - | CL_FP_INF_NAN - | CL_FP_DENORM; - else - buf.as_scalar<cl_device_fp_config>() = 0; - break; - - case CL_DEVICE_GLOBAL_MEM_CACHE_TYPE: - buf.as_scalar<cl_device_mem_cache_type>() = CL_NONE; - break; - - case CL_DEVICE_GLOBAL_MEM_CACHELINE_SIZE: - buf.as_scalar<cl_uint>() = 0; - break; - - case CL_DEVICE_GLOBAL_MEM_CACHE_SIZE: - buf.as_scalar<cl_ulong>() = 0; - break; - - case CL_DEVICE_GLOBAL_MEM_SIZE: - buf.as_scalar<cl_ulong>() = dev.max_mem_global(); - break; - - case CL_DEVICE_MAX_CONSTANT_BUFFER_SIZE: - buf.as_scalar<cl_ulong>() = dev.max_const_buffer_size(); - break; - - case CL_DEVICE_MAX_CONSTANT_ARGS: - buf.as_scalar<cl_uint>() = dev.max_const_buffers(); - break; - - case CL_DEVICE_LOCAL_MEM_TYPE: - buf.as_scalar<cl_device_local_mem_type>() = CL_LOCAL; - break; - - case CL_DEVICE_LOCAL_MEM_SIZE: - buf.as_scalar<cl_ulong>() = dev.max_mem_local(); - break; - - case CL_DEVICE_ERROR_CORRECTION_SUPPORT: - buf.as_scalar<cl_bool>() = CL_FALSE; - break; - - case CL_DEVICE_PROFILING_TIMER_RESOLUTION: - buf.as_scalar<size_t>() = 0; - break; - - case CL_DEVICE_ENDIAN_LITTLE: - buf.as_scalar<cl_bool>() = (dev.endianness() == PIPE_ENDIAN_LITTLE); - break; - - case CL_DEVICE_AVAILABLE: - case CL_DEVICE_COMPILER_AVAILABLE: - case CL_DEVICE_LINKER_AVAILABLE: - buf.as_scalar<cl_bool>() = CL_TRUE; - break; - - case CL_DEVICE_EXECUTION_CAPABILITIES: - buf.as_scalar<cl_device_exec_capabilities>() = CL_EXEC_KERNEL; - break; - - case CL_DEVICE_QUEUE_PROPERTIES: - buf.as_scalar<cl_command_queue_properties>() = CL_QUEUE_PROFILING_ENABLE; - break; - - case CL_DEVICE_BUILT_IN_KERNELS: - buf.as_string() = ""; - break; - - case CL_DEVICE_NAME: - buf.as_string() = dev.device_name(); - break; - - case CL_DEVICE_VENDOR: - buf.as_string() = dev.vendor_name(); - break; - - case CL_DRIVER_VERSION: - buf.as_string() = PACKAGE_VERSION; - break; - - case CL_DEVICE_PROFILE: - buf.as_string() = "FULL_PROFILE"; - break; - - case CL_DEVICE_VERSION: - buf.as_string() = "OpenCL " + dev.device_version() + " Mesa " PACKAGE_VERSION MESA_GIT_SHA1; - break; - - case CL_DEVICE_EXTENSIONS: - buf.as_string() = dev.supported_extensions(); - break; - - case CL_DEVICE_PLATFORM: - buf.as_scalar<cl_platform_id>() = desc(dev.platform); - break; - - case CL_DEVICE_HOST_UNIFIED_MEMORY: - buf.as_scalar<cl_bool>() = dev.has_unified_memory(); - break; - - case CL_DEVICE_NATIVE_VECTOR_WIDTH_CHAR: - buf.as_scalar<cl_uint>() = 16; - break; - - case CL_DEVICE_NATIVE_VECTOR_WIDTH_SHORT: - buf.as_scalar<cl_uint>() = 8; - break; - - case CL_DEVICE_NATIVE_VECTOR_WIDTH_INT: - buf.as_scalar<cl_uint>() = 4; - break; - - case CL_DEVICE_NATIVE_VECTOR_WIDTH_LONG: - buf.as_scalar<cl_uint>() = 2; - break; - - case CL_DEVICE_NATIVE_VECTOR_WIDTH_FLOAT: - buf.as_scalar<cl_uint>() = 4; - break; - - case CL_DEVICE_NATIVE_VECTOR_WIDTH_DOUBLE: - buf.as_scalar<cl_uint>() = dev.has_doubles() ? 2 : 0; - break; - - case CL_DEVICE_NATIVE_VECTOR_WIDTH_HALF: - buf.as_scalar<cl_uint>() = dev.has_halves() ? 8 : 0; - break; - - case CL_DEVICE_OPENCL_C_VERSION: - buf.as_string() = "OpenCL C " + dev.device_clc_version() + " "; - break; - - case CL_DEVICE_PRINTF_BUFFER_SIZE: - // Per the spec, the minimum value for the FULL profile is 1 MB. - // However, clover is not ready yet to support it - buf.as_scalar<size_t>() = 0 /* 1024 */; - break; - - case CL_DEVICE_PREFERRED_INTEROP_USER_SYNC: - buf.as_scalar<cl_bool>() = CL_TRUE; - break; - - case CL_DEVICE_PARENT_DEVICE: - buf.as_scalar<cl_device_id>() = NULL; - break; - - case CL_DEVICE_PARTITION_MAX_SUB_DEVICES: - buf.as_scalar<cl_uint>() = 0; - break; - - case CL_DEVICE_PARTITION_PROPERTIES: - buf.as_vector<cl_device_partition_property>() = - desc(property_list<cl_device_partition_property>()); - break; - - case CL_DEVICE_PARTITION_AFFINITY_DOMAIN: - buf.as_scalar<cl_device_affinity_domain>() = 0; - break; - - case CL_DEVICE_PARTITION_TYPE: - buf.as_vector<cl_device_partition_property>() = - desc(property_list<cl_device_partition_property>()); - break; - - case CL_DEVICE_REFERENCE_COUNT: - buf.as_scalar<cl_uint>() = 1; - break; - - case CL_DEVICE_SVM_CAPABILITIES: - case CL_DEVICE_SVM_CAPABILITIES_ARM: - buf.as_scalar<cl_device_svm_capabilities>() = dev.svm_support(); - break; - - default: - throw error(CL_INVALID_VALUE); - } - - return CL_SUCCESS; - -} catch (error &e) { - return e.get(); -} diff --git a/src/gallium/state_trackers/clover/api/dispatch.cpp b/src/gallium/state_trackers/clover/api/dispatch.cpp deleted file mode 100644 index 6e1b0351afa..00000000000 --- a/src/gallium/state_trackers/clover/api/dispatch.cpp +++ /dev/null @@ -1,174 +0,0 @@ -// -// Copyright 2013 Francisco Jerez -// -// Permission is hereby granted, free of charge, to any person obtaining a -// copy of this software and associated documentation files (the "Software"), -// to deal in the Software without restriction, including without limitation -// the rights to use, copy, modify, merge, publish, distribute, sublicense, -// and/or sell copies of the Software, and to permit persons to whom the -// Software is furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL -// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR -// OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, -// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR -// OTHER DEALINGS IN THE SOFTWARE. -// - -#include "api/dispatch.hpp" - -namespace clover { - const cl_icd_dispatch _dispatch = { - clGetPlatformIDs, - GetPlatformInfo, - clGetDeviceIDs, - clGetDeviceInfo, - clCreateContext, - clCreateContextFromType, - clRetainContext, - clReleaseContext, - clGetContextInfo, - clCreateCommandQueue, - clRetainCommandQueue, - clReleaseCommandQueue, - clGetCommandQueueInfo, - NULL, // clSetCommandQueueProperty - clCreateBuffer, - clCreateImage2D, - clCreateImage3D, - clRetainMemObject, - clReleaseMemObject, - clGetSupportedImageFormats, - clGetMemObjectInfo, - clGetImageInfo, - clCreateSampler, - clRetainSampler, - clReleaseSampler, - clGetSamplerInfo, - clCreateProgramWithSource, - clCreateProgramWithBinary, - clRetainProgram, - clReleaseProgram, - clBuildProgram, - clUnloadCompiler, - clGetProgramInfo, - clGetProgramBuildInfo, - clCreateKernel, - clCreateKernelsInProgram, - clRetainKernel, - clReleaseKernel, - clSetKernelArg, - clGetKernelInfo, - clGetKernelWorkGroupInfo, - clWaitForEvents, - clGetEventInfo, - clRetainEvent, - clReleaseEvent, - clGetEventProfilingInfo, - clFlush, - clFinish, - clEnqueueReadBuffer, - clEnqueueWriteBuffer, - clEnqueueCopyBuffer, - clEnqueueReadImage, - clEnqueueWriteImage, - clEnqueueCopyImage, - clEnqueueCopyImageToBuffer, - clEnqueueCopyBufferToImage, - clEnqueueMapBuffer, - clEnqueueMapImage, - clEnqueueUnmapMemObject, - clEnqueueNDRangeKernel, - clEnqueueTask, - clEnqueueNativeKernel, - clEnqueueMarker, - clEnqueueWaitForEvents, - clEnqueueBarrier, - GetExtensionFunctionAddress, - NULL, // clCreateFromGLBuffer - NULL, // clCreateFromGLTexture2D - NULL, // clCreateFromGLTexture3D - NULL, // clCreateFromGLRenderbuffer - NULL, // clGetGLObjectInfo - NULL, // clGetGLTextureInfo - NULL, // clEnqueueAcquireGLObjects - NULL, // clEnqueueReleaseGLObjects - NULL, // clGetGLContextInfoKHR - NULL, // clGetDeviceIDsFromD3D10KHR - NULL, // clCreateFromD3D10BufferKHR - NULL, // clCreateFromD3D10Texture2DKHR - NULL, // clCreateFromD3D10Texture3DKHR - NULL, // clEnqueueAcquireD3D10ObjectsKHR - NULL, // clEnqueueReleaseD3D10ObjectsKHR - clSetEventCallback, - clCreateSubBuffer, - clSetMemObjectDestructorCallback, - clCreateUserEvent, - clSetUserEventStatus, - clEnqueueReadBufferRect, - clEnqueueWriteBufferRect, - clEnqueueCopyBufferRect, - NULL, // clCreateSubDevicesEXT - NULL, // clRetainDeviceEXT - NULL, // clReleaseDeviceEXT - NULL, // clCreateEventFromGLsyncKHR - clCreateSubDevices, - clRetainDevice, - clReleaseDevice, - clCreateImage, - clCreateProgramWithBuiltInKernels, - clCompileProgram, - clLinkProgram, - clUnloadPlatformCompiler, - clGetKernelArgInfo, - clEnqueueFillBuffer, - clEnqueueFillImage, - clEnqueueMigrateMemObjects, - clEnqueueMarkerWithWaitList, - clEnqueueBarrierWithWaitList, - GetExtensionFunctionAddressForPlatform, - NULL, // clCreateFromGLTexture - NULL, // clGetDeviceIDsFromD3D11KHR - NULL, // clCreateFromD3D11BufferKHR - NULL, // clCreateFromD3D11Texture2DKHR - NULL, // clCreateFromD3D11Texture3DKHR - NULL, // clCreateFromDX9MediaSurfaceKHR - NULL, // clEnqueueAcquireD3D11ObjectsKHR - NULL, // clEnqueueReleaseD3D11ObjectsKHR - NULL, // clGetDeviceIDsFromDX9MediaAdapterKHR - NULL, // clEnqueueAcquireDX9MediaSurfacesKHR - NULL, // clEnqueueReleaseDX9MediaSurfacesKHR - NULL, // clCreateFromEGLImageKHR - NULL, // clEnqueueAcquireEGLObjectsKHR - NULL, // clEnqueueReleaseEGLObjectsKHR - NULL, // clCreateEventFromEGLSyncKHR - clCreateCommandQueueWithProperties, - NULL, // clCreatePipe - NULL, // clGetPipeInfo - clSVMAlloc, - clSVMFree, - clEnqueueSVMFree, - clEnqueueSVMMemcpy, - clEnqueueSVMMemFill, - clEnqueueSVMMap, - clEnqueueSVMUnmap, - NULL, // clCreateSamplerWithProperties - clSetKernelArgSVMPointer, - clSetKernelExecInfo, - NULL, // clGetKernelSubGroupInfoKHR - NULL, // clCloneKernel - NULL, // clCreateProgramWithIL - clEnqueueSVMMigrateMem, - NULL, // clGetDeviceAndHostTimer - NULL, // clGetHostTimer - NULL, // clGetKernelSubGroupInfo - NULL, // clSetDefaultDeviceCommandQueue - NULL, // clSetProgramReleaseCallback - NULL, // clSetProgramSpecializationConstant - }; -} diff --git a/src/gallium/state_trackers/clover/api/dispatch.hpp b/src/gallium/state_trackers/clover/api/dispatch.hpp deleted file mode 100644 index ea835ed6da4..00000000000 --- a/src/gallium/state_trackers/clover/api/dispatch.hpp +++ /dev/null @@ -1,105 +0,0 @@ -// -// Copyright 2013 Francisco Jerez -// -// Permission is hereby granted, free of charge, to any person obtaining a -// copy of this software and associated documentation files (the "Software"), -// to deal in the Software without restriction, including without limitation -// the rights to use, copy, modify, merge, publish, distribute, sublicense, -// and/or sell copies of the Software, and to permit persons to whom the -// Software is furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL -// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR -// OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, -// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR -// OTHER DEALINGS IN THE SOFTWARE. -// - -#ifndef API_DISPATCH_HPP -#define API_DISPATCH_HPP - -#include "CL/cl.h" -#include "CL/cl_ext.h" -#include "CL/cl_egl.h" -#include "CL/cl_gl.h" -#include "CL/cl_icd.h" - -namespace clover { - extern const cl_icd_dispatch _dispatch; - - cl_int - GetPlatformInfo(cl_platform_id d_platform, cl_platform_info param, - size_t size, void *r_buf, size_t *r_size); - - void * - GetExtensionFunctionAddress(const char *p_name); - - void * - GetExtensionFunctionAddressForPlatform(cl_platform_id d_platform, - const char *p_name); - - cl_int - IcdGetPlatformIDsKHR(cl_uint num_entries, cl_platform_id *rd_platforms, - cl_uint *rnum_platforms); - - cl_int - EnqueueSVMFree(cl_command_queue command_queue, - cl_uint num_svm_pointers, - void *svm_pointers[], - void (CL_CALLBACK *pfn_free_func) ( - cl_command_queue queue, cl_uint num_svm_pointers, - void *svm_pointers[], void *user_data), - void *user_data, - cl_uint num_events_in_wait_list, - const cl_event *event_wait_list, - cl_event *event, - cl_int cmd); - - cl_int - EnqueueSVMMemcpy(cl_command_queue command_queue, - cl_bool blocking_copy, - void *dst_ptr, - const void *src_ptr, - size_t size, - cl_uint num_events_in_wait_list, - const cl_event *event_wait_list, - cl_event *event, - cl_int cmd); - - cl_int - EnqueueSVMMap(cl_command_queue command_queue, - cl_bool blocking_map, - cl_map_flags map_flags, - void *svm_ptr, - size_t size, - cl_uint num_events_in_wait_list, - const cl_event *event_wait_list, - cl_event *event, - cl_int cmd); - - cl_int - EnqueueSVMMemFill(cl_command_queue command_queue, - void *svm_ptr, - const void *pattern, - size_t pattern_size, - size_t size, - cl_uint num_events_in_wait_list, - const cl_event *event_wait_list, - cl_event *event, - cl_int cmd); - - cl_int - EnqueueSVMUnmap(cl_command_queue command_queue, - void *svm_ptr, - cl_uint num_events_in_wait_list, - const cl_event *event_wait_list, - cl_event *event, - cl_int cmd); -} - -#endif diff --git a/src/gallium/state_trackers/clover/api/event.cpp b/src/gallium/state_trackers/clover/api/event.cpp deleted file mode 100644 index 3f89644d0a4..00000000000 --- a/src/gallium/state_trackers/clover/api/event.cpp +++ /dev/null @@ -1,309 +0,0 @@ -// -// Copyright 2012 Francisco Jerez -// -// Permission is hereby granted, free of charge, to any person obtaining a -// copy of this software and associated documentation files (the "Software"), -// to deal in the Software without restriction, including without limitation -// the rights to use, copy, modify, merge, publish, distribute, sublicense, -// and/or sell copies of the Software, and to permit persons to whom the -// Software is furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL -// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR -// OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, -// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR -// OTHER DEALINGS IN THE SOFTWARE. -// - -#include "api/util.hpp" -#include "core/event.hpp" - -using namespace clover; - -CLOVER_API cl_event -clCreateUserEvent(cl_context d_ctx, cl_int *r_errcode) try { - auto &ctx = obj(d_ctx); - - ret_error(r_errcode, CL_SUCCESS); - return desc(new soft_event(ctx, {}, false)); - -} catch (error &e) { - ret_error(r_errcode, e); - return NULL; -} - -CLOVER_API cl_int -clSetUserEventStatus(cl_event d_ev, cl_int status) try { - auto &sev = obj<soft_event>(d_ev); - - if (status > 0) - return CL_INVALID_VALUE; - - if (sev.status() <= 0) - return CL_INVALID_OPERATION; - - if (status) - sev.abort(status); - else - sev.trigger(); - - return CL_SUCCESS; - -} catch (error &e) { - return e.get(); -} - -CLOVER_API cl_int -clWaitForEvents(cl_uint num_evs, const cl_event *d_evs) try { - auto evs = objs(d_evs, num_evs); - - for (auto &ev : evs) { - if (ev.context() != evs.front().context()) - throw error(CL_INVALID_CONTEXT); - - if (ev.status() < 0) - throw error(CL_EXEC_STATUS_ERROR_FOR_EVENTS_IN_WAIT_LIST); - } - - // Create a temporary soft event that depends on all the events in - // the wait list - auto sev = create<soft_event>(evs.front().context(), evs, true); - - // ...and wait on it. - sev().wait(); - - return CL_SUCCESS; - -} catch (error &e) { - return e.get(); -} - -CLOVER_API cl_int -clGetEventInfo(cl_event d_ev, cl_event_info param, - size_t size, void *r_buf, size_t *r_size) try { - property_buffer buf { r_buf, size, r_size }; - auto &ev = obj(d_ev); - - switch (param) { - case CL_EVENT_COMMAND_QUEUE: - buf.as_scalar<cl_command_queue>() = desc(ev.queue()); - break; - - case CL_EVENT_CONTEXT: - buf.as_scalar<cl_context>() = desc(ev.context()); - break; - - case CL_EVENT_COMMAND_TYPE: - buf.as_scalar<cl_command_type>() = ev.command(); - break; - - case CL_EVENT_COMMAND_EXECUTION_STATUS: - buf.as_scalar<cl_int>() = ev.status(); - break; - - case CL_EVENT_REFERENCE_COUNT: - buf.as_scalar<cl_uint>() = ev.ref_count(); - break; - - default: - throw error(CL_INVALID_VALUE); - } - - return CL_SUCCESS; - -} catch (error &e) { - return e.get(); -} - -CLOVER_API cl_int -clSetEventCallback(cl_event d_ev, cl_int type, - void (CL_CALLBACK *pfn_notify)(cl_event, cl_int, void *), - void *user_data) try { - auto &ev = obj(d_ev); - - if (!pfn_notify || - (type != CL_COMPLETE && type != CL_SUBMITTED && type != CL_RUNNING)) - throw error(CL_INVALID_VALUE); - - // Create a temporary soft event that depends on ev, with - // pfn_notify as completion action. - create<soft_event>(ev.context(), ref_vector<event> { ev }, true, - [=, &ev](event &) { - ev.wait(); - pfn_notify(desc(ev), ev.status(), user_data); - }); - - return CL_SUCCESS; - -} catch (error &e) { - return e.get(); -} - -CLOVER_API cl_int -clRetainEvent(cl_event d_ev) try { - obj(d_ev).retain(); - return CL_SUCCESS; - -} catch (error &e) { - return e.get(); -} - -CLOVER_API cl_int -clReleaseEvent(cl_event d_ev) try { - if (obj(d_ev).release()) - delete pobj(d_ev); - - return CL_SUCCESS; - -} catch (error &e) { - return e.get(); -} - -CLOVER_API cl_int -clEnqueueMarker(cl_command_queue d_q, cl_event *rd_ev) try { - auto &q = obj(d_q); - - if (!rd_ev) - throw error(CL_INVALID_VALUE); - - *rd_ev = desc(new hard_event(q, CL_COMMAND_MARKER, {})); - - return CL_SUCCESS; - -} catch (error &e) { - return e.get(); -} - -CLOVER_API cl_int -clEnqueueMarkerWithWaitList(cl_command_queue d_q, cl_uint num_deps, - const cl_event *d_deps, cl_event *rd_ev) try { - auto &q = obj(d_q); - auto deps = objs<wait_list_tag>(d_deps, num_deps); - - for (auto &ev : deps) { - if (ev.context() != q.context()) - throw error(CL_INVALID_CONTEXT); - } - - // Create a hard event that depends on the events in the wait list: - // previous commands in the same queue are implicitly serialized - // with respect to it -- hard events always are. - auto hev = create<hard_event>(q, CL_COMMAND_MARKER, deps); - - ret_object(rd_ev, hev); - return CL_SUCCESS; - -} catch (error &e) { - return e.get(); -} - -CLOVER_API cl_int -clEnqueueBarrier(cl_command_queue d_q) try { - obj(d_q); - - // No need to do anything, q preserves data ordering strictly. - - return CL_SUCCESS; - -} catch (error &e) { - return e.get(); -} - -CLOVER_API cl_int -clEnqueueBarrierWithWaitList(cl_command_queue d_q, cl_uint num_deps, - const cl_event *d_deps, cl_event *rd_ev) try { - auto &q = obj(d_q); - auto deps = objs<wait_list_tag>(d_deps, num_deps); - - for (auto &ev : deps) { - if (ev.context() != q.context()) - throw error(CL_INVALID_CONTEXT); - } - - // Create a hard event that depends on the events in the wait list: - // subsequent commands in the same queue will be implicitly - // serialized with respect to it -- hard events always are. - auto hev = create<hard_event>(q, CL_COMMAND_BARRIER, deps); - - ret_object(rd_ev, hev); - return CL_SUCCESS; - -} catch (error &e) { - return e.get(); -} - -CLOVER_API cl_int -clEnqueueWaitForEvents(cl_command_queue d_q, cl_uint num_evs, - const cl_event *d_evs) try { - // The wait list is mandatory for clEnqueueWaitForEvents(). - objs(d_evs, num_evs); - - return clEnqueueBarrierWithWaitList(d_q, num_evs, d_evs, NULL); - -} catch (error &e) { - return e.get(); -} - -CLOVER_API cl_int -clGetEventProfilingInfo(cl_event d_ev, cl_profiling_info param, - size_t size, void *r_buf, size_t *r_size) try { - property_buffer buf { r_buf, size, r_size }; - hard_event &hev = dynamic_cast<hard_event &>(obj(d_ev)); - - if (hev.status() != CL_COMPLETE) - throw error(CL_PROFILING_INFO_NOT_AVAILABLE); - - switch (param) { - case CL_PROFILING_COMMAND_QUEUED: - buf.as_scalar<cl_ulong>() = hev.time_queued(); - break; - - case CL_PROFILING_COMMAND_SUBMIT: - buf.as_scalar<cl_ulong>() = hev.time_submit(); - break; - - case CL_PROFILING_COMMAND_START: - buf.as_scalar<cl_ulong>() = hev.time_start(); - break; - - case CL_PROFILING_COMMAND_END: - buf.as_scalar<cl_ulong>() = hev.time_end(); - break; - - default: - throw error(CL_INVALID_VALUE); - } - - return CL_SUCCESS; - -} catch (std::bad_cast &e) { - return CL_PROFILING_INFO_NOT_AVAILABLE; - -} catch (lazy<cl_ulong>::undefined_error &e) { - return CL_PROFILING_INFO_NOT_AVAILABLE; - -} catch (error &e) { - return e.get(); -} - -CLOVER_API cl_int -clFinish(cl_command_queue d_q) try { - auto &q = obj(d_q); - - // Create a temporary hard event -- it implicitly depends on all - // the previously queued hard events. - auto hev = create<hard_event>(q, 0, ref_vector<event> {}); - - // And wait on it. - hev().wait(); - - return CL_SUCCESS; - -} catch (error &e) { - return e.get(); -} diff --git a/src/gallium/state_trackers/clover/api/interop.cpp b/src/gallium/state_trackers/clover/api/interop.cpp deleted file mode 100644 index b96069f5167..00000000000 --- a/src/gallium/state_trackers/clover/api/interop.cpp +++ /dev/null @@ -1,69 +0,0 @@ -// -// Copyright 2015 Advanced Micro Devices, Inc. -// All Rights Reserved. -// -// Permission is hereby granted, free of charge, to any person obtaining a -// copy of this software and associated documentation files (the "Software"), -// to deal in the Software without restriction, including without limitation -// the rights to use, copy, modify, merge, publish, distribute, sublicense, -// and/or sell copies of the Software, and to permit persons to whom the -// Software is furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL -// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR -// OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, -// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR -// OTHER DEALINGS IN THE SOFTWARE. -// - -#include "core/event.hpp" -#include "api/util.hpp" - -using namespace clover; - -extern "C" { - -PUBLIC bool -opencl_dri_event_add_ref(cl_event event) -{ - /* This should fail if the event hasn't been created by - * clEnqueueReleaseGLObjects or clEnqueueReleaseEGLObjects. - * - * TODO: implement the CL functions - */ - return false; /*return clRetainEvent(event) == CL_SUCCESS;*/ -} - -PUBLIC bool -opencl_dri_event_release(cl_event event) -{ - return clReleaseEvent(event) == CL_SUCCESS; -} - -PUBLIC bool -opencl_dri_event_wait(cl_event event, uint64_t timeout) try { - if (!timeout) { - return obj(event).status() == CL_COMPLETE; - } - - obj(event).wait(); - return true; - -} catch (error &) { - return false; -} - -PUBLIC struct pipe_fence_handle * -opencl_dri_event_get_fence(cl_event event) try { - return obj(event).fence(); - -} catch (error &) { - return NULL; -} - -} diff --git a/src/gallium/state_trackers/clover/api/kernel.cpp b/src/gallium/state_trackers/clover/api/kernel.cpp deleted file mode 100644 index 31a87b63868..00000000000 --- a/src/gallium/state_trackers/clover/api/kernel.cpp +++ /dev/null @@ -1,390 +0,0 @@ -// -// Copyright 2012 Francisco Jerez -// -// Permission is hereby granted, free of charge, to any person obtaining a -// copy of this software and associated documentation files (the "Software"), -// to deal in the Software without restriction, including without limitation -// the rights to use, copy, modify, merge, publish, distribute, sublicense, -// and/or sell copies of the Software, and to permit persons to whom the -// Software is furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL -// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR -// OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, -// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR -// OTHER DEALINGS IN THE SOFTWARE. -// - -#include "api/util.hpp" -#include "core/kernel.hpp" -#include "core/event.hpp" - -using namespace clover; - -CLOVER_API cl_kernel -clCreateKernel(cl_program d_prog, const char *name, cl_int *r_errcode) try { - auto &prog = obj(d_prog); - - if (!name) - throw error(CL_INVALID_VALUE); - - auto &sym = find(name_equals(name), prog.symbols()); - - ret_error(r_errcode, CL_SUCCESS); - return new kernel(prog, name, range(sym.args)); - -} catch (std::out_of_range &e) { - ret_error(r_errcode, CL_INVALID_KERNEL_NAME); - return NULL; - -} catch (error &e) { - ret_error(r_errcode, e); - return NULL; -} - -CLOVER_API cl_int -clCreateKernelsInProgram(cl_program d_prog, cl_uint count, - cl_kernel *rd_kerns, cl_uint *r_count) try { - auto &prog = obj(d_prog); - auto &syms = prog.symbols(); - - if (rd_kerns && count < syms.size()) - throw error(CL_INVALID_VALUE); - - if (rd_kerns) - copy(map([&](const module::symbol &sym) { - return desc(new kernel(prog, - std::string(sym.name.begin(), - sym.name.end()), - range(sym.args))); - }, syms), - rd_kerns); - - if (r_count) - *r_count = syms.size(); - - return CL_SUCCESS; - -} catch (error &e) { - return e.get(); -} - -CLOVER_API cl_int -clRetainKernel(cl_kernel d_kern) try { - obj(d_kern).retain(); - return CL_SUCCESS; - -} catch (error &e) { - return e.get(); -} - -CLOVER_API cl_int -clReleaseKernel(cl_kernel d_kern) try { - if (obj(d_kern).release()) - delete pobj(d_kern); - - return CL_SUCCESS; - -} catch (error &e) { - return e.get(); -} - -CLOVER_API cl_int -clSetKernelArg(cl_kernel d_kern, cl_uint idx, size_t size, - const void *value) try { - obj(d_kern).args().at(idx).set(size, value); - return CL_SUCCESS; - -} catch (std::out_of_range &e) { - return CL_INVALID_ARG_INDEX; - -} catch (error &e) { - return e.get(); -} - -CLOVER_API cl_int -clGetKernelInfo(cl_kernel d_kern, cl_kernel_info param, - size_t size, void *r_buf, size_t *r_size) try { - property_buffer buf { r_buf, size, r_size }; - auto &kern = obj(d_kern); - - switch (param) { - case CL_KERNEL_FUNCTION_NAME: - buf.as_string() = kern.name(); - break; - - case CL_KERNEL_NUM_ARGS: - buf.as_scalar<cl_uint>() = kern.args().size(); - break; - - case CL_KERNEL_REFERENCE_COUNT: - buf.as_scalar<cl_uint>() = kern.ref_count(); - break; - - case CL_KERNEL_CONTEXT: - buf.as_scalar<cl_context>() = desc(kern.program().context()); - break; - - case CL_KERNEL_PROGRAM: - buf.as_scalar<cl_program>() = desc(kern.program()); - break; - - default: - throw error(CL_INVALID_VALUE); - } - - return CL_SUCCESS; - -} catch (error &e) { - return e.get(); -} - -CLOVER_API cl_int -clGetKernelWorkGroupInfo(cl_kernel d_kern, cl_device_id d_dev, - cl_kernel_work_group_info param, - size_t size, void *r_buf, size_t *r_size) try { - property_buffer buf { r_buf, size, r_size }; - auto &kern = obj(d_kern); - auto &dev = (d_dev ? *pobj(d_dev) : unique(kern.program().devices())); - - if (!count(dev, kern.program().devices())) - throw error(CL_INVALID_DEVICE); - - switch (param) { - case CL_KERNEL_WORK_GROUP_SIZE: - buf.as_scalar<size_t>() = dev.max_threads_per_block(); - break; - - case CL_KERNEL_COMPILE_WORK_GROUP_SIZE: - buf.as_vector<size_t>() = kern.required_block_size(); - break; - - case CL_KERNEL_LOCAL_MEM_SIZE: - buf.as_scalar<cl_ulong>() = kern.mem_local(); - break; - - case CL_KERNEL_PREFERRED_WORK_GROUP_SIZE_MULTIPLE: - buf.as_scalar<size_t>() = dev.subgroup_size(); - break; - - case CL_KERNEL_PRIVATE_MEM_SIZE: - buf.as_scalar<cl_ulong>() = kern.mem_private(); - break; - - default: - throw error(CL_INVALID_VALUE); - } - - return CL_SUCCESS; - -} catch (error &e) { - return e.get(); - -} catch (std::out_of_range &e) { - return CL_INVALID_DEVICE; -} - -CLOVER_API cl_int -clGetKernelArgInfo(cl_kernel d_kern, - cl_uint idx, cl_kernel_arg_info param, - size_t size, void *r_buf, size_t *r_size) { - CLOVER_NOT_SUPPORTED_UNTIL("1.2"); - return CL_KERNEL_ARG_INFO_NOT_AVAILABLE; -} - -namespace { - /// - /// Common argument checking shared by kernel invocation commands. - /// - void - validate_common(const command_queue &q, kernel &kern, - const ref_vector<event> &deps) { - if (kern.program().context() != q.context() || - any_of([&](const event &ev) { - return ev.context() != q.context(); - }, deps)) - throw error(CL_INVALID_CONTEXT); - - if (any_of([](kernel::argument &arg) { - return !arg.set(); - }, kern.args())) - throw error(CL_INVALID_KERNEL_ARGS); - - // If the command queue's device is not associated to the program, we get - // a module, with no sections, which will also fail the following test. - auto &m = kern.program().build(q.device()).binary; - if (!any_of(type_equals(module::section::text_executable), m.secs)) - throw error(CL_INVALID_PROGRAM_EXECUTABLE); - } - - std::vector<size_t> - validate_grid_size(const command_queue &q, cl_uint dims, - const size_t *d_grid_size) { - auto grid_size = range(d_grid_size, dims); - - if (dims < 1 || dims > q.device().max_block_size().size()) - throw error(CL_INVALID_WORK_DIMENSION); - - if (!d_grid_size || any_of(is_zero(), grid_size)) - throw error(CL_INVALID_GLOBAL_WORK_SIZE); - - return grid_size; - } - - std::vector<size_t> - validate_grid_offset(const command_queue &q, cl_uint dims, - const size_t *d_grid_offset) { - if (d_grid_offset) - return range(d_grid_offset, dims); - else - return std::vector<size_t>(dims, 0); - } - - std::vector<size_t> - validate_block_size(const command_queue &q, const kernel &kern, - cl_uint dims, const size_t *d_grid_size, - const size_t *d_block_size) { - auto grid_size = range(d_grid_size, dims); - - if (d_block_size) { - auto block_size = range(d_block_size, dims); - - if (any_of(is_zero(), block_size) || - any_of(greater(), block_size, q.device().max_block_size())) - throw error(CL_INVALID_WORK_ITEM_SIZE); - - if (any_of(modulus(), grid_size, block_size)) - throw error(CL_INVALID_WORK_GROUP_SIZE); - - if (fold(multiplies(), 1u, block_size) > - q.device().max_threads_per_block()) - throw error(CL_INVALID_WORK_GROUP_SIZE); - - return block_size; - - } else { - return kern.optimal_block_size(q, grid_size); - } - } -} - -CLOVER_API cl_int -clEnqueueNDRangeKernel(cl_command_queue d_q, cl_kernel d_kern, - cl_uint dims, const size_t *d_grid_offset, - const size_t *d_grid_size, const size_t *d_block_size, - cl_uint num_deps, const cl_event *d_deps, - cl_event *rd_ev) try { - auto &q = obj(d_q); - auto &kern = obj(d_kern); - auto deps = objs<wait_list_tag>(d_deps, num_deps); - auto grid_size = validate_grid_size(q, dims, d_grid_size); - auto grid_offset = validate_grid_offset(q, dims, d_grid_offset); - auto block_size = validate_block_size(q, kern, dims, - d_grid_size, d_block_size); - - validate_common(q, kern, deps); - - auto hev = create<hard_event>( - q, CL_COMMAND_NDRANGE_KERNEL, deps, - [=, &kern, &q](event &) { - kern.launch(q, grid_offset, grid_size, block_size); - }); - - ret_object(rd_ev, hev); - return CL_SUCCESS; - -} catch (error &e) { - return e.get(); -} - -CLOVER_API cl_int -clEnqueueTask(cl_command_queue d_q, cl_kernel d_kern, - cl_uint num_deps, const cl_event *d_deps, - cl_event *rd_ev) try { - auto &q = obj(d_q); - auto &kern = obj(d_kern); - auto deps = objs<wait_list_tag>(d_deps, num_deps); - - validate_common(q, kern, deps); - - auto hev = create<hard_event>( - q, CL_COMMAND_TASK, deps, - [=, &kern, &q](event &) { - kern.launch(q, { 0 }, { 1 }, { 1 }); - }); - - ret_object(rd_ev, hev); - return CL_SUCCESS; - -} catch (error &e) { - return e.get(); -} - -CLOVER_API cl_int -clEnqueueNativeKernel(cl_command_queue d_q, void (*func)(void *), - void *args, size_t args_size, - cl_uint num_mems, const cl_mem *d_mems, - const void **mem_handles, cl_uint num_deps, - const cl_event *d_deps, cl_event *rd_ev) { - return CL_INVALID_OPERATION; -} - -CLOVER_API cl_int -clSetKernelArgSVMPointer(cl_kernel d_kern, - cl_uint arg_index, - const void *arg_value) try { - obj(d_kern).args().at(arg_index).set_svm(arg_value); - return CL_SUCCESS; - -} catch (std::out_of_range &e) { - return CL_INVALID_ARG_INDEX; - -} catch (error &e) { - return e.get(); -} - -CLOVER_API cl_int -clSetKernelExecInfo(cl_kernel d_kern, - cl_kernel_exec_info param_name, - size_t param_value_size, - const void *param_value) try { - auto &kern = obj(d_kern); - const bool has_system_svm = all_of(std::mem_fn(&device::has_system_svm), - kern.program().context().devices()); - - if (!param_value) - return CL_INVALID_VALUE; - - switch (param_name) { - case CL_KERNEL_EXEC_INFO_SVM_FINE_GRAIN_SYSTEM: - case CL_KERNEL_EXEC_INFO_SVM_FINE_GRAIN_SYSTEM_ARM: { - if (param_value_size != sizeof(cl_bool)) - return CL_INVALID_VALUE; - - cl_bool val = *static_cast<const cl_bool*>(param_value); - if (val == CL_TRUE && !has_system_svm) - return CL_INVALID_OPERATION; - else - return CL_SUCCESS; - } - - case CL_KERNEL_EXEC_INFO_SVM_PTRS: - case CL_KERNEL_EXEC_INFO_SVM_PTRS_ARM: - if (has_system_svm) - return CL_SUCCESS; - - CLOVER_NOT_SUPPORTED_UNTIL("2.0"); - return CL_INVALID_VALUE; - - default: - return CL_INVALID_VALUE; - } - -} catch (error &e) { - return e.get(); -} diff --git a/src/gallium/state_trackers/clover/api/memory.cpp b/src/gallium/state_trackers/clover/api/memory.cpp deleted file mode 100644 index e03793339c1..00000000000 --- a/src/gallium/state_trackers/clover/api/memory.cpp +++ /dev/null @@ -1,497 +0,0 @@ -// -// Copyright 2012 Francisco Jerez -// -// Permission is hereby granted, free of charge, to any person obtaining a -// copy of this software and associated documentation files (the "Software"), -// to deal in the Software without restriction, including without limitation -// the rights to use, copy, modify, merge, publish, distribute, sublicense, -// and/or sell copies of the Software, and to permit persons to whom the -// Software is furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL -// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR -// OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, -// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR -// OTHER DEALINGS IN THE SOFTWARE. -// - -#include "util/u_math.h" -#include "api/util.hpp" -#include "core/memory.hpp" -#include "core/format.hpp" - -using namespace clover; - -namespace { - cl_mem_flags - validate_flags(cl_mem d_parent, cl_mem_flags d_flags, bool svm) { - const cl_mem_flags dev_access_flags = - CL_MEM_READ_WRITE | CL_MEM_WRITE_ONLY | CL_MEM_READ_ONLY; - const cl_mem_flags host_ptr_flags = - CL_MEM_USE_HOST_PTR | CL_MEM_ALLOC_HOST_PTR | CL_MEM_COPY_HOST_PTR; - const cl_mem_flags host_access_flags = - CL_MEM_HOST_WRITE_ONLY | CL_MEM_HOST_READ_ONLY | CL_MEM_HOST_NO_ACCESS; - const cl_mem_flags svm_flags = - CL_MEM_SVM_FINE_GRAIN_BUFFER | CL_MEM_SVM_ATOMICS; - - const cl_mem_flags valid_flags = - dev_access_flags - | (svm || d_parent ? 0 : host_ptr_flags) - | (svm ? svm_flags : host_access_flags); - - if ((d_flags & ~valid_flags) || - util_bitcount(d_flags & dev_access_flags) > 1 || - util_bitcount(d_flags & host_access_flags) > 1) - throw error(CL_INVALID_VALUE); - - if ((d_flags & CL_MEM_USE_HOST_PTR) && - (d_flags & (CL_MEM_COPY_HOST_PTR | CL_MEM_ALLOC_HOST_PTR))) - throw error(CL_INVALID_VALUE); - - if ((d_flags & CL_MEM_SVM_ATOMICS) && - !(d_flags & CL_MEM_SVM_FINE_GRAIN_BUFFER)) - throw error(CL_INVALID_VALUE); - - if (d_parent) { - const auto &parent = obj(d_parent); - const cl_mem_flags flags = (d_flags | - (d_flags & dev_access_flags ? 0 : - parent.flags() & dev_access_flags) | - (d_flags & host_access_flags ? 0 : - parent.flags() & host_access_flags) | - (parent.flags() & host_ptr_flags)); - - if (~flags & parent.flags() & (dev_access_flags & ~CL_MEM_READ_WRITE)) - throw error(CL_INVALID_VALUE); - - // Check if new host access flags cause a mismatch between - // host-read/write-only. - if (!(flags & CL_MEM_HOST_NO_ACCESS) && - (~flags & parent.flags() & host_access_flags)) - throw error(CL_INVALID_VALUE); - - return flags; - - } else { - return d_flags | (d_flags & dev_access_flags ? 0 : CL_MEM_READ_WRITE); - } - } -} - -CLOVER_API cl_mem -clCreateBuffer(cl_context d_ctx, cl_mem_flags d_flags, size_t size, - void *host_ptr, cl_int *r_errcode) try { - const cl_mem_flags flags = validate_flags(NULL, d_flags, false); - auto &ctx = obj(d_ctx); - - if (bool(host_ptr) != bool(flags & (CL_MEM_USE_HOST_PTR | - CL_MEM_COPY_HOST_PTR))) - throw error(CL_INVALID_HOST_PTR); - - if (!size || - size > fold(maximum(), cl_ulong(0), - map(std::mem_fn(&device::max_mem_alloc_size), ctx.devices()) - )) - throw error(CL_INVALID_BUFFER_SIZE); - - ret_error(r_errcode, CL_SUCCESS); - return new root_buffer(ctx, flags, size, host_ptr); - -} catch (error &e) { - ret_error(r_errcode, e); - return NULL; -} - -CLOVER_API cl_mem -clCreateSubBuffer(cl_mem d_mem, cl_mem_flags d_flags, - cl_buffer_create_type op, - const void *op_info, cl_int *r_errcode) try { - auto &parent = obj<root_buffer>(d_mem); - const cl_mem_flags flags = validate_flags(d_mem, d_flags, false); - - if (op == CL_BUFFER_CREATE_TYPE_REGION) { - auto reg = reinterpret_cast<const cl_buffer_region *>(op_info); - - if (!reg || - reg->origin > parent.size() || - reg->origin + reg->size > parent.size()) - throw error(CL_INVALID_VALUE); - - if (!reg->size) - throw error(CL_INVALID_BUFFER_SIZE); - - ret_error(r_errcode, CL_SUCCESS); - return new sub_buffer(parent, flags, reg->origin, reg->size); - - } else { - throw error(CL_INVALID_VALUE); - } - -} catch (error &e) { - ret_error(r_errcode, e); - return NULL; -} - -CLOVER_API cl_mem -clCreateImage(cl_context d_ctx, cl_mem_flags d_flags, - const cl_image_format *format, - const cl_image_desc *desc, - void *host_ptr, cl_int *r_errcode) try { - auto &ctx = obj(d_ctx); - - if (!any_of(std::mem_fn(&device::image_support), ctx.devices())) - throw error(CL_INVALID_OPERATION); - - if (!format) - throw error(CL_INVALID_IMAGE_FORMAT_DESCRIPTOR); - - if (!desc) - throw error(CL_INVALID_IMAGE_DESCRIPTOR); - - if (desc->image_array_size == 0 && - (desc->image_type == CL_MEM_OBJECT_IMAGE1D_ARRAY || - desc->image_type == CL_MEM_OBJECT_IMAGE2D_ARRAY)) - throw error(CL_INVALID_IMAGE_DESCRIPTOR); - - if (!host_ptr && - (desc->image_row_pitch || desc->image_slice_pitch)) - throw error(CL_INVALID_IMAGE_DESCRIPTOR); - - if (desc->num_mip_levels || desc->num_samples) - throw error(CL_INVALID_IMAGE_DESCRIPTOR); - - if (bool(desc->buffer) != (desc->image_type == CL_MEM_OBJECT_IMAGE1D_BUFFER)) - throw error(CL_INVALID_IMAGE_DESCRIPTOR); - - if (bool(host_ptr) != bool(d_flags & (CL_MEM_USE_HOST_PTR | - CL_MEM_COPY_HOST_PTR))) - throw error(CL_INVALID_HOST_PTR); - - const cl_mem_flags flags = validate_flags(desc->buffer, d_flags, false); - - if (!supported_formats(ctx, desc->image_type).count(*format)) - throw error(CL_IMAGE_FORMAT_NOT_SUPPORTED); - - ret_error(r_errcode, CL_SUCCESS); - - switch (desc->image_type) { - case CL_MEM_OBJECT_IMAGE2D: - if (!desc->image_width || !desc->image_height) - throw error(CL_INVALID_IMAGE_SIZE); - - if (all_of([=](const device &dev) { - const size_t max = 1 << dev.max_image_levels_2d(); - return (desc->image_width > max || - desc->image_height > max); - }, ctx.devices())) - throw error(CL_INVALID_IMAGE_SIZE); - - return new image2d(ctx, flags, format, - desc->image_width, desc->image_height, - desc->image_row_pitch, host_ptr); - - case CL_MEM_OBJECT_IMAGE3D: - if (!desc->image_width || !desc->image_height || !desc->image_depth) - throw error(CL_INVALID_IMAGE_SIZE); - - if (all_of([=](const device &dev) { - const size_t max = 1 << dev.max_image_levels_3d(); - return (desc->image_width > max || - desc->image_height > max || - desc->image_depth > max); - }, ctx.devices())) - throw error(CL_INVALID_IMAGE_SIZE); - - return new image3d(ctx, flags, format, - desc->image_width, desc->image_height, - desc->image_depth, desc->image_row_pitch, - desc->image_slice_pitch, host_ptr); - - case CL_MEM_OBJECT_IMAGE1D: - case CL_MEM_OBJECT_IMAGE1D_ARRAY: - case CL_MEM_OBJECT_IMAGE1D_BUFFER: - case CL_MEM_OBJECT_IMAGE2D_ARRAY: - // XXX - Not implemented. - throw error(CL_IMAGE_FORMAT_NOT_SUPPORTED); - - default: - throw error(CL_INVALID_IMAGE_DESCRIPTOR); - } - -} catch (error &e) { - ret_error(r_errcode, e); - return NULL; -} - -CLOVER_API cl_mem -clCreateImage2D(cl_context d_ctx, cl_mem_flags d_flags, - const cl_image_format *format, - size_t width, size_t height, size_t row_pitch, - void *host_ptr, cl_int *r_errcode) { - const cl_image_desc desc = { CL_MEM_OBJECT_IMAGE2D, width, height, 0, 0, - row_pitch, 0, 0, 0, NULL }; - - return clCreateImage(d_ctx, d_flags, format, &desc, host_ptr, r_errcode); -} - -CLOVER_API cl_mem -clCreateImage3D(cl_context d_ctx, cl_mem_flags d_flags, - const cl_image_format *format, - size_t width, size_t height, size_t depth, - size_t row_pitch, size_t slice_pitch, - void *host_ptr, cl_int *r_errcode) { - const cl_image_desc desc = { CL_MEM_OBJECT_IMAGE3D, width, height, depth, 0, - row_pitch, slice_pitch, 0, 0, NULL }; - - return clCreateImage(d_ctx, d_flags, format, &desc, host_ptr, r_errcode); -} - -CLOVER_API cl_int -clGetSupportedImageFormats(cl_context d_ctx, cl_mem_flags flags, - cl_mem_object_type type, cl_uint count, - cl_image_format *r_buf, cl_uint *r_count) try { - auto &ctx = obj(d_ctx); - auto formats = supported_formats(ctx, type); - - validate_flags(NULL, flags, false); - - if (r_buf && !r_count) - throw error(CL_INVALID_VALUE); - - if (r_buf) - std::copy_n(formats.begin(), - std::min((cl_uint)formats.size(), count), - r_buf); - - if (r_count) - *r_count = formats.size(); - - return CL_SUCCESS; - -} catch (error &e) { - return e.get(); -} - -CLOVER_API cl_int -clGetMemObjectInfo(cl_mem d_mem, cl_mem_info param, - size_t size, void *r_buf, size_t *r_size) try { - property_buffer buf { r_buf, size, r_size }; - auto &mem = obj(d_mem); - - switch (param) { - case CL_MEM_TYPE: - buf.as_scalar<cl_mem_object_type>() = mem.type(); - break; - - case CL_MEM_FLAGS: - buf.as_scalar<cl_mem_flags>() = mem.flags(); - break; - - case CL_MEM_SIZE: - buf.as_scalar<size_t>() = mem.size(); - break; - - case CL_MEM_HOST_PTR: - buf.as_scalar<void *>() = mem.host_ptr(); - break; - - case CL_MEM_MAP_COUNT: - buf.as_scalar<cl_uint>() = 0; - break; - - case CL_MEM_REFERENCE_COUNT: - buf.as_scalar<cl_uint>() = mem.ref_count(); - break; - - case CL_MEM_CONTEXT: - buf.as_scalar<cl_context>() = desc(mem.context()); - break; - - case CL_MEM_ASSOCIATED_MEMOBJECT: { - sub_buffer *sub = dynamic_cast<sub_buffer *>(&mem); - buf.as_scalar<cl_mem>() = (sub ? desc(sub->parent()) : NULL); - break; - } - case CL_MEM_OFFSET: { - sub_buffer *sub = dynamic_cast<sub_buffer *>(&mem); - buf.as_scalar<size_t>() = (sub ? sub->offset() : 0); - break; - } - case CL_MEM_USES_SVM_POINTER: - case CL_MEM_USES_SVM_POINTER_ARM: { - // with system SVM all host ptrs are SVM pointers - // TODO: once we support devices with lower levels of SVM, we have to - // check the ptr in more detail - const bool system_svm = all_of(std::mem_fn(&device::has_system_svm), - mem.context().devices()); - buf.as_scalar<cl_bool>() = mem.host_ptr() && system_svm; - break; - } - default: - throw error(CL_INVALID_VALUE); - } - - return CL_SUCCESS; - -} catch (error &e) { - return e.get(); -} - -CLOVER_API cl_int -clGetImageInfo(cl_mem d_mem, cl_image_info param, - size_t size, void *r_buf, size_t *r_size) try { - property_buffer buf { r_buf, size, r_size }; - auto &img = obj<image>(d_mem); - - switch (param) { - case CL_IMAGE_FORMAT: - buf.as_scalar<cl_image_format>() = img.format(); - break; - - case CL_IMAGE_ELEMENT_SIZE: - buf.as_scalar<size_t>() = 0; - break; - - case CL_IMAGE_ROW_PITCH: - buf.as_scalar<size_t>() = img.row_pitch(); - break; - - case CL_IMAGE_SLICE_PITCH: - buf.as_scalar<size_t>() = img.slice_pitch(); - break; - - case CL_IMAGE_WIDTH: - buf.as_scalar<size_t>() = img.width(); - break; - - case CL_IMAGE_HEIGHT: - buf.as_scalar<size_t>() = img.height(); - break; - - case CL_IMAGE_DEPTH: - buf.as_scalar<size_t>() = img.depth(); - break; - - default: - throw error(CL_INVALID_VALUE); - } - - return CL_SUCCESS; - -} catch (error &e) { - return e.get(); -} - -CLOVER_API cl_int -clRetainMemObject(cl_mem d_mem) try { - obj(d_mem).retain(); - return CL_SUCCESS; - -} catch (error &e) { - return e.get(); -} - -CLOVER_API cl_int -clReleaseMemObject(cl_mem d_mem) try { - if (obj(d_mem).release()) - delete pobj(d_mem); - - return CL_SUCCESS; - -} catch (error &e) { - return e.get(); -} - -CLOVER_API cl_int -clSetMemObjectDestructorCallback(cl_mem d_mem, - void (CL_CALLBACK *pfn_notify)(cl_mem, void *), - void *user_data) try { - auto &mem = obj(d_mem); - - if (!pfn_notify) - return CL_INVALID_VALUE; - - mem.destroy_notify([=]{ pfn_notify(d_mem, user_data); }); - - return CL_SUCCESS; - -} catch (error &e) { - return e.get(); -} - -CLOVER_API cl_int -clEnqueueFillBuffer(cl_command_queue command_queue, cl_mem buffer, - const void *pattern, size_t pattern_size, - size_t offset, size_t size, - cl_uint num_events_in_wait_list, - const cl_event *event_wait_list, - cl_event *event) { - CLOVER_NOT_SUPPORTED_UNTIL("1.2"); - return CL_INVALID_VALUE; -} - -CLOVER_API cl_int -clEnqueueFillImage(cl_command_queue command_queue, cl_mem image, - const void *fill_color, - const size_t *origin, const size_t *region, - cl_uint num_events_in_wait_list, - const cl_event *event_wait_list, - cl_event *event) { - CLOVER_NOT_SUPPORTED_UNTIL("1.2"); - return CL_INVALID_VALUE; -} - -CLOVER_API void * -clSVMAlloc(cl_context d_ctx, - cl_svm_mem_flags flags, - size_t size, - unsigned int alignment) try { - auto &ctx = obj(d_ctx); - validate_flags(NULL, flags, true); - - if (!size || - size > fold(minimum(), cl_ulong(ULONG_MAX), - map(std::mem_fn(&device::max_mem_alloc_size), ctx.devices()))) - return nullptr; - - if (!util_is_power_of_two_or_zero(alignment)) - return nullptr; - - if (!alignment) - alignment = 0x80; // sizeof(long16) - - bool can_emulate = all_of(std::mem_fn(&device::has_system_svm), ctx.devices()); - if (can_emulate) { - // we can ignore all the flags as it's not required to honor them. - void *ptr = nullptr; - if (alignment < sizeof(void*)) - alignment = sizeof(void*); - posix_memalign(&ptr, alignment, size); - return ptr; - } - - CLOVER_NOT_SUPPORTED_UNTIL("2.0"); - return nullptr; - -} catch (error &e) { - return nullptr; -} - -CLOVER_API void -clSVMFree(cl_context d_ctx, - void *svm_pointer) try { - auto &ctx = obj(d_ctx); - bool can_emulate = all_of(std::mem_fn(&device::has_system_svm), ctx.devices()); - - if (can_emulate) - return free(svm_pointer); - - CLOVER_NOT_SUPPORTED_UNTIL("2.0"); - -} catch (error &e) { -} diff --git a/src/gallium/state_trackers/clover/api/platform.cpp b/src/gallium/state_trackers/clover/api/platform.cpp deleted file mode 100644 index 7360461e62f..00000000000 --- a/src/gallium/state_trackers/clover/api/platform.cpp +++ /dev/null @@ -1,235 +0,0 @@ -// -// Copyright 2012 Francisco Jerez -// -// Permission is hereby granted, free of charge, to any person obtaining a -// copy of this software and associated documentation files (the "Software"), -// to deal in the Software without restriction, including without limitation -// the rights to use, copy, modify, merge, publish, distribute, sublicense, -// and/or sell copies of the Software, and to permit persons to whom the -// Software is furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL -// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR -// OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, -// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR -// OTHER DEALINGS IN THE SOFTWARE. -// - -#include <unordered_map> - -#include "api/dispatch.hpp" -#include "api/util.hpp" -#include "core/platform.hpp" -#include "git_sha1.h" -#include "util/u_debug.h" - -using namespace clover; - -namespace { - platform _clover_platform; -} - -CLOVER_API cl_int -clGetPlatformIDs(cl_uint num_entries, cl_platform_id *rd_platforms, - cl_uint *rnum_platforms) { - if ((!num_entries && rd_platforms) || - (!rnum_platforms && !rd_platforms)) - return CL_INVALID_VALUE; - - if (rnum_platforms) - *rnum_platforms = 1; - if (rd_platforms) - *rd_platforms = desc(_clover_platform); - - return CL_SUCCESS; -} - -cl_int -clover::GetPlatformInfo(cl_platform_id d_platform, cl_platform_info param, - size_t size, void *r_buf, size_t *r_size) try { - property_buffer buf { r_buf, size, r_size }; - - auto &platform = obj(d_platform); - - switch (param) { - case CL_PLATFORM_PROFILE: - buf.as_string() = "FULL_PROFILE"; - break; - - case CL_PLATFORM_VERSION: { - static const std::string version_string = - debug_get_option("CLOVER_PLATFORM_VERSION_OVERRIDE", "1.1"); - - buf.as_string() = "OpenCL " + version_string + " Mesa " PACKAGE_VERSION MESA_GIT_SHA1; - break; - } - case CL_PLATFORM_NAME: - buf.as_string() = "Clover"; - break; - - case CL_PLATFORM_VENDOR: - buf.as_string() = "Mesa"; - break; - - case CL_PLATFORM_EXTENSIONS: - buf.as_string() = platform.supported_extensions(); - break; - - case CL_PLATFORM_ICD_SUFFIX_KHR: - buf.as_string() = "MESA"; - break; - - default: - throw error(CL_INVALID_VALUE); - } - - return CL_SUCCESS; - -} catch (error &e) { - return e.get(); -} - -void * -clover::GetExtensionFunctionAddressForPlatform(cl_platform_id d_platform, - const char *p_name) try { - obj(d_platform); - return GetExtensionFunctionAddress(p_name); - -} catch (error &e) { - return NULL; -} - -namespace { - -cl_int -enqueueSVMFreeARM(cl_command_queue command_queue, - cl_uint num_svm_pointers, - void *svm_pointers[], - void (CL_CALLBACK *pfn_free_func) ( - cl_command_queue queue, cl_uint num_svm_pointers, - void *svm_pointers[], void *user_data), - void *user_data, - cl_uint num_events_in_wait_list, - const cl_event *event_wait_list, - cl_event *event) { - - return EnqueueSVMFree(command_queue, num_svm_pointers, svm_pointers, - pfn_free_func, user_data, num_events_in_wait_list, - event_wait_list, event, CL_COMMAND_SVM_FREE_ARM); -} - -cl_int -enqueueSVMMapARM(cl_command_queue command_queue, - cl_bool blocking_map, - cl_map_flags map_flags, - void *svm_ptr, - size_t size, - cl_uint num_events_in_wait_list, - const cl_event *event_wait_list, - cl_event *event) { - - return EnqueueSVMMap(command_queue, blocking_map, map_flags, svm_ptr, size, - num_events_in_wait_list, event_wait_list, event, - CL_COMMAND_SVM_MAP_ARM); -} - -cl_int -enqueueSVMMemcpyARM(cl_command_queue command_queue, - cl_bool blocking_copy, - void *dst_ptr, - const void *src_ptr, - size_t size, - cl_uint num_events_in_wait_list, - const cl_event *event_wait_list, - cl_event *event) { - - return EnqueueSVMMemcpy(command_queue, blocking_copy, dst_ptr, src_ptr, - size, num_events_in_wait_list, event_wait_list, - event, CL_COMMAND_SVM_MEMCPY_ARM); -} - -cl_int -enqueueSVMMemFillARM(cl_command_queue command_queue, - void *svm_ptr, - const void *pattern, - size_t pattern_size, - size_t size, - cl_uint num_events_in_wait_list, - const cl_event *event_wait_list, - cl_event *event) { - - return EnqueueSVMMemFill(command_queue, svm_ptr, pattern, pattern_size, - size, num_events_in_wait_list, event_wait_list, - event, CL_COMMAND_SVM_MEMFILL_ARM); -} - -cl_int -enqueueSVMUnmapARM(cl_command_queue command_queue, - void *svm_ptr, - cl_uint num_events_in_wait_list, - const cl_event *event_wait_list, - cl_event *event) { - - return EnqueueSVMUnmap(command_queue, svm_ptr, num_events_in_wait_list, - event_wait_list, event, CL_COMMAND_SVM_UNMAP_ARM); -} - -const std::unordered_map<std::string, void *> -ext_funcs = { - // cl_arm_shared_virtual_memory - { "clEnqueueSVMFreeARM", reinterpret_cast<void *>(enqueueSVMFreeARM) }, - { "clEnqueueSVMMapARM", reinterpret_cast<void *>(enqueueSVMMapARM) }, - { "clEnqueueSVMMemcpyARM", reinterpret_cast<void *>(enqueueSVMMemcpyARM) }, - { "clEnqueueSVMMemFillARM", reinterpret_cast<void *>(enqueueSVMMemFillARM) }, - { "clEnqueueSVMUnmapARM", reinterpret_cast<void *>(enqueueSVMUnmapARM) }, - { "clSetKernelArgSVMPointerARM", reinterpret_cast<void *>(clSetKernelArgSVMPointer) }, - { "clSetKernelExecInfoARM", reinterpret_cast<void *>(clSetKernelExecInfo) }, - { "clSVMAllocARM", reinterpret_cast<void *>(clSVMAlloc) }, - { "clSVMFreeARM", reinterpret_cast<void *>(clSVMFree) }, - - // cl_khr_icd - { "clIcdGetPlatformIDsKHR", reinterpret_cast<void *>(IcdGetPlatformIDsKHR) }, -}; - -} // anonymous namespace - -void * -clover::GetExtensionFunctionAddress(const char *p_name) try { - return ext_funcs.at(p_name); -} catch (...) { - return nullptr; -} - -cl_int -clover::IcdGetPlatformIDsKHR(cl_uint num_entries, cl_platform_id *rd_platforms, - cl_uint *rnum_platforms) { - return clGetPlatformIDs(num_entries, rd_platforms, rnum_platforms); -} - -CLOVER_ICD_API cl_int -clGetPlatformInfo(cl_platform_id d_platform, cl_platform_info param, - size_t size, void *r_buf, size_t *r_size) { - return GetPlatformInfo(d_platform, param, size, r_buf, r_size); -} - -CLOVER_ICD_API void * -clGetExtensionFunctionAddress(const char *p_name) { - return GetExtensionFunctionAddress(p_name); -} - -CLOVER_ICD_API void * -clGetExtensionFunctionAddressForPlatform(cl_platform_id d_platform, - const char *p_name) { - return GetExtensionFunctionAddressForPlatform(d_platform, p_name); -} - -CLOVER_ICD_API cl_int -clIcdGetPlatformIDsKHR(cl_uint num_entries, cl_platform_id *rd_platforms, - cl_uint *rnum_platforms) { - return IcdGetPlatformIDsKHR(num_entries, rd_platforms, rnum_platforms); -} diff --git a/src/gallium/state_trackers/clover/api/program.cpp b/src/gallium/state_trackers/clover/api/program.cpp deleted file mode 100644 index 33f843e9c87..00000000000 --- a/src/gallium/state_trackers/clover/api/program.cpp +++ /dev/null @@ -1,479 +0,0 @@ -// -// Copyright 2012 Francisco Jerez -// -// Permission is hereby granted, free of charge, to any person obtaining a -// copy of this software and associated documentation files (the "Software"), -// to deal in the Software without restriction, including without limitation -// the rights to use, copy, modify, merge, publish, distribute, sublicense, -// and/or sell copies of the Software, and to permit persons to whom the -// Software is furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL -// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR -// OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, -// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR -// OTHER DEALINGS IN THE SOFTWARE. -// - -#include "api/util.hpp" -#include "core/program.hpp" -#include "util/u_debug.h" - -#include <sstream> - -using namespace clover; - -namespace { - void - validate_build_common(const program &prog, cl_uint num_devs, - const cl_device_id *d_devs, - void (*pfn_notify)(cl_program, void *), - void *user_data) { - if (!pfn_notify && user_data) - throw error(CL_INVALID_VALUE); - - if (prog.kernel_ref_count()) - throw error(CL_INVALID_OPERATION); - - if (any_of([&](const device &dev) { - return !count(dev, prog.devices()); - }, objs<allow_empty_tag>(d_devs, num_devs))) - throw error(CL_INVALID_DEVICE); - } -} - -CLOVER_API cl_program -clCreateProgramWithSource(cl_context d_ctx, cl_uint count, - const char **strings, const size_t *lengths, - cl_int *r_errcode) try { - auto &ctx = obj(d_ctx); - std::string source; - - if (!count || !strings || - any_of(is_zero(), range(strings, count))) - throw error(CL_INVALID_VALUE); - - // Concatenate all the provided fragments together - for (unsigned i = 0; i < count; ++i) - source += (lengths && lengths[i] ? - std::string(strings[i], strings[i] + lengths[i]) : - std::string(strings[i])); - - // ...and create a program object for them. - ret_error(r_errcode, CL_SUCCESS); - return new program(ctx, source); - -} catch (error &e) { - ret_error(r_errcode, e); - return NULL; -} - -CLOVER_API cl_program -clCreateProgramWithBinary(cl_context d_ctx, cl_uint n, - const cl_device_id *d_devs, - const size_t *lengths, - const unsigned char **binaries, - cl_int *r_status, cl_int *r_errcode) try { - auto &ctx = obj(d_ctx); - auto devs = objs(d_devs, n); - - if (!lengths || !binaries) - throw error(CL_INVALID_VALUE); - - if (any_of([&](const device &dev) { - return !count(dev, ctx.devices()); - }, devs)) - throw error(CL_INVALID_DEVICE); - - // Deserialize the provided binaries, - std::vector<std::pair<cl_int, module>> result = map( - [](const unsigned char *p, size_t l) -> std::pair<cl_int, module> { - if (!p || !l) - return { CL_INVALID_VALUE, {} }; - - try { - std::stringbuf bin( { (char*)p, l } ); - std::istream s(&bin); - - return { CL_SUCCESS, module::deserialize(s) }; - - } catch (std::istream::failure &e) { - return { CL_INVALID_BINARY, {} }; - } - }, - range(binaries, n), - range(lengths, n)); - - // update the status array, - if (r_status) - copy(map(keys(), result), r_status); - - if (any_of(key_equals(CL_INVALID_VALUE), result)) - throw error(CL_INVALID_VALUE); - - if (any_of(key_equals(CL_INVALID_BINARY), result)) - throw error(CL_INVALID_BINARY); - - // initialize a program object with them. - ret_error(r_errcode, CL_SUCCESS); - return new program(ctx, devs, map(values(), result)); - -} catch (error &e) { - ret_error(r_errcode, e); - return NULL; -} - -CLOVER_API cl_program -clCreateProgramWithBuiltInKernels(cl_context d_ctx, cl_uint n, - const cl_device_id *d_devs, - const char *kernel_names, - cl_int *r_errcode) try { - auto &ctx = obj(d_ctx); - auto devs = objs(d_devs, n); - - if (any_of([&](const device &dev) { - return !count(dev, ctx.devices()); - }, devs)) - throw error(CL_INVALID_DEVICE); - - // No currently supported built-in kernels. - throw error(CL_INVALID_VALUE); - -} catch (error &e) { - ret_error(r_errcode, e); - return NULL; -} - - -CLOVER_API cl_int -clRetainProgram(cl_program d_prog) try { - obj(d_prog).retain(); - return CL_SUCCESS; - -} catch (error &e) { - return e.get(); -} - -CLOVER_API cl_int -clReleaseProgram(cl_program d_prog) try { - if (obj(d_prog).release()) - delete pobj(d_prog); - - return CL_SUCCESS; - -} catch (error &e) { - return e.get(); -} - -CLOVER_API cl_int -clBuildProgram(cl_program d_prog, cl_uint num_devs, - const cl_device_id *d_devs, const char *p_opts, - void (*pfn_notify)(cl_program, void *), - void *user_data) try { - auto &prog = obj(d_prog); - auto devs = - (d_devs ? objs(d_devs, num_devs) : ref_vector<device>(prog.devices())); - const auto opts = std::string(p_opts ? p_opts : "") + " " + - debug_get_option("CLOVER_EXTRA_BUILD_OPTIONS", ""); - - validate_build_common(prog, num_devs, d_devs, pfn_notify, user_data); - - if (prog.has_source) { - prog.compile(devs, opts); - prog.link(devs, opts, { prog }); - } else if (any_of([&](const device &dev){ - return prog.build(dev).binary_type() != CL_PROGRAM_BINARY_TYPE_EXECUTABLE; - }, devs)) { - // According to the OpenCL 1.2 specification, “if program is created - // with clCreateProgramWithBinary, then the program binary must be an - // executable binary (not a compiled binary or library).” - throw error(CL_INVALID_BINARY); - } - - return CL_SUCCESS; - -} catch (error &e) { - return e.get(); -} - -CLOVER_API cl_int -clCompileProgram(cl_program d_prog, cl_uint num_devs, - const cl_device_id *d_devs, const char *p_opts, - cl_uint num_headers, const cl_program *d_header_progs, - const char **header_names, - void (*pfn_notify)(cl_program, void *), - void *user_data) try { - auto &prog = obj(d_prog); - auto devs = - (d_devs ? objs(d_devs, num_devs) : ref_vector<device>(prog.devices())); - const auto opts = std::string(p_opts ? p_opts : "") + " " + - debug_get_option("CLOVER_EXTRA_COMPILE_OPTIONS", ""); - header_map headers; - - validate_build_common(prog, num_devs, d_devs, pfn_notify, user_data); - - if (bool(num_headers) != bool(header_names)) - throw error(CL_INVALID_VALUE); - - if (!prog.has_source) - throw error(CL_INVALID_OPERATION); - - for_each([&](const char *name, const program &header) { - if (!header.has_source) - throw error(CL_INVALID_OPERATION); - - if (!any_of(key_equals(name), headers)) - headers.push_back(std::pair<std::string, std::string>( - name, header.source())); - }, - range(header_names, num_headers), - objs<allow_empty_tag>(d_header_progs, num_headers)); - - prog.compile(devs, opts, headers); - return CL_SUCCESS; - -} catch (invalid_build_options_error &e) { - return CL_INVALID_COMPILER_OPTIONS; - -} catch (build_error &e) { - return CL_COMPILE_PROGRAM_FAILURE; - -} catch (error &e) { - return e.get(); -} - -namespace { - ref_vector<device> - validate_link_devices(const ref_vector<program> &progs, - const ref_vector<device> &all_devs, - const std::string &opts) { - std::vector<device *> devs; - const bool create_library = - opts.find("-create-library") != std::string::npos; - const bool enable_link_options = - opts.find("-enable-link-options") != std::string::npos; - const bool has_link_options = - opts.find("-cl-denorms-are-zero") != std::string::npos || - opts.find("-cl-no-signed-zeroes") != std::string::npos || - opts.find("-cl-unsafe-math-optimizations") != std::string::npos || - opts.find("-cl-finite-math-only") != std::string::npos || - opts.find("-cl-fast-relaxed-math") != std::string::npos || - opts.find("-cl-no-subgroup-ifp") != std::string::npos; - - // According to the OpenCL 1.2 specification, "[the - // -enable-link-options] option must be specified with the - // create-library option". - if (enable_link_options && !create_library) - throw error(CL_INVALID_LINKER_OPTIONS); - - // According to the OpenCL 1.2 specification, "the - // [program linking options] can be specified when linking a program - // executable". - if (has_link_options && create_library) - throw error(CL_INVALID_LINKER_OPTIONS); - - for (auto &dev : all_devs) { - const auto has_binary = [&](const program &prog) { - const auto t = prog.build(dev).binary_type(); - return t == CL_PROGRAM_BINARY_TYPE_COMPILED_OBJECT || - t == CL_PROGRAM_BINARY_TYPE_LIBRARY; - }; - - // According to the OpenCL 1.2 specification, a library is made of - // “compiled binaries specified in input_programs argument to - // clLinkProgram“; compiled binaries does not refer to libraries: - // “input_programs is an array of program objects that are compiled - // binaries or libraries that are to be linked to create the program - // executable”. - if (create_library && any_of([&](const program &prog) { - const auto t = prog.build(dev).binary_type(); - return t != CL_PROGRAM_BINARY_TYPE_COMPILED_OBJECT; - }, progs)) - throw error(CL_INVALID_OPERATION); - - // According to the CL 1.2 spec, when "all programs specified [..] - // contain a compiled binary or library for the device [..] a link is - // performed", - else if (all_of(has_binary, progs)) - devs.push_back(&dev); - - // otherwise if "none of the programs contain a compiled binary or - // library for that device [..] no link is performed. All other - // cases will return a CL_INVALID_OPERATION error." - else if (any_of(has_binary, progs)) - throw error(CL_INVALID_OPERATION); - - // According to the OpenCL 1.2 specification, "[t]he linker may apply - // [program linking options] to all compiled program objects - // specified to clLinkProgram. The linker may apply these options - // only to libraries which were created with the - // -enable-link-option." - else if (has_link_options && any_of([&](const program &prog) { - const auto t = prog.build(dev).binary_type(); - return !(t == CL_PROGRAM_BINARY_TYPE_COMPILED_OBJECT || - (t == CL_PROGRAM_BINARY_TYPE_LIBRARY && - prog.build(dev).opts.find("-enable-link-options") != - std::string::npos)); - }, progs)) - throw error(CL_INVALID_LINKER_OPTIONS); - } - - return map(derefs(), devs); - } -} - -CLOVER_API cl_program -clLinkProgram(cl_context d_ctx, cl_uint num_devs, const cl_device_id *d_devs, - const char *p_opts, cl_uint num_progs, const cl_program *d_progs, - void (*pfn_notify) (cl_program, void *), void *user_data, - cl_int *r_errcode) try { - auto &ctx = obj(d_ctx); - const auto opts = std::string(p_opts ? p_opts : "") + " " + - debug_get_option("CLOVER_EXTRA_LINK_OPTIONS", ""); - auto progs = objs(d_progs, num_progs); - auto all_devs = - (d_devs ? objs(d_devs, num_devs) : ref_vector<device>(ctx.devices())); - auto prog = create<program>(ctx, all_devs); - auto devs = validate_link_devices(progs, all_devs, opts); - - validate_build_common(prog, num_devs, d_devs, pfn_notify, user_data); - - try { - prog().link(devs, opts, progs); - ret_error(r_errcode, CL_SUCCESS); - - } catch (build_error &e) { - ret_error(r_errcode, CL_LINK_PROGRAM_FAILURE); - } - - return ret_object(prog); - -} catch (invalid_build_options_error &e) { - ret_error(r_errcode, CL_INVALID_LINKER_OPTIONS); - return NULL; - -} catch (error &e) { - ret_error(r_errcode, e); - return NULL; -} - -CLOVER_API cl_int -clUnloadCompiler() { - return CL_SUCCESS; -} - -CLOVER_API cl_int -clUnloadPlatformCompiler(cl_platform_id d_platform) { - return CL_SUCCESS; -} - -CLOVER_API cl_int -clGetProgramInfo(cl_program d_prog, cl_program_info param, - size_t size, void *r_buf, size_t *r_size) try { - property_buffer buf { r_buf, size, r_size }; - auto &prog = obj(d_prog); - - switch (param) { - case CL_PROGRAM_REFERENCE_COUNT: - buf.as_scalar<cl_uint>() = prog.ref_count(); - break; - - case CL_PROGRAM_CONTEXT: - buf.as_scalar<cl_context>() = desc(prog.context()); - break; - - case CL_PROGRAM_NUM_DEVICES: - buf.as_scalar<cl_uint>() = (prog.devices().size() ? - prog.devices().size() : - prog.context().devices().size()); - break; - - case CL_PROGRAM_DEVICES: - buf.as_vector<cl_device_id>() = (prog.devices().size() ? - descs(prog.devices()) : - descs(prog.context().devices())); - break; - - case CL_PROGRAM_SOURCE: - buf.as_string() = prog.source(); - break; - - case CL_PROGRAM_BINARY_SIZES: - buf.as_vector<size_t>() = map([&](const device &dev) { - return prog.build(dev).binary.size(); - }, - prog.devices()); - break; - - case CL_PROGRAM_BINARIES: - buf.as_matrix<unsigned char>() = map([&](const device &dev) { - std::stringbuf bin; - std::ostream s(&bin); - prog.build(dev).binary.serialize(s); - return bin.str(); - }, - prog.devices()); - break; - - case CL_PROGRAM_NUM_KERNELS: - buf.as_scalar<cl_uint>() = prog.symbols().size(); - break; - - case CL_PROGRAM_KERNEL_NAMES: - buf.as_string() = fold([](const std::string &a, const module::symbol &s) { - return ((a.empty() ? "" : a + ";") + s.name); - }, std::string(), prog.symbols()); - break; - - default: - throw error(CL_INVALID_VALUE); - } - - return CL_SUCCESS; - -} catch (error &e) { - return e.get(); -} - -CLOVER_API cl_int -clGetProgramBuildInfo(cl_program d_prog, cl_device_id d_dev, - cl_program_build_info param, - size_t size, void *r_buf, size_t *r_size) try { - property_buffer buf { r_buf, size, r_size }; - auto &prog = obj(d_prog); - auto &dev = obj(d_dev); - - if (!count(dev, prog.context().devices())) - return CL_INVALID_DEVICE; - - switch (param) { - case CL_PROGRAM_BUILD_STATUS: - buf.as_scalar<cl_build_status>() = prog.build(dev).status(); - break; - - case CL_PROGRAM_BUILD_OPTIONS: - buf.as_string() = prog.build(dev).opts; - break; - - case CL_PROGRAM_BUILD_LOG: - buf.as_string() = prog.build(dev).log; - break; - - case CL_PROGRAM_BINARY_TYPE: - buf.as_scalar<cl_program_binary_type>() = prog.build(dev).binary_type(); - break; - - default: - throw error(CL_INVALID_VALUE); - } - - return CL_SUCCESS; - -} catch (error &e) { - return e.get(); -} diff --git a/src/gallium/state_trackers/clover/api/queue.cpp b/src/gallium/state_trackers/clover/api/queue.cpp deleted file mode 100644 index 65b271b216f..00000000000 --- a/src/gallium/state_trackers/clover/api/queue.cpp +++ /dev/null @@ -1,135 +0,0 @@ -// -// Copyright 2012 Francisco Jerez -// -// Permission is hereby granted, free of charge, to any person obtaining a -// copy of this software and associated documentation files (the "Software"), -// to deal in the Software without restriction, including without limitation -// the rights to use, copy, modify, merge, publish, distribute, sublicense, -// and/or sell copies of the Software, and to permit persons to whom the -// Software is furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL -// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR -// OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, -// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR -// OTHER DEALINGS IN THE SOFTWARE. -// - -#include "api/util.hpp" -#include "core/queue.hpp" - -using namespace clover; - -CLOVER_API cl_command_queue -clCreateCommandQueue(cl_context d_ctx, cl_device_id d_dev, - cl_command_queue_properties props, - cl_int *r_errcode) try { - auto &ctx = obj(d_ctx); - auto &dev = obj(d_dev); - - if (!count(dev, ctx.devices())) - throw error(CL_INVALID_DEVICE); - - if (props & ~(CL_QUEUE_OUT_OF_ORDER_EXEC_MODE_ENABLE | - CL_QUEUE_PROFILING_ENABLE)) - throw error(CL_INVALID_VALUE); - - ret_error(r_errcode, CL_SUCCESS); - return new command_queue(ctx, dev, props); - -} catch (error &e) { - ret_error(r_errcode, e); - return NULL; -} - -CLOVER_API cl_int -clRetainCommandQueue(cl_command_queue d_q) try { - obj(d_q).retain(); - return CL_SUCCESS; - -} catch (error &e) { - return e.get(); -} - -CLOVER_API cl_int -clReleaseCommandQueue(cl_command_queue d_q) try { - auto &q = obj(d_q); - - q.flush(); - - if (q.release()) - delete pobj(d_q); - - return CL_SUCCESS; - -} catch (error &e) { - return e.get(); -} - -CLOVER_API cl_int -clGetCommandQueueInfo(cl_command_queue d_q, cl_command_queue_info param, - size_t size, void *r_buf, size_t *r_size) try { - property_buffer buf { r_buf, size, r_size }; - auto &q = obj(d_q); - - switch (param) { - case CL_QUEUE_CONTEXT: - buf.as_scalar<cl_context>() = desc(q.context()); - break; - - case CL_QUEUE_DEVICE: - buf.as_scalar<cl_device_id>() = desc(q.device()); - break; - - case CL_QUEUE_REFERENCE_COUNT: - buf.as_scalar<cl_uint>() = q.ref_count(); - break; - - case CL_QUEUE_PROPERTIES: - buf.as_scalar<cl_command_queue_properties>() = q.properties(); - break; - - default: - throw error(CL_INVALID_VALUE); - } - - return CL_SUCCESS; - -} catch (error &e) { - return e.get(); -} - -CLOVER_API cl_int -clFlush(cl_command_queue d_q) try { - obj(d_q).flush(); - return CL_SUCCESS; - -} catch (error &e) { - return e.get(); -} - -CLOVER_API cl_command_queue -clCreateCommandQueueWithProperties(cl_context context, cl_device_id device, - const cl_queue_properties *properties, - cl_int *errcode_ret) try { - cl_command_queue_properties props = 0; - if (properties) { - for (auto idx = 0; properties[idx]; idx += 2) { - if (properties[idx] == CL_QUEUE_PROPERTIES) - props |= properties[idx + 1]; - else - throw error(CL_INVALID_VALUE); - } - } - - return clCreateCommandQueue(context, device, props, errcode_ret); - -} catch (error &e) { - ret_error(errcode_ret, e); - return NULL; -} diff --git a/src/gallium/state_trackers/clover/api/sampler.cpp b/src/gallium/state_trackers/clover/api/sampler.cpp deleted file mode 100644 index 482e55a9ce9..00000000000 --- a/src/gallium/state_trackers/clover/api/sampler.cpp +++ /dev/null @@ -1,100 +0,0 @@ -// -// Copyright 2012 Francisco Jerez -// -// Permission is hereby granted, free of charge, to any person obtaining a -// copy of this software and associated documentation files (the "Software"), -// to deal in the Software without restriction, including without limitation -// the rights to use, copy, modify, merge, publish, distribute, sublicense, -// and/or sell copies of the Software, and to permit persons to whom the -// Software is furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL -// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR -// OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, -// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR -// OTHER DEALINGS IN THE SOFTWARE. -// - -#include "api/util.hpp" -#include "core/sampler.hpp" - -using namespace clover; - -CLOVER_API cl_sampler -clCreateSampler(cl_context d_ctx, cl_bool norm_mode, - cl_addressing_mode addr_mode, cl_filter_mode filter_mode, - cl_int *r_errcode) try { - auto &ctx = obj(d_ctx); - - if (!any_of(std::mem_fn(&device::image_support), ctx.devices())) - throw error(CL_INVALID_OPERATION); - - ret_error(r_errcode, CL_SUCCESS); - return new sampler(ctx, norm_mode, addr_mode, filter_mode); - -} catch (error &e) { - ret_error(r_errcode, e); - return NULL; -} - -CLOVER_API cl_int -clRetainSampler(cl_sampler d_s) try { - obj(d_s).retain(); - return CL_SUCCESS; - -} catch (error &e) { - return e.get(); -} - -CLOVER_API cl_int -clReleaseSampler(cl_sampler d_s) try { - if (obj(d_s).release()) - delete pobj(d_s); - - return CL_SUCCESS; - -} catch (error &e) { - return e.get(); -} - -CLOVER_API cl_int -clGetSamplerInfo(cl_sampler d_s, cl_sampler_info param, - size_t size, void *r_buf, size_t *r_size) try { - property_buffer buf { r_buf, size, r_size }; - auto &s = obj(d_s); - - switch (param) { - case CL_SAMPLER_REFERENCE_COUNT: - buf.as_scalar<cl_uint>() = s.ref_count(); - break; - - case CL_SAMPLER_CONTEXT: - buf.as_scalar<cl_context>() = desc(s.context()); - break; - - case CL_SAMPLER_NORMALIZED_COORDS: - buf.as_scalar<cl_bool>() = s.norm_mode(); - break; - - case CL_SAMPLER_ADDRESSING_MODE: - buf.as_scalar<cl_addressing_mode>() = s.addr_mode(); - break; - - case CL_SAMPLER_FILTER_MODE: - buf.as_scalar<cl_filter_mode>() = s.filter_mode(); - break; - - default: - throw error(CL_INVALID_VALUE); - } - - return CL_SUCCESS; - -} catch (error &e) { - return e.get(); -} diff --git a/src/gallium/state_trackers/clover/api/transfer.cpp b/src/gallium/state_trackers/clover/api/transfer.cpp deleted file mode 100644 index fa8741e02b4..00000000000 --- a/src/gallium/state_trackers/clover/api/transfer.cpp +++ /dev/null @@ -1,1059 +0,0 @@ -// -// Copyright 2012 Francisco Jerez -// -// Permission is hereby granted, free of charge, to any person obtaining a -// copy of this software and associated documentation files (the "Software"), -// to deal in the Software without restriction, including without limitation -// the rights to use, copy, modify, merge, publish, distribute, sublicense, -// and/or sell copies of the Software, and to permit persons to whom the -// Software is furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL -// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR -// OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, -// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR -// OTHER DEALINGS IN THE SOFTWARE. -// - -#include <cstring> - -#include "util/bitscan.h" - -#include "api/dispatch.hpp" -#include "api/util.hpp" -#include "core/event.hpp" -#include "core/memory.hpp" - -using namespace clover; - -namespace { - typedef resource::vector vector_t; - - vector_t - vector(const size_t *p) { - return range(p, 3); - } - - vector_t - pitch(const vector_t ®ion, vector_t pitch) { - for (auto x : zip(tail(pitch), - map(multiplies(), region, pitch))) { - // The spec defines a value of zero as the natural pitch, - // i.e. the unaligned size of the previous dimension. - if (std::get<0>(x) == 0) - std::get<0>(x) = std::get<1>(x); - } - - return pitch; - } - - /// - /// Size of a region in bytes. - /// - size_t - size(const vector_t &pitch, const vector_t ®ion) { - if (any_of(is_zero(), region)) - return 0; - else - return dot(pitch, region - vector_t{ 0, 1, 1 }); - } - - /// - /// Common argument checking shared by memory transfer commands. - /// - void - validate_common(command_queue &q, - const ref_vector<event> &deps) { - if (any_of([&](const event &ev) { - return ev.context() != q.context(); - }, deps)) - throw error(CL_INVALID_CONTEXT); - } - - /// - /// Common error checking for a buffer object argument. - /// - void - validate_object(command_queue &q, buffer &mem, const vector_t &origin, - const vector_t &pitch, const vector_t ®ion) { - if (mem.context() != q.context()) - throw error(CL_INVALID_CONTEXT); - - // The region must fit within the specified pitch, - if (any_of(greater(), map(multiplies(), pitch, region), tail(pitch))) - throw error(CL_INVALID_VALUE); - - // ...and within the specified object. - if (dot(pitch, origin) + size(pitch, region) > mem.size()) - throw error(CL_INVALID_VALUE); - - if (any_of(is_zero(), region)) - throw error(CL_INVALID_VALUE); - } - - /// - /// Common error checking for an image argument. - /// - void - validate_object(command_queue &q, image &img, - const vector_t &orig, const vector_t ®ion) { - vector_t size = { img.width(), img.height(), img.depth() }; - - if (!q.device().image_support()) - throw error(CL_INVALID_OPERATION); - - if (img.context() != q.context()) - throw error(CL_INVALID_CONTEXT); - - if (any_of(greater(), orig + region, size)) - throw error(CL_INVALID_VALUE); - - if (any_of(is_zero(), region)) - throw error(CL_INVALID_VALUE); - } - - /// - /// Common error checking for a host pointer argument. - /// - void - validate_object(command_queue &q, const void *ptr, const vector_t &orig, - const vector_t &pitch, const vector_t ®ion) { - if (!ptr) - throw error(CL_INVALID_VALUE); - - // The region must fit within the specified pitch. - if (any_of(greater(), map(multiplies(), pitch, region), tail(pitch))) - throw error(CL_INVALID_VALUE); - } - - /// - /// Common argument checking for a copy between two buffer objects. - /// - void - validate_copy(command_queue &q, buffer &dst_mem, - const vector_t &dst_orig, const vector_t &dst_pitch, - buffer &src_mem, - const vector_t &src_orig, const vector_t &src_pitch, - const vector_t ®ion) { - if (dst_mem == src_mem) { - auto dst_offset = dot(dst_pitch, dst_orig); - auto src_offset = dot(src_pitch, src_orig); - - if (interval_overlaps()( - dst_offset, dst_offset + size(dst_pitch, region), - src_offset, src_offset + size(src_pitch, region))) - throw error(CL_MEM_COPY_OVERLAP); - } - } - - /// - /// Common argument checking for a copy between two image objects. - /// - void - validate_copy(command_queue &q, - image &dst_img, const vector_t &dst_orig, - image &src_img, const vector_t &src_orig, - const vector_t ®ion) { - if (dst_img.format() != src_img.format()) - throw error(CL_IMAGE_FORMAT_MISMATCH); - - if (dst_img == src_img) { - if (all_of(interval_overlaps(), - dst_orig, dst_orig + region, - src_orig, src_orig + region)) - throw error(CL_MEM_COPY_OVERLAP); - } - } - - /// - /// Checks that the host access flags of the memory object are - /// within the allowed set \a flags. - /// - void - validate_object_access(const memory_obj &mem, const cl_mem_flags flags) { - if (mem.flags() & ~flags & - (CL_MEM_HOST_READ_ONLY | CL_MEM_HOST_WRITE_ONLY | - CL_MEM_HOST_NO_ACCESS)) - throw error(CL_INVALID_OPERATION); - } - - /// - /// Checks that the mapping flags are correct. - /// - void - validate_map_flags(const memory_obj &mem, const cl_map_flags flags) { - if ((flags & (CL_MAP_WRITE | CL_MAP_READ)) && - (flags & CL_MAP_WRITE_INVALIDATE_REGION)) - throw error(CL_INVALID_VALUE); - - if (flags & CL_MAP_READ) - validate_object_access(mem, CL_MEM_HOST_READ_ONLY); - - if (flags & (CL_MAP_WRITE | CL_MAP_WRITE_INVALIDATE_REGION)) - validate_object_access(mem, CL_MEM_HOST_WRITE_ONLY); - } - - /// - /// Class that encapsulates the task of mapping an object of type - /// \a T. The return value of get() should be implicitly - /// convertible to \a void *. - /// - template<typename T> - struct _map { - static mapping - get(command_queue &q, T obj, cl_map_flags flags, - size_t offset, size_t size) { - return { q, obj->resource(q), flags, true, - {{ offset }}, {{ size, 1, 1 }} }; - } - }; - - template<> - struct _map<void *> { - static void * - get(command_queue &q, void *obj, cl_map_flags flags, - size_t offset, size_t size) { - return (char *)obj + offset; - } - }; - - template<> - struct _map<const void *> { - static const void * - get(command_queue &q, const void *obj, cl_map_flags flags, - size_t offset, size_t size) { - return (const char *)obj + offset; - } - }; - - /// - /// Software copy from \a src_obj to \a dst_obj. They can be - /// either pointers or memory objects. - /// - template<typename T, typename S> - std::function<void (event &)> - soft_copy_op(command_queue &q, - T dst_obj, const vector_t &dst_orig, const vector_t &dst_pitch, - S src_obj, const vector_t &src_orig, const vector_t &src_pitch, - const vector_t ®ion) { - return [=, &q](event &) { - auto dst = _map<T>::get(q, dst_obj, CL_MAP_WRITE, - dot(dst_pitch, dst_orig), - size(dst_pitch, region)); - auto src = _map<S>::get(q, src_obj, CL_MAP_READ, - dot(src_pitch, src_orig), - size(src_pitch, region)); - vector_t v = {}; - - for (v[2] = 0; v[2] < region[2]; ++v[2]) { - for (v[1] = 0; v[1] < region[1]; ++v[1]) { - std::memcpy( - static_cast<char *>(dst) + dot(dst_pitch, v), - static_cast<const char *>(src) + dot(src_pitch, v), - src_pitch[0] * region[0]); - } - } - }; - } - - /// - /// Hardware copy from \a src_obj to \a dst_obj. - /// - template<typename T, typename S> - std::function<void (event &)> - hard_copy_op(command_queue &q, T dst_obj, const vector_t &dst_orig, - S src_obj, const vector_t &src_orig, const vector_t ®ion) { - return [=, &q](event &) { - dst_obj->resource(q).copy(q, dst_orig, region, - src_obj->resource(q), src_orig); - }; - } -} - -CLOVER_API cl_int -clEnqueueReadBuffer(cl_command_queue d_q, cl_mem d_mem, cl_bool blocking, - size_t offset, size_t size, void *ptr, - cl_uint num_deps, const cl_event *d_deps, - cl_event *rd_ev) try { - auto &q = obj(d_q); - auto &mem = obj<buffer>(d_mem); - auto deps = objs<wait_list_tag>(d_deps, num_deps); - vector_t region = { size, 1, 1 }; - vector_t obj_origin = { offset }; - auto obj_pitch = pitch(region, {{ 1 }}); - - validate_common(q, deps); - validate_object(q, ptr, {}, obj_pitch, region); - validate_object(q, mem, obj_origin, obj_pitch, region); - validate_object_access(mem, CL_MEM_HOST_READ_ONLY); - - auto hev = create<hard_event>( - q, CL_COMMAND_READ_BUFFER, deps, - soft_copy_op(q, ptr, {}, obj_pitch, - &mem, obj_origin, obj_pitch, - region)); - - if (blocking) - hev().wait_signalled(); - - ret_object(rd_ev, hev); - return CL_SUCCESS; - -} catch (error &e) { - return e.get(); -} - -CLOVER_API cl_int -clEnqueueWriteBuffer(cl_command_queue d_q, cl_mem d_mem, cl_bool blocking, - size_t offset, size_t size, const void *ptr, - cl_uint num_deps, const cl_event *d_deps, - cl_event *rd_ev) try { - auto &q = obj(d_q); - auto &mem = obj<buffer>(d_mem); - auto deps = objs<wait_list_tag>(d_deps, num_deps); - vector_t region = { size, 1, 1 }; - vector_t obj_origin = { offset }; - auto obj_pitch = pitch(region, {{ 1 }}); - - validate_common(q, deps); - validate_object(q, mem, obj_origin, obj_pitch, region); - validate_object(q, ptr, {}, obj_pitch, region); - validate_object_access(mem, CL_MEM_HOST_WRITE_ONLY); - - auto hev = create<hard_event>( - q, CL_COMMAND_WRITE_BUFFER, deps, - soft_copy_op(q, &mem, obj_origin, obj_pitch, - ptr, {}, obj_pitch, - region)); - - if (blocking) - hev().wait_signalled(); - - ret_object(rd_ev, hev); - return CL_SUCCESS; - -} catch (error &e) { - return e.get(); -} - -CLOVER_API cl_int -clEnqueueReadBufferRect(cl_command_queue d_q, cl_mem d_mem, cl_bool blocking, - const size_t *p_obj_origin, - const size_t *p_host_origin, - const size_t *p_region, - size_t obj_row_pitch, size_t obj_slice_pitch, - size_t host_row_pitch, size_t host_slice_pitch, - void *ptr, - cl_uint num_deps, const cl_event *d_deps, - cl_event *rd_ev) try { - auto &q = obj(d_q); - auto &mem = obj<buffer>(d_mem); - auto deps = objs<wait_list_tag>(d_deps, num_deps); - auto region = vector(p_region); - auto obj_origin = vector(p_obj_origin); - auto obj_pitch = pitch(region, {{ 1, obj_row_pitch, obj_slice_pitch }}); - auto host_origin = vector(p_host_origin); - auto host_pitch = pitch(region, {{ 1, host_row_pitch, host_slice_pitch }}); - - validate_common(q, deps); - validate_object(q, ptr, host_origin, host_pitch, region); - validate_object(q, mem, obj_origin, obj_pitch, region); - validate_object_access(mem, CL_MEM_HOST_READ_ONLY); - - auto hev = create<hard_event>( - q, CL_COMMAND_READ_BUFFER_RECT, deps, - soft_copy_op(q, ptr, host_origin, host_pitch, - &mem, obj_origin, obj_pitch, - region)); - - if (blocking) - hev().wait_signalled(); - - ret_object(rd_ev, hev); - return CL_SUCCESS; - -} catch (error &e) { - return e.get(); -} - -CLOVER_API cl_int -clEnqueueWriteBufferRect(cl_command_queue d_q, cl_mem d_mem, cl_bool blocking, - const size_t *p_obj_origin, - const size_t *p_host_origin, - const size_t *p_region, - size_t obj_row_pitch, size_t obj_slice_pitch, - size_t host_row_pitch, size_t host_slice_pitch, - const void *ptr, - cl_uint num_deps, const cl_event *d_deps, - cl_event *rd_ev) try { - auto &q = obj(d_q); - auto &mem = obj<buffer>(d_mem); - auto deps = objs<wait_list_tag>(d_deps, num_deps); - auto region = vector(p_region); - auto obj_origin = vector(p_obj_origin); - auto obj_pitch = pitch(region, {{ 1, obj_row_pitch, obj_slice_pitch }}); - auto host_origin = vector(p_host_origin); - auto host_pitch = pitch(region, {{ 1, host_row_pitch, host_slice_pitch }}); - - validate_common(q, deps); - validate_object(q, mem, obj_origin, obj_pitch, region); - validate_object(q, ptr, host_origin, host_pitch, region); - validate_object_access(mem, CL_MEM_HOST_WRITE_ONLY); - - auto hev = create<hard_event>( - q, CL_COMMAND_WRITE_BUFFER_RECT, deps, - soft_copy_op(q, &mem, obj_origin, obj_pitch, - ptr, host_origin, host_pitch, - region)); - - if (blocking) - hev().wait_signalled(); - - ret_object(rd_ev, hev); - return CL_SUCCESS; - -} catch (error &e) { - return e.get(); -} - -CLOVER_API cl_int -clEnqueueCopyBuffer(cl_command_queue d_q, cl_mem d_src_mem, cl_mem d_dst_mem, - size_t src_offset, size_t dst_offset, size_t size, - cl_uint num_deps, const cl_event *d_deps, - cl_event *rd_ev) try { - auto &q = obj(d_q); - auto &src_mem = obj<buffer>(d_src_mem); - auto &dst_mem = obj<buffer>(d_dst_mem); - auto deps = objs<wait_list_tag>(d_deps, num_deps); - vector_t region = { size, 1, 1 }; - vector_t dst_origin = { dst_offset }; - auto dst_pitch = pitch(region, {{ 1 }}); - vector_t src_origin = { src_offset }; - auto src_pitch = pitch(region, {{ 1 }}); - - validate_common(q, deps); - validate_object(q, dst_mem, dst_origin, dst_pitch, region); - validate_object(q, src_mem, src_origin, src_pitch, region); - validate_copy(q, dst_mem, dst_origin, dst_pitch, - src_mem, src_origin, src_pitch, region); - - auto hev = create<hard_event>( - q, CL_COMMAND_COPY_BUFFER, deps, - hard_copy_op(q, &dst_mem, dst_origin, - &src_mem, src_origin, region)); - - ret_object(rd_ev, hev); - return CL_SUCCESS; - -} catch (error &e) { - return e.get(); -} - -CLOVER_API cl_int -clEnqueueCopyBufferRect(cl_command_queue d_q, cl_mem d_src_mem, - cl_mem d_dst_mem, - const size_t *p_src_origin, const size_t *p_dst_origin, - const size_t *p_region, - size_t src_row_pitch, size_t src_slice_pitch, - size_t dst_row_pitch, size_t dst_slice_pitch, - cl_uint num_deps, const cl_event *d_deps, - cl_event *rd_ev) try { - auto &q = obj(d_q); - auto &src_mem = obj<buffer>(d_src_mem); - auto &dst_mem = obj<buffer>(d_dst_mem); - auto deps = objs<wait_list_tag>(d_deps, num_deps); - auto region = vector(p_region); - auto dst_origin = vector(p_dst_origin); - auto dst_pitch = pitch(region, {{ 1, dst_row_pitch, dst_slice_pitch }}); - auto src_origin = vector(p_src_origin); - auto src_pitch = pitch(region, {{ 1, src_row_pitch, src_slice_pitch }}); - - validate_common(q, deps); - validate_object(q, dst_mem, dst_origin, dst_pitch, region); - validate_object(q, src_mem, src_origin, src_pitch, region); - validate_copy(q, dst_mem, dst_origin, dst_pitch, - src_mem, src_origin, src_pitch, region); - - auto hev = create<hard_event>( - q, CL_COMMAND_COPY_BUFFER_RECT, deps, - soft_copy_op(q, &dst_mem, dst_origin, dst_pitch, - &src_mem, src_origin, src_pitch, - region)); - - ret_object(rd_ev, hev); - return CL_SUCCESS; - -} catch (error &e) { - return e.get(); -} - -CLOVER_API cl_int -clEnqueueReadImage(cl_command_queue d_q, cl_mem d_mem, cl_bool blocking, - const size_t *p_origin, const size_t *p_region, - size_t row_pitch, size_t slice_pitch, void *ptr, - cl_uint num_deps, const cl_event *d_deps, - cl_event *rd_ev) try { - auto &q = obj(d_q); - auto &img = obj<image>(d_mem); - auto deps = objs<wait_list_tag>(d_deps, num_deps); - auto region = vector(p_region); - auto dst_pitch = pitch(region, {{ img.pixel_size(), - row_pitch, slice_pitch }}); - auto src_origin = vector(p_origin); - auto src_pitch = pitch(region, {{ img.pixel_size(), - img.row_pitch(), img.slice_pitch() }}); - - validate_common(q, deps); - validate_object(q, ptr, {}, dst_pitch, region); - validate_object(q, img, src_origin, region); - validate_object_access(img, CL_MEM_HOST_READ_ONLY); - - auto hev = create<hard_event>( - q, CL_COMMAND_READ_IMAGE, deps, - soft_copy_op(q, ptr, {}, dst_pitch, - &img, src_origin, src_pitch, - region)); - - if (blocking) - hev().wait_signalled(); - - ret_object(rd_ev, hev); - return CL_SUCCESS; - -} catch (error &e) { - return e.get(); -} - -CLOVER_API cl_int -clEnqueueWriteImage(cl_command_queue d_q, cl_mem d_mem, cl_bool blocking, - const size_t *p_origin, const size_t *p_region, - size_t row_pitch, size_t slice_pitch, const void *ptr, - cl_uint num_deps, const cl_event *d_deps, - cl_event *rd_ev) try { - auto &q = obj(d_q); - auto &img = obj<image>(d_mem); - auto deps = objs<wait_list_tag>(d_deps, num_deps); - auto region = vector(p_region); - auto dst_origin = vector(p_origin); - auto dst_pitch = pitch(region, {{ img.pixel_size(), - img.row_pitch(), img.slice_pitch() }}); - auto src_pitch = pitch(region, {{ img.pixel_size(), - row_pitch, slice_pitch }}); - - validate_common(q, deps); - validate_object(q, img, dst_origin, region); - validate_object(q, ptr, {}, src_pitch, region); - validate_object_access(img, CL_MEM_HOST_WRITE_ONLY); - - auto hev = create<hard_event>( - q, CL_COMMAND_WRITE_IMAGE, deps, - soft_copy_op(q, &img, dst_origin, dst_pitch, - ptr, {}, src_pitch, - region)); - - if (blocking) - hev().wait_signalled(); - - ret_object(rd_ev, hev); - return CL_SUCCESS; - -} catch (error &e) { - return e.get(); -} - -CLOVER_API cl_int -clEnqueueCopyImage(cl_command_queue d_q, cl_mem d_src_mem, cl_mem d_dst_mem, - const size_t *p_src_origin, const size_t *p_dst_origin, - const size_t *p_region, - cl_uint num_deps, const cl_event *d_deps, - cl_event *rd_ev) try { - auto &q = obj(d_q); - auto &src_img = obj<image>(d_src_mem); - auto &dst_img = obj<image>(d_dst_mem); - auto deps = objs<wait_list_tag>(d_deps, num_deps); - auto region = vector(p_region); - auto dst_origin = vector(p_dst_origin); - auto src_origin = vector(p_src_origin); - - validate_common(q, deps); - validate_object(q, dst_img, dst_origin, region); - validate_object(q, src_img, src_origin, region); - validate_copy(q, dst_img, dst_origin, src_img, src_origin, region); - - auto hev = create<hard_event>( - q, CL_COMMAND_COPY_IMAGE, deps, - hard_copy_op(q, &dst_img, dst_origin, - &src_img, src_origin, - region)); - - ret_object(rd_ev, hev); - return CL_SUCCESS; - -} catch (error &e) { - return e.get(); -} - -CLOVER_API cl_int -clEnqueueCopyImageToBuffer(cl_command_queue d_q, - cl_mem d_src_mem, cl_mem d_dst_mem, - const size_t *p_src_origin, const size_t *p_region, - size_t dst_offset, - cl_uint num_deps, const cl_event *d_deps, - cl_event *rd_ev) try { - auto &q = obj(d_q); - auto &src_img = obj<image>(d_src_mem); - auto &dst_mem = obj<buffer>(d_dst_mem); - auto deps = objs<wait_list_tag>(d_deps, num_deps); - auto region = vector(p_region); - vector_t dst_origin = { dst_offset }; - auto dst_pitch = pitch(region, {{ src_img.pixel_size() }}); - auto src_origin = vector(p_src_origin); - auto src_pitch = pitch(region, {{ src_img.pixel_size(), - src_img.row_pitch(), - src_img.slice_pitch() }}); - - validate_common(q, deps); - validate_object(q, dst_mem, dst_origin, dst_pitch, region); - validate_object(q, src_img, src_origin, region); - - auto hev = create<hard_event>( - q, CL_COMMAND_COPY_IMAGE_TO_BUFFER, deps, - soft_copy_op(q, &dst_mem, dst_origin, dst_pitch, - &src_img, src_origin, src_pitch, - region)); - - ret_object(rd_ev, hev); - return CL_SUCCESS; - -} catch (error &e) { - return e.get(); -} - -CLOVER_API cl_int -clEnqueueCopyBufferToImage(cl_command_queue d_q, - cl_mem d_src_mem, cl_mem d_dst_mem, - size_t src_offset, - const size_t *p_dst_origin, const size_t *p_region, - cl_uint num_deps, const cl_event *d_deps, - cl_event *rd_ev) try { - auto &q = obj(d_q); - auto &src_mem = obj<buffer>(d_src_mem); - auto &dst_img = obj<image>(d_dst_mem); - auto deps = objs<wait_list_tag>(d_deps, num_deps); - auto region = vector(p_region); - auto dst_origin = vector(p_dst_origin); - auto dst_pitch = pitch(region, {{ dst_img.pixel_size(), - dst_img.row_pitch(), - dst_img.slice_pitch() }}); - vector_t src_origin = { src_offset }; - auto src_pitch = pitch(region, {{ dst_img.pixel_size() }}); - - validate_common(q, deps); - validate_object(q, dst_img, dst_origin, region); - validate_object(q, src_mem, src_origin, src_pitch, region); - - auto hev = create<hard_event>( - q, CL_COMMAND_COPY_BUFFER_TO_IMAGE, deps, - soft_copy_op(q, &dst_img, dst_origin, dst_pitch, - &src_mem, src_origin, src_pitch, - region)); - - ret_object(rd_ev, hev); - return CL_SUCCESS; - -} catch (error &e) { - return e.get(); -} - -CLOVER_API void * -clEnqueueMapBuffer(cl_command_queue d_q, cl_mem d_mem, cl_bool blocking, - cl_map_flags flags, size_t offset, size_t size, - cl_uint num_deps, const cl_event *d_deps, - cl_event *rd_ev, cl_int *r_errcode) try { - auto &q = obj(d_q); - auto &mem = obj<buffer>(d_mem); - auto deps = objs<wait_list_tag>(d_deps, num_deps); - vector_t region = { size, 1, 1 }; - vector_t obj_origin = { offset }; - auto obj_pitch = pitch(region, {{ 1 }}); - - validate_common(q, deps); - validate_object(q, mem, obj_origin, obj_pitch, region); - validate_map_flags(mem, flags); - - void *map = mem.resource(q).add_map(q, flags, blocking, obj_origin, region); - - auto hev = create<hard_event>(q, CL_COMMAND_MAP_BUFFER, deps); - if (blocking) - hev().wait_signalled(); - - ret_object(rd_ev, hev); - ret_error(r_errcode, CL_SUCCESS); - return map; - -} catch (error &e) { - ret_error(r_errcode, e); - return NULL; -} - -CLOVER_API void * -clEnqueueMapImage(cl_command_queue d_q, cl_mem d_mem, cl_bool blocking, - cl_map_flags flags, - const size_t *p_origin, const size_t *p_region, - size_t *row_pitch, size_t *slice_pitch, - cl_uint num_deps, const cl_event *d_deps, - cl_event *rd_ev, cl_int *r_errcode) try { - auto &q = obj(d_q); - auto &img = obj<image>(d_mem); - auto deps = objs<wait_list_tag>(d_deps, num_deps); - auto region = vector(p_region); - auto origin = vector(p_origin); - - validate_common(q, deps); - validate_object(q, img, origin, region); - validate_map_flags(img, flags); - - void *map = img.resource(q).add_map(q, flags, blocking, origin, region); - - auto hev = create<hard_event>(q, CL_COMMAND_MAP_IMAGE, deps); - if (blocking) - hev().wait_signalled(); - - ret_object(rd_ev, hev); - ret_error(r_errcode, CL_SUCCESS); - return map; - -} catch (error &e) { - ret_error(r_errcode, e); - return NULL; -} - -CLOVER_API cl_int -clEnqueueUnmapMemObject(cl_command_queue d_q, cl_mem d_mem, void *ptr, - cl_uint num_deps, const cl_event *d_deps, - cl_event *rd_ev) try { - auto &q = obj(d_q); - auto &mem = obj(d_mem); - auto deps = objs<wait_list_tag>(d_deps, num_deps); - - validate_common(q, deps); - - auto hev = create<hard_event>( - q, CL_COMMAND_UNMAP_MEM_OBJECT, deps, - [=, &q, &mem](event &) { - mem.resource(q).del_map(ptr); - }); - - ret_object(rd_ev, hev); - return CL_SUCCESS; - -} catch (error &e) { - return e.get(); -} - -CLOVER_API cl_int -clEnqueueMigrateMemObjects(cl_command_queue command_queue, - cl_uint num_mem_objects, - const cl_mem *mem_objects, - cl_mem_migration_flags flags, - cl_uint num_events_in_wait_list, - const cl_event *event_wait_list, - cl_event *event) { - CLOVER_NOT_SUPPORTED_UNTIL("1.2"); - return CL_INVALID_VALUE; -} - -cl_int -clover::EnqueueSVMFree(cl_command_queue d_q, - cl_uint num_svm_pointers, - void *svm_pointers[], - void (CL_CALLBACK *pfn_free_func) ( - cl_command_queue queue, cl_uint num_svm_pointers, - void *svm_pointers[], void *user_data), - void *user_data, - cl_uint num_events_in_wait_list, - const cl_event *event_wait_list, - cl_event *event, - cl_int cmd) try { - - if (bool(num_svm_pointers) != bool(svm_pointers)) - return CL_INVALID_VALUE; - - auto &q = obj(d_q); - bool can_emulate = q.device().has_system_svm(); - auto deps = objs<wait_list_tag>(event_wait_list, num_events_in_wait_list); - - validate_common(q, deps); - - std::vector<void *> svm_pointers_cpy(svm_pointers, - svm_pointers + num_svm_pointers); - if (!pfn_free_func) { - if (!can_emulate) { - CLOVER_NOT_SUPPORTED_UNTIL("2.0"); - return CL_INVALID_VALUE; - } - pfn_free_func = [](cl_command_queue, cl_uint num_svm_pointers, - void *svm_pointers[], void *) { - for (void *p : range(svm_pointers, num_svm_pointers)) - free(p); - }; - } - - auto hev = create<hard_event>(q, cmd, deps, - [=](clover::event &) mutable { - pfn_free_func(d_q, num_svm_pointers, svm_pointers_cpy.data(), - user_data); - }); - - ret_object(event, hev); - return CL_SUCCESS; - -} catch (error &e) { - return e.get(); -} - -CLOVER_API cl_int -clEnqueueSVMFree(cl_command_queue d_q, - cl_uint num_svm_pointers, - void *svm_pointers[], - void (CL_CALLBACK *pfn_free_func) ( - cl_command_queue queue, cl_uint num_svm_pointers, - void *svm_pointers[], void *user_data), - void *user_data, - cl_uint num_events_in_wait_list, - const cl_event *event_wait_list, - cl_event *event) { - - return EnqueueSVMFree(d_q, num_svm_pointers, svm_pointers, - pfn_free_func, user_data, num_events_in_wait_list, - event_wait_list, event, CL_COMMAND_SVM_FREE); -} - -cl_int -clover::EnqueueSVMMemcpy(cl_command_queue d_q, - cl_bool blocking_copy, - void *dst_ptr, - const void *src_ptr, - size_t size, - cl_uint num_events_in_wait_list, - const cl_event *event_wait_list, - cl_event *event, - cl_int cmd) try { - - if (dst_ptr == nullptr || src_ptr == nullptr) - return CL_INVALID_VALUE; - - if (static_cast<size_t>(abs(reinterpret_cast<ptrdiff_t>(dst_ptr) - - reinterpret_cast<ptrdiff_t>(src_ptr))) < size) - return CL_MEM_COPY_OVERLAP; - - auto &q = obj(d_q); - bool can_emulate = q.device().has_system_svm(); - auto deps = objs<wait_list_tag>(event_wait_list, num_events_in_wait_list); - - validate_common(q, deps); - - if (can_emulate) { - auto hev = create<hard_event>(q, cmd, deps, - [=](clover::event &) { - memcpy(dst_ptr, src_ptr, size); - }); - - if (blocking_copy) - hev().wait(); - ret_object(event, hev); - return CL_SUCCESS; - } - - CLOVER_NOT_SUPPORTED_UNTIL("2.0"); - return CL_INVALID_VALUE; - -} catch (error &e) { - return e.get(); -} - -CLOVER_API cl_int -clEnqueueSVMMemcpy(cl_command_queue d_q, - cl_bool blocking_copy, - void *dst_ptr, - const void *src_ptr, - size_t size, - cl_uint num_events_in_wait_list, - const cl_event *event_wait_list, - cl_event *event) { - - return EnqueueSVMMemcpy(d_q, blocking_copy, dst_ptr, src_ptr, - size, num_events_in_wait_list, event_wait_list, - event, CL_COMMAND_SVM_MEMCPY); -} - -cl_int -clover::EnqueueSVMMemFill(cl_command_queue d_q, - void *svm_ptr, - const void *pattern, - size_t pattern_size, - size_t size, - cl_uint num_events_in_wait_list, - const cl_event *event_wait_list, - cl_event *event, - cl_int cmd) try { - - if (svm_ptr == nullptr || pattern == nullptr || - !util_is_power_of_two_nonzero(pattern_size) || - pattern_size > 128 || - !ptr_is_aligned(svm_ptr, pattern_size) || - size % pattern_size) - return CL_INVALID_VALUE; - - auto &q = obj(d_q); - bool can_emulate = q.device().has_system_svm(); - auto deps = objs<wait_list_tag>(event_wait_list, num_events_in_wait_list); - - validate_common(q, deps); - - if (can_emulate) { - auto hev = create<hard_event>(q, cmd, deps, - [=](clover::event &) { - void *ptr = svm_ptr; - for (size_t s = size; s; s -= pattern_size) { - memcpy(ptr, pattern, pattern_size); - ptr = static_cast<uint8_t*>(ptr) + pattern_size; - } - }); - - ret_object(event, hev); - return CL_SUCCESS; - } - - CLOVER_NOT_SUPPORTED_UNTIL("2.0"); - return CL_INVALID_VALUE; - -} catch (error &e) { - return e.get(); -} - -CLOVER_API cl_int -clEnqueueSVMMemFill(cl_command_queue d_q, - void *svm_ptr, - const void *pattern, - size_t pattern_size, - size_t size, - cl_uint num_events_in_wait_list, - const cl_event *event_wait_list, - cl_event *event) { - - return EnqueueSVMMemFill(d_q, svm_ptr, pattern, pattern_size, - size, num_events_in_wait_list, event_wait_list, - event, CL_COMMAND_SVM_MEMFILL); -} - -cl_int -clover::EnqueueSVMMap(cl_command_queue d_q, - cl_bool blocking_map, - cl_map_flags map_flags, - void *svm_ptr, - size_t size, - cl_uint num_events_in_wait_list, - const cl_event *event_wait_list, - cl_event *event, - cl_int cmd) try { - - if (svm_ptr == nullptr || size == 0) - return CL_INVALID_VALUE; - - auto &q = obj(d_q); - bool can_emulate = q.device().has_system_svm(); - auto deps = objs<wait_list_tag>(event_wait_list, num_events_in_wait_list); - - validate_common(q, deps); - - if (can_emulate) { - auto hev = create<hard_event>(q, cmd, deps, - [](clover::event &) { }); - - ret_object(event, hev); - return CL_SUCCESS; - } - - CLOVER_NOT_SUPPORTED_UNTIL("2.0"); - return CL_INVALID_VALUE; - -} catch (error &e) { - return e.get(); -} - -CLOVER_API cl_int -clEnqueueSVMMap(cl_command_queue d_q, - cl_bool blocking_map, - cl_map_flags map_flags, - void *svm_ptr, - size_t size, - cl_uint num_events_in_wait_list, - const cl_event *event_wait_list, - cl_event *event) { - - return EnqueueSVMMap(d_q, blocking_map, map_flags, svm_ptr, size, - num_events_in_wait_list, event_wait_list, event, - CL_COMMAND_SVM_MAP); -} - -cl_int -clover::EnqueueSVMUnmap(cl_command_queue d_q, - void *svm_ptr, - cl_uint num_events_in_wait_list, - const cl_event *event_wait_list, - cl_event *event, - cl_int cmd) try { - - if (svm_ptr == nullptr) - return CL_INVALID_VALUE; - - auto &q = obj(d_q); - bool can_emulate = q.device().has_system_svm(); - auto deps = objs<wait_list_tag>(event_wait_list, num_events_in_wait_list); - - validate_common(q, deps); - - if (can_emulate) { - auto hev = create<hard_event>(q, cmd, deps, - [](clover::event &) { }); - - ret_object(event, hev); - return CL_SUCCESS; - } - - CLOVER_NOT_SUPPORTED_UNTIL("2.0"); - return CL_INVALID_VALUE; - -} catch (error &e) { - return e.get(); -} - -CLOVER_API cl_int -clEnqueueSVMUnmap(cl_command_queue d_q, - void *svm_ptr, - cl_uint num_events_in_wait_list, - const cl_event *event_wait_list, - cl_event *event) { - - return EnqueueSVMUnmap(d_q, svm_ptr, num_events_in_wait_list, - event_wait_list, event, CL_COMMAND_SVM_UNMAP); -} - -CLOVER_API cl_int -clEnqueueSVMMigrateMem(cl_command_queue d_q, - cl_uint num_svm_pointers, - const void **svm_pointers, - const size_t *sizes, - const cl_mem_migration_flags flags, - cl_uint num_events_in_wait_list, - const cl_event *event_wait_list, - cl_event *event) { - CLOVER_NOT_SUPPORTED_UNTIL("2.1"); - return CL_INVALID_VALUE; -} diff --git a/src/gallium/state_trackers/clover/api/util.hpp b/src/gallium/state_trackers/clover/api/util.hpp deleted file mode 100644 index 66bd12597c6..00000000000 --- a/src/gallium/state_trackers/clover/api/util.hpp +++ /dev/null @@ -1,84 +0,0 @@ -// -// Copyright 2012 Francisco Jerez -// -// Permission is hereby granted, free of charge, to any person obtaining a -// copy of this software and associated documentation files (the "Software"), -// to deal in the Software without restriction, including without limitation -// the rights to use, copy, modify, merge, publish, distribute, sublicense, -// and/or sell copies of the Software, and to permit persons to whom the -// Software is furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL -// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR -// OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, -// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR -// OTHER DEALINGS IN THE SOFTWARE. -// - -#ifndef CLOVER_API_UTIL_HPP -#define CLOVER_API_UTIL_HPP - -#include <cassert> -#include <iostream> - -#include "core/error.hpp" -#include "core/property.hpp" -#include "util/algorithm.hpp" - -#ifdef HAVE_CLOVER_ICD -#define CLOVER_API -#define CLOVER_ICD_API PUBLIC -#else -#define CLOVER_API PUBLIC -#define CLOVER_ICD_API PUBLIC -#endif - -#define CLOVER_NOT_SUPPORTED_UNTIL(version) \ - do { \ - std::cerr << "CL user error: " << __func__ \ - << "() requires OpenCL version " << (version) \ - << " or greater." << std::endl; \ - } while (0) - -namespace clover { - /// - /// Return an error code in \a p if non-zero. - /// - inline void - ret_error(cl_int *p, const clover::error &e) { - if (p) - *p = e.get(); - } - - /// - /// Return a clover object in \a p if non-zero incrementing the - /// reference count of the object. - /// - template<typename T> - void - ret_object(typename T::descriptor_type **p, - const intrusive_ref<T> &v) { - if (p) { - v().retain(); - *p = desc(v()); - } - } - - /// - /// Return an API object from an intrusive reference to a Clover object, - /// incrementing the reference count of the object. - /// - template<typename T> - typename T::descriptor_type * - ret_object(const intrusive_ref<T> &v) { - v().retain(); - return desc(v()); - } -} - -#endif diff --git a/src/gallium/state_trackers/clover/core/compiler.hpp b/src/gallium/state_trackers/clover/core/compiler.hpp deleted file mode 100644 index 6ef30df9b7f..00000000000 --- a/src/gallium/state_trackers/clover/core/compiler.hpp +++ /dev/null @@ -1,68 +0,0 @@ -// -// Copyright 2019 Red Hat, Inc. -// -// Permission is hereby granted, free of charge, to any person obtaining a -// copy of this software and associated documentation files (the "Software"), -// to deal in the Software without restriction, including without limitation -// the rights to use, copy, modify, merge, publish, distribute, sublicense, -// and/or sell copies of the Software, and to permit persons to whom the -// Software is furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL -// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR -// OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, -// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR -// OTHER DEALINGS IN THE SOFTWARE. -// - -#ifndef CLOVER_CORE_COMPILER_HPP -#define CLOVER_CORE_COMPILER_HPP - -#include "core/device.hpp" -#include "core/module.hpp" -#include "llvm/invocation.hpp" -#include "nir/invocation.hpp" -#include "spirv/invocation.hpp" - -namespace clover { - namespace compiler { - static inline module - compile_program(const std::string &source, const header_map &headers, - const device &dev, const std::string &opts, - std::string &log) { - switch (dev.ir_format()) { -#ifdef HAVE_CLOVER_SPIRV - case PIPE_SHADER_IR_NIR_SERIALIZED: - return llvm::compile_to_spirv(source, headers, dev, opts, log); -#endif - case PIPE_SHADER_IR_NATIVE: - return llvm::compile_program(source, headers, dev, opts, log); - default: - unreachable("device with unsupported IR"); - throw error(CL_INVALID_VALUE); - } - } - - static inline module - link_program(const std::vector<module> &ms, const device &dev, - const std::string &opts, std::string &log) { - switch (dev.ir_format()) { - case PIPE_SHADER_IR_NIR_SERIALIZED: - return nir::spirv_to_nir(spirv::link_program(ms, dev, opts, log), - dev, log); - case PIPE_SHADER_IR_NATIVE: - return llvm::link_program(ms, dev, opts, log); - default: - unreachable("device with unsupported IR"); - throw error(CL_INVALID_VALUE); - } - } - } -} - -#endif diff --git a/src/gallium/state_trackers/clover/core/context.cpp b/src/gallium/state_trackers/clover/core/context.cpp deleted file mode 100644 index c3e20829384..00000000000 --- a/src/gallium/state_trackers/clover/core/context.cpp +++ /dev/null @@ -1,51 +0,0 @@ -// -// Copyright 2012 Francisco Jerez -// -// Permission is hereby granted, free of charge, to any person obtaining a -// copy of this software and associated documentation files (the "Software"), -// to deal in the Software without restriction, including without limitation -// the rights to use, copy, modify, merge, publish, distribute, sublicense, -// and/or sell copies of the Software, and to permit persons to whom the -// Software is furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL -// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR -// OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, -// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR -// OTHER DEALINGS IN THE SOFTWARE. -// - -#include "core/context.hpp" - -using namespace clover; - -context::context(const property_list &props, - const ref_vector<device> &devs, - const notify_action ¬ify) : - notify(notify), props(props), devs(devs) { -} - -bool -context::operator==(const context &ctx) const { - return this == &ctx; -} - -bool -context::operator!=(const context &ctx) const { - return this != &ctx; -} - -const context::property_list & -context::properties() const { - return props; -} - -context::device_range -context::devices() const { - return map(evals(), devs); -} diff --git a/src/gallium/state_trackers/clover/core/context.hpp b/src/gallium/state_trackers/clover/core/context.hpp deleted file mode 100644 index 7b22ccae78f..00000000000 --- a/src/gallium/state_trackers/clover/core/context.hpp +++ /dev/null @@ -1,67 +0,0 @@ -// -// Copyright 2012 Francisco Jerez -// -// Permission is hereby granted, free of charge, to any person obtaining a -// copy of this software and associated documentation files (the "Software"), -// to deal in the Software without restriction, including without limitation -// the rights to use, copy, modify, merge, publish, distribute, sublicense, -// and/or sell copies of the Software, and to permit persons to whom the -// Software is furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL -// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR -// OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, -// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR -// OTHER DEALINGS IN THE SOFTWARE. -// - -#ifndef CLOVER_CORE_CONTEXT_HPP -#define CLOVER_CORE_CONTEXT_HPP - -#include "core/object.hpp" -#include "core/device.hpp" -#include "core/property.hpp" - -namespace clover { - class context : public ref_counter, public _cl_context { - private: - typedef adaptor_range< - evals, const std::vector<intrusive_ref<device>> & - > device_range; - typedef clover::property_list<cl_context_properties> property_list; - - public: - typedef std::function<void (const char *)> notify_action; - - context(const property_list &props, const ref_vector<device> &devs, - const notify_action ¬ify); - - context(const context &ctx) = delete; - context & - operator=(const context &ctx) = delete; - - bool - operator==(const context &ctx) const; - bool - operator!=(const context &ctx) const; - - const property_list & - properties() const; - - device_range - devices() const; - - const notify_action notify; - - private: - property_list props; - const std::vector<intrusive_ref<device>> devs; - }; -} - -#endif diff --git a/src/gallium/state_trackers/clover/core/device.cpp b/src/gallium/state_trackers/clover/core/device.cpp deleted file mode 100644 index 609885c21bc..00000000000 --- a/src/gallium/state_trackers/clover/core/device.cpp +++ /dev/null @@ -1,337 +0,0 @@ -// -// Copyright 2012 Francisco Jerez -// -// Permission is hereby granted, free of charge, to any person obtaining a -// copy of this software and associated documentation files (the "Software"), -// to deal in the Software without restriction, including without limitation -// the rights to use, copy, modify, merge, publish, distribute, sublicense, -// and/or sell copies of the Software, and to permit persons to whom the -// Software is furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL -// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR -// OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, -// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR -// OTHER DEALINGS IN THE SOFTWARE. -// - -#include <unistd.h> -#include "core/device.hpp" -#include "core/platform.hpp" -#include "pipe/p_screen.h" -#include "pipe/p_state.h" -#include "util/bitscan.h" -#include "util/u_debug.h" - -using namespace clover; - -namespace { - template<typename T> - std::vector<T> - get_compute_param(pipe_screen *pipe, pipe_shader_ir ir_format, - pipe_compute_cap cap) { - int sz = pipe->get_compute_param(pipe, ir_format, cap, NULL); - std::vector<T> v(sz / sizeof(T)); - - pipe->get_compute_param(pipe, ir_format, cap, &v.front()); - return v; - } -} - -device::device(clover::platform &platform, pipe_loader_device *ldev) : - platform(platform), ldev(ldev) { - pipe = pipe_loader_create_screen(ldev); - if (pipe && pipe->get_param(pipe, PIPE_CAP_COMPUTE)) { - if (supports_ir(PIPE_SHADER_IR_NATIVE)) - return; -#ifdef HAVE_CLOVER_SPIRV - if (supports_ir(PIPE_SHADER_IR_NIR_SERIALIZED)) - return; -#endif - } - if (pipe) - pipe->destroy(pipe); - throw error(CL_INVALID_DEVICE); -} - -device::~device() { - if (pipe) - pipe->destroy(pipe); - if (ldev) - pipe_loader_release(&ldev, 1); -} - -bool -device::operator==(const device &dev) const { - return this == &dev; -} - -cl_device_type -device::type() const { - switch (ldev->type) { - case PIPE_LOADER_DEVICE_SOFTWARE: - return CL_DEVICE_TYPE_CPU; - case PIPE_LOADER_DEVICE_PCI: - case PIPE_LOADER_DEVICE_PLATFORM: - return CL_DEVICE_TYPE_GPU; - default: - unreachable("Unknown device type."); - } -} - -cl_uint -device::vendor_id() const { - switch (ldev->type) { - case PIPE_LOADER_DEVICE_SOFTWARE: - case PIPE_LOADER_DEVICE_PLATFORM: - return 0; - case PIPE_LOADER_DEVICE_PCI: - return ldev->u.pci.vendor_id; - default: - unreachable("Unknown device type."); - } -} - -size_t -device::max_images_read() const { - return PIPE_MAX_SHADER_IMAGES; -} - -size_t -device::max_images_write() const { - return PIPE_MAX_SHADER_IMAGES; -} - -size_t -device::max_image_buffer_size() const { - return pipe->get_param(pipe, PIPE_CAP_MAX_TEXTURE_BUFFER_SIZE); -} - -cl_uint -device::max_image_levels_2d() const { - return util_last_bit(pipe->get_param(pipe, PIPE_CAP_MAX_TEXTURE_2D_SIZE)); -} - -cl_uint -device::max_image_levels_3d() const { - return pipe->get_param(pipe, PIPE_CAP_MAX_TEXTURE_3D_LEVELS); -} - -size_t -device::max_image_array_number() const { - return pipe->get_param(pipe, PIPE_CAP_MAX_TEXTURE_ARRAY_LAYERS); -} - -cl_uint -device::max_samplers() const { - return pipe->get_shader_param(pipe, PIPE_SHADER_COMPUTE, - PIPE_SHADER_CAP_MAX_TEXTURE_SAMPLERS); -} - -cl_ulong -device::max_mem_global() const { - return get_compute_param<uint64_t>(pipe, ir_format(), - PIPE_COMPUTE_CAP_MAX_GLOBAL_SIZE)[0]; -} - -cl_ulong -device::max_mem_local() const { - return get_compute_param<uint64_t>(pipe, ir_format(), - PIPE_COMPUTE_CAP_MAX_LOCAL_SIZE)[0]; -} - -cl_ulong -device::max_mem_input() const { - return get_compute_param<uint64_t>(pipe, ir_format(), - PIPE_COMPUTE_CAP_MAX_INPUT_SIZE)[0]; -} - -cl_ulong -device::max_const_buffer_size() const { - return pipe->get_shader_param(pipe, PIPE_SHADER_COMPUTE, - PIPE_SHADER_CAP_MAX_CONST_BUFFER_SIZE); -} - -cl_uint -device::max_const_buffers() const { - return pipe->get_shader_param(pipe, PIPE_SHADER_COMPUTE, - PIPE_SHADER_CAP_MAX_CONST_BUFFERS); -} - -size_t -device::max_threads_per_block() const { - return get_compute_param<uint64_t>( - pipe, ir_format(), PIPE_COMPUTE_CAP_MAX_THREADS_PER_BLOCK)[0]; -} - -cl_ulong -device::max_mem_alloc_size() const { - return get_compute_param<uint64_t>(pipe, ir_format(), - PIPE_COMPUTE_CAP_MAX_MEM_ALLOC_SIZE)[0]; -} - -cl_uint -device::max_clock_frequency() const { - return get_compute_param<uint32_t>(pipe, ir_format(), - PIPE_COMPUTE_CAP_MAX_CLOCK_FREQUENCY)[0]; -} - -cl_uint -device::max_compute_units() const { - return get_compute_param<uint32_t>(pipe, ir_format(), - PIPE_COMPUTE_CAP_MAX_COMPUTE_UNITS)[0]; -} - -bool -device::image_support() const { - return get_compute_param<uint32_t>(pipe, ir_format(), - PIPE_COMPUTE_CAP_IMAGES_SUPPORTED)[0]; -} - -bool -device::has_doubles() const { - return pipe->get_param(pipe, PIPE_CAP_DOUBLES); -} - -bool -device::has_halves() const { - return pipe->get_shader_param(pipe, PIPE_SHADER_COMPUTE, - PIPE_SHADER_CAP_FP16); -} - -bool -device::has_int64_atomics() const { - return pipe->get_shader_param(pipe, PIPE_SHADER_COMPUTE, - PIPE_SHADER_CAP_INT64_ATOMICS); -} - -bool -device::has_unified_memory() const { - return pipe->get_param(pipe, PIPE_CAP_UMA); -} - -cl_uint -device::mem_base_addr_align() const { - return sysconf(_SC_PAGESIZE); -} - -cl_device_svm_capabilities -device::svm_support() const { - // Without CAP_RESOURCE_FROM_USER_MEMORY SVM and CL_MEM_USE_HOST_PTR - // interactions won't work according to spec as clover manages a GPU side - // copy of the host data. - // - // The biggest problem are memory buffers created with CL_MEM_USE_HOST_PTR, - // but the application and/or the kernel updates the memory via SVM and not - // the cl_mem buffer. - // We can't even do proper tracking on what memory might have been accessed - // as the host ptr to the buffer could be within a SVM region, where through - // the CL API there is no reliable way of knowing if a certain cl_mem buffer - // was accessed by a kernel or not and the runtime can't reliably know from - // which side the GPU buffer content needs to be updated. - // - // Another unsolvable scenario is a cl_mem object passed by cl_mem reference - // and SVM pointer into the same kernel at the same time. - if (pipe->get_param(pipe, PIPE_CAP_RESOURCE_FROM_USER_MEMORY) && - pipe->get_param(pipe, PIPE_CAP_SYSTEM_SVM)) - // we can emulate all lower levels if we support fine grain system - return CL_DEVICE_SVM_FINE_GRAIN_SYSTEM | - CL_DEVICE_SVM_COARSE_GRAIN_BUFFER | - CL_DEVICE_SVM_FINE_GRAIN_BUFFER; - return 0; -} - -std::vector<size_t> -device::max_block_size() const { - auto v = get_compute_param<uint64_t>(pipe, ir_format(), - PIPE_COMPUTE_CAP_MAX_BLOCK_SIZE); - return { v.begin(), v.end() }; -} - -cl_uint -device::subgroup_size() const { - return get_compute_param<uint32_t>(pipe, ir_format(), - PIPE_COMPUTE_CAP_SUBGROUP_SIZE)[0]; -} - -cl_uint -device::address_bits() const { - return get_compute_param<uint32_t>(pipe, ir_format(), - PIPE_COMPUTE_CAP_ADDRESS_BITS)[0]; -} - -std::string -device::device_name() const { - return pipe->get_name(pipe); -} - -std::string -device::vendor_name() const { - return pipe->get_device_vendor(pipe); -} - -enum pipe_shader_ir -device::ir_format() const { - if (supports_ir(PIPE_SHADER_IR_NATIVE)) - return PIPE_SHADER_IR_NATIVE; - - assert(supports_ir(PIPE_SHADER_IR_NIR_SERIALIZED)); - return PIPE_SHADER_IR_NIR_SERIALIZED; -} - -std::string -device::ir_target() const { - std::vector<char> target = get_compute_param<char>( - pipe, ir_format(), PIPE_COMPUTE_CAP_IR_TARGET); - return { target.data() }; -} - -enum pipe_endian -device::endianness() const { - return (enum pipe_endian)pipe->get_param(pipe, PIPE_CAP_ENDIANNESS); -} - -std::string -device::device_version() const { - static const std::string device_version = - debug_get_option("CLOVER_DEVICE_VERSION_OVERRIDE", "1.1"); - return device_version; -} - -std::string -device::device_clc_version() const { - static const std::string device_clc_version = - debug_get_option("CLOVER_DEVICE_CLC_VERSION_OVERRIDE", "1.1"); - return device_clc_version; -} - -bool -device::supports_ir(enum pipe_shader_ir ir) const { - return pipe->get_shader_param(pipe, PIPE_SHADER_COMPUTE, - PIPE_SHADER_CAP_SUPPORTED_IRS) & (1 << ir); -} - -std::string -device::supported_extensions() const { - return - "cl_khr_byte_addressable_store" - " cl_khr_global_int32_base_atomics" - " cl_khr_global_int32_extended_atomics" - " cl_khr_local_int32_base_atomics" - " cl_khr_local_int32_extended_atomics" - + std::string(has_int64_atomics() ? " cl_khr_int64_base_atomics" : "") - + std::string(has_int64_atomics() ? " cl_khr_int64_extended_atomics" : "") - + std::string(has_doubles() ? " cl_khr_fp64" : "") - + std::string(has_halves() ? " cl_khr_fp16" : "") - + std::string(svm_support() ? " cl_arm_shared_virtual_memory" : ""); -} - -const void * -device::get_compiler_options(enum pipe_shader_ir ir) const { - return pipe->get_compiler_options(pipe, ir, PIPE_SHADER_COMPUTE); -} diff --git a/src/gallium/state_trackers/clover/core/device.hpp b/src/gallium/state_trackers/clover/core/device.hpp deleted file mode 100644 index 597f9489b2c..00000000000 --- a/src/gallium/state_trackers/clover/core/device.hpp +++ /dev/null @@ -1,109 +0,0 @@ -// -// Copyright 2012 Francisco Jerez -// -// Permission is hereby granted, free of charge, to any person obtaining a -// copy of this software and associated documentation files (the "Software"), -// to deal in the Software without restriction, including without limitation -// the rights to use, copy, modify, merge, publish, distribute, sublicense, -// and/or sell copies of the Software, and to permit persons to whom the -// Software is furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL -// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR -// OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, -// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR -// OTHER DEALINGS IN THE SOFTWARE. -// - -#ifndef CLOVER_CORE_DEVICE_HPP -#define CLOVER_CORE_DEVICE_HPP - -#include <set> -#include <vector> - -#include "core/object.hpp" -#include "core/format.hpp" -#include "pipe-loader/pipe_loader.h" - -namespace clover { - class platform; - class root_resource; - class hard_event; - - class device : public ref_counter, public _cl_device_id { - public: - device(clover::platform &platform, pipe_loader_device *ldev); - ~device(); - - device(const device &dev) = delete; - device & - operator=(const device &dev) = delete; - - bool - operator==(const device &dev) const; - - cl_device_type type() const; - cl_uint vendor_id() const; - size_t max_images_read() const; - size_t max_images_write() const; - size_t max_image_buffer_size() const; - cl_uint max_image_levels_2d() const; - cl_uint max_image_levels_3d() const; - size_t max_image_array_number() const; - cl_uint max_samplers() const; - cl_ulong max_mem_global() const; - cl_ulong max_mem_local() const; - cl_ulong max_mem_input() const; - cl_ulong max_const_buffer_size() const; - cl_uint max_const_buffers() const; - size_t max_threads_per_block() const; - cl_ulong max_mem_alloc_size() const; - cl_uint max_clock_frequency() const; - cl_uint max_compute_units() const; - bool image_support() const; - bool has_doubles() const; - bool has_halves() const; - bool has_int64_atomics() const; - bool has_unified_memory() const; - cl_uint mem_base_addr_align() const; - cl_device_svm_capabilities svm_support() const; - - std::vector<size_t> max_block_size() const; - cl_uint subgroup_size() const; - cl_uint address_bits() const; - std::string device_name() const; - std::string vendor_name() const; - std::string device_version() const; - std::string device_clc_version() const; - enum pipe_shader_ir ir_format() const; - std::string ir_target() const; - enum pipe_endian endianness() const; - bool supports_ir(enum pipe_shader_ir ir) const; - std::string supported_extensions() const; - - friend class command_queue; - friend class root_resource; - friend class hard_event; - friend std::set<cl_image_format> - supported_formats(const context &, cl_mem_object_type); - const void *get_compiler_options(enum pipe_shader_ir ir) const; - - clover::platform &platform; - - inline bool - has_system_svm() const { - return svm_support() & CL_DEVICE_SVM_FINE_GRAIN_SYSTEM; - } - - private: - pipe_screen *pipe; - pipe_loader_device *ldev; - }; -} - -#endif diff --git a/src/gallium/state_trackers/clover/core/error.hpp b/src/gallium/state_trackers/clover/core/error.hpp deleted file mode 100644 index 0490c19a276..00000000000 --- a/src/gallium/state_trackers/clover/core/error.hpp +++ /dev/null @@ -1,202 +0,0 @@ -// -// Copyright 2013 Francisco Jerez -// -// Permission is hereby granted, free of charge, to any person obtaining a -// copy of this software and associated documentation files (the "Software"), -// to deal in the Software without restriction, including without limitation -// the rights to use, copy, modify, merge, publish, distribute, sublicense, -// and/or sell copies of the Software, and to permit persons to whom the -// Software is furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL -// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR -// OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, -// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR -// OTHER DEALINGS IN THE SOFTWARE. -// - -#ifndef CLOVER_CORE_ERROR_HPP -#define CLOVER_CORE_ERROR_HPP - -#include "CL/cl.h" - -#include <stdexcept> -#include <string> - -namespace clover { - class command_queue; - class context; - class device; - class event; - class hard_event; - class soft_event; - class kernel; - class memory_obj; - class buffer; - class root_buffer; - class sub_buffer; - class image; - class image2d; - class image3d; - class platform; - class program; - class sampler; - - /// - /// Class that represents an error that can be converted to an - /// OpenCL status code. - /// - class error : public std::runtime_error { - public: - error(cl_int code, std::string what = "") : - std::runtime_error(what), code(code) { - } - - cl_int get() const { - return code; - } - - protected: - cl_int code; - }; - - class invalid_build_options_error : public error { - public: - invalid_build_options_error(const std::string &what = "") : - error(CL_INVALID_BUILD_OPTIONS, what) {} - }; - - class build_error : public error { - public: - build_error(const std::string &what = "") : - error(CL_BUILD_PROGRAM_FAILURE, what) {} - }; - - template<typename O> - class invalid_object_error; - - template<> - class invalid_object_error<command_queue> : public error { - public: - invalid_object_error(std::string what = "") : - error(CL_INVALID_COMMAND_QUEUE, what) {} - }; - - template<> - class invalid_object_error<context> : public error { - public: - invalid_object_error(std::string what = "") : - error(CL_INVALID_CONTEXT, what) {} - }; - - template<> - class invalid_object_error<device> : public error { - public: - invalid_object_error(std::string what = "") : - error(CL_INVALID_DEVICE, what) {} - }; - - template<> - class invalid_object_error<event> : public error { - public: - invalid_object_error(std::string what = "") : - error(CL_INVALID_EVENT, what) {} - }; - - template<> - class invalid_object_error<soft_event> : public error { - public: - invalid_object_error(std::string what = "") : - error(CL_INVALID_EVENT, what) {} - }; - - template<> - class invalid_object_error<kernel> : public error { - public: - invalid_object_error(std::string what = "") : - error(CL_INVALID_KERNEL, what) {} - }; - - template<> - class invalid_object_error<memory_obj> : public error { - public: - invalid_object_error(std::string what = "") : - error(CL_INVALID_MEM_OBJECT, what) {} - }; - - template<> - class invalid_object_error<buffer> : public error { - public: - invalid_object_error(std::string what = "") : - error(CL_INVALID_MEM_OBJECT, what) {} - }; - - template<> - class invalid_object_error<root_buffer> : public error { - public: - invalid_object_error(std::string what = "") : - error(CL_INVALID_MEM_OBJECT, what) {} - }; - - template<> - class invalid_object_error<sub_buffer> : public error { - public: - invalid_object_error(std::string what = "") : - error(CL_INVALID_MEM_OBJECT, what) {} - }; - - template<> - class invalid_object_error<image> : public error { - public: - invalid_object_error(std::string what = "") : - error(CL_INVALID_MEM_OBJECT, what) {} - }; - - template<> - class invalid_object_error<image2d> : public error { - public: - invalid_object_error(std::string what = "") : - error(CL_INVALID_MEM_OBJECT, what) {} - }; - - template<> - class invalid_object_error<image3d> : public error { - public: - invalid_object_error(std::string what = "") : - error(CL_INVALID_MEM_OBJECT, what) {} - }; - - template<> - class invalid_object_error<platform> : public error { - public: - invalid_object_error(std::string what = "") : - error(CL_INVALID_PLATFORM, what) {} - }; - - template<> - class invalid_object_error<program> : public error { - public: - invalid_object_error(std::string what = "") : - error(CL_INVALID_PROGRAM, what) {} - }; - - template<> - class invalid_object_error<sampler> : public error { - public: - invalid_object_error(std::string what = "") : - error(CL_INVALID_SAMPLER, what) {} - }; - - class invalid_wait_list_error : public error { - public: - invalid_wait_list_error(std::string what = "") : - error(CL_INVALID_EVENT_WAIT_LIST, what) {} - }; -} - -#endif diff --git a/src/gallium/state_trackers/clover/core/event.cpp b/src/gallium/state_trackers/clover/core/event.cpp deleted file mode 100644 index 3d313ce8969..00000000000 --- a/src/gallium/state_trackers/clover/core/event.cpp +++ /dev/null @@ -1,267 +0,0 @@ -// -// Copyright 2012 Francisco Jerez -// -// Permission is hereby granted, free of charge, to any person obtaining a -// copy of this software and associated documentation files (the "Software"), -// to deal in the Software without restriction, including without limitation -// the rights to use, copy, modify, merge, publish, distribute, sublicense, -// and/or sell copies of the Software, and to permit persons to whom the -// Software is furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL -// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR -// OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, -// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR -// OTHER DEALINGS IN THE SOFTWARE. -// - -#include "core/event.hpp" -#include "pipe/p_screen.h" - -using namespace clover; - -event::event(clover::context &ctx, const ref_vector<event> &deps, - action action_ok, action action_fail) : - context(ctx), _wait_count(1), _status(0), - action_ok(action_ok), action_fail(action_fail) { - for (auto &ev : deps) - ev.chain(*this); -} - -event::~event() { -} - -std::vector<intrusive_ref<event>> -event::trigger_self() { - std::lock_guard<std::mutex> lock(mutex); - std::vector<intrusive_ref<event>> evs; - - if (_wait_count && !--_wait_count) - std::swap(_chain, evs); - - cv.notify_all(); - return evs; -} - -void -event::trigger() try { - if (wait_count() == 1) - action_ok(*this); - - for (event &ev : trigger_self()) - ev.trigger(); -} catch (error &e) { - abort(e.get()); -} - -std::vector<intrusive_ref<event>> -event::abort_self(cl_int status) { - std::lock_guard<std::mutex> lock(mutex); - std::vector<intrusive_ref<event>> evs; - - _status = status; - _wait_count = 0; - std::swap(_chain, evs); - - cv.notify_all(); - return evs; -} - -void -event::abort(cl_int status) { - action_fail(*this); - - for (event &ev : abort_self(status)) - ev.abort(status); -} - -unsigned -event::wait_count() const { - std::lock_guard<std::mutex> lock(mutex); - return _wait_count; -} - -bool -event::signalled() const { - return !wait_count(); -} - -cl_int -event::status() const { - std::lock_guard<std::mutex> lock(mutex); - return _status; -} - -void -event::chain(event &ev) { - std::unique_lock<std::mutex> lock(mutex, std::defer_lock); - std::unique_lock<std::mutex> lock_ev(ev.mutex, std::defer_lock); - std::lock(lock, lock_ev); - - if (_wait_count) { - ev._wait_count++; - _chain.push_back(ev); - } - ev.deps.push_back(*this); -} - -void -event::wait_signalled() const { - std::unique_lock<std::mutex> lock(mutex); - cv.wait(lock, [=]{ return !_wait_count; }); -} - -void -event::wait() const { - for (event &ev : deps) - ev.wait(); - - wait_signalled(); -} - -hard_event::hard_event(command_queue &q, cl_command_type command, - const ref_vector<event> &deps, action action) : - event(q.context(), deps, profile(q, action), [](event &ev){}), - _queue(q), _command(command), _fence(NULL) { - if (q.profiling_enabled()) - _time_queued = timestamp::current(q); - - q.sequence(*this); - trigger(); -} - -hard_event::~hard_event() { - pipe_screen *screen = queue()->device().pipe; - screen->fence_reference(screen, &_fence, NULL); -} - -cl_int -hard_event::status() const { - pipe_screen *screen = queue()->device().pipe; - - if (event::status() < 0) - return event::status(); - - else if (!_fence) - return CL_QUEUED; - - else if (!screen->fence_finish(screen, NULL, _fence, 0)) - return CL_SUBMITTED; - - else - return CL_COMPLETE; -} - -command_queue * -hard_event::queue() const { - return &_queue(); -} - -cl_command_type -hard_event::command() const { - return _command; -} - -void -hard_event::wait() const { - pipe_screen *screen = queue()->device().pipe; - - event::wait(); - - if (status() == CL_QUEUED) - queue()->flush(); - - if (!_fence || - !screen->fence_finish(screen, NULL, _fence, PIPE_TIMEOUT_INFINITE)) - throw error(CL_EXEC_STATUS_ERROR_FOR_EVENTS_IN_WAIT_LIST); -} - -const lazy<cl_ulong> & -hard_event::time_queued() const { - return _time_queued; -} - -const lazy<cl_ulong> & -hard_event::time_submit() const { - return _time_submit; -} - -const lazy<cl_ulong> & -hard_event::time_start() const { - return _time_start; -} - -const lazy<cl_ulong> & -hard_event::time_end() const { - return _time_end; -} - -void -hard_event::fence(pipe_fence_handle *fence) { - pipe_screen *screen = queue()->device().pipe; - screen->fence_reference(screen, &_fence, fence); -} - -event::action -hard_event::profile(command_queue &q, const action &action) const { - if (q.profiling_enabled()) { - return [&q, action] (event &ev) { - auto &hev = static_cast<hard_event &>(ev); - - hev._time_submit = timestamp::current(q); - hev._time_start = timestamp::query(q); - - action(ev); - - hev._time_end = timestamp::query(q); - }; - - } else { - return action; - } -} - -soft_event::soft_event(clover::context &ctx, const ref_vector<event> &deps, - bool _trigger, action action) : - event(ctx, deps, action, action) { - if (_trigger) - trigger(); -} - -cl_int -soft_event::status() const { - if (event::status() < 0) - return event::status(); - - else if (!signalled() || - any_of([](const event &ev) { - return ev.status() != CL_COMPLETE; - }, deps)) - return CL_SUBMITTED; - - else - return CL_COMPLETE; -} - -command_queue * -soft_event::queue() const { - return NULL; -} - -cl_command_type -soft_event::command() const { - return CL_COMMAND_USER; -} - -void -soft_event::wait() const { - event::wait(); - - if (status() != CL_COMPLETE) - throw error(CL_EXEC_STATUS_ERROR_FOR_EVENTS_IN_WAIT_LIST); -} diff --git a/src/gallium/state_trackers/clover/core/event.hpp b/src/gallium/state_trackers/clover/core/event.hpp deleted file mode 100644 index 03c97bcf4da..00000000000 --- a/src/gallium/state_trackers/clover/core/event.hpp +++ /dev/null @@ -1,164 +0,0 @@ -// -// Copyright 2012 Francisco Jerez -// -// Permission is hereby granted, free of charge, to any person obtaining a -// copy of this software and associated documentation files (the "Software"), -// to deal in the Software without restriction, including without limitation -// the rights to use, copy, modify, merge, publish, distribute, sublicense, -// and/or sell copies of the Software, and to permit persons to whom the -// Software is furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL -// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR -// OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, -// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR -// OTHER DEALINGS IN THE SOFTWARE. -// - -#ifndef CLOVER_CORE_EVENT_HPP -#define CLOVER_CORE_EVENT_HPP - -#include <condition_variable> -#include <functional> - -#include "core/object.hpp" -#include "core/queue.hpp" -#include "core/timestamp.hpp" -#include "util/lazy.hpp" - -namespace clover { - /// - /// Class that represents a task that might be executed - /// asynchronously at some point in the future. - /// - /// An event consists of a list of dependencies, a boolean - /// signalled() flag, and an associated task. An event is - /// considered signalled as soon as all its dependencies (if any) - /// are signalled as well, and the trigger() method is called; at - /// that point the associated task will be started through the - /// specified \a action_ok. If the abort() method is called - /// instead, the specified \a action_fail is executed and the - /// associated task will never be started. Dependent events will - /// be aborted recursively. - /// - /// The execution status of the associated task can be queried - /// using the status() method, and it can be waited for completion - /// using the wait() method. - /// - class event : public ref_counter, public _cl_event { - public: - typedef std::function<void (event &)> action; - - event(clover::context &ctx, const ref_vector<event> &deps, - action action_ok, action action_fail); - virtual ~event(); - - event(const event &ev) = delete; - event & - operator=(const event &ev) = delete; - - void trigger(); - void abort(cl_int status); - bool signalled() const; - - virtual cl_int status() const; - virtual command_queue *queue() const = 0; - virtual cl_command_type command() const = 0; - void wait_signalled() const; - virtual void wait() const; - - virtual struct pipe_fence_handle *fence() const { - return NULL; - } - - const intrusive_ref<clover::context> context; - - protected: - void chain(event &ev); - - std::vector<intrusive_ref<event>> deps; - - private: - std::vector<intrusive_ref<event>> trigger_self(); - std::vector<intrusive_ref<event>> abort_self(cl_int status); - unsigned wait_count() const; - - unsigned _wait_count; - cl_int _status; - action action_ok; - action action_fail; - std::vector<intrusive_ref<event>> _chain; - mutable std::condition_variable cv; - mutable std::mutex mutex; - }; - - /// - /// Class that represents a task executed by a command queue. - /// - /// Similar to a normal clover::event. In addition it's associated - /// with a given command queue \a q and a given OpenCL \a command. - /// hard_event instances created for the same queue are implicitly - /// ordered with respect to each other, and they are implicitly - /// triggered on construction. - /// - /// A hard_event is considered complete when the associated - /// hardware task finishes execution. - /// - class hard_event : public event { - public: - hard_event(command_queue &q, cl_command_type command, - const ref_vector<event> &deps, - action action = [](event &){}); - ~hard_event(); - - virtual cl_int status() const; - virtual command_queue *queue() const; - virtual cl_command_type command() const; - virtual void wait() const; - - const lazy<cl_ulong> &time_queued() const; - const lazy<cl_ulong> &time_submit() const; - const lazy<cl_ulong> &time_start() const; - const lazy<cl_ulong> &time_end() const; - - friend class command_queue; - - virtual struct pipe_fence_handle *fence() const { - return _fence; - } - - private: - virtual void fence(pipe_fence_handle *fence); - action profile(command_queue &q, const action &action) const; - - const intrusive_ref<command_queue> _queue; - cl_command_type _command; - pipe_fence_handle *_fence; - lazy<cl_ulong> _time_queued, _time_submit, _time_start, _time_end; - }; - - /// - /// Class that represents a software event. - /// - /// A soft_event is not associated with any specific hardware task - /// or command queue. It's considered complete as soon as all its - /// dependencies finish execution. - /// - class soft_event : public event { - public: - soft_event(clover::context &ctx, const ref_vector<event> &deps, - bool trigger, action action = [](event &){}); - - virtual cl_int status() const; - virtual command_queue *queue() const; - virtual cl_command_type command() const; - virtual void wait() const; - }; -} - -#endif diff --git a/src/gallium/state_trackers/clover/core/format.cpp b/src/gallium/state_trackers/clover/core/format.cpp deleted file mode 100644 index dee1872c829..00000000000 --- a/src/gallium/state_trackers/clover/core/format.cpp +++ /dev/null @@ -1,162 +0,0 @@ -// -// Copyright 2012 Francisco Jerez -// -// Permission is hereby granted, free of charge, to any person obtaining a -// copy of this software and associated documentation files (the "Software"), -// to deal in the Software without restriction, including without limitation -// the rights to use, copy, modify, merge, publish, distribute, sublicense, -// and/or sell copies of the Software, and to permit persons to whom the -// Software is furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL -// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR -// OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, -// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR -// OTHER DEALINGS IN THE SOFTWARE. -// - -#include "core/format.hpp" -#include "core/memory.hpp" -#include "pipe/p_screen.h" -#include "pipe/p_context.h" - -namespace clover { - static const std::map<cl_image_format, pipe_format> formats { - { { CL_BGRA, CL_UNORM_INT8 }, PIPE_FORMAT_B8G8R8A8_UNORM }, - { { CL_ARGB, CL_UNORM_INT8 }, PIPE_FORMAT_A8R8G8B8_UNORM }, - { { CL_RGB, CL_UNORM_SHORT_565 }, PIPE_FORMAT_B5G6R5_UNORM }, - { { CL_LUMINANCE, CL_UNORM_INT8 }, PIPE_FORMAT_L8_UNORM }, - { { CL_A, CL_UNORM_INT8 }, PIPE_FORMAT_A8_UNORM }, - { { CL_INTENSITY, CL_UNORM_INT8 }, PIPE_FORMAT_I8_UNORM }, - { { CL_LUMINANCE, CL_UNORM_INT16 }, PIPE_FORMAT_L16_UNORM }, - { { CL_R, CL_FLOAT }, PIPE_FORMAT_R32_FLOAT }, - { { CL_RG, CL_FLOAT }, PIPE_FORMAT_R32G32_FLOAT }, - { { CL_RGB, CL_FLOAT }, PIPE_FORMAT_R32G32B32_FLOAT }, - { { CL_RGBA, CL_FLOAT }, PIPE_FORMAT_R32G32B32A32_FLOAT }, - { { CL_R, CL_UNORM_INT16 }, PIPE_FORMAT_R16_UNORM }, - { { CL_RG, CL_UNORM_INT16 }, PIPE_FORMAT_R16G16_UNORM }, - { { CL_RGB, CL_UNORM_INT16 }, PIPE_FORMAT_R16G16B16_UNORM }, - { { CL_RGBA, CL_UNORM_INT16 }, PIPE_FORMAT_R16G16B16A16_UNORM }, - { { CL_R, CL_SNORM_INT16 }, PIPE_FORMAT_R16_SNORM }, - { { CL_RG, CL_SNORM_INT16 }, PIPE_FORMAT_R16G16_SNORM }, - { { CL_RGB, CL_SNORM_INT16 }, PIPE_FORMAT_R16G16B16_SNORM }, - { { CL_RGBA, CL_SNORM_INT16 }, PIPE_FORMAT_R16G16B16A16_SNORM }, - { { CL_R, CL_UNORM_INT8 }, PIPE_FORMAT_R8_UNORM }, - { { CL_RG, CL_UNORM_INT8 }, PIPE_FORMAT_R8G8_UNORM }, - { { CL_RGB, CL_UNORM_INT8 }, PIPE_FORMAT_R8G8B8_UNORM }, - { { CL_RGBA, CL_UNORM_INT8 }, PIPE_FORMAT_R8G8B8A8_UNORM }, - { { CL_R, CL_SNORM_INT8 }, PIPE_FORMAT_R8_SNORM }, - { { CL_RG, CL_SNORM_INT8 }, PIPE_FORMAT_R8G8_SNORM }, - { { CL_RGB, CL_SNORM_INT8 }, PIPE_FORMAT_R8G8B8_SNORM }, - { { CL_RGBA, CL_SNORM_INT8 }, PIPE_FORMAT_R8G8B8A8_SNORM }, - { { CL_R, CL_HALF_FLOAT }, PIPE_FORMAT_R16_FLOAT }, - { { CL_RG, CL_HALF_FLOAT }, PIPE_FORMAT_R16G16_FLOAT }, - { { CL_RGB, CL_HALF_FLOAT }, PIPE_FORMAT_R16G16B16_FLOAT }, - { { CL_RGBA, CL_HALF_FLOAT }, PIPE_FORMAT_R16G16B16A16_FLOAT }, - { { CL_RGBx, CL_UNORM_SHORT_555 }, PIPE_FORMAT_B5G5R5X1_UNORM }, - { { CL_RGBx, CL_UNORM_INT8 }, PIPE_FORMAT_R8G8B8X8_UNORM }, - { { CL_A, CL_UNORM_INT16 }, PIPE_FORMAT_A16_UNORM }, - { { CL_INTENSITY, CL_UNORM_INT16 }, PIPE_FORMAT_I16_UNORM }, - { { CL_LUMINANCE, CL_SNORM_INT8 }, PIPE_FORMAT_L8_SNORM }, - { { CL_INTENSITY, CL_SNORM_INT8 }, PIPE_FORMAT_I8_SNORM }, - { { CL_A, CL_SNORM_INT16 }, PIPE_FORMAT_A16_SNORM }, - { { CL_LUMINANCE, CL_SNORM_INT16 }, PIPE_FORMAT_L16_SNORM }, - { { CL_INTENSITY, CL_SNORM_INT16 }, PIPE_FORMAT_I16_SNORM }, - { { CL_A, CL_HALF_FLOAT }, PIPE_FORMAT_A16_FLOAT }, - { { CL_LUMINANCE, CL_HALF_FLOAT }, PIPE_FORMAT_L16_FLOAT }, - { { CL_INTENSITY, CL_HALF_FLOAT }, PIPE_FORMAT_I16_FLOAT }, - { { CL_A, CL_FLOAT }, PIPE_FORMAT_A32_FLOAT }, - { { CL_LUMINANCE, CL_FLOAT }, PIPE_FORMAT_L32_FLOAT }, - { { CL_INTENSITY, CL_FLOAT }, PIPE_FORMAT_I32_FLOAT }, - { { CL_RA, CL_UNORM_INT8 }, PIPE_FORMAT_R8A8_UNORM }, - { { CL_R, CL_UNSIGNED_INT8 }, PIPE_FORMAT_R8_UINT }, - { { CL_RG, CL_UNSIGNED_INT8 }, PIPE_FORMAT_R8G8_UINT }, - { { CL_RGB, CL_UNSIGNED_INT8 }, PIPE_FORMAT_R8G8B8_UINT }, - { { CL_RGBA, CL_UNSIGNED_INT8 }, PIPE_FORMAT_R8G8B8A8_UINT }, - { { CL_R, CL_SIGNED_INT8 }, PIPE_FORMAT_R8_SINT }, - { { CL_RG, CL_SIGNED_INT8 }, PIPE_FORMAT_R8G8_SINT }, - { { CL_RGB, CL_SIGNED_INT8 }, PIPE_FORMAT_R8G8B8_SINT }, - { { CL_RGBA, CL_SIGNED_INT8 }, PIPE_FORMAT_R8G8B8A8_SINT }, - { { CL_R, CL_UNSIGNED_INT16 }, PIPE_FORMAT_R16_UINT }, - { { CL_RG, CL_UNSIGNED_INT16 }, PIPE_FORMAT_R16G16_UINT }, - { { CL_RGB, CL_UNSIGNED_INT16 }, PIPE_FORMAT_R16G16B16_UINT }, - { { CL_RGBA, CL_UNSIGNED_INT16 }, PIPE_FORMAT_R16G16B16A16_UINT }, - { { CL_R, CL_SIGNED_INT16 }, PIPE_FORMAT_R16_SINT }, - { { CL_RG, CL_SIGNED_INT16 }, PIPE_FORMAT_R16G16_SINT }, - { { CL_RGB, CL_SIGNED_INT16 }, PIPE_FORMAT_R16G16B16_SINT }, - { { CL_RGBA, CL_SIGNED_INT16 }, PIPE_FORMAT_R16G16B16A16_SINT }, - { { CL_R, CL_UNSIGNED_INT32 }, PIPE_FORMAT_R32_UINT }, - { { CL_RG, CL_UNSIGNED_INT32 }, PIPE_FORMAT_R32G32_UINT }, - { { CL_RGB, CL_UNSIGNED_INT32 }, PIPE_FORMAT_R32G32B32_UINT }, - { { CL_RGBA, CL_UNSIGNED_INT32 }, PIPE_FORMAT_R32G32B32A32_UINT }, - { { CL_R, CL_SIGNED_INT32 }, PIPE_FORMAT_R32_SINT }, - { { CL_RG, CL_SIGNED_INT32 }, PIPE_FORMAT_R32G32_SINT }, - { { CL_RGB, CL_SIGNED_INT32 }, PIPE_FORMAT_R32G32B32_SINT }, - { { CL_RGBA, CL_SIGNED_INT32 }, PIPE_FORMAT_R32G32B32A32_SINT }, - { { CL_A, CL_UNSIGNED_INT8 }, PIPE_FORMAT_A8_UINT }, - { { CL_INTENSITY, CL_UNSIGNED_INT8 }, PIPE_FORMAT_I8_UINT }, - { { CL_LUMINANCE, CL_UNSIGNED_INT8 }, PIPE_FORMAT_L8_UINT }, - { { CL_A, CL_SIGNED_INT8 }, PIPE_FORMAT_A8_SINT }, - { { CL_INTENSITY, CL_SIGNED_INT8 }, PIPE_FORMAT_I8_SINT }, - { { CL_LUMINANCE, CL_SIGNED_INT8 }, PIPE_FORMAT_L8_SINT }, - { { CL_A, CL_UNSIGNED_INT16 }, PIPE_FORMAT_A16_UINT }, - { { CL_INTENSITY, CL_UNSIGNED_INT16 }, PIPE_FORMAT_I16_UINT }, - { { CL_LUMINANCE, CL_UNSIGNED_INT16 }, PIPE_FORMAT_L16_UINT }, - { { CL_A, CL_SIGNED_INT16 }, PIPE_FORMAT_A16_SINT }, - { { CL_INTENSITY, CL_SIGNED_INT16 }, PIPE_FORMAT_I16_SINT }, - { { CL_LUMINANCE, CL_SIGNED_INT16 }, PIPE_FORMAT_L16_SINT }, - { { CL_A, CL_UNSIGNED_INT32 }, PIPE_FORMAT_A32_UINT }, - { { CL_INTENSITY, CL_UNSIGNED_INT32 }, PIPE_FORMAT_I32_UINT }, - { { CL_LUMINANCE, CL_UNSIGNED_INT32 }, PIPE_FORMAT_L32_UINT }, - { { CL_A, CL_SIGNED_INT32 }, PIPE_FORMAT_A32_SINT }, - { { CL_INTENSITY, CL_SIGNED_INT32 }, PIPE_FORMAT_I32_SINT }, - { { CL_LUMINANCE, CL_SIGNED_INT32 }, PIPE_FORMAT_L32_SINT } - }; - - pipe_texture_target - translate_target(cl_mem_object_type type) { - switch (type) { - case CL_MEM_OBJECT_BUFFER: - return PIPE_BUFFER; - case CL_MEM_OBJECT_IMAGE2D: - return PIPE_TEXTURE_2D; - case CL_MEM_OBJECT_IMAGE3D: - return PIPE_TEXTURE_3D; - default: - throw error(CL_INVALID_VALUE); - } - } - - pipe_format - translate_format(const cl_image_format &format) { - auto it = formats.find(format); - - if (it == formats.end()) - throw error(CL_IMAGE_FORMAT_NOT_SUPPORTED); - - return it->second; - } - - std::set<cl_image_format> - supported_formats(const context &ctx, cl_mem_object_type type) { - std::set<cl_image_format> s; - pipe_texture_target target = translate_target(type); - unsigned bindings = (PIPE_BIND_SAMPLER_VIEW | - PIPE_BIND_COMPUTE_RESOURCE); - - for (auto f : formats) { - if (all_of([=](const device &dev) { - return dev.pipe->is_format_supported( - dev.pipe, f.second, target, 1, 1, bindings); - }, ctx.devices())) - s.insert(f.first); - } - - return s; - } -} diff --git a/src/gallium/state_trackers/clover/core/format.hpp b/src/gallium/state_trackers/clover/core/format.hpp deleted file mode 100644 index a8b7053c5dc..00000000000 --- a/src/gallium/state_trackers/clover/core/format.hpp +++ /dev/null @@ -1,62 +0,0 @@ -// -// Copyright 2012 Francisco Jerez -// -// Permission is hereby granted, free of charge, to any person obtaining a -// copy of this software and associated documentation files (the "Software"), -// to deal in the Software without restriction, including without limitation -// the rights to use, copy, modify, merge, publish, distribute, sublicense, -// and/or sell copies of the Software, and to permit persons to whom the -// Software is furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL -// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR -// OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, -// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR -// OTHER DEALINGS IN THE SOFTWARE. -// - -#ifndef CLOVER_CORE_FORMAT_HPP -#define CLOVER_CORE_FORMAT_HPP - -#include <set> - -#include "core/object.hpp" -#include "pipe/p_defines.h" -#include "pipe/p_format.h" - -namespace clover { - pipe_texture_target translate_target(cl_mem_object_type type); - pipe_format translate_format(const cl_image_format &format); - - /// - /// Return all the image formats supported by a given context for - /// the given memory object type. - /// - std::set<cl_image_format> supported_formats(const context &ctx, - cl_mem_object_type type); -} - -static inline bool -operator<(const cl_image_format &a, const cl_image_format &b) { - return (a.image_channel_order != b.image_channel_order ? - a.image_channel_order < b.image_channel_order : - a.image_channel_data_type < b.image_channel_data_type); -} - -static inline bool -operator==(const cl_image_format &a, const cl_image_format &b) { - return (a.image_channel_order == b.image_channel_order && - a.image_channel_data_type == b.image_channel_data_type); -} - -static inline bool -operator!=(const cl_image_format &a, const cl_image_format &b) { - return !(a == b); -} - -#endif diff --git a/src/gallium/state_trackers/clover/core/kernel.cpp b/src/gallium/state_trackers/clover/core/kernel.cpp deleted file mode 100644 index 7d839767aa0..00000000000 --- a/src/gallium/state_trackers/clover/core/kernel.cpp +++ /dev/null @@ -1,610 +0,0 @@ -// -// Copyright 2012 Francisco Jerez -// -// Permission is hereby granted, free of charge, to any person obtaining a -// copy of this software and associated documentation files (the "Software"), -// to deal in the Software without restriction, including without limitation -// the rights to use, copy, modify, merge, publish, distribute, sublicense, -// and/or sell copies of the Software, and to permit persons to whom the -// Software is furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL -// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR -// OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, -// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR -// OTHER DEALINGS IN THE SOFTWARE. -// - -#include "core/kernel.hpp" -#include "core/resource.hpp" -#include "util/factor.hpp" -#include "util/u_math.h" -#include "pipe/p_context.h" - -using namespace clover; - -kernel::kernel(clover::program &prog, const std::string &name, - const std::vector<module::argument> &margs) : - program(prog), _name(name), exec(*this), - program_ref(prog._kernel_ref_counter) { - for (auto &marg : margs) { - if (marg.semantic == module::argument::general) - _args.emplace_back(argument::create(marg)); - } -} - -template<typename V> -static inline std::vector<uint> -pad_vector(command_queue &q, const V &v, uint x) { - std::vector<uint> w { v.begin(), v.end() }; - w.resize(q.device().max_block_size().size(), x); - return w; -} - -void -kernel::launch(command_queue &q, - const std::vector<size_t> &grid_offset, - const std::vector<size_t> &grid_size, - const std::vector<size_t> &block_size) { - const auto m = program().build(q.device()).binary; - const auto reduced_grid_size = - map(divides(), grid_size, block_size); - void *st = exec.bind(&q, grid_offset); - struct pipe_grid_info info = {}; - - // The handles are created during exec_context::bind(), so we need make - // sure to call exec_context::bind() before retrieving them. - std::vector<uint32_t *> g_handles = map([&](size_t h) { - return (uint32_t *)&exec.input[h]; - }, exec.g_handles); - - q.pipe->bind_compute_state(q.pipe, st); - q.pipe->bind_sampler_states(q.pipe, PIPE_SHADER_COMPUTE, - 0, exec.samplers.size(), - exec.samplers.data()); - - q.pipe->set_sampler_views(q.pipe, PIPE_SHADER_COMPUTE, 0, - exec.sviews.size(), exec.sviews.data()); - q.pipe->set_compute_resources(q.pipe, 0, exec.resources.size(), - exec.resources.data()); - q.pipe->set_global_binding(q.pipe, 0, exec.g_buffers.size(), - exec.g_buffers.data(), g_handles.data()); - - // Fill information for the launch_grid() call. - info.work_dim = grid_size.size(); - copy(pad_vector(q, block_size, 1), info.block); - copy(pad_vector(q, reduced_grid_size, 1), info.grid); - info.pc = find(name_equals(_name), m.syms).offset; - info.input = exec.input.data(); - - q.pipe->launch_grid(q.pipe, &info); - - q.pipe->set_global_binding(q.pipe, 0, exec.g_buffers.size(), NULL, NULL); - q.pipe->set_compute_resources(q.pipe, 0, exec.resources.size(), NULL); - q.pipe->set_sampler_views(q.pipe, PIPE_SHADER_COMPUTE, 0, - exec.sviews.size(), NULL); - q.pipe->bind_sampler_states(q.pipe, PIPE_SHADER_COMPUTE, 0, - exec.samplers.size(), NULL); - - q.pipe->memory_barrier(q.pipe, PIPE_BARRIER_GLOBAL_BUFFER); - exec.unbind(); -} - -size_t -kernel::mem_local() const { - size_t sz = 0; - - for (auto &arg : args()) { - if (dynamic_cast<local_argument *>(&arg)) - sz += arg.storage(); - } - - return sz; -} - -size_t -kernel::mem_private() const { - return 0; -} - -const std::string & -kernel::name() const { - return _name; -} - -std::vector<size_t> -kernel::optimal_block_size(const command_queue &q, - const std::vector<size_t> &grid_size) const { - return factor::find_grid_optimal_factor<size_t>( - q.device().max_threads_per_block(), q.device().max_block_size(), - grid_size); -} - -std::vector<size_t> -kernel::required_block_size() const { - return { 0, 0, 0 }; -} - -kernel::argument_range -kernel::args() { - return map(derefs(), _args); -} - -kernel::const_argument_range -kernel::args() const { - return map(derefs(), _args); -} - -const module & -kernel::module(const command_queue &q) const { - return program().build(q.device()).binary; -} - -kernel::exec_context::exec_context(kernel &kern) : - kern(kern), q(NULL), mem_local(0), st(NULL), cs() { -} - -kernel::exec_context::~exec_context() { - if (st) - q->pipe->delete_compute_state(q->pipe, st); -} - -void * -kernel::exec_context::bind(intrusive_ptr<command_queue> _q, - const std::vector<size_t> &grid_offset) { - std::swap(q, _q); - - // Bind kernel arguments. - auto &m = kern.program().build(q->device()).binary; - auto msym = find(name_equals(kern.name()), m.syms); - auto margs = msym.args; - auto msec = find(id_equals(msym.section), m.secs); - auto explicit_arg = kern._args.begin(); - - for (auto &marg : margs) { - switch (marg.semantic) { - case module::argument::general: - (*(explicit_arg++))->bind(*this, marg); - break; - - case module::argument::grid_dimension: { - const cl_uint dimension = grid_offset.size(); - auto arg = argument::create(marg); - - arg->set(sizeof(dimension), &dimension); - arg->bind(*this, marg); - break; - } - case module::argument::grid_offset: { - for (cl_uint x : pad_vector(*q, grid_offset, 0)) { - auto arg = argument::create(marg); - - arg->set(sizeof(x), &x); - arg->bind(*this, marg); - } - break; - } - case module::argument::image_size: { - auto img = dynamic_cast<image_argument &>(**(explicit_arg - 1)).get(); - std::vector<cl_uint> image_size{ - static_cast<cl_uint>(img->width()), - static_cast<cl_uint>(img->height()), - static_cast<cl_uint>(img->depth())}; - for (auto x : image_size) { - auto arg = argument::create(marg); - - arg->set(sizeof(x), &x); - arg->bind(*this, marg); - } - break; - } - case module::argument::image_format: { - auto img = dynamic_cast<image_argument &>(**(explicit_arg - 1)).get(); - cl_image_format fmt = img->format(); - std::vector<cl_uint> image_format{ - static_cast<cl_uint>(fmt.image_channel_data_type), - static_cast<cl_uint>(fmt.image_channel_order)}; - for (auto x : image_format) { - auto arg = argument::create(marg); - - arg->set(sizeof(x), &x); - arg->bind(*this, marg); - } - break; - } - } - } - - // Create a new compute state if anything changed. - if (!st || q != _q || - cs.req_local_mem != mem_local || - cs.req_input_mem != input.size()) { - if (st) - _q->pipe->delete_compute_state(_q->pipe, st); - - cs.ir_type = q->device().ir_format(); - cs.prog = &(msec.data[0]); - cs.req_local_mem = mem_local; - cs.req_input_mem = input.size(); - st = q->pipe->create_compute_state(q->pipe, &cs); - if (!st) { - unbind(); // Cleanup - throw error(CL_OUT_OF_RESOURCES); - } - } - - return st; -} - -void -kernel::exec_context::unbind() { - for (auto &arg : kern.args()) - arg.unbind(*this); - - input.clear(); - samplers.clear(); - sviews.clear(); - resources.clear(); - g_buffers.clear(); - g_handles.clear(); - mem_local = 0; -} - -namespace { - template<typename T> - std::vector<uint8_t> - bytes(const T& x) { - return { (uint8_t *)&x, (uint8_t *)&x + sizeof(x) }; - } - - /// - /// Transform buffer \a v from the native byte order into the byte - /// order specified by \a e. - /// - template<typename T> - void - byteswap(T &v, pipe_endian e) { - if (PIPE_ENDIAN_NATIVE != e) - std::reverse(v.begin(), v.end()); - } - - /// - /// Pad buffer \a v to the next multiple of \a n. - /// - template<typename T> - void - align(T &v, size_t n) { - v.resize(util_align_npot(v.size(), n)); - } - - bool - msb(const std::vector<uint8_t> &s) { - if (PIPE_ENDIAN_NATIVE == PIPE_ENDIAN_LITTLE) - return s.back() & 0x80; - else - return s.front() & 0x80; - } - - /// - /// Resize buffer \a v to size \a n using sign or zero extension - /// according to \a ext. - /// - template<typename T> - void - extend(T &v, enum module::argument::ext_type ext, size_t n) { - const size_t m = std::min(v.size(), n); - const bool sign_ext = (ext == module::argument::sign_ext); - const uint8_t fill = (sign_ext && msb(v) ? ~0 : 0); - T w(n, fill); - - if (PIPE_ENDIAN_NATIVE == PIPE_ENDIAN_LITTLE) - std::copy_n(v.begin(), m, w.begin()); - else - std::copy_n(v.end() - m, m, w.end() - m); - - std::swap(v, w); - } - - /// - /// Append buffer \a w to \a v. - /// - template<typename T> - void - insert(T &v, const T &w) { - v.insert(v.end(), w.begin(), w.end()); - } - - /// - /// Append \a n elements to the end of buffer \a v. - /// - template<typename T> - size_t - allocate(T &v, size_t n) { - size_t pos = v.size(); - v.resize(pos + n); - return pos; - } -} - -std::unique_ptr<kernel::argument> -kernel::argument::create(const module::argument &marg) { - switch (marg.type) { - case module::argument::scalar: - return std::unique_ptr<kernel::argument>(new scalar_argument(marg.size)); - - case module::argument::global: - return std::unique_ptr<kernel::argument>(new global_argument); - - case module::argument::local: - return std::unique_ptr<kernel::argument>(new local_argument); - - case module::argument::constant: - return std::unique_ptr<kernel::argument>(new constant_argument); - - case module::argument::image2d_rd: - case module::argument::image3d_rd: - return std::unique_ptr<kernel::argument>(new image_rd_argument); - - case module::argument::image2d_wr: - case module::argument::image3d_wr: - return std::unique_ptr<kernel::argument>(new image_wr_argument); - - case module::argument::sampler: - return std::unique_ptr<kernel::argument>(new sampler_argument); - - } - throw error(CL_INVALID_KERNEL_DEFINITION); -} - -kernel::argument::argument() : _set(false) { -} - -bool -kernel::argument::set() const { - return _set; -} - -size_t -kernel::argument::storage() const { - return 0; -} - -kernel::scalar_argument::scalar_argument(size_t size) : size(size) { -} - -void -kernel::scalar_argument::set(size_t size, const void *value) { - if (!value) - throw error(CL_INVALID_ARG_VALUE); - - if (size != this->size) - throw error(CL_INVALID_ARG_SIZE); - - v = { (uint8_t *)value, (uint8_t *)value + size }; - _set = true; -} - -void -kernel::scalar_argument::bind(exec_context &ctx, - const module::argument &marg) { - auto w = v; - - extend(w, marg.ext_type, marg.target_size); - byteswap(w, ctx.q->device().endianness()); - align(ctx.input, marg.target_align); - insert(ctx.input, w); -} - -void -kernel::scalar_argument::unbind(exec_context &ctx) { -} - -void -kernel::global_argument::set(size_t size, const void *value) { - if (size != sizeof(cl_mem)) - throw error(CL_INVALID_ARG_SIZE); - - buf = pobj<buffer>(value ? *(cl_mem *)value : NULL); - svm = nullptr; - _set = true; -} - -void -kernel::global_argument::set_svm(const void *value) { - svm = value; - buf = nullptr; - _set = true; -} - -void -kernel::global_argument::bind(exec_context &ctx, - const module::argument &marg) { - align(ctx.input, marg.target_align); - - if (buf) { - const resource &r = buf->resource(*ctx.q); - ctx.g_handles.push_back(ctx.input.size()); - ctx.g_buffers.push_back(r.pipe); - - // How to handle multi-demensional offsets? - // We don't need to. Buffer offsets are always - // one-dimensional. - auto v = bytes(r.offset[0]); - extend(v, marg.ext_type, marg.target_size); - byteswap(v, ctx.q->device().endianness()); - insert(ctx.input, v); - } else if (svm) { - auto v = bytes(svm); - extend(v, marg.ext_type, marg.target_size); - byteswap(v, ctx.q->device().endianness()); - insert(ctx.input, v); - } else { - // Null pointer. - allocate(ctx.input, marg.target_size); - } -} - -void -kernel::global_argument::unbind(exec_context &ctx) { -} - -size_t -kernel::local_argument::storage() const { - return _storage; -} - -void -kernel::local_argument::set(size_t size, const void *value) { - if (value) - throw error(CL_INVALID_ARG_VALUE); - - if (!size) - throw error(CL_INVALID_ARG_SIZE); - - _storage = size; - _set = true; -} - -void -kernel::local_argument::bind(exec_context &ctx, - const module::argument &marg) { - auto v = bytes(ctx.mem_local); - - extend(v, module::argument::zero_ext, marg.target_size); - byteswap(v, ctx.q->device().endianness()); - align(ctx.input, marg.target_align); - insert(ctx.input, v); - - ctx.mem_local += _storage; -} - -void -kernel::local_argument::unbind(exec_context &ctx) { -} - -void -kernel::constant_argument::set(size_t size, const void *value) { - if (size != sizeof(cl_mem)) - throw error(CL_INVALID_ARG_SIZE); - - buf = pobj<buffer>(value ? *(cl_mem *)value : NULL); - _set = true; -} - -void -kernel::constant_argument::bind(exec_context &ctx, - const module::argument &marg) { - align(ctx.input, marg.target_align); - - if (buf) { - resource &r = buf->resource(*ctx.q); - auto v = bytes(ctx.resources.size() << 24 | r.offset[0]); - - extend(v, module::argument::zero_ext, marg.target_size); - byteswap(v, ctx.q->device().endianness()); - insert(ctx.input, v); - - st = r.bind_surface(*ctx.q, false); - ctx.resources.push_back(st); - } else { - // Null pointer. - allocate(ctx.input, marg.target_size); - } -} - -void -kernel::constant_argument::unbind(exec_context &ctx) { - if (buf) - buf->resource(*ctx.q).unbind_surface(*ctx.q, st); -} - -void -kernel::image_rd_argument::set(size_t size, const void *value) { - if (!value) - throw error(CL_INVALID_ARG_VALUE); - - if (size != sizeof(cl_mem)) - throw error(CL_INVALID_ARG_SIZE); - - img = &obj<image>(*(cl_mem *)value); - _set = true; -} - -void -kernel::image_rd_argument::bind(exec_context &ctx, - const module::argument &marg) { - auto v = bytes(ctx.sviews.size()); - - extend(v, module::argument::zero_ext, marg.target_size); - byteswap(v, ctx.q->device().endianness()); - align(ctx.input, marg.target_align); - insert(ctx.input, v); - - st = img->resource(*ctx.q).bind_sampler_view(*ctx.q); - ctx.sviews.push_back(st); -} - -void -kernel::image_rd_argument::unbind(exec_context &ctx) { - img->resource(*ctx.q).unbind_sampler_view(*ctx.q, st); -} - -void -kernel::image_wr_argument::set(size_t size, const void *value) { - if (!value) - throw error(CL_INVALID_ARG_VALUE); - - if (size != sizeof(cl_mem)) - throw error(CL_INVALID_ARG_SIZE); - - img = &obj<image>(*(cl_mem *)value); - _set = true; -} - -void -kernel::image_wr_argument::bind(exec_context &ctx, - const module::argument &marg) { - auto v = bytes(ctx.resources.size()); - - extend(v, module::argument::zero_ext, marg.target_size); - byteswap(v, ctx.q->device().endianness()); - align(ctx.input, marg.target_align); - insert(ctx.input, v); - - st = img->resource(*ctx.q).bind_surface(*ctx.q, true); - ctx.resources.push_back(st); -} - -void -kernel::image_wr_argument::unbind(exec_context &ctx) { - img->resource(*ctx.q).unbind_surface(*ctx.q, st); -} - -void -kernel::sampler_argument::set(size_t size, const void *value) { - if (!value) - throw error(CL_INVALID_SAMPLER); - - if (size != sizeof(cl_sampler)) - throw error(CL_INVALID_ARG_SIZE); - - s = &obj(*(cl_sampler *)value); - _set = true; -} - -void -kernel::sampler_argument::bind(exec_context &ctx, - const module::argument &marg) { - st = s->bind(*ctx.q); - ctx.samplers.push_back(st); -} - -void -kernel::sampler_argument::unbind(exec_context &ctx) { - s->unbind(*ctx.q, st); -} diff --git a/src/gallium/state_trackers/clover/core/kernel.hpp b/src/gallium/state_trackers/clover/core/kernel.hpp deleted file mode 100644 index 4441091f300..00000000000 --- a/src/gallium/state_trackers/clover/core/kernel.hpp +++ /dev/null @@ -1,251 +0,0 @@ -// -// Copyright 2012 Francisco Jerez -// -// Permission is hereby granted, free of charge, to any person obtaining a -// copy of this software and associated documentation files (the "Software"), -// to deal in the Software without restriction, including without limitation -// the rights to use, copy, modify, merge, publish, distribute, sublicense, -// and/or sell copies of the Software, and to permit persons to whom the -// Software is furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL -// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR -// OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, -// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR -// OTHER DEALINGS IN THE SOFTWARE. -// - -#ifndef CLOVER_CORE_KERNEL_HPP -#define CLOVER_CORE_KERNEL_HPP - -#include <memory> - -#include "core/object.hpp" -#include "core/program.hpp" -#include "core/memory.hpp" -#include "core/sampler.hpp" -#include "pipe/p_state.h" - -namespace clover { - class kernel : public ref_counter, public _cl_kernel { - private: - /// - /// Class containing all the state required to execute a compute - /// kernel. - /// - struct exec_context { - exec_context(kernel &kern); - ~exec_context(); - - exec_context(const exec_context &) = delete; - exec_context & - operator=(const exec_context &) = delete; - - void *bind(intrusive_ptr<command_queue> _q, - const std::vector<size_t> &grid_offset); - void unbind(); - - kernel &kern; - intrusive_ptr<command_queue> q; - - std::vector<uint8_t> input; - std::vector<void *> samplers; - std::vector<pipe_sampler_view *> sviews; - std::vector<pipe_surface *> resources; - std::vector<pipe_resource *> g_buffers; - std::vector<size_t> g_handles; - size_t mem_local; - - private: - void *st; - pipe_compute_state cs; - }; - - public: - class argument { - public: - static std::unique_ptr<argument> - create(const module::argument &marg); - - argument(const argument &arg) = delete; - argument & - operator=(const argument &arg) = delete; - - /// \a true if the argument has been set. - bool set() const; - - /// Storage space required for the referenced object. - virtual size_t storage() const; - - /// Set this argument to some object. - virtual void set(size_t size, const void *value) = 0; - - /// Set this argument to an SVM pointer. - virtual void set_svm(const void *value) { - throw error(CL_INVALID_ARG_INDEX); - }; - - /// Allocate the necessary resources to bind the specified - /// object to this argument, and update \a ctx accordingly. - virtual void bind(exec_context &ctx, - const module::argument &marg) = 0; - - /// Free any resources that were allocated in bind(). - virtual void unbind(exec_context &ctx) = 0; - - virtual ~argument() {}; - protected: - argument(); - - bool _set; - }; - - private: - typedef adaptor_range< - derefs, std::vector<std::unique_ptr<argument>> & - > argument_range; - - typedef adaptor_range< - derefs, const std::vector<std::unique_ptr<argument>> & - > const_argument_range; - - public: - kernel(clover::program &prog, const std::string &name, - const std::vector<clover::module::argument> &margs); - - kernel(const kernel &kern) = delete; - kernel & - operator=(const kernel &kern) = delete; - - void launch(command_queue &q, - const std::vector<size_t> &grid_offset, - const std::vector<size_t> &grid_size, - const std::vector<size_t> &block_size); - - size_t mem_local() const; - size_t mem_private() const; - - const std::string &name() const; - - std::vector<size_t> - optimal_block_size(const command_queue &q, - const std::vector<size_t> &grid_size) const; - std::vector<size_t> - required_block_size() const; - - argument_range args(); - const_argument_range args() const; - - const intrusive_ref<clover::program> program; - - private: - const clover::module &module(const command_queue &q) const; - - class scalar_argument : public argument { - public: - scalar_argument(size_t size); - - virtual void set(size_t size, const void *value); - virtual void bind(exec_context &ctx, - const module::argument &marg); - virtual void unbind(exec_context &ctx); - - private: - size_t size; - std::vector<uint8_t> v; - }; - - class global_argument : public argument { - public: - virtual void set(size_t size, const void *value); - virtual void set_svm(const void *value); - virtual void bind(exec_context &ctx, - const module::argument &marg); - virtual void unbind(exec_context &ctx); - - private: - buffer *buf; - const void *svm; - }; - - class local_argument : public argument { - public: - virtual size_t storage() const; - - virtual void set(size_t size, const void *value); - virtual void bind(exec_context &ctx, - const module::argument &marg); - virtual void unbind(exec_context &ctx); - - private: - size_t _storage = 0; - }; - - class constant_argument : public argument { - public: - virtual void set(size_t size, const void *value); - virtual void bind(exec_context &ctx, - const module::argument &marg); - virtual void unbind(exec_context &ctx); - - private: - buffer *buf; - pipe_surface *st; - }; - - class image_argument : public argument { - public: - const image *get() const { - return img; - } - protected: - image *img; - }; - - class image_rd_argument : public image_argument { - public: - virtual void set(size_t size, const void *value); - virtual void bind(exec_context &ctx, - const module::argument &marg); - virtual void unbind(exec_context &ctx); - - private: - pipe_sampler_view *st; - }; - - class image_wr_argument : public image_argument { - public: - virtual void set(size_t size, const void *value); - virtual void bind(exec_context &ctx, - const module::argument &marg); - virtual void unbind(exec_context &ctx); - - private: - pipe_surface *st; - }; - - class sampler_argument : public argument { - public: - virtual void set(size_t size, const void *value); - virtual void bind(exec_context &ctx, - const module::argument &marg); - virtual void unbind(exec_context &ctx); - - private: - sampler *s; - void *st; - }; - - std::vector<std::unique_ptr<argument>> _args; - std::string _name; - exec_context exec; - const ref_holder program_ref; - }; -} - -#endif diff --git a/src/gallium/state_trackers/clover/core/memory.cpp b/src/gallium/state_trackers/clover/core/memory.cpp deleted file mode 100644 index ed13d92c281..00000000000 --- a/src/gallium/state_trackers/clover/core/memory.cpp +++ /dev/null @@ -1,214 +0,0 @@ -// -// Copyright 2012 Francisco Jerez -// -// Permission is hereby granted, free of charge, to any person obtaining a -// copy of this software and associated documentation files (the "Software"), -// to deal in the Software without restriction, including without limitation -// the rights to use, copy, modify, merge, publish, distribute, sublicense, -// and/or sell copies of the Software, and to permit persons to whom the -// Software is furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL -// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR -// OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, -// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR -// OTHER DEALINGS IN THE SOFTWARE. -// - -#include "core/memory.hpp" -#include "core/resource.hpp" -#include "util/format/u_format.h" - -using namespace clover; - -memory_obj::memory_obj(clover::context &ctx, cl_mem_flags flags, - size_t size, void *host_ptr) : - context(ctx), _flags(flags), - _size(size), _host_ptr(host_ptr) { - if (flags & CL_MEM_COPY_HOST_PTR) - data.append((char *)host_ptr, size); -} - -memory_obj::~memory_obj() { - while (_destroy_notify.size()) { - _destroy_notify.top()(); - _destroy_notify.pop(); - } -} - -bool -memory_obj::operator==(const memory_obj &obj) const { - return this == &obj; -} - -void -memory_obj::destroy_notify(std::function<void ()> f) { - _destroy_notify.push(f); -} - -cl_mem_flags -memory_obj::flags() const { - return _flags; -} - -size_t -memory_obj::size() const { - return _size; -} - -void * -memory_obj::host_ptr() const { - return _host_ptr; -} - -buffer::buffer(clover::context &ctx, cl_mem_flags flags, - size_t size, void *host_ptr) : - memory_obj(ctx, flags, size, host_ptr) { -} - -cl_mem_object_type -buffer::type() const { - return CL_MEM_OBJECT_BUFFER; -} - -root_buffer::root_buffer(clover::context &ctx, cl_mem_flags flags, - size_t size, void *host_ptr) : - buffer(ctx, flags, size, host_ptr) { -} - -resource & -root_buffer::resource(command_queue &q) { - // Create a new resource if there's none for this device yet. - if (!resources.count(&q.device())) { - auto r = (!resources.empty() ? - new root_resource(q.device(), *this, - *resources.begin()->second) : - new root_resource(q.device(), *this, q, data)); - - resources.insert(std::make_pair(&q.device(), - std::unique_ptr<root_resource>(r))); - data.clear(); - } - - return *resources.find(&q.device())->second; -} - -sub_buffer::sub_buffer(root_buffer &parent, cl_mem_flags flags, - size_t offset, size_t size) : - buffer(parent.context(), flags, size, - (char *)parent.host_ptr() + offset), - parent(parent), _offset(offset) { -} - -resource & -sub_buffer::resource(command_queue &q) { - // Create a new resource if there's none for this device yet. - if (!resources.count(&q.device())) { - auto r = new sub_resource(parent().resource(q), {{ offset() }}); - - resources.insert(std::make_pair(&q.device(), - std::unique_ptr<sub_resource>(r))); - } - - return *resources.find(&q.device())->second; -} - -size_t -sub_buffer::offset() const { - return _offset; -} - -image::image(clover::context &ctx, cl_mem_flags flags, - const cl_image_format *format, - size_t width, size_t height, size_t depth, - size_t row_pitch, size_t slice_pitch, size_t size, - void *host_ptr) : - memory_obj(ctx, flags, size, host_ptr), - _format(*format), _width(width), _height(height), _depth(depth), - _row_pitch(row_pitch), _slice_pitch(slice_pitch) { -} - -resource & -image::resource(command_queue &q) { - // Create a new resource if there's none for this device yet. - if (!resources.count(&q.device())) { - auto r = (!resources.empty() ? - new root_resource(q.device(), *this, - *resources.begin()->second) : - new root_resource(q.device(), *this, q, data)); - - resources.insert(std::make_pair(&q.device(), - std::unique_ptr<root_resource>(r))); - data.clear(); - } - - return *resources.find(&q.device())->second; -} - -cl_image_format -image::format() const { - return _format; -} - -size_t -image::width() const { - return _width; -} - -size_t -image::height() const { - return _height; -} - -size_t -image::depth() const { - return _depth; -} - -size_t -image::pixel_size() const { - return util_format_get_blocksize(translate_format(_format)); -} - -size_t -image::row_pitch() const { - return _row_pitch; -} - -size_t -image::slice_pitch() const { - return _slice_pitch; -} - -image2d::image2d(clover::context &ctx, cl_mem_flags flags, - const cl_image_format *format, size_t width, - size_t height, size_t row_pitch, - void *host_ptr) : - image(ctx, flags, format, width, height, 1, - row_pitch, 0, height * row_pitch, host_ptr) { -} - -cl_mem_object_type -image2d::type() const { - return CL_MEM_OBJECT_IMAGE2D; -} - -image3d::image3d(clover::context &ctx, cl_mem_flags flags, - const cl_image_format *format, - size_t width, size_t height, size_t depth, - size_t row_pitch, size_t slice_pitch, - void *host_ptr) : - image(ctx, flags, format, width, height, depth, - row_pitch, slice_pitch, depth * slice_pitch, - host_ptr) { -} - -cl_mem_object_type -image3d::type() const { - return CL_MEM_OBJECT_IMAGE3D; -} diff --git a/src/gallium/state_trackers/clover/core/memory.hpp b/src/gallium/state_trackers/clover/core/memory.hpp deleted file mode 100644 index bd6da6be4d1..00000000000 --- a/src/gallium/state_trackers/clover/core/memory.hpp +++ /dev/null @@ -1,159 +0,0 @@ -// -// Copyright 2012 Francisco Jerez -// -// Permission is hereby granted, free of charge, to any person obtaining a -// copy of this software and associated documentation files (the "Software"), -// to deal in the Software without restriction, including without limitation -// the rights to use, copy, modify, merge, publish, distribute, sublicense, -// and/or sell copies of the Software, and to permit persons to whom the -// Software is furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL -// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR -// OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, -// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR -// OTHER DEALINGS IN THE SOFTWARE. -// - -#ifndef CLOVER_CORE_MEMORY_HPP -#define CLOVER_CORE_MEMORY_HPP - -#include <functional> -#include <map> -#include <memory> -#include <stack> - -#include "core/object.hpp" -#include "core/queue.hpp" -#include "core/resource.hpp" - -namespace clover { - class memory_obj : public ref_counter, public _cl_mem { - protected: - memory_obj(clover::context &ctx, cl_mem_flags flags, - size_t size, void *host_ptr); - - memory_obj(const memory_obj &obj) = delete; - memory_obj & - operator=(const memory_obj &obj) = delete; - - public: - virtual ~memory_obj(); - - bool - operator==(const memory_obj &obj) const; - - virtual cl_mem_object_type type() const = 0; - virtual clover::resource &resource(command_queue &q) = 0; - - void destroy_notify(std::function<void ()> f); - cl_mem_flags flags() const; - size_t size() const; - void *host_ptr() const; - - const intrusive_ref<clover::context> context; - - private: - cl_mem_flags _flags; - size_t _size; - void *_host_ptr; - std::stack<std::function<void ()>> _destroy_notify; - - protected: - std::string data; - }; - - class buffer : public memory_obj { - protected: - buffer(clover::context &ctx, cl_mem_flags flags, - size_t size, void *host_ptr); - - public: - virtual cl_mem_object_type type() const; - }; - - class root_buffer : public buffer { - public: - root_buffer(clover::context &ctx, cl_mem_flags flags, - size_t size, void *host_ptr); - - virtual clover::resource &resource(command_queue &q); - - private: - std::map<device *, - std::unique_ptr<root_resource>> resources; - }; - - class sub_buffer : public buffer { - public: - sub_buffer(root_buffer &parent, cl_mem_flags flags, - size_t offset, size_t size); - - virtual clover::resource &resource(command_queue &q); - size_t offset() const; - - const intrusive_ref<root_buffer> parent; - - private: - size_t _offset; - std::map<device *, - std::unique_ptr<sub_resource>> resources; - }; - - class image : public memory_obj { - protected: - image(clover::context &ctx, cl_mem_flags flags, - const cl_image_format *format, - size_t width, size_t height, size_t depth, - size_t row_pitch, size_t slice_pitch, size_t size, - void *host_ptr); - - public: - virtual clover::resource &resource(command_queue &q); - cl_image_format format() const; - size_t width() const; - size_t height() const; - size_t depth() const; - size_t pixel_size() const; - size_t row_pitch() const; - size_t slice_pitch() const; - - private: - cl_image_format _format; - size_t _width; - size_t _height; - size_t _depth; - size_t _row_pitch; - size_t _slice_pitch; - std::map<device *, - std::unique_ptr<root_resource>> resources; - }; - - class image2d : public image { - public: - image2d(clover::context &ctx, cl_mem_flags flags, - const cl_image_format *format, size_t width, - size_t height, size_t row_pitch, - void *host_ptr); - - virtual cl_mem_object_type type() const; - }; - - class image3d : public image { - public: - image3d(clover::context &ctx, cl_mem_flags flags, - const cl_image_format *format, - size_t width, size_t height, size_t depth, - size_t row_pitch, size_t slice_pitch, - void *host_ptr); - - virtual cl_mem_object_type type() const; - }; -} - -#endif diff --git a/src/gallium/state_trackers/clover/core/module.cpp b/src/gallium/state_trackers/clover/core/module.cpp deleted file mode 100644 index a6c5b98d8e0..00000000000 --- a/src/gallium/state_trackers/clover/core/module.cpp +++ /dev/null @@ -1,228 +0,0 @@ -// -// Copyright 2012 Francisco Jerez -// -// Permission is hereby granted, free of charge, to any person obtaining a -// copy of this software and associated documentation files (the "Software"), -// to deal in the Software without restriction, including without limitation -// the rights to use, copy, modify, merge, publish, distribute, sublicense, -// and/or sell copies of the Software, and to permit persons to whom the -// Software is furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL -// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR -// OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, -// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR -// OTHER DEALINGS IN THE SOFTWARE. -// - -#include <type_traits> -#include <iostream> - -#include "core/module.hpp" - -using namespace clover; - -namespace { - template<typename T, typename = void> - struct _serializer; - - /// Serialize the specified object. - template<typename T> - void - _proc(std::ostream &os, const T &x) { - _serializer<T>::proc(os, x); - } - - /// Deserialize the specified object. - template<typename T> - void - _proc(std::istream &is, T &x) { - _serializer<T>::proc(is, x); - } - - template<typename T> - T - _proc(std::istream &is) { - T x; - _serializer<T>::proc(is, x); - return x; - } - - /// Calculate the size of the specified object. - template<typename T> - void - _proc(module::size_t &sz, const T &x) { - _serializer<T>::proc(sz, x); - } - - /// (De)serialize a scalar value. - template<typename T> - struct _serializer<T, typename std::enable_if< - std::is_scalar<T>::value>::type> { - static void - proc(std::ostream &os, const T &x) { - os.write(reinterpret_cast<const char *>(&x), sizeof(x)); - } - - static void - proc(std::istream &is, T &x) { - is.read(reinterpret_cast<char *>(&x), sizeof(x)); - } - - static void - proc(module::size_t &sz, const T &x) { - sz += sizeof(x); - } - }; - - /// (De)serialize a vector. - template<typename T> - struct _serializer<std::vector<T>, - typename std::enable_if< - !std::is_scalar<T>::value>::type> { - static void - proc(std::ostream &os, const std::vector<T> &v) { - _proc<uint32_t>(os, v.size()); - - for (size_t i = 0; i < v.size(); i++) - _proc<T>(os, v[i]); - } - - static void - proc(std::istream &is, std::vector<T> &v) { - v.resize(_proc<uint32_t>(is)); - - for (size_t i = 0; i < v.size(); i++) - new(&v[i]) T(_proc<T>(is)); - } - - static void - proc(module::size_t &sz, const std::vector<T> &v) { - sz += sizeof(uint32_t); - - for (size_t i = 0; i < v.size(); i++) - _proc<T>(sz, v[i]); - } - }; - - template<typename T> - struct _serializer<std::vector<T>, - typename std::enable_if< - std::is_scalar<T>::value>::type> { - static void - proc(std::ostream &os, const std::vector<T> &v) { - _proc<uint32_t>(os, v.size()); - os.write(reinterpret_cast<const char *>(&v[0]), - v.size() * sizeof(T)); - } - - static void - proc(std::istream &is, std::vector<T> &v) { - v.resize(_proc<uint32_t>(is)); - is.read(reinterpret_cast<char *>(&v[0]), - v.size() * sizeof(T)); - } - - static void - proc(module::size_t &sz, const std::vector<T> &v) { - sz += sizeof(uint32_t) + sizeof(T) * v.size(); - } - }; - - /// (De)serialize a string. - template<> - struct _serializer<std::string> { - static void - proc(std::ostream &os, const std::string &s) { - _proc<uint32_t>(os, s.size()); - os.write(&s[0], s.size() * sizeof(std::string::value_type)); - } - - static void - proc(std::istream &is, std::string &s) { - s.resize(_proc<uint32_t>(is)); - is.read(&s[0], s.size() * sizeof(std::string::value_type)); - } - - static void - proc(module::size_t &sz, const std::string &s) { - sz += sizeof(uint32_t) + sizeof(std::string::value_type) * s.size(); - } - }; - - /// (De)serialize a module::section. - template<> - struct _serializer<module::section> { - template<typename S, typename QT> - static void - proc(S &s, QT &x) { - _proc(s, x.id); - _proc(s, x.type); - _proc(s, x.size); - _proc(s, x.data); - } - }; - - /// (De)serialize a module::argument. - template<> - struct _serializer<module::argument> { - template<typename S, typename QT> - static void - proc(S &s, QT &x) { - _proc(s, x.type); - _proc(s, x.size); - _proc(s, x.target_size); - _proc(s, x.target_align); - _proc(s, x.ext_type); - _proc(s, x.semantic); - } - }; - - /// (De)serialize a module::symbol. - template<> - struct _serializer<module::symbol> { - template<typename S, typename QT> - static void - proc(S &s, QT &x) { - _proc(s, x.name); - _proc(s, x.section); - _proc(s, x.offset); - _proc(s, x.args); - } - }; - - /// (De)serialize a module. - template<> - struct _serializer<module> { - template<typename S, typename QT> - static void - proc(S &s, QT &x) { - _proc(s, x.syms); - _proc(s, x.secs); - } - }; -}; - -namespace clover { - void - module::serialize(std::ostream &os) const { - _proc(os, *this); - } - - module - module::deserialize(std::istream &is) { - return _proc<module>(is); - } - - module::size_t - module::size() const { - size_t sz = 0; - _proc(sz, *this); - return sz; - } -} diff --git a/src/gallium/state_trackers/clover/core/module.hpp b/src/gallium/state_trackers/clover/core/module.hpp deleted file mode 100644 index 2ddd26426fb..00000000000 --- a/src/gallium/state_trackers/clover/core/module.hpp +++ /dev/null @@ -1,128 +0,0 @@ -// -// Copyright 2012 Francisco Jerez -// -// Permission is hereby granted, free of charge, to any person obtaining a -// copy of this software and associated documentation files (the "Software"), -// to deal in the Software without restriction, including without limitation -// the rights to use, copy, modify, merge, publish, distribute, sublicense, -// and/or sell copies of the Software, and to permit persons to whom the -// Software is furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL -// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR -// OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, -// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR -// OTHER DEALINGS IN THE SOFTWARE. -// - -#ifndef CLOVER_CORE_MODULE_HPP -#define CLOVER_CORE_MODULE_HPP - -#include <vector> -#include <string> - -namespace clover { - struct module { - typedef uint32_t resource_id; - typedef uint32_t size_t; - - struct section { - enum type { - text_intermediate, - text_library, - text_executable, - data_constant, - data_global, - data_local, - data_private - }; - - section(resource_id id, enum type type, size_t size, - const std::vector<char> &data) : - id(id), type(type), size(size), data(data) { } - section() : id(0), type(text_intermediate), size(0), data() { } - - resource_id id; - type type; - size_t size; - std::vector<char> data; - }; - - struct argument { - enum type { - scalar, - constant, - global, - local, - image2d_rd, - image2d_wr, - image3d_rd, - image3d_wr, - sampler - }; - - enum ext_type { - zero_ext, - sign_ext - }; - - enum semantic { - general, - grid_dimension, - grid_offset, - image_size, - image_format - }; - - argument(enum type type, size_t size, - size_t target_size, size_t target_align, - enum ext_type ext_type, - enum semantic semantic = general) : - type(type), size(size), - target_size(target_size), target_align(target_align), - ext_type(ext_type), semantic(semantic) { } - - argument(enum type type, size_t size) : - type(type), size(size), - target_size(size), target_align(1), - ext_type(zero_ext), semantic(general) { } - - argument() : type(scalar), size(0), - target_size(0), target_align(1), - ext_type(zero_ext), semantic(general) { } - - type type; - size_t size; - size_t target_size; - size_t target_align; - ext_type ext_type; - semantic semantic; - }; - - struct symbol { - symbol(const std::string &name, resource_id section, - size_t offset, const std::vector<argument> &args) : - name(name), section(section), offset(offset), args(args) { } - symbol() : name(), section(0), offset(0), args() { } - - std::string name; - resource_id section; - size_t offset; - std::vector<argument> args; - }; - - void serialize(std::ostream &os) const; - static module deserialize(std::istream &is); - size_t size() const; - - std::vector<symbol> syms; - std::vector<section> secs; - }; -} - -#endif diff --git a/src/gallium/state_trackers/clover/core/object.hpp b/src/gallium/state_trackers/clover/core/object.hpp deleted file mode 100644 index 8fc2175d236..00000000000 --- a/src/gallium/state_trackers/clover/core/object.hpp +++ /dev/null @@ -1,239 +0,0 @@ -// -// Copyright 2013 Francisco Jerez -// -// Permission is hereby granted, free of charge, to any person obtaining a -// copy of this software and associated documentation files (the "Software"), -// to deal in the Software without restriction, including without limitation -// the rights to use, copy, modify, merge, publish, distribute, sublicense, -// and/or sell copies of the Software, and to permit persons to whom the -// Software is furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL -// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR -// OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, -// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR -// OTHER DEALINGS IN THE SOFTWARE. -// - -#ifndef CLOVER_CORE_OBJECT_HPP -#define CLOVER_CORE_OBJECT_HPP - -#include <cassert> -#include <functional> -#include <vector> - -#include "CL/cl.h" - -#include "core/error.hpp" -#include "core/property.hpp" -#include "api/dispatch.hpp" -#include "util/macros.h" - -/// -/// Main namespace of the CL state tracker. -/// -namespace clover { - /// - /// Class that represents a CL API object. - /// - template<typename T, typename S> - struct descriptor { - typedef T object_type; - typedef S descriptor_type; - - descriptor() : dispatch(&_dispatch) { - static_assert(std::is_standard_layout<descriptor_type>::value, - "ICD requires CL API objects to be standard layout."); - } - - const cl_icd_dispatch *dispatch; - }; - - struct default_tag; - struct allow_empty_tag; - struct wait_list_tag; - struct property_list_tag; - - namespace detail { - template<typename T, typename D> - struct descriptor_traits { - typedef T object_type; - - static void - validate(D *d) { - auto o = static_cast<typename D::object_type *>(d); - if (!o || o->dispatch != &_dispatch || - !dynamic_cast<object_type *>(o)) - throw invalid_object_error<T>(); - } - - static void - validate_list(D * const *ds, size_t n) { - if (!ds || !n) - throw error(CL_INVALID_VALUE); - } - }; - - template<typename D> - struct descriptor_traits<default_tag, D> { - typedef typename D::object_type object_type; - - static void - validate(D *d) { - if (!d || d->dispatch != &_dispatch) - throw invalid_object_error<object_type>(); - } - - static void - validate_list(D *const *ds, size_t n) { - if (!ds || !n) - throw error(CL_INVALID_VALUE); - } - }; - - template<typename D> - struct descriptor_traits<allow_empty_tag, D> { - typedef typename D::object_type object_type; - - static void - validate(D *d) { - if (!d || d->dispatch != &_dispatch) - throw invalid_object_error<object_type>(); - } - - static void - validate_list(D *const *ds, size_t n) { - if (bool(ds) != bool(n)) - throw error(CL_INVALID_VALUE); - } - }; - - template<typename D> - struct descriptor_traits<wait_list_tag, D> { - typedef typename D::object_type object_type; - - static void - validate(D *d) { - if (!d || d->dispatch != &_dispatch) - throw invalid_wait_list_error(); - } - - static void - validate_list(D *const *ds, size_t n) { - if (bool(ds) != bool(n)) - throw invalid_wait_list_error(); - } - }; - } - - /// - /// Get a Clover object from an API object performing object - /// validation. - /// - /// \a T can either be the Clover object type to return or a \a tag - /// object to select some special validation behavior by means of a - /// specialization of the detail::descriptor_traits template. The - /// default behavior is to infer the most general Clover object - /// type for the given API object. - /// - template<typename T = default_tag, typename D> - typename detail::descriptor_traits<T, D>::object_type & - obj(D *d) { - detail::descriptor_traits<T, D>::validate(d); - - return static_cast< - typename detail::descriptor_traits<T, D>::object_type &>(*d); - } - - /// - /// Get a pointer to a Clover object from an API object performing - /// object validation. Returns \c NULL if its argument is \c NULL. - /// - /// \sa obj - /// - template<typename T = default_tag, typename D> - typename detail::descriptor_traits<T, D>::object_type * - pobj(D *d) { - if (d) - detail::descriptor_traits<T, D>::validate(d); - - return static_cast< - typename detail::descriptor_traits<T, D>::object_type *>(d); - } - - /// - /// Get an API object from a Clover object. - /// - template<typename O> - typename O::descriptor_type * - desc(O &o) { - return static_cast<typename O::descriptor_type *>(&o); - } - - /// - /// Get an API object from a pointer to a Clover object. - /// - template<typename O> - typename O::descriptor_type * - desc(O *o) { - return static_cast<typename O::descriptor_type *>(o); - } - - /// - /// Get a range of Clover objects from a range of API objects - /// performing object validation. - /// - /// \sa obj - /// - template<typename T = default_tag, typename D> - ref_vector<typename detail::descriptor_traits<T, D>::object_type> - objs(D *const *ds, size_t n) { - detail::descriptor_traits<T, D>::validate_list(ds, n); - return map(obj<T, D>, range(ds, n)); - } - - /// - /// Get a range of API objects from a range of Clover objects. - /// - template<typename Os> - std::vector<typename Os::value_type::descriptor_type *> - descs(const Os &os) { - return map([](typename Os::value_type &o) { - return desc(o); - }, os); - } -} - -struct _cl_context : - public clover::descriptor<clover::context, _cl_context> {}; - -struct _cl_device_id : - public clover::descriptor<clover::device, _cl_device_id> {}; - -struct _cl_event : - public clover::descriptor<clover::event, _cl_event> {}; - -struct _cl_kernel : - public clover::descriptor<clover::kernel, _cl_kernel> {}; - -struct _cl_mem : - public clover::descriptor<clover::memory_obj, _cl_mem> {}; - -struct _cl_platform_id : - public clover::descriptor<clover::platform, _cl_platform_id> {}; - -struct _cl_program : - public clover::descriptor<clover::program, _cl_program> {}; - -struct _cl_command_queue : - public clover::descriptor<clover::command_queue, _cl_command_queue> {}; - -struct _cl_sampler : - public clover::descriptor<clover::sampler, _cl_sampler> {}; - -#endif diff --git a/src/gallium/state_trackers/clover/core/platform.cpp b/src/gallium/state_trackers/clover/core/platform.cpp deleted file mode 100644 index ddd63fc5a0d..00000000000 --- a/src/gallium/state_trackers/clover/core/platform.cpp +++ /dev/null @@ -1,46 +0,0 @@ -// -// Copyright 2012 Francisco Jerez -// -// Permission is hereby granted, free of charge, to any person obtaining a -// copy of this software and associated documentation files (the "Software"), -// to deal in the Software without restriction, including without limitation -// the rights to use, copy, modify, merge, publish, distribute, sublicense, -// and/or sell copies of the Software, and to permit persons to whom the -// Software is furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL -// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR -// OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, -// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR -// OTHER DEALINGS IN THE SOFTWARE. -// - -#include "core/platform.hpp" - -using namespace clover; - -platform::platform() : adaptor_range(evals(), devs) { - int n = pipe_loader_probe(NULL, 0); - std::vector<pipe_loader_device *> ldevs(n); - - pipe_loader_probe(&ldevs.front(), n); - - for (pipe_loader_device *ldev : ldevs) { - try { - if (ldev) - devs.push_back(create<device>(*this, ldev)); - } catch (error &) { - pipe_loader_release(&ldev, 1); - } - } -} - -std::string -platform::supported_extensions() const { - return "cl_khr_icd"; -} diff --git a/src/gallium/state_trackers/clover/core/platform.hpp b/src/gallium/state_trackers/clover/core/platform.hpp deleted file mode 100644 index b94434c983c..00000000000 --- a/src/gallium/state_trackers/clover/core/platform.hpp +++ /dev/null @@ -1,50 +0,0 @@ -// -// Copyright 2013 Francisco Jerez -// -// Permission is hereby granted, free of charge, to any person obtaining a -// copy of this software and associated documentation files (the "Software"), -// to deal in the Software without restriction, including without limitation -// the rights to use, copy, modify, merge, publish, distribute, sublicense, -// and/or sell copies of the Software, and to permit persons to whom the -// Software is furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL -// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR -// OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, -// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR -// OTHER DEALINGS IN THE SOFTWARE. -// - -#ifndef CLOVER_CORE_PLATFORM_HPP -#define CLOVER_CORE_PLATFORM_HPP - -#include <vector> - -#include "core/object.hpp" -#include "core/device.hpp" -#include "util/range.hpp" - -namespace clover { - class platform : public _cl_platform_id, - public adaptor_range< - evals, std::vector<intrusive_ref<device>> &> { - public: - platform(); - - platform(const platform &platform) = delete; - platform & - operator=(const platform &platform) = delete; - - std::string supported_extensions() const; - - protected: - std::vector<intrusive_ref<device>> devs; - }; -} - -#endif diff --git a/src/gallium/state_trackers/clover/core/program.cpp b/src/gallium/state_trackers/clover/core/program.cpp deleted file mode 100644 index 526e06a26c3..00000000000 --- a/src/gallium/state_trackers/clover/core/program.cpp +++ /dev/null @@ -1,135 +0,0 @@ -// -// Copyright 2012 Francisco Jerez -// -// Permission is hereby granted, free of charge, to any person obtaining a -// copy of this software and associated documentation files (the "Software"), -// to deal in the Software without restriction, including without limitation -// the rights to use, copy, modify, merge, publish, distribute, sublicense, -// and/or sell copies of the Software, and to permit persons to whom the -// Software is furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL -// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR -// OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, -// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR -// OTHER DEALINGS IN THE SOFTWARE. -// - -#include "core/compiler.hpp" -#include "core/program.hpp" - -using namespace clover; - -program::program(clover::context &ctx, const std::string &source) : - has_source(true), context(ctx), _devices(ctx.devices()), _source(source), - _kernel_ref_counter(0) { -} - -program::program(clover::context &ctx, - const ref_vector<device> &devs, - const std::vector<module> &binaries) : - has_source(false), context(ctx), - _devices(devs), _kernel_ref_counter(0) { - for_each([&](device &dev, const module &bin) { - _builds[&dev] = { bin }; - }, - devs, binaries); -} - -void -program::compile(const ref_vector<device> &devs, const std::string &opts, - const header_map &headers) { - if (has_source) { - _devices = devs; - - for (auto &dev : devs) { - std::string log; - - try { - const module m = - compiler::compile_program(_source, headers, dev, opts, log); - _builds[&dev] = { m, opts, log }; - } catch (...) { - _builds[&dev] = { module(), opts, log }; - throw; - } - } - } -} - -void -program::link(const ref_vector<device> &devs, const std::string &opts, - const ref_vector<program> &progs) { - _devices = devs; - - for (auto &dev : devs) { - const std::vector<module> ms = map([&](const program &prog) { - return prog.build(dev).binary; - }, progs); - std::string log = _builds[&dev].log; - - try { - const module m = compiler::link_program(ms, dev, opts, log); - _builds[&dev] = { m, opts, log }; - } catch (...) { - _builds[&dev] = { module(), opts, log }; - throw; - } - } -} - -const std::string & -program::source() const { - return _source; -} - -program::device_range -program::devices() const { - return map(evals(), _devices); -} - -cl_build_status -program::build::status() const { - if (!binary.secs.empty()) - return CL_BUILD_SUCCESS; - else if (log.size()) - return CL_BUILD_ERROR; - else - return CL_BUILD_NONE; -} - -cl_program_binary_type -program::build::binary_type() const { - if (any_of(type_equals(module::section::text_intermediate), binary.secs)) - return CL_PROGRAM_BINARY_TYPE_COMPILED_OBJECT; - else if (any_of(type_equals(module::section::text_library), binary.secs)) - return CL_PROGRAM_BINARY_TYPE_LIBRARY; - else if (any_of(type_equals(module::section::text_executable), binary.secs)) - return CL_PROGRAM_BINARY_TYPE_EXECUTABLE; - else - return CL_PROGRAM_BINARY_TYPE_NONE; -} - -const struct program::build & -program::build(const device &dev) const { - static const struct build null; - return _builds.count(&dev) ? _builds.find(&dev)->second : null; -} - -const std::vector<module::symbol> & -program::symbols() const { - if (_builds.empty()) - throw error(CL_INVALID_PROGRAM_EXECUTABLE); - - return _builds.begin()->second.binary.syms; -} - -unsigned -program::kernel_ref_count() const { - return _kernel_ref_counter.ref_count(); -} diff --git a/src/gallium/state_trackers/clover/core/program.hpp b/src/gallium/state_trackers/clover/core/program.hpp deleted file mode 100644 index 05964e78a79..00000000000 --- a/src/gallium/state_trackers/clover/core/program.hpp +++ /dev/null @@ -1,91 +0,0 @@ -// -// Copyright 2012 Francisco Jerez -// -// Permission is hereby granted, free of charge, to any person obtaining a -// copy of this software and associated documentation files (the "Software"), -// to deal in the Software without restriction, including without limitation -// the rights to use, copy, modify, merge, publish, distribute, sublicense, -// and/or sell copies of the Software, and to permit persons to whom the -// Software is furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL -// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR -// OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, -// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR -// OTHER DEALINGS IN THE SOFTWARE. -// - -#ifndef CLOVER_CORE_PROGRAM_HPP -#define CLOVER_CORE_PROGRAM_HPP - -#include <map> - -#include "core/object.hpp" -#include "core/context.hpp" -#include "core/module.hpp" - -namespace clover { - typedef std::vector<std::pair<std::string, std::string>> header_map; - - class program : public ref_counter, public _cl_program { - private: - typedef adaptor_range< - evals, const std::vector<intrusive_ref<device>> &> device_range; - - public: - program(clover::context &ctx, - const std::string &source); - program(clover::context &ctx, - const ref_vector<device> &devs = {}, - const std::vector<module> &binaries = {}); - - program(const program &prog) = delete; - program & - operator=(const program &prog) = delete; - - void compile(const ref_vector<device> &devs, const std::string &opts, - const header_map &headers = {}); - void link(const ref_vector<device> &devs, const std::string &opts, - const ref_vector<program> &progs); - - const bool has_source; - const std::string &source() const; - - device_range devices() const; - - struct build { - build(const module &m = {}, const std::string &opts = {}, - const std::string &log = {}) : binary(m), opts(opts), log(log) {} - - cl_build_status status() const; - cl_program_binary_type binary_type() const; - - module binary; - std::string opts; - std::string log; - }; - - const build &build(const device &dev) const; - - const std::vector<module::symbol> &symbols() const; - - unsigned kernel_ref_count() const; - - const intrusive_ref<clover::context> context; - - friend class kernel; - - private: - std::vector<intrusive_ref<device>> _devices; - std::map<const device *, struct build> _builds; - std::string _source; - ref_counter _kernel_ref_counter; - }; -} - -#endif diff --git a/src/gallium/state_trackers/clover/core/property.hpp b/src/gallium/state_trackers/clover/core/property.hpp deleted file mode 100644 index 7f8e17684d9..00000000000 --- a/src/gallium/state_trackers/clover/core/property.hpp +++ /dev/null @@ -1,261 +0,0 @@ -// -// Copyright 2013 Francisco Jerez -// -// Permission is hereby granted, free of charge, to any person obtaining a -// copy of this software and associated documentation files (the "Software"), -// to deal in the Software without restriction, including without limitation -// the rights to use, copy, modify, merge, publish, distribute, sublicense, -// and/or sell copies of the Software, and to permit persons to whom the -// Software is furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL -// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR -// OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, -// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR -// OTHER DEALINGS IN THE SOFTWARE. -// - -#ifndef CLOVER_CORE_PROPERTY_HPP -#define CLOVER_CORE_PROPERTY_HPP - -#include <map> - -#include "util/range.hpp" -#include "util/algorithm.hpp" - -namespace clover { - class property_buffer; - - namespace detail { - template<typename T> - class property_scalar { - public: - property_scalar(property_buffer &buf) : buf(buf) { - } - - inline property_scalar & - operator=(const T &x); - - private: - property_buffer &buf; - }; - - template<typename T> - class property_vector { - public: - property_vector(property_buffer &buf) : buf(buf) { - } - - template<typename S> - inline property_vector & - operator=(const S &v); - - private: - property_buffer &buf; - }; - - template<typename T> - class property_matrix { - public: - property_matrix(property_buffer &buf) : buf(buf) { - } - - template<typename S> - inline property_matrix & - operator=(const S &v); - - private: - property_buffer &buf; - }; - - class property_string { - public: - property_string(property_buffer &buf) : buf(buf) { - } - - inline property_string & - operator=(const std::string &v); - - private: - property_buffer &buf; - }; - }; - - /// - /// Return value buffer used by the CL property query functions. - /// - class property_buffer { - public: - property_buffer(void *r_buf, size_t size, size_t *r_size) : - r_buf(r_buf), size(size), r_size(r_size) { - } - - template<typename T> - detail::property_scalar<T> - as_scalar() { - return { *this }; - } - - template<typename T> - detail::property_vector<T> - as_vector() { - return { *this }; - } - - template<typename T> - detail::property_matrix<T> - as_matrix() { - return { *this }; - } - - detail::property_string - as_string() { - return { *this }; - } - - template<typename T> - iterator_range<T *> - allocate(size_t n) { - if (r_buf && size < n * sizeof(T)) - throw error(CL_INVALID_VALUE); - - if (r_size) - *r_size = n * sizeof(T); - - if (r_buf) - return range((T *)r_buf, n); - else - return { }; - } - - private: - void *const r_buf; - const size_t size; - size_t *const r_size; - }; - - namespace detail { - template<typename T> - inline property_scalar<T> & - property_scalar<T>::operator=(const T &x) { - auto r = buf.allocate<T>(1); - - if (!r.empty()) - r.front() = x; - - return *this; - } - - template<typename T> - template<typename S> - inline property_vector<T> & - property_vector<T>::operator=(const S &v) { - auto r = buf.allocate<T>(v.size()); - - if (!r.empty()) - copy(v, r.begin()); - - return *this; - } - - template<typename T> - template<typename S> - inline property_matrix<T> & - property_matrix<T>::operator=(const S &v) { - auto r = buf.allocate<T *>(v.size()); - - if (!r.empty()) - for_each([](typename S::value_type src, T *dst) { - if (dst) - copy(src, dst); - }, v, r); - - return *this; - } - - inline property_string & - property_string::operator=(const std::string &v) { - auto r = buf.allocate<char>(v.size() + 1); - - if (!r.empty()) - copy(range(v.begin(), r.size()), r.begin()); - - return *this; - } - }; - - template<typename T> - class property_element { - public: - property_element() : x() { - } - - property_element(T x) : x(x) { - } - - template<typename S> - S - as() const { - assert(sizeof(S) <= sizeof(T)); - return reinterpret_cast<S>(x); - } - - private: - T x; - }; - - template<typename D> - using property_list = std::map<D, property_element<D>>; - - struct property_list_tag; - - /// - /// Create a clover::property_list object from a zero-terminated - /// CL property list. - /// - template<typename T, typename D, - typename = typename std::enable_if< - std::is_same<T, property_list_tag>::value>::type> - property_list<D> - obj(const D *d_props) { - property_list<D> props; - - while (d_props && *d_props) { - auto key = *d_props++; - auto value = *d_props++; - - if (props.count(key)) - throw error(CL_INVALID_PROPERTY); - - props.insert({ key, value }); - } - - return props; - } - - /// - /// Create a zero-terminated CL property list from a - /// clover::property_list object. - /// - template<typename D> - std::vector<D> - desc(const property_list<D> &props) { - std::vector<D> d_props; - - for (auto &prop : props) { - d_props.push_back(prop.first); - d_props.push_back(prop.second.template as<D>()); - } - - d_props.push_back(0); - - return d_props; - } -} - -#endif diff --git a/src/gallium/state_trackers/clover/core/queue.cpp b/src/gallium/state_trackers/clover/core/queue.cpp deleted file mode 100644 index c91b97ad15e..00000000000 --- a/src/gallium/state_trackers/clover/core/queue.cpp +++ /dev/null @@ -1,102 +0,0 @@ -// -// Copyright 2012 Francisco Jerez -// -// Permission is hereby granted, free of charge, to any person obtaining a -// copy of this software and associated documentation files (the "Software"), -// to deal in the Software without restriction, including without limitation -// the rights to use, copy, modify, merge, publish, distribute, sublicense, -// and/or sell copies of the Software, and to permit persons to whom the -// Software is furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL -// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR -// OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, -// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR -// OTHER DEALINGS IN THE SOFTWARE. -// - -#include "core/queue.hpp" -#include "core/event.hpp" -#include "pipe/p_screen.h" -#include "pipe/p_context.h" -#include "pipe/p_state.h" - -using namespace clover; - -namespace { - void - debug_notify_callback(void *data, - unsigned *id, - enum pipe_debug_type type, - const char *fmt, - va_list args) { - const command_queue *queue = (const command_queue *)data; - char buffer[1024]; - vsnprintf(buffer, sizeof(buffer), fmt, args); - queue->context().notify(buffer); - } -} - -command_queue::command_queue(clover::context &ctx, clover::device &dev, - cl_command_queue_properties props) : - context(ctx), device(dev), props(props) { - pipe = dev.pipe->context_create(dev.pipe, NULL, PIPE_CONTEXT_COMPUTE_ONLY); - if (!pipe) - throw error(CL_INVALID_DEVICE); - - if (ctx.notify) { - struct pipe_debug_callback cb; - memset(&cb, 0, sizeof(cb)); - cb.debug_message = &debug_notify_callback; - cb.data = this; - if (pipe->set_debug_callback) - pipe->set_debug_callback(pipe, &cb); - } -} - -command_queue::~command_queue() { - pipe->destroy(pipe); -} - -void -command_queue::flush() { - pipe_screen *screen = device().pipe; - pipe_fence_handle *fence = NULL; - - std::lock_guard<std::mutex> lock(queued_events_mutex); - if (!queued_events.empty()) { - pipe->flush(pipe, &fence, 0); - - while (!queued_events.empty() && - queued_events.front()().signalled()) { - queued_events.front()().fence(fence); - queued_events.pop_front(); - } - - screen->fence_reference(screen, &fence, NULL); - } -} - -cl_command_queue_properties -command_queue::properties() const { - return props; -} - -bool -command_queue::profiling_enabled() const { - return props & CL_QUEUE_PROFILING_ENABLE; -} - -void -command_queue::sequence(hard_event &ev) { - std::lock_guard<std::mutex> lock(queued_events_mutex); - if (!queued_events.empty()) - queued_events.back()().chain(ev); - - queued_events.push_back(ev); -} diff --git a/src/gallium/state_trackers/clover/core/queue.hpp b/src/gallium/state_trackers/clover/core/queue.hpp deleted file mode 100644 index bddb86c0e4c..00000000000 --- a/src/gallium/state_trackers/clover/core/queue.hpp +++ /dev/null @@ -1,78 +0,0 @@ -// -// Copyright 2012 Francisco Jerez -// -// Permission is hereby granted, free of charge, to any person obtaining a -// copy of this software and associated documentation files (the "Software"), -// to deal in the Software without restriction, including without limitation -// the rights to use, copy, modify, merge, publish, distribute, sublicense, -// and/or sell copies of the Software, and to permit persons to whom the -// Software is furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL -// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR -// OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, -// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR -// OTHER DEALINGS IN THE SOFTWARE. -// - -#ifndef CLOVER_CORE_QUEUE_HPP -#define CLOVER_CORE_QUEUE_HPP - -#include <deque> -#include <mutex> - -#include "core/object.hpp" -#include "core/context.hpp" -#include "core/timestamp.hpp" -#include "pipe/p_context.h" - -namespace clover { - class resource; - class mapping; - class hard_event; - - class command_queue : public ref_counter, public _cl_command_queue { - public: - command_queue(clover::context &ctx, clover::device &dev, - cl_command_queue_properties props); - ~command_queue(); - - command_queue(const command_queue &q) = delete; - command_queue & - operator=(const command_queue &q) = delete; - - void flush(); - - cl_command_queue_properties properties() const; - bool profiling_enabled() const; - - const intrusive_ref<clover::context> context; - const intrusive_ref<clover::device> device; - - friend class resource; - friend class root_resource; - friend class mapping; - friend class hard_event; - friend class sampler; - friend class kernel; - friend class clover::timestamp::query; - friend class clover::timestamp::current; - - private: - /// Serialize a hardware event with respect to the previous ones, - /// and push it to the pending list. - void sequence(hard_event &ev); - - cl_command_queue_properties props; - pipe_context *pipe; - std::mutex queued_events_mutex; - std::deque<intrusive_ref<hard_event>> queued_events; - }; -} - -#endif diff --git a/src/gallium/state_trackers/clover/core/resource.cpp b/src/gallium/state_trackers/clover/core/resource.cpp deleted file mode 100644 index dd207982588..00000000000 --- a/src/gallium/state_trackers/clover/core/resource.cpp +++ /dev/null @@ -1,231 +0,0 @@ -// -// Copyright 2012 Francisco Jerez -// -// Permission is hereby granted, free of charge, to any person obtaining a -// copy of this software and associated documentation files (the "Software"), -// to deal in the Software without restriction, including without limitation -// the rights to use, copy, modify, merge, publish, distribute, sublicense, -// and/or sell copies of the Software, and to permit persons to whom the -// Software is furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL -// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR -// OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, -// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR -// OTHER DEALINGS IN THE SOFTWARE. -// - -#include "core/resource.hpp" -#include "core/memory.hpp" -#include "pipe/p_screen.h" -#include "util/u_sampler.h" -#include "util/format/u_format.h" -#include "util/u_inlines.h" - -using namespace clover; - -namespace { - class box { - public: - box(const resource::vector &origin, const resource::vector &size) : - pipe({ (int)origin[0], (int16_t)origin[1], - (int16_t)origin[2], (int)size[0], - (int16_t)size[1], (int16_t)size[2] }) { - } - - operator const pipe_box *() { - return &pipe; - } - - protected: - pipe_box pipe; - }; -} - -resource::resource(clover::device &dev, memory_obj &obj) : - device(dev), obj(obj), pipe(NULL), offset() { -} - -resource::~resource() { -} - -void -resource::copy(command_queue &q, const vector &origin, const vector ®ion, - resource &src_res, const vector &src_origin) { - auto p = offset + origin; - - q.pipe->resource_copy_region(q.pipe, pipe, 0, p[0], p[1], p[2], - src_res.pipe, 0, - box(src_res.offset + src_origin, region)); -} - -void * -resource::add_map(command_queue &q, cl_map_flags flags, bool blocking, - const vector &origin, const vector ®ion) { - maps.emplace_back(q, *this, flags, blocking, origin, region); - return maps.back(); -} - -void -resource::del_map(void *p) { - erase_if([&](const mapping &m) { - return static_cast<void *>(m) == p; - }, maps); -} - -unsigned -resource::map_count() const { - return maps.size(); -} - -pipe_sampler_view * -resource::bind_sampler_view(command_queue &q) { - pipe_sampler_view info; - - u_sampler_view_default_template(&info, pipe, pipe->format); - return q.pipe->create_sampler_view(q.pipe, pipe, &info); -} - -void -resource::unbind_sampler_view(command_queue &q, - pipe_sampler_view *st) { - q.pipe->sampler_view_destroy(q.pipe, st); -} - -pipe_surface * -resource::bind_surface(command_queue &q, bool rw) { - pipe_surface info {}; - - info.format = pipe->format; - info.writable = rw; - - if (pipe->target == PIPE_BUFFER) - info.u.buf.last_element = pipe->width0 - 1; - - return q.pipe->create_surface(q.pipe, pipe, &info); -} - -void -resource::unbind_surface(command_queue &q, pipe_surface *st) { - q.pipe->surface_destroy(q.pipe, st); -} - -root_resource::root_resource(clover::device &dev, memory_obj &obj, - command_queue &q, const std::string &data) : - resource(dev, obj) { - pipe_resource info {}; - const bool user_ptr_support = dev.pipe->get_param(dev.pipe, - PIPE_CAP_RESOURCE_FROM_USER_MEMORY); - - if (image *img = dynamic_cast<image *>(&obj)) { - info.format = translate_format(img->format()); - info.width0 = img->width(); - info.height0 = img->height(); - info.depth0 = img->depth(); - } else { - info.width0 = obj.size(); - info.height0 = 1; - info.depth0 = 1; - } - - info.array_size = 1; - info.target = translate_target(obj.type()); - info.bind = (PIPE_BIND_SAMPLER_VIEW | - PIPE_BIND_COMPUTE_RESOURCE | - PIPE_BIND_GLOBAL); - - if (obj.flags() & CL_MEM_USE_HOST_PTR && user_ptr_support) { - // Page alignment is normally required for this, just try, hope for the - // best and fall back if it fails. - pipe = dev.pipe->resource_from_user_memory(dev.pipe, &info, obj.host_ptr()); - if (pipe) - return; - } - - if (obj.flags() & (CL_MEM_ALLOC_HOST_PTR | CL_MEM_USE_HOST_PTR)) { - info.usage = PIPE_USAGE_STAGING; - } - - pipe = dev.pipe->resource_create(dev.pipe, &info); - if (!pipe) - throw error(CL_OUT_OF_RESOURCES); - - if (obj.flags() & (CL_MEM_USE_HOST_PTR | CL_MEM_COPY_HOST_PTR)) { - const void *data_ptr = !data.empty() ? data.data() : obj.host_ptr(); - box rect { {{ 0, 0, 0 }}, {{ info.width0, info.height0, info.depth0 }} }; - unsigned cpp = util_format_get_blocksize(info.format); - - if (pipe->target == PIPE_BUFFER) - q.pipe->buffer_subdata(q.pipe, pipe, PIPE_TRANSFER_WRITE, - 0, info.width0, data_ptr); - else - q.pipe->texture_subdata(q.pipe, pipe, 0, PIPE_TRANSFER_WRITE, - rect, data_ptr, cpp * info.width0, - cpp * info.width0 * info.height0); - } -} - -root_resource::root_resource(clover::device &dev, memory_obj &obj, - root_resource &r) : - resource(dev, obj) { - assert(0); // XXX -- resource shared among dev and r.dev -} - -root_resource::~root_resource() { - pipe_resource_reference(&this->pipe, NULL); -} - -sub_resource::sub_resource(resource &r, const vector &offset) : - resource(r.device(), r.obj) { - this->pipe = r.pipe; - this->offset = r.offset + offset; -} - -mapping::mapping(command_queue &q, resource &r, - cl_map_flags flags, bool blocking, - const resource::vector &origin, - const resource::vector ®ion) : - pctx(q.pipe), pres(NULL) { - unsigned usage = ((flags & CL_MAP_WRITE ? PIPE_TRANSFER_WRITE : 0 ) | - (flags & CL_MAP_READ ? PIPE_TRANSFER_READ : 0 ) | - (flags & CL_MAP_WRITE_INVALIDATE_REGION ? - PIPE_TRANSFER_DISCARD_RANGE : 0) | - (!blocking ? PIPE_TRANSFER_UNSYNCHRONIZED : 0)); - - p = pctx->transfer_map(pctx, r.pipe, 0, usage, - box(origin + r.offset, region), &pxfer); - if (!p) { - pxfer = NULL; - throw error(CL_OUT_OF_RESOURCES); - } - pipe_resource_reference(&pres, r.pipe); -} - -mapping::mapping(mapping &&m) : - pctx(m.pctx), pxfer(m.pxfer), pres(m.pres), p(m.p) { - m.pctx = NULL; - m.pxfer = NULL; - m.pres = NULL; - m.p = NULL; -} - -mapping::~mapping() { - if (pxfer) { - pctx->transfer_unmap(pctx, pxfer); - } - pipe_resource_reference(&pres, NULL); -} - -mapping & -mapping::operator=(mapping m) { - std::swap(pctx, m.pctx); - std::swap(pxfer, m.pxfer); - std::swap(pres, m.pres); - std::swap(p, m.p); - return *this; -} diff --git a/src/gallium/state_trackers/clover/core/resource.hpp b/src/gallium/state_trackers/clover/core/resource.hpp deleted file mode 100644 index 3b994b4008b..00000000000 --- a/src/gallium/state_trackers/clover/core/resource.hpp +++ /dev/null @@ -1,133 +0,0 @@ -// -// Copyright 2012 Francisco Jerez -// -// Permission is hereby granted, free of charge, to any person obtaining a -// copy of this software and associated documentation files (the "Software"), -// to deal in the Software without restriction, including without limitation -// the rights to use, copy, modify, merge, publish, distribute, sublicense, -// and/or sell copies of the Software, and to permit persons to whom the -// Software is furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL -// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR -// OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, -// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR -// OTHER DEALINGS IN THE SOFTWARE. -// - -#ifndef CLOVER_CORE_RESOURCE_HPP -#define CLOVER_CORE_RESOURCE_HPP - -#include <list> - -#include "core/queue.hpp" -#include "util/algebra.hpp" -#include "pipe/p_state.h" - -namespace clover { - class memory_obj; - class mapping; - - /// - /// Class that represents a device-specific instance of some memory - /// object. - /// - class resource { - public: - typedef std::array<size_t, 3> vector; - - virtual ~resource(); - - resource(const resource &r) = delete; - resource & - operator=(const resource &r) = delete; - - void copy(command_queue &q, const vector &origin, const vector ®ion, - resource &src_resource, const vector &src_origin); - - void *add_map(command_queue &q, cl_map_flags flags, bool blocking, - const vector &origin, const vector ®ion); - void del_map(void *p); - unsigned map_count() const; - - const intrusive_ref<clover::device> device; - memory_obj &obj; - - friend class sub_resource; - friend class mapping; - friend class kernel; - - protected: - resource(clover::device &dev, memory_obj &obj); - - pipe_sampler_view *bind_sampler_view(command_queue &q); - void unbind_sampler_view(command_queue &q, - pipe_sampler_view *st); - - pipe_surface *bind_surface(command_queue &q, bool rw); - void unbind_surface(command_queue &q, pipe_surface *st); - - pipe_resource *pipe; - vector offset; - - private: - std::list<mapping> maps; - }; - - /// - /// Resource associated with its own top-level data storage - /// allocated in some device. - /// - class root_resource : public resource { - public: - root_resource(clover::device &dev, memory_obj &obj, - command_queue &q, const std::string &data); - root_resource(clover::device &dev, memory_obj &obj, root_resource &r); - virtual ~root_resource(); - }; - - /// - /// Resource that reuses a portion of some other resource as data - /// storage. - /// - class sub_resource : public resource { - public: - sub_resource(resource &r, const vector &offset); - }; - - /// - /// Class that represents a mapping of some resource into the CPU - /// memory space. - /// - class mapping { - public: - mapping(command_queue &q, resource &r, cl_map_flags flags, - bool blocking, const resource::vector &origin, - const resource::vector ®ion); - mapping(mapping &&m); - ~mapping(); - - mapping & - operator=(mapping m); - - mapping(const mapping &m) = delete; - - template<typename T> - operator T *() const { - return (T *)p; - } - - private: - pipe_context *pctx; - pipe_transfer *pxfer; - pipe_resource *pres; - void *p; - }; -} - -#endif diff --git a/src/gallium/state_trackers/clover/core/sampler.cpp b/src/gallium/state_trackers/clover/core/sampler.cpp deleted file mode 100644 index 6f2784b538e..00000000000 --- a/src/gallium/state_trackers/clover/core/sampler.cpp +++ /dev/null @@ -1,73 +0,0 @@ -// -// Copyright 2012 Francisco Jerez -// -// Permission is hereby granted, free of charge, to any person obtaining a -// copy of this software and associated documentation files (the "Software"), -// to deal in the Software without restriction, including without limitation -// the rights to use, copy, modify, merge, publish, distribute, sublicense, -// and/or sell copies of the Software, and to permit persons to whom the -// Software is furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL -// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR -// OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, -// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR -// OTHER DEALINGS IN THE SOFTWARE. -// - -#include "core/sampler.hpp" -#include "pipe/p_state.h" - -using namespace clover; - -sampler::sampler(clover::context &ctx, bool norm_mode, - cl_addressing_mode addr_mode, - cl_filter_mode filter_mode) : - context(ctx), _norm_mode(norm_mode), - _addr_mode(addr_mode), _filter_mode(filter_mode) { -} - -bool -sampler::norm_mode() { - return _norm_mode; -} - -cl_addressing_mode -sampler::addr_mode() { - return _addr_mode; -} - -cl_filter_mode -sampler::filter_mode() { - return _filter_mode; -} - -void * -sampler::bind(command_queue &q) { - struct pipe_sampler_state info {}; - - info.normalized_coords = norm_mode(); - - info.wrap_s = info.wrap_t = info.wrap_r = - (addr_mode() == CL_ADDRESS_CLAMP_TO_EDGE ? PIPE_TEX_WRAP_CLAMP_TO_EDGE : - addr_mode() == CL_ADDRESS_CLAMP ? PIPE_TEX_WRAP_CLAMP_TO_BORDER : - addr_mode() == CL_ADDRESS_REPEAT ? PIPE_TEX_WRAP_REPEAT : - addr_mode() == CL_ADDRESS_MIRRORED_REPEAT ? PIPE_TEX_WRAP_MIRROR_REPEAT : - PIPE_TEX_WRAP_CLAMP_TO_EDGE); - - info.min_img_filter = info.mag_img_filter = - (filter_mode() == CL_FILTER_LINEAR ? PIPE_TEX_FILTER_LINEAR : - PIPE_TEX_FILTER_NEAREST); - - return q.pipe->create_sampler_state(q.pipe, &info); -} - -void -sampler::unbind(command_queue &q, void *st) { - q.pipe->delete_sampler_state(q.pipe, st); -} diff --git a/src/gallium/state_trackers/clover/core/sampler.hpp b/src/gallium/state_trackers/clover/core/sampler.hpp deleted file mode 100644 index 2632c3067fa..00000000000 --- a/src/gallium/state_trackers/clover/core/sampler.hpp +++ /dev/null @@ -1,58 +0,0 @@ -// -// Copyright 2012 Francisco Jerez -// -// Permission is hereby granted, free of charge, to any person obtaining a -// copy of this software and associated documentation files (the "Software"), -// to deal in the Software without restriction, including without limitation -// the rights to use, copy, modify, merge, publish, distribute, sublicense, -// and/or sell copies of the Software, and to permit persons to whom the -// Software is furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL -// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR -// OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, -// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR -// OTHER DEALINGS IN THE SOFTWARE. -// - -#ifndef CLOVER_CORE_SAMPLER_HPP -#define CLOVER_CORE_SAMPLER_HPP - -#include "core/object.hpp" -#include "core/queue.hpp" - -namespace clover { - class sampler : public ref_counter, public _cl_sampler { - public: - sampler(clover::context &ctx, bool norm_mode, - cl_addressing_mode addr_mode, - cl_filter_mode filter_mode); - - sampler(const sampler &s) = delete; - sampler & - operator=(const sampler &s) = delete; - - bool norm_mode(); - cl_addressing_mode addr_mode(); - cl_filter_mode filter_mode(); - - const intrusive_ref<clover::context> context; - - friend class kernel; - - private: - void *bind(command_queue &q); - void unbind(command_queue &q, void *st); - - bool _norm_mode; - cl_addressing_mode _addr_mode; - cl_filter_mode _filter_mode; - }; -} - -#endif diff --git a/src/gallium/state_trackers/clover/core/timestamp.cpp b/src/gallium/state_trackers/clover/core/timestamp.cpp deleted file mode 100644 index 3fd341f30da..00000000000 --- a/src/gallium/state_trackers/clover/core/timestamp.cpp +++ /dev/null @@ -1,64 +0,0 @@ -// -// Copyright 2013 Francisco Jerez -// -// Permission is hereby granted, free of charge, to any person obtaining a -// copy of this software and associated documentation files (the "Software"), -// to deal in the Software without restriction, including without limitation -// the rights to use, copy, modify, merge, publish, distribute, sublicense, -// and/or sell copies of the Software, and to permit persons to whom the -// Software is furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL -// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR -// OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, -// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR -// OTHER DEALINGS IN THE SOFTWARE. -// - -#include "core/timestamp.hpp" -#include "core/queue.hpp" -#include "pipe/p_screen.h" -#include "pipe/p_context.h" - -using namespace clover; - -timestamp::query::query(command_queue &q) : - q(q), - _query(q.pipe->create_query(q.pipe, PIPE_QUERY_TIMESTAMP, 0)) { - q.pipe->end_query(q.pipe, _query); -} - -timestamp::query::query(query &&other) : - q(other.q), - _query(other._query) { - other._query = NULL; -} - -timestamp::query::~query() { - if (_query) - q().pipe->destroy_query(q().pipe, _query); -} - -cl_ulong -timestamp::query::operator()() const { - pipe_query_result result; - - if (!q().pipe->get_query_result(q().pipe, _query, false, &result)) - throw error(CL_PROFILING_INFO_NOT_AVAILABLE); - - return result.u64; -} - -timestamp::current::current(command_queue &q) : - result(q.pipe->screen->get_timestamp(q.pipe->screen)) { -} - -cl_ulong -timestamp::current::operator()() const { - return result; -} diff --git a/src/gallium/state_trackers/clover/core/timestamp.hpp b/src/gallium/state_trackers/clover/core/timestamp.hpp deleted file mode 100644 index b4b2c83eb92..00000000000 --- a/src/gallium/state_trackers/clover/core/timestamp.hpp +++ /dev/null @@ -1,74 +0,0 @@ -// -// Copyright 2013 Francisco Jerez -// -// Permission is hereby granted, free of charge, to any person obtaining a -// copy of this software and associated documentation files (the "Software"), -// to deal in the Software without restriction, including without limitation -// the rights to use, copy, modify, merge, publish, distribute, sublicense, -// and/or sell copies of the Software, and to permit persons to whom the -// Software is furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL -// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR -// OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, -// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR -// OTHER DEALINGS IN THE SOFTWARE. -// - -#ifndef CLOVER_CORE_TIMESTAMP_HPP -#define CLOVER_CORE_TIMESTAMP_HPP - -#include "core/object.hpp" - -struct pipe_query; - -namespace clover { - class command_queue; - - namespace timestamp { - /// - /// Emit a timestamp query that is executed asynchronously by - /// the command queue \a q. - /// - class query { - public: - query(command_queue &q); - query(query &&other); - ~query(); - - query &operator=(const query &) = delete; - - /// - /// Retrieve the query results. - /// - cl_ulong operator()() const; - - private: - const intrusive_ref<command_queue> q; - pipe_query *_query; - }; - - /// - /// Get the current timestamp value. - /// - class current { - public: - current(command_queue &q); - - /// - /// Retrieve the query results. - /// - cl_ulong operator()() const; - - private: - cl_ulong result; - }; - } -} - -#endif diff --git a/src/gallium/state_trackers/clover/llvm/codegen.hpp b/src/gallium/state_trackers/clover/llvm/codegen.hpp deleted file mode 100644 index e35627c4729..00000000000 --- a/src/gallium/state_trackers/clover/llvm/codegen.hpp +++ /dev/null @@ -1,68 +0,0 @@ -// -// Copyright 2016 Francisco Jerez -// -// Permission is hereby granted, free of charge, to any person obtaining a -// copy of this software and associated documentation files (the "Software"), -// to deal in the Software without restriction, including without limitation -// the rights to use, copy, modify, merge, publish, distribute, sublicense, -// and/or sell copies of the Software, and to permit persons to whom the -// Software is furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL -// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR -// OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, -// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR -// OTHER DEALINGS IN THE SOFTWARE. -// - -/// -/// \file -/// Tools to generate various forms of binary code from existing LLVM IR in -/// the given llvm::Module object and output the result as a clover::module. -/// - -#ifndef CLOVER_LLVM_CODEGEN_HPP -#define CLOVER_LLVM_CODEGEN_HPP - -#include "llvm/util.hpp" -#include "core/module.hpp" - -#include <llvm/IR/Module.h> - -#include <clang/Frontend/CompilerInstance.h> - -namespace clover { - namespace llvm { - std::string - print_module_bitcode(const ::llvm::Module &mod); - - module - build_module_library(const ::llvm::Module &mod, - enum module::section::type section_type); - - std::unique_ptr< ::llvm::Module> - parse_module_library(const module &m, ::llvm::LLVMContext &ctx, - std::string &r_log); - - module - build_module_native(::llvm::Module &mod, const target &target, - const clang::CompilerInstance &c, - std::string &r_log); - - std::string - print_module_native(const ::llvm::Module &mod, const target &target); - - module - build_module_common(const ::llvm::Module &mod, - const std::vector<char> &code, - const std::map<std::string, unsigned> &offsets, - const clang::CompilerInstance &c); - } -} - -#endif diff --git a/src/gallium/state_trackers/clover/llvm/codegen/bitcode.cpp b/src/gallium/state_trackers/clover/llvm/codegen/bitcode.cpp deleted file mode 100644 index 7434e8cf6c9..00000000000 --- a/src/gallium/state_trackers/clover/llvm/codegen/bitcode.cpp +++ /dev/null @@ -1,91 +0,0 @@ -// -// Copyright 2012-2016 Francisco Jerez -// Copyright 2012-2016 Advanced Micro Devices, Inc. -// -// Permission is hereby granted, free of charge, to any person obtaining a -// copy of this software and associated documentation files (the "Software"), -// to deal in the Software without restriction, including without limitation -// the rights to use, copy, modify, merge, publish, distribute, sublicense, -// and/or sell copies of the Software, and to permit persons to whom the -// Software is furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL -// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR -// OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, -// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR -// OTHER DEALINGS IN THE SOFTWARE. -// - -/// -/// \file -/// Trivial codegen back-end that simply passes through the existing LLVM IR -/// and either formats it so it can be consumed by pipe drivers (if -/// build_module_bitcode() is used) or serializes so it can be deserialized at -/// a later point and passed to the actual codegen back-end (if -/// build_module_library() / parse_module_library() is used), potentially -/// after linking against other bitcode object files. -/// - -#include "llvm/codegen.hpp" -#include "llvm/compat.hpp" -#include "llvm/metadata.hpp" -#include "core/error.hpp" -#include "util/algorithm.hpp" - -#include <map> -#include <llvm/Config/llvm-config.h> -#if LLVM_VERSION_MAJOR < 4 -#include <llvm/Bitcode/ReaderWriter.h> -#else -#include <llvm/Bitcode/BitcodeReader.h> -#include <llvm/Bitcode/BitcodeWriter.h> -#endif -#include <llvm/Support/raw_ostream.h> - -using namespace clover; -using namespace clover::llvm; - -namespace { - std::vector<char> - emit_code(const ::llvm::Module &mod) { - ::llvm::SmallVector<char, 1024> data; - ::llvm::raw_svector_ostream os { data }; - compat::write_bitcode_to_file(mod, os); - return { os.str().begin(), os.str().end() }; - } -} - -std::string -clover::llvm::print_module_bitcode(const ::llvm::Module &mod) { - std::string s; - ::llvm::raw_string_ostream os { s }; - mod.print(os, NULL); - return os.str(); -} - -module -clover::llvm::build_module_library(const ::llvm::Module &mod, - enum module::section::type section_type) { - module m; - const auto code = emit_code(mod); - m.secs.emplace_back(0, section_type, code.size(), code); - return m; -} - -std::unique_ptr< ::llvm::Module> -clover::llvm::parse_module_library(const module &m, ::llvm::LLVMContext &ctx, - std::string &r_log) { - auto mod = ::llvm::parseBitcodeFile(::llvm::MemoryBufferRef( - as_string(m.secs[0].data), " "), ctx); - - compat::handle_module_error(mod, [&](const std::string &s) { - fail(r_log, error(CL_INVALID_PROGRAM), s); - }); - - return std::unique_ptr< ::llvm::Module>(std::move(*mod)); -} diff --git a/src/gallium/state_trackers/clover/llvm/codegen/common.cpp b/src/gallium/state_trackers/clover/llvm/codegen/common.cpp deleted file mode 100644 index 730ba5a2ff7..00000000000 --- a/src/gallium/state_trackers/clover/llvm/codegen/common.cpp +++ /dev/null @@ -1,209 +0,0 @@ -// -// Copyright 2012-2016 Francisco Jerez -// Copyright 2012-2016 Advanced Micro Devices, Inc. -// Copyright 2015 Zoltan Gilian -// -// Permission is hereby granted, free of charge, to any person obtaining a -// copy of this software and associated documentation files (the "Software"), -// to deal in the Software without restriction, including without limitation -// the rights to use, copy, modify, merge, publish, distribute, sublicense, -// and/or sell copies of the Software, and to permit persons to whom the -// Software is furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL -// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR -// OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, -// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR -// OTHER DEALINGS IN THE SOFTWARE. -// - -/// -/// \file -/// Codegen back-end-independent part of the construction of an executable -/// clover::module, including kernel argument metadata extraction and -/// formatting of the pre-generated binary code in a form that can be -/// understood by pipe drivers. -/// - -#include "llvm/codegen.hpp" -#include "llvm/metadata.hpp" - -#include "CL/cl.h" - -#include "pipe/p_state.h" -#include "util/u_math.h" - -#include <clang/Basic/TargetInfo.h> - -using namespace clover; -using namespace clover::llvm; - -using ::llvm::Module; -using ::llvm::Function; -using ::llvm::Type; -using ::llvm::isa; -using ::llvm::cast; -using ::llvm::dyn_cast; - -namespace { - enum module::argument::type - get_image_type(const std::string &type, - const std::string &qual) { - if (type == "image2d_t" && qual == "read_only") - return module::argument::image2d_rd; - else if (type == "image2d_t" && qual == "write_only") - return module::argument::image2d_wr; - else if (type == "image3d_t" && qual == "read_only") - return module::argument::image3d_rd; - else if (type == "image3d_t" && qual == "write_only") - return module::argument::image3d_wr; - else - unreachable("Unknown image type"); - } - - std::vector<module::argument> - make_kernel_args(const Module &mod, const std::string &kernel_name, - const clang::CompilerInstance &c) { - std::vector<module::argument> args; - const Function &f = *mod.getFunction(kernel_name); - ::llvm::DataLayout dl(&mod); - const auto size_type = - dl.getSmallestLegalIntType(mod.getContext(), sizeof(cl_uint) * 8); - - for (const auto &arg : f.args()) { - const auto arg_type = arg.getType(); - - // OpenCL 1.2 specification, Ch. 6.1.5: "A built-in data - // type that is not a power of two bytes in size must be - // aligned to the next larger power of two. - // This rule applies to built-in types only, not structs or unions." - const unsigned arg_store_size = dl.getTypeStoreSize(arg_type); - const unsigned arg_api_size = dl.getTypeAllocSize(arg_type); - - const auto target_type = compat::get_abi_type(arg_type, mod); - const unsigned target_size = dl.getTypeStoreSize(target_type); - const unsigned target_align = dl.getABITypeAlignment(target_type); - - const auto type_name = get_argument_metadata(f, arg, - "kernel_arg_type"); - - if (type_name == "image2d_t" || type_name == "image3d_t") { - // Image. - const auto access_qual = get_argument_metadata( - f, arg, "kernel_arg_access_qual"); - args.emplace_back(get_image_type(type_name, access_qual), - arg_store_size, target_size, - target_align, module::argument::zero_ext); - - } else if (type_name == "__llvm_image_size") { - // Image size implicit argument. - args.emplace_back(module::argument::scalar, sizeof(cl_uint), - dl.getTypeStoreSize(size_type), - dl.getABITypeAlignment(size_type), - module::argument::zero_ext, - module::argument::image_size); - - } else if (type_name == "__llvm_image_format") { - // Image format implicit argument. - args.emplace_back(module::argument::scalar, sizeof(cl_uint), - dl.getTypeStoreSize(size_type), - dl.getABITypeAlignment(size_type), - module::argument::zero_ext, - module::argument::image_format); - - } else { - // Other types. - const auto actual_type = - isa< ::llvm::PointerType>(arg_type) && arg.hasByValAttr() ? - cast< ::llvm::PointerType>(arg_type)->getElementType() : arg_type; - - if (actual_type->isPointerTy()) { - const unsigned address_space = - cast< ::llvm::PointerType>(actual_type)->getAddressSpace(); - - if (address_space == compat::target_address_space( - c.getTarget(), clang::LangAS::opencl_local)) { - args.emplace_back(module::argument::local, arg_api_size, - target_size, target_align, - module::argument::zero_ext); - } else { - // XXX: Correctly handle constant address space. There is no - // way for r600g to pass a handle for constant buffers back - // to clover like it can for global buffers, so - // creating constant arguments will break r600g. For now, - // continue treating constant buffers as global buffers - // until we can come up with a way to create handles for - // constant buffers. - args.emplace_back(module::argument::global, arg_api_size, - target_size, target_align, - module::argument::zero_ext); - } - - } else { - const bool needs_sign_ext = f.getAttributes().hasAttribute( - arg.getArgNo() + 1, ::llvm::Attribute::SExt); - - args.emplace_back(module::argument::scalar, arg_api_size, - target_size, target_align, - (needs_sign_ext ? module::argument::sign_ext : - module::argument::zero_ext)); - } - } - } - - // Append implicit arguments. XXX - The types, ordering and - // vector size of the implicit arguments should depend on the - // target according to the selected calling convention. - args.emplace_back(module::argument::scalar, sizeof(cl_uint), - dl.getTypeStoreSize(size_type), - dl.getABITypeAlignment(size_type), - module::argument::zero_ext, - module::argument::grid_dimension); - - args.emplace_back(module::argument::scalar, sizeof(cl_uint), - dl.getTypeStoreSize(size_type), - dl.getABITypeAlignment(size_type), - module::argument::zero_ext, - module::argument::grid_offset); - - return args; - } - - module::section - make_text_section(const std::vector<char> &code) { - const pipe_binary_program_header header { uint32_t(code.size()) }; - module::section text { 0, module::section::text_executable, - header.num_bytes, {} }; - - text.data.insert(text.data.end(), reinterpret_cast<const char *>(&header), - reinterpret_cast<const char *>(&header) + sizeof(header)); - text.data.insert(text.data.end(), code.begin(), code.end()); - - return text; - } -} - -module -clover::llvm::build_module_common(const Module &mod, - const std::vector<char> &code, - const std::map<std::string, - unsigned> &offsets, - const clang::CompilerInstance &c) { - module m; - - for (const auto &llvm_name : map(std::mem_fn(&Function::getName), - get_kernels(mod))) { - const ::std::string name(llvm_name); - if (offsets.count(name)) - m.syms.emplace_back(name, 0, offsets.at(name), - make_kernel_args(mod, name, c)); - } - - m.secs.push_back(make_text_section(code)); - return m; -} diff --git a/src/gallium/state_trackers/clover/llvm/codegen/native.cpp b/src/gallium/state_trackers/clover/llvm/codegen/native.cpp deleted file mode 100644 index 52346131200..00000000000 --- a/src/gallium/state_trackers/clover/llvm/codegen/native.cpp +++ /dev/null @@ -1,163 +0,0 @@ -// -// Copyright 2012-2016 Francisco Jerez -// Copyright 2012-2016 Advanced Micro Devices, Inc. -// -// Permission is hereby granted, free of charge, to any person obtaining a -// copy of this software and associated documentation files (the "Software"), -// to deal in the Software without restriction, including without limitation -// the rights to use, copy, modify, merge, publish, distribute, sublicense, -// and/or sell copies of the Software, and to permit persons to whom the -// Software is furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL -// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR -// OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, -// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR -// OTHER DEALINGS IN THE SOFTWARE. -// - -/// -/// \file -/// Generate code using an arbitrary LLVM back-end capable of emitting -/// executable code as an ELF object file. -/// - -#include "llvm/codegen.hpp" -#include "llvm/compat.hpp" -#include "llvm/util.hpp" -#include "core/error.hpp" - -#include <llvm/Target/TargetMachine.h> -#include <llvm/Support/TargetRegistry.h> -#include <llvm/Transforms/Utils/Cloning.h> - -#include <libelf.h> -#include <gelf.h> - -using namespace clover; -using namespace clover::llvm; -using ::llvm::TargetMachine; - -namespace { - namespace elf { - std::unique_ptr<Elf, int (*)(Elf *)> - get(const std::vector<char> &code) { - // One of the libelf implementations - // (http://www.mr511.de/software/english.htm) requires calling - // elf_version() before elf_memory(). - elf_version(EV_CURRENT); - return { elf_memory(const_cast<char *>(code.data()), code.size()), - elf_end }; - } - - Elf_Scn * - get_symbol_table(Elf *elf) { - size_t section_str_index; - elf_getshdrstrndx(elf, §ion_str_index); - - for (Elf_Scn *s = elf_nextscn(elf, NULL); s; s = elf_nextscn(elf, s)) { - GElf_Shdr header; - if (gelf_getshdr(s, &header) != &header) - return nullptr; - - if (!std::strcmp(elf_strptr(elf, section_str_index, header.sh_name), - ".symtab")) - return s; - } - - return nullptr; - } - - std::map<std::string, unsigned> - get_symbol_offsets(Elf *elf, Elf_Scn *symtab) { - Elf_Data *const symtab_data = elf_getdata(symtab, NULL); - GElf_Shdr header; - if (gelf_getshdr(symtab, &header) != &header) - return {}; - - std::map<std::string, unsigned> symbol_offsets; - GElf_Sym symbol; - unsigned i = 0; - - while (GElf_Sym *s = gelf_getsym(symtab_data, i++, &symbol)) { - const char *name = elf_strptr(elf, header.sh_link, s->st_name); - symbol_offsets[name] = s->st_value; - } - - return symbol_offsets; - } - } - - std::map<std::string, unsigned> - get_symbol_offsets(const std::vector<char> &code, std::string &r_log) { - const auto elf = elf::get(code); - const auto symtab = elf::get_symbol_table(elf.get()); - if (!symtab) - fail(r_log, build_error(), "Unable to find symbol table."); - - return elf::get_symbol_offsets(elf.get(), symtab); - } - - std::vector<char> - emit_code(::llvm::Module &mod, const target &target, - compat::CodeGenFileType ft, - std::string &r_log) { - std::string err; - auto t = ::llvm::TargetRegistry::lookupTarget(target.triple, err); - if (!t) - fail(r_log, build_error(), err); - - std::unique_ptr<TargetMachine> tm { - t->createTargetMachine(target.triple, target.cpu, "", {}, - ::llvm::None, compat::default_code_model, - ::llvm::CodeGenOpt::Default) }; - if (!tm) - fail(r_log, build_error(), - "Could not create TargetMachine: " + target.triple); - - ::llvm::SmallVector<char, 1024> data; - - { - ::llvm::legacy::PassManager pm; - ::llvm::raw_svector_ostream os { data }; - - mod.setDataLayout(tm->createDataLayout()); - tm->Options.MCOptions.AsmVerbose = - (ft == compat::CGFT_AssemblyFile); - - if (compat::add_passes_to_emit_file(*tm, pm, os, ft)) - fail(r_log, build_error(), "TargetMachine can't emit this file"); - - pm.run(mod); - } - - return { data.begin(), data.end() }; - } -} - -module -clover::llvm::build_module_native(::llvm::Module &mod, const target &target, - const clang::CompilerInstance &c, - std::string &r_log) { - const auto code = emit_code(mod, target, - compat::CGFT_ObjectFile, r_log); - return build_module_common(mod, code, get_symbol_offsets(code, r_log), c); -} - -std::string -clover::llvm::print_module_native(const ::llvm::Module &mod, - const target &target) { - std::string log; - try { - std::unique_ptr< ::llvm::Module> cmod { compat::clone_module(mod) }; - return as_string(emit_code(*cmod, target, - compat::CGFT_AssemblyFile, log)); - } catch (...) { - return "Couldn't output native disassembly: " + log; - } -} diff --git a/src/gallium/state_trackers/clover/llvm/compat.hpp b/src/gallium/state_trackers/clover/llvm/compat.hpp deleted file mode 100644 index 51902739acc..00000000000 --- a/src/gallium/state_trackers/clover/llvm/compat.hpp +++ /dev/null @@ -1,216 +0,0 @@ -// -// Copyright 2016 Francisco Jerez -// -// Permission is hereby granted, free of charge, to any person obtaining a -// copy of this software and associated documentation files (the "Software"), -// to deal in the Software without restriction, including without limitation -// the rights to use, copy, modify, merge, publish, distribute, sublicense, -// and/or sell copies of the Software, and to permit persons to whom the -// Software is furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL -// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR -// OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, -// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR -// OTHER DEALINGS IN THE SOFTWARE. -// - -/// -/// \file -/// Some thin wrappers around the Clang/LLVM API used to preserve -/// compatibility with older API versions while keeping the ifdef clutter low -/// in the rest of the clover::llvm subtree. In case of an API break please -/// consider whether it's possible to preserve backwards compatibility by -/// introducing a new one-liner inline function or typedef here under the -/// compat namespace in order to keep the running code free from preprocessor -/// conditionals. -/// - -#ifndef CLOVER_LLVM_COMPAT_HPP -#define CLOVER_LLVM_COMPAT_HPP - -#include "util/algorithm.hpp" - -#include <llvm/Config/llvm-config.h> -#if LLVM_VERSION_MAJOR < 4 -#include <llvm/Bitcode/ReaderWriter.h> -#else -#include <llvm/Bitcode/BitcodeReader.h> -#include <llvm/Bitcode/BitcodeWriter.h> -#endif - -#include <llvm/IR/LLVMContext.h> -#include <llvm/Linker/Linker.h> -#include <llvm/Transforms/IPO.h> -#include <llvm/Transforms/Utils/Cloning.h> -#include <llvm/Target/TargetMachine.h> -#if LLVM_VERSION_MAJOR >= 4 -#include <llvm/Support/Error.h> -#else -#include <llvm/Support/ErrorOr.h> -#endif - -#include <llvm/IR/LegacyPassManager.h> -#include <llvm/Analysis/TargetLibraryInfo.h> - -#include <clang/Basic/TargetInfo.h> -#include <clang/Frontend/CompilerInstance.h> - -#if LLVM_VERSION_MAJOR >= 8 -#include <clang/Basic/CodeGenOptions.h> -#else -#include <clang/Frontend/CodeGenOptions.h> -#endif - -#if LLVM_VERSION_MAJOR >= 10 -#include <llvm/Support/CodeGen.h> -#endif - -namespace clover { - namespace llvm { - namespace compat { - -#if LLVM_VERSION_MAJOR >= 10 - const auto CGFT_ObjectFile = ::llvm::CGFT_ObjectFile; - const auto CGFT_AssemblyFile = ::llvm::CGFT_AssemblyFile; - typedef ::llvm::CodeGenFileType CodeGenFileType; -#else - const auto CGFT_ObjectFile = ::llvm::TargetMachine::CGFT_ObjectFile; - const auto CGFT_AssemblyFile = - ::llvm::TargetMachine::CGFT_AssemblyFile; - typedef ::llvm::TargetMachine::CodeGenFileType CodeGenFileType; -#endif - - template<typename T, typename AS> - unsigned target_address_space(const T &target, const AS lang_as) { - const auto &map = target.getAddressSpaceMap(); -#if LLVM_VERSION_MAJOR >= 5 - return map[static_cast<unsigned>(lang_as)]; -#else - return map[lang_as - clang::LangAS::Offset]; -#endif - } - -#if LLVM_VERSION_MAJOR >= 10 - const clang::InputKind ik_opencl = clang::Language::OpenCL; -#elif LLVM_VERSION_MAJOR >= 5 - const clang::InputKind ik_opencl = clang::InputKind::OpenCL; -#else - const clang::InputKind ik_opencl = clang::IK_OpenCL; -#endif - -#if LLVM_VERSION_MAJOR >= 5 - const clang::LangStandard::Kind lang_opencl10 = clang::LangStandard::lang_opencl10; -#else - const clang::LangStandard::Kind lang_opencl10 = clang::LangStandard::lang_opencl; -#endif - - inline void - add_link_bitcode_file(clang::CodeGenOptions &opts, - const std::string &path) { -#if LLVM_VERSION_MAJOR >= 5 - clang::CodeGenOptions::BitcodeFileToLink F; - - F.Filename = path; - F.PropagateAttrs = true; - F.LinkFlags = ::llvm::Linker::Flags::None; - opts.LinkBitcodeFiles.emplace_back(F); -#else - opts.LinkBitcodeFiles.emplace_back(::llvm::Linker::Flags::None, path); -#endif - } - -#if LLVM_VERSION_MAJOR >= 6 - const auto default_code_model = ::llvm::None; -#else - const auto default_code_model = ::llvm::CodeModel::Default; -#endif - - template<typename M, typename F> void - handle_module_error(M &mod, const F &f) { -#if LLVM_VERSION_MAJOR >= 4 - if (::llvm::Error err = mod.takeError()) - ::llvm::handleAllErrors(std::move(err), [&](::llvm::ErrorInfoBase &eib) { - f(eib.message()); - }); -#else - if (!mod) - f(mod.getError().message()); -#endif - } - - template<typename T> void - set_diagnostic_handler(::llvm::LLVMContext &ctx, - T *diagnostic_handler, void *data) { -#if LLVM_VERSION_MAJOR >= 6 - ctx.setDiagnosticHandlerCallBack(diagnostic_handler, data); -#else - ctx.setDiagnosticHandler(diagnostic_handler, data); -#endif - } - - inline std::unique_ptr< ::llvm::Module> - clone_module(const ::llvm::Module &mod) - { -#if LLVM_VERSION_MAJOR >= 7 - return ::llvm::CloneModule(mod); -#else - return ::llvm::CloneModule(&mod); -#endif - } - - template<typename T> void - write_bitcode_to_file(const ::llvm::Module &mod, T &os) - { -#if LLVM_VERSION_MAJOR >= 7 - ::llvm::WriteBitcodeToFile(mod, os); -#else - ::llvm::WriteBitcodeToFile(&mod, os); -#endif - } - - template<typename TM, typename PM, typename OS, typename FT> - bool add_passes_to_emit_file(TM &tm, PM &pm, OS &os, FT &ft) - { -#if LLVM_VERSION_MAJOR >= 7 - return tm.addPassesToEmitFile(pm, os, nullptr, ft); -#else - return tm.addPassesToEmitFile(pm, os, ft); -#endif - } - - template<typename T> inline bool - create_compiler_invocation_from_args(clang::CompilerInvocation &cinv, - T copts, - clang::DiagnosticsEngine &diag) - { -#if LLVM_VERSION_MAJOR >= 10 - return clang::CompilerInvocation::CreateFromArgs( - cinv, copts, diag); -#else - return clang::CompilerInvocation::CreateFromArgs( - cinv, copts.data(), copts.data() + copts.size(), diag); -#endif - } - - template<typename T, typename M> - T get_abi_type(const T &arg_type, const M &mod) { -#if LLVM_VERSION_MAJOR >= 7 - return arg_type; -#else - ::llvm::DataLayout dl(&mod); - const unsigned arg_store_size = dl.getTypeStoreSize(arg_type); - return !arg_type->isIntegerTy() ? arg_type : - dl.getSmallestLegalIntType(mod.getContext(), arg_store_size * 8); -#endif - } - } - } -} - -#endif diff --git a/src/gallium/state_trackers/clover/llvm/invocation.cpp b/src/gallium/state_trackers/clover/llvm/invocation.cpp deleted file mode 100644 index 95a9d036622..00000000000 --- a/src/gallium/state_trackers/clover/llvm/invocation.cpp +++ /dev/null @@ -1,465 +0,0 @@ -// -// Copyright 2012-2016 Francisco Jerez -// Copyright 2012-2016 Advanced Micro Devices, Inc. -// Copyright 2014-2016 Jan Vesely -// Copyright 2014-2015 Serge Martin -// Copyright 2015 Zoltan Gilian -// -// Permission is hereby granted, free of charge, to any person obtaining a -// copy of this software and associated documentation files (the "Software"), -// to deal in the Software without restriction, including without limitation -// the rights to use, copy, modify, merge, publish, distribute, sublicense, -// and/or sell copies of the Software, and to permit persons to whom the -// Software is furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL -// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR -// OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, -// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR -// OTHER DEALINGS IN THE SOFTWARE. -// - -#include <llvm/IR/DiagnosticPrinter.h> -#include <llvm/IR/DiagnosticInfo.h> -#include <llvm/IR/LLVMContext.h> -#include <llvm/Support/raw_ostream.h> -#include <llvm/Transforms/IPO/PassManagerBuilder.h> -#include <llvm-c/Target.h> -#ifdef HAVE_CLOVER_SPIRV -#include <LLVMSPIRVLib/LLVMSPIRVLib.h> -#endif - -#include <clang/CodeGen/CodeGenAction.h> -#include <clang/Lex/PreprocessorOptions.h> -#include <clang/Frontend/TextDiagnosticBuffer.h> -#include <clang/Frontend/TextDiagnosticPrinter.h> -#include <clang/Basic/TargetInfo.h> - -// We need to include internal headers last, because the internal headers -// include CL headers which have #define's like: -// -//#define cl_khr_gl_sharing 1 -//#define cl_khr_icd 1 -// -// Which will break the compilation of clang/Basic/OpenCLOptions.h - -#include "core/error.hpp" -#include "llvm/codegen.hpp" -#include "llvm/compat.hpp" -#include "llvm/invocation.hpp" -#include "llvm/metadata.hpp" -#include "llvm/util.hpp" -#ifdef HAVE_CLOVER_SPIRV -#include "spirv/invocation.hpp" -#endif -#include "util/algorithm.hpp" - - -using namespace clover; -using namespace clover::llvm; - -using ::llvm::Function; -using ::llvm::LLVMContext; -using ::llvm::Module; -using ::llvm::raw_string_ostream; - -namespace { - - struct cl_version { - std::string version_str; // CL Version - unsigned version_number; // Numeric CL Version - }; - - static const unsigned ANY_VERSION = 999; - const cl_version cl_versions[] = { - { "1.0", 100}, - { "1.1", 110}, - { "1.2", 120}, - { "2.0", 200}, - { "2.1", 210}, - { "2.2", 220}, - }; - - struct clc_version_lang_std { - unsigned version_number; // CLC Version - clang::LangStandard::Kind clc_lang_standard; - }; - - const clc_version_lang_std cl_version_lang_stds[] = { - { 100, compat::lang_opencl10}, - { 110, clang::LangStandard::lang_opencl11}, - { 120, clang::LangStandard::lang_opencl12}, - { 200, clang::LangStandard::lang_opencl20}, - }; - - void - init_targets() { - static bool targets_initialized = false; - if (!targets_initialized) { - LLVMInitializeAllTargets(); - LLVMInitializeAllTargetInfos(); - LLVMInitializeAllTargetMCs(); - LLVMInitializeAllAsmParsers(); - LLVMInitializeAllAsmPrinters(); - targets_initialized = true; - } - } - - void - diagnostic_handler(const ::llvm::DiagnosticInfo &di, void *data) { - if (di.getSeverity() == ::llvm::DS_Error) { - raw_string_ostream os { *reinterpret_cast<std::string *>(data) }; - ::llvm::DiagnosticPrinterRawOStream printer { os }; - di.print(printer); - throw build_error(); - } - } - - std::unique_ptr<LLVMContext> - create_context(std::string &r_log) { - init_targets(); - std::unique_ptr<LLVMContext> ctx { new LLVMContext }; - compat::set_diagnostic_handler(*ctx, diagnostic_handler, &r_log); - return ctx; - } - - const struct clc_version_lang_std& - get_cl_lang_standard(unsigned requested, unsigned max = ANY_VERSION) { - for (const struct clc_version_lang_std &version : cl_version_lang_stds) { - if (version.version_number == max || - version.version_number == requested) { - return version; - } - } - throw build_error("Unknown/Unsupported language version"); - } - - const struct cl_version& - get_cl_version(const std::string &version_str, - unsigned max = ANY_VERSION) { - for (const struct cl_version &version : cl_versions) { - if (version.version_number == max || version.version_str == version_str) { - return version; - } - } - throw build_error("Unknown/Unsupported language version"); - } - - clang::LangStandard::Kind - get_lang_standard_from_version_str(const std::string &version_str, - bool is_build_opt = false) { - - //Per CL 2.0 spec, section 5.8.4.5: - // If it's an option, use the value directly. - // If it's a device version, clamp to max 1.x version, a.k.a. 1.2 - const cl_version version = - get_cl_version(version_str, is_build_opt ? ANY_VERSION : 120); - - const struct clc_version_lang_std standard = - get_cl_lang_standard(version.version_number); - - return standard.clc_lang_standard; - } - - clang::LangStandard::Kind - get_language_version(const std::vector<std::string> &opts, - const std::string &device_version) { - - const std::string search = "-cl-std=CL"; - - for (auto &opt: opts) { - auto pos = opt.find(search); - if (pos == 0){ - const auto ver = opt.substr(pos + search.size()); - const auto device_ver = get_cl_version(device_version); - const auto requested = get_cl_version(ver); - if (requested.version_number > device_ver.version_number) { - throw build_error(); - } - return get_lang_standard_from_version_str(ver, true); - } - } - - return get_lang_standard_from_version_str(device_version); - } - - std::unique_ptr<clang::CompilerInstance> - create_compiler_instance(const device &dev, const std::string& ir_target, - const std::vector<std::string> &opts, - std::string &r_log) { - std::unique_ptr<clang::CompilerInstance> c { new clang::CompilerInstance }; - clang::TextDiagnosticBuffer *diag_buffer = new clang::TextDiagnosticBuffer; - clang::DiagnosticsEngine diag { new clang::DiagnosticIDs, - new clang::DiagnosticOptions, diag_buffer }; - - // Parse the compiler options. A file name should be present at the end - // and must have the .cl extension in order for the CompilerInvocation - // class to recognize it as an OpenCL source file. - const std::vector<const char *> copts = - map(std::mem_fn(&std::string::c_str), opts); - - const target &target = ir_target; - const std::string &device_clc_version = dev.device_clc_version(); - - if (!compat::create_compiler_invocation_from_args( - c->getInvocation(), copts, diag)) - throw invalid_build_options_error(); - - diag_buffer->FlushDiagnostics(diag); - if (diag.hasErrorOccurred()) - throw invalid_build_options_error(); - - c->getTargetOpts().CPU = target.cpu; - c->getTargetOpts().Triple = target.triple; - c->getLangOpts().NoBuiltin = true; - - // This is a workaround for a Clang bug which causes the number - // of warnings and errors to be printed to stderr. - // http://www.llvm.org/bugs/show_bug.cgi?id=19735 - c->getDiagnosticOpts().ShowCarets = false; - - c->getInvocation().setLangDefaults(c->getLangOpts(), - compat::ik_opencl, ::llvm::Triple(target.triple), - c->getPreprocessorOpts(), - get_language_version(opts, device_clc_version)); - - c->createDiagnostics(new clang::TextDiagnosticPrinter( - *new raw_string_ostream(r_log), - &c->getDiagnosticOpts(), true)); - - c->setTarget(clang::TargetInfo::CreateTargetInfo( - c->getDiagnostics(), c->getInvocation().TargetOpts)); - - return c; - } - - std::unique_ptr<Module> - compile(LLVMContext &ctx, clang::CompilerInstance &c, - const std::string &name, const std::string &source, - const header_map &headers, const device &dev, - const std::string &opts, bool use_libclc, std::string &r_log) { - c.getFrontendOpts().ProgramAction = clang::frontend::EmitLLVMOnly; - c.getHeaderSearchOpts().UseBuiltinIncludes = true; - c.getHeaderSearchOpts().UseStandardSystemIncludes = true; - c.getHeaderSearchOpts().ResourceDir = CLANG_RESOURCE_DIR; - - if (use_libclc) { - // Add libclc generic search path - c.getHeaderSearchOpts().AddPath(LIBCLC_INCLUDEDIR, - clang::frontend::Angled, - false, false); - - // Add libclc include - c.getPreprocessorOpts().Includes.push_back("clc/clc.h"); - } else { - // Add opencl-c generic search path - c.getHeaderSearchOpts().AddPath(CLANG_RESOURCE_DIR, - clang::frontend::Angled, - false, false); - - // Add opencl include - c.getPreprocessorOpts().Includes.push_back("opencl-c.h"); - } - - // Add definition for the OpenCL version - c.getPreprocessorOpts().addMacroDef("__OPENCL_VERSION__=" + - std::to_string(get_cl_version( - dev.device_version()).version_number)); - - // clc.h requires that this macro be defined: - c.getPreprocessorOpts().addMacroDef("cl_clang_storage_class_specifiers"); - c.getPreprocessorOpts().addRemappedFile( - name, ::llvm::MemoryBuffer::getMemBuffer(source).release()); - - if (headers.size()) { - const std::string tmp_header_path = "/tmp/clover/"; - - c.getHeaderSearchOpts().AddPath(tmp_header_path, - clang::frontend::Angled, - false, false); - - for (const auto &header : headers) - c.getPreprocessorOpts().addRemappedFile( - tmp_header_path + header.first, - ::llvm::MemoryBuffer::getMemBuffer(header.second).release()); - } - - // Tell clang to link this file before performing any - // optimizations. This is required so that we can replace calls - // to the OpenCL C barrier() builtin with calls to target - // intrinsics that have the noduplicate attribute. This - // attribute will prevent Clang from creating illegal uses of - // barrier() (e.g. Moving barrier() inside a conditional that is - // no executed by all threads) during its optimizaton passes. - if (use_libclc) - compat::add_link_bitcode_file(c.getCodeGenOpts(), - LIBCLC_LIBEXECDIR + dev.ir_target() + ".bc"); - - // Compile the code - clang::EmitLLVMOnlyAction act(&ctx); - if (!c.ExecuteAction(act)) - throw build_error(); - - return act.takeModule(); - } -} - -module -clover::llvm::compile_program(const std::string &source, - const header_map &headers, - const device &dev, - const std::string &opts, - std::string &r_log) { - if (has_flag(debug::clc)) - debug::log(".cl", "// Options: " + opts + '\n' + source); - - auto ctx = create_context(r_log); - auto c = create_compiler_instance(dev, dev.ir_target(), - tokenize(opts + " input.cl"), r_log); - auto mod = compile(*ctx, *c, "input.cl", source, headers, dev, opts, true, - r_log); - - if (has_flag(debug::llvm)) - debug::log(".ll", print_module_bitcode(*mod)); - - return build_module_library(*mod, module::section::text_intermediate); -} - -namespace { - void - optimize(Module &mod, unsigned optimization_level, - bool internalize_symbols) { - ::llvm::legacy::PassManager pm; - - // By default, the function internalizer pass will look for a function - // called "main" and then mark all other functions as internal. Marking - // functions as internal enables the optimizer to perform optimizations - // like function inlining and global dead-code elimination. - // - // When there is no "main" function in a module, the internalize pass will - // treat the module like a library, and it won't internalize any functions. - // Since there is no "main" function in our kernels, we need to tell - // the internalizer pass that this module is not a library by passing a - // list of kernel functions to the internalizer. The internalizer will - // treat the functions in the list as "main" functions and internalize - // all of the other functions. - if (internalize_symbols) { - std::vector<std::string> names = - map(std::mem_fn(&Function::getName), get_kernels(mod)); - pm.add(::llvm::createInternalizePass( - [=](const ::llvm::GlobalValue &gv) { - return std::find(names.begin(), names.end(), - gv.getName()) != names.end(); - })); - } - - ::llvm::PassManagerBuilder pmb; - pmb.OptLevel = optimization_level; - pmb.LibraryInfo = new ::llvm::TargetLibraryInfoImpl( - ::llvm::Triple(mod.getTargetTriple())); - pmb.populateModulePassManager(pm); - pm.run(mod); - } - - std::unique_ptr<Module> - link(LLVMContext &ctx, const clang::CompilerInstance &c, - const std::vector<module> &modules, std::string &r_log) { - std::unique_ptr<Module> mod { new Module("link", ctx) }; - std::unique_ptr< ::llvm::Linker> linker { new ::llvm::Linker(*mod) }; - - for (auto &m : modules) { - if (linker->linkInModule(parse_module_library(m, ctx, r_log))) - throw build_error(); - } - - return mod; - } -} - -module -clover::llvm::link_program(const std::vector<module> &modules, - const device &dev, const std::string &opts, - std::string &r_log) { - std::vector<std::string> options = tokenize(opts + " input.cl"); - const bool create_library = count("-create-library", options); - erase_if(equals("-create-library"), options); - - auto ctx = create_context(r_log); - auto c = create_compiler_instance(dev, dev.ir_target(), options, r_log); - auto mod = link(*ctx, *c, modules, r_log); - - optimize(*mod, c->getCodeGenOpts().OptimizationLevel, !create_library); - - static std::atomic_uint seq(0); - const std::string id = "." + mod->getModuleIdentifier() + "-" + - std::to_string(seq++); - - if (has_flag(debug::llvm)) - debug::log(id + ".ll", print_module_bitcode(*mod)); - - if (create_library) { - return build_module_library(*mod, module::section::text_library); - - } else if (dev.ir_format() == PIPE_SHADER_IR_NATIVE) { - if (has_flag(debug::native)) - debug::log(id + ".asm", print_module_native(*mod, dev.ir_target())); - - return build_module_native(*mod, dev.ir_target(), *c, r_log); - - } else { - unreachable("Unsupported IR."); - } -} - -#ifdef HAVE_CLOVER_SPIRV -module -clover::llvm::compile_to_spirv(const std::string &source, - const header_map &headers, - const device &dev, - const std::string &opts, - std::string &r_log) { - if (has_flag(debug::clc)) - debug::log(".cl", "// Options: " + opts + '\n' + source); - - auto ctx = create_context(r_log); - const std::string target = dev.address_bits() == 32u ? - "-spir-unknown-unknown" : - "-spir64-unknown-unknown"; - auto c = create_compiler_instance(dev, target, - tokenize(opts + " input.cl"), r_log); - auto mod = compile(*ctx, *c, "input.cl", source, headers, dev, opts, false, - r_log); - - if (has_flag(debug::llvm)) - debug::log(".ll", print_module_bitcode(*mod)); - - std::string error_msg; - if (!::llvm::regularizeLlvmForSpirv(mod.get(), error_msg)) { - r_log += "Failed to regularize LLVM IR for SPIR-V: " + error_msg + ".\n"; - throw error(CL_INVALID_VALUE); - } - - std::ostringstream os; - if (!::llvm::writeSpirv(mod.get(), os, error_msg)) { - r_log += "Translation from LLVM IR to SPIR-V failed: " + error_msg + ".\n"; - throw error(CL_INVALID_VALUE); - } - - const std::string osContent = os.str(); - std::vector<char> binary(osContent.begin(), osContent.end()); - if (binary.empty()) { - r_log += "Failed to retrieve SPIR-V binary.\n"; - throw error(CL_INVALID_VALUE); - } - - if (has_flag(debug::spirv)) - debug::log(".spvasm", spirv::print_module(binary, dev.device_version())); - - return spirv::compile_program(binary, dev, r_log); -} -#endif diff --git a/src/gallium/state_trackers/clover/llvm/invocation.hpp b/src/gallium/state_trackers/clover/llvm/invocation.hpp deleted file mode 100644 index 1f0e9db2cf7..00000000000 --- a/src/gallium/state_trackers/clover/llvm/invocation.hpp +++ /dev/null @@ -1,54 +0,0 @@ -// -// Copyright 2016 Francisco Jerez -// -// Permission is hereby granted, free of charge, to any person obtaining a -// copy of this software and associated documentation files (the "Software"), -// to deal in the Software without restriction, including without limitation -// the rights to use, copy, modify, merge, publish, distribute, sublicense, -// and/or sell copies of the Software, and to permit persons to whom the -// Software is furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL -// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR -// OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, -// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR -// OTHER DEALINGS IN THE SOFTWARE. -// - -#ifndef CLOVER_LLVM_INVOCATION_HPP -#define CLOVER_LLVM_INVOCATION_HPP - -#include "core/error.hpp" -#include "core/module.hpp" -#include "core/program.hpp" -#include "pipe/p_defines.h" - -namespace clover { - namespace llvm { - module compile_program(const std::string &source, - const header_map &headers, - const device &device, - const std::string &opts, - std::string &r_log); - - module link_program(const std::vector<module> &modules, - const device &device, - const std::string &opts, - std::string &r_log); - -#ifdef HAVE_CLOVER_SPIRV - module compile_to_spirv(const std::string &source, - const header_map &headers, - const device &dev, - const std::string &opts, - std::string &r_log); -#endif - } -} - -#endif diff --git a/src/gallium/state_trackers/clover/llvm/metadata.hpp b/src/gallium/state_trackers/clover/llvm/metadata.hpp deleted file mode 100644 index 58042f4b4da..00000000000 --- a/src/gallium/state_trackers/clover/llvm/metadata.hpp +++ /dev/null @@ -1,86 +0,0 @@ -// -// Copyright 2016 Francisco Jerez -// -// Permission is hereby granted, free of charge, to any person obtaining a -// copy of this software and associated documentation files (the "Software"), -// to deal in the Software without restriction, including without limitation -// the rights to use, copy, modify, merge, publish, distribute, sublicense, -// and/or sell copies of the Software, and to permit persons to whom the -// Software is furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL -// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR -// OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, -// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR -// OTHER DEALINGS IN THE SOFTWARE. -// - -/// -/// \file -/// Utility functions for LLVM IR metadata introspection. -/// - -#ifndef CLOVER_LLVM_METADATA_HPP -#define CLOVER_LLVM_METADATA_HPP - -#include "llvm/compat.hpp" -#include "util/algorithm.hpp" - -#include <vector> -#include <llvm/Config/llvm-config.h> -#include <llvm/IR/Module.h> -#include <llvm/IR/Metadata.h> - -namespace clover { - namespace llvm { - namespace detail { - inline bool - is_kernel(const ::llvm::Function &f) { - return f.getMetadata("kernel_arg_type"); - } - - inline iterator_range< ::llvm::MDNode::op_iterator> - get_kernel_metadata_operands(const ::llvm::Function &f, - const std::string &name) { - const auto data_node = f.getMetadata(name); - return range(data_node->op_begin(), data_node->op_end()); - } - } - - /// - /// Extract the string metadata node \p name corresponding to the kernel - /// argument given by \p arg. - /// - inline std::string - get_argument_metadata(const ::llvm::Function &f, - const ::llvm::Argument &arg, - const std::string &name) { - return ::llvm::cast< ::llvm::MDString>( - detail::get_kernel_metadata_operands(f, name)[arg.getArgNo()]) - ->getString().str(); - } - - /// - /// Return a vector with all CL kernel functions found in the LLVM - /// module \p mod. - /// - inline std::vector<const ::llvm::Function *> - get_kernels(const ::llvm::Module &mod) { - std::vector<const ::llvm::Function *> fs; - - for (auto &f : mod.getFunctionList()) { - if (detail::is_kernel(f)) - fs.push_back(&f); - } - - return fs; - } - } -} - -#endif diff --git a/src/gallium/state_trackers/clover/llvm/util.hpp b/src/gallium/state_trackers/clover/llvm/util.hpp deleted file mode 100644 index 02e73e65071..00000000000 --- a/src/gallium/state_trackers/clover/llvm/util.hpp +++ /dev/null @@ -1,137 +0,0 @@ -// -// Copyright 2012-2016 Francisco Jerez -// Copyright 2012-2016 Advanced Micro Devices, Inc. -// -// Permission is hereby granted, free of charge, to any person obtaining a -// copy of this software and associated documentation files (the "Software"), -// to deal in the Software without restriction, including without limitation -// the rights to use, copy, modify, merge, publish, distribute, sublicense, -// and/or sell copies of the Software, and to permit persons to whom the -// Software is furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL -// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR -// OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, -// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR -// OTHER DEALINGS IN THE SOFTWARE. -// - -#ifndef CLOVER_LLVM_UTIL_HPP -#define CLOVER_LLVM_UTIL_HPP - -#include "core/error.hpp" -#include "util/u_debug.h" - -#include <vector> -#include <fstream> -#include <iostream> -#include <sstream> - -namespace clover { - namespace llvm { - template<typename E> void - fail(std::string &r_log, E &&e, const std::string &s) { - r_log += s; - throw e; - } - - inline std::vector<std::string> - tokenize(const std::string &s) { - std::vector<std::string> ss; - std::ostringstream oss; - - // OpenCL programs can pass a quoted argument, most frequently the - // include path. This is useful so that path containing spaces is - // treated as a single argument instead of being split by the spaces. - // Additionally, the argument should also be unquoted before being - // passed to the compiler. We avoid using std::string::replace here to - // remove quotes, as the single and double quote characters can be a - // part of the file name. - bool escape_next = false; - bool in_quote_double = false; - bool in_quote_single = false; - - for (auto c : s) { - if (escape_next) { - oss.put(c); - escape_next = false; - } else if (c == '\\') { - escape_next = true; - } else if (c == '"' && !in_quote_single) { - in_quote_double = !in_quote_double; - } else if (c == '\'' && !in_quote_double) { - in_quote_single = !in_quote_single; - } else if (c != ' ' || in_quote_single || in_quote_double) { - oss.put(c); - } else if (oss.tellp() > 0) { - ss.emplace_back(oss.str()); - oss.str(""); - } - } - - if (oss.tellp() > 0) - ss.emplace_back(oss.str()); - - if (in_quote_double || in_quote_single) - throw invalid_build_options_error(); - - return ss; - } - - inline std::string - as_string(const std::vector<char> &v) { - return { v.begin(), v.end() }; - } - - struct target { - target(const std::string &s) : - cpu(s.begin(), s.begin() + s.find_first_of("-")), - triple(s.begin() + s.find_first_of("-") + 1, s.end()) {} - - std::string cpu; - std::string triple; - }; - - namespace debug { - enum flag { - clc = 1 << 0, - llvm = 1 << 1, - native = 1 << 2, - spirv = 1 << 3, - }; - - inline bool - has_flag(flag f) { - static const struct debug_named_value debug_options[] = { - { "clc", clc, "Dump the OpenCL C code for all kernels." }, - { "llvm", llvm, "Dump the generated LLVM IR for all kernels." }, - { "native", native, "Dump kernel assembly code for targets " - "specifying PIPE_SHADER_IR_NATIVE" }, - { "spirv", spirv, "Dump the generated SPIR-V for all kernels." }, - DEBUG_NAMED_VALUE_END - }; - static const unsigned flags = - debug_get_flags_option("CLOVER_DEBUG", debug_options, 0); - - return flags & f; - } - - inline void - log(const std::string &suffix, const std::string &s) { - const std::string path = debug_get_option("CLOVER_DEBUG_FILE", - "stderr"); - if (path == "stderr") - std::cerr << s; - else - std::ofstream(path + suffix, std::ios::app) << s; - } - } - } -} - -#endif diff --git a/src/gallium/state_trackers/clover/meson.build b/src/gallium/state_trackers/clover/meson.build deleted file mode 100644 index 7606a6beaf6..00000000000 --- a/src/gallium/state_trackers/clover/meson.build +++ /dev/null @@ -1,164 +0,0 @@ -# Copyright © 2017-2018 Intel Corporation - -# Permission is hereby granted, free of charge, to any person obtaining a copy -# of this software and associated documentation files (the "Software"), to deal -# in the Software without restriction, including without limitation the rights -# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -# copies of the Software, and to permit persons to whom the Software is -# furnished to do so, subject to the following conditions: - -# The above copyright notice and this permission notice shall be included in -# all copies or substantial portions of the Software. - -# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -# SOFTWARE. - -clover_cpp_args = [] -clover_opencl_cpp_args = [ - '-DCL_TARGET_OPENCL_VERSION=220', - '-DCL_USE_DEPRECATED_OPENCL_1_0_APIS', - '-DCL_USE_DEPRECATED_OPENCL_1_1_APIS', - '-DCL_USE_DEPRECATED_OPENCL_1_2_APIS', - '-DCL_USE_DEPRECATED_OPENCL_2_0_APIS', - '-DCL_USE_DEPRECATED_OPENCL_2_1_APIS' -] -clover_spirv_cpp_args = [] -clover_incs = [inc_include, inc_src, inc_gallium, inc_gallium_aux] - -# the CL header files declare attributes on the CL types. Compilers warn if -# we use them as template arguments. Disable the warning as there isn't -# anything we can do about it -if cpp.has_argument('-Wno-ignored-attributes') - clover_cpp_args += '-Wno-ignored-attributes' -endif - -if with_opencl_icd - clover_cpp_args += '-DHAVE_CLOVER_ICD' -endif - -if with_opencl_spirv - clover_spirv_cpp_args += '-DHAVE_CLOVER_SPIRV' -endif - -libclllvm = static_library( - 'clllvm', - files( - 'llvm/codegen/bitcode.cpp', - 'llvm/codegen/common.cpp', - 'llvm/codegen/native.cpp', - 'llvm/codegen.hpp', - 'llvm/compat.hpp', - 'llvm/invocation.cpp', - 'llvm/invocation.hpp', - 'llvm/metadata.hpp', - 'llvm/util.hpp', - ), - include_directories : clover_incs, - cpp_args : [ - clover_cpp_args, - clover_opencl_cpp_args, - clover_spirv_cpp_args, - cpp_vis_args, - '-DLIBCLC_INCLUDEDIR="@0@/"'.format(dep_clc.get_pkgconfig_variable('includedir')), - '-DLIBCLC_LIBEXECDIR="@0@/"'.format(dep_clc.get_pkgconfig_variable('libexecdir')), - '-DCLANG_RESOURCE_DIR="@0@"'.format(join_paths( - dep_llvm.get_configtool_variable('libdir'), 'clang', - dep_llvm.version(), 'include', - )), - ], - dependencies : [dep_llvm, dep_elf, dep_llvmspirvlib], - override_options : clover_cpp_std, -) - -libclspirv = static_library( - 'clspirv', - files('spirv/invocation.cpp', 'spirv/invocation.hpp'), - include_directories : clover_incs, - cpp_args : [clover_opencl_cpp_args, clover_spirv_cpp_args, cpp_vis_args], - dependencies : [dep_spirv_tools], - override_options : clover_cpp_std, -) - -libclnir = static_library( - 'clnir', - files('nir/invocation.cpp', 'nir/invocation.hpp'), - include_directories : [clover_incs, inc_mesa], - dependencies : idep_nir, - cpp_args : [clover_opencl_cpp_args, clover_spirv_cpp_args, cpp_vis_args], - override_options : clover_cpp_std, -) - -clover_files = files( - 'api/context.cpp', - 'api/device.cpp', - 'api/dispatch.cpp', - 'api/dispatch.hpp', - 'api/event.cpp', - 'api/interop.cpp', - 'api/kernel.cpp', - 'api/memory.cpp', - 'api/platform.cpp', - 'api/program.cpp', - 'api/queue.cpp', - 'api/sampler.cpp', - 'api/transfer.cpp', - 'api/util.hpp', - 'core/compiler.hpp', - 'core/context.cpp', - 'core/context.hpp', - 'core/device.cpp', - 'core/device.hpp', - 'core/error.hpp', - 'core/event.cpp', - 'core/event.hpp', - 'core/format.cpp', - 'core/format.hpp', - 'core/kernel.cpp', - 'core/kernel.hpp', - 'core/memory.cpp', - 'core/memory.hpp', - 'core/module.cpp', - 'core/module.hpp', - 'core/object.hpp', - 'core/platform.cpp', - 'core/platform.hpp', - 'core/program.cpp', - 'core/program.hpp', - 'core/property.hpp', - 'core/queue.cpp', - 'core/queue.hpp', - 'core/resource.cpp', - 'core/resource.hpp', - 'core/sampler.cpp', - 'core/sampler.hpp', - 'core/timestamp.cpp', - 'core/timestamp.hpp', - 'util/adaptor.hpp', - 'util/algebra.hpp', - 'util/algorithm.hpp', - 'util/factor.hpp', - 'util/functional.hpp', - 'util/lazy.hpp', - 'util/pointer.hpp', - 'util/range.hpp', - 'util/tuple.hpp', -) - -libclover = static_library( - 'clover', - [clover_files, sha1_h], - include_directories : clover_incs, - cpp_args : [ - clover_opencl_cpp_args, - clover_spirv_cpp_args, - clover_cpp_args, - cpp_vis_args - ], - link_with : [libclllvm, libclspirv, libclnir], - override_options : clover_cpp_std, -) diff --git a/src/gallium/state_trackers/clover/nir/invocation.cpp b/src/gallium/state_trackers/clover/nir/invocation.cpp deleted file mode 100644 index 46440d96e09..00000000000 --- a/src/gallium/state_trackers/clover/nir/invocation.cpp +++ /dev/null @@ -1,173 +0,0 @@ -// -// Copyright 2019 Karol Herbst -// -// Permission is hereby granted, free of charge, to any person obtaining a -// copy of this software and associated documentation files (the "Software"), -// to deal in the Software without restriction, including without limitation -// the rights to use, copy, modify, merge, publish, distribute, sublicense, -// and/or sell copies of the Software, and to permit persons to whom the -// Software is furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL -// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR -// OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, -// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR -// OTHER DEALINGS IN THE SOFTWARE. -// - -#include "invocation.hpp" - -#include <tuple> - -#include "core/device.hpp" -#include "core/error.hpp" -#include "pipe/p_state.h" -#include "util/algorithm.hpp" -#include "util/functional.hpp" - -#include <compiler/glsl_types.h> -#include <compiler/nir/nir_serialize.h> -#include <compiler/spirv/nir_spirv.h> -#include <util/u_math.h> - -using namespace clover; - -#ifdef HAVE_CLOVER_SPIRV - -// Refs and unrefs the glsl_type_singleton. -static class glsl_type_ref { -public: - glsl_type_ref() { - glsl_type_singleton_init_or_ref(); - } - - ~glsl_type_ref() { - glsl_type_singleton_decref(); - } -} glsl_type_ref; - -static const nir_shader_compiler_options * -dev_get_nir_compiler_options(const device &dev) -{ - const void *co = dev.get_compiler_options(PIPE_SHADER_IR_NIR); - return static_cast<const nir_shader_compiler_options*>(co); -} - -module clover::nir::spirv_to_nir(const module &mod, const device &dev, - std::string &r_log) -{ - struct spirv_to_nir_options spirv_options = {}; - spirv_options.environment = NIR_SPIRV_OPENCL; - spirv_options.caps.address = true; - spirv_options.caps.float64 = true; - spirv_options.caps.int8 = true; - spirv_options.caps.int16 = true; - spirv_options.caps.int64 = true; - spirv_options.caps.kernel = true; - spirv_options.constant_as_global = true; - - module m; - // We only insert one section. - assert(mod.secs.size() == 1); - auto §ion = mod.secs[0]; - - module::resource_id section_id = 0; - for (const auto &sym : mod.syms) { - assert(sym.section == 0); - - const auto *binary = - reinterpret_cast<const pipe_binary_program_header *>(section.data.data()); - const uint32_t *data = reinterpret_cast<const uint32_t *>(binary->blob); - const size_t num_words = binary->num_bytes / 4; - const char *name = sym.name.c_str(); - auto *compiler_options = dev_get_nir_compiler_options(dev); - - nir_shader *nir = spirv_to_nir(data, num_words, nullptr, 0, - MESA_SHADER_KERNEL, name, - &spirv_options, compiler_options); - if (!nir) { - r_log += "Translation from SPIR-V to NIR for kernel \"" + sym.name + - "\" failed.\n"; - throw build_error(); - } - - nir->info.cs.local_size_variable = true; - nir_validate_shader(nir, "clover"); - - // Calculate input offsets. - unsigned offset = 0; - nir_foreach_variable_safe(var, &nir->inputs) { - offset = align(offset, glsl_get_cl_alignment(var->type)); - var->data.driver_location = offset; - offset += glsl_get_cl_size(var->type); - } - - // Inline all functions first. - // according to the comment on nir_inline_functions - NIR_PASS_V(nir, nir_lower_variable_initializers, nir_var_function_temp); - NIR_PASS_V(nir, nir_lower_returns); - NIR_PASS_V(nir, nir_inline_functions); - NIR_PASS_V(nir, nir_opt_deref); - - // Pick off the single entrypoint that we want. - foreach_list_typed_safe(nir_function, func, node, &nir->functions) { - if (!func->is_entrypoint) - exec_node_remove(&func->node); - } - assert(exec_list_length(&nir->functions) == 1); - - nir_validate_shader(nir, "clover after function inlining"); - - NIR_PASS_V(nir, nir_lower_variable_initializers, - static_cast<nir_variable_mode>(~nir_var_function_temp)); - - // copy propagate to prepare for lower_explicit_io - NIR_PASS_V(nir, nir_split_var_copies); - NIR_PASS_V(nir, nir_opt_copy_prop_vars); - NIR_PASS_V(nir, nir_lower_var_copies); - NIR_PASS_V(nir, nir_lower_vars_to_ssa); - NIR_PASS_V(nir, nir_opt_dce); - - nir_variable_mode modes = (nir_variable_mode)( - nir_var_shader_in | - nir_var_mem_global | - nir_var_mem_shared); - nir_address_format format = nir->info.cs.ptr_size == 64 ? - nir_address_format_64bit_global : nir_address_format_32bit_global; - NIR_PASS_V(nir, nir_lower_explicit_io, modes, format); - - NIR_PASS_V(nir, nir_lower_system_values); - if (compiler_options->lower_int64_options) - NIR_PASS_V(nir, nir_lower_int64, - compiler_options->lower_int64_options); - - NIR_PASS_V(nir, nir_opt_dce); - - struct blob blob; - blob_init(&blob); - nir_serialize(&blob, nir, false); - - const pipe_binary_program_header header { uint32_t(blob.size) }; - module::section text { section_id, module::section::text_executable, header.num_bytes, {} }; - text.data.insert(text.data.end(), reinterpret_cast<const char *>(&header), - reinterpret_cast<const char *>(&header) + sizeof(header)); - text.data.insert(text.data.end(), blob.data, blob.data + blob.size); - - m.syms.emplace_back(sym.name, section_id, 0, sym.args); - m.secs.push_back(text); - section_id++; - } - return m; -} -#else -module clover::nir::spirv_to_nir(const module &mod, const device &dev, std::string &r_log) -{ - r_log += "SPIR-V support in clover is not enabled.\n"; - throw error(CL_LINKER_NOT_AVAILABLE); -} -#endif diff --git a/src/gallium/state_trackers/clover/nir/invocation.hpp b/src/gallium/state_trackers/clover/nir/invocation.hpp deleted file mode 100644 index 41407a79765..00000000000 --- a/src/gallium/state_trackers/clover/nir/invocation.hpp +++ /dev/null @@ -1,36 +0,0 @@ -// -// Copyright 2019 Karol Herbst -// -// Permission is hereby granted, free of charge, to any person obtaining a -// copy of this software and associated documentation files (the "Software"), -// to deal in the Software without restriction, including without limitation -// the rights to use, copy, modify, merge, publish, distribute, sublicense, -// and/or sell copies of the Software, and to permit persons to whom the -// Software is furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL -// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR -// OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, -// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR -// OTHER DEALINGS IN THE SOFTWARE. -// - -#ifndef CLOVER_NIR_INVOCATION_HPP -#define CLOVER_NIR_INVOCATION_HPP - -#include "core/module.hpp" - -namespace clover { - class device; - namespace nir { - // converts a given spirv module to nir - module spirv_to_nir(const module &mod, const device &dev, std::string &r_log); - } -} - -#endif diff --git a/src/gallium/state_trackers/clover/spirv/invocation.cpp b/src/gallium/state_trackers/clover/spirv/invocation.cpp deleted file mode 100644 index 01ced45c13b..00000000000 --- a/src/gallium/state_trackers/clover/spirv/invocation.cpp +++ /dev/null @@ -1,740 +0,0 @@ -// -// Copyright 2018 Pierre Moreau -// -// Permission is hereby granted, free of charge, to any person obtaining a -// copy of this software and associated documentation files (the "Software"), -// to deal in the Software without restriction, including without limitation -// the rights to use, copy, modify, merge, publish, distribute, sublicense, -// and/or sell copies of the Software, and to permit persons to whom the -// Software is furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL -// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR -// OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, -// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR -// OTHER DEALINGS IN THE SOFTWARE. -// - -#include "invocation.hpp" - -#include <tuple> -#include <unordered_map> -#include <unordered_set> -#include <vector> - -#ifdef HAVE_CLOVER_SPIRV -#include <spirv-tools/libspirv.hpp> -#include <spirv-tools/linker.hpp> -#endif - -#include "core/error.hpp" -#include "core/platform.hpp" -#include "invocation.hpp" -#include "llvm/util.hpp" -#include "pipe/p_state.h" -#include "util/algorithm.hpp" -#include "util/functional.hpp" -#include "util/u_math.h" - -#include "compiler/spirv/spirv.h" - -#define SPIRV_HEADER_WORD_SIZE 5 - -using namespace clover; - -#ifdef HAVE_CLOVER_SPIRV -namespace { - - template<typename T> - T get(const char *source, size_t index) { - const uint32_t *word_ptr = reinterpret_cast<const uint32_t *>(source); - return static_cast<T>(word_ptr[index]); - } - - enum module::argument::type - convert_storage_class(SpvStorageClass storage_class, std::string &err) { - switch (storage_class) { - case SpvStorageClassFunction: - return module::argument::scalar; - case SpvStorageClassUniformConstant: - return module::argument::global; - case SpvStorageClassWorkgroup: - return module::argument::local; - case SpvStorageClassCrossWorkgroup: - return module::argument::global; - default: - err += "Invalid storage type " + std::to_string(storage_class) + "\n"; - throw build_error(); - } - } - - enum module::argument::type - convert_image_type(SpvId id, SpvDim dim, SpvAccessQualifier access, - std::string &err) { - if (dim == SpvDim2D && access == SpvAccessQualifierReadOnly) - return module::argument::image2d_rd; - else if (dim == SpvDim2D && access == SpvAccessQualifierWriteOnly) - return module::argument::image2d_wr; - else if (dim == SpvDim3D && access == SpvAccessQualifierReadOnly) - return module::argument::image3d_rd; - else if (dim == SpvDim3D && access == SpvAccessQualifierWriteOnly) - return module::argument::image3d_wr; - else { - err += "Unknown access qualifier " + std::to_string(access) - + " or dimension " + std::to_string(dim) + " for image " - + std::to_string(id) + ".\n"; - throw build_error(); - } - } - - module::section - make_text_section(const std::vector<char> &code, - enum module::section::type section_type) { - const pipe_binary_program_header header { uint32_t(code.size()) }; - module::section text { 0, section_type, header.num_bytes, {} }; - - text.data.insert(text.data.end(), reinterpret_cast<const char *>(&header), - reinterpret_cast<const char *>(&header) + sizeof(header)); - text.data.insert(text.data.end(), code.begin(), code.end()); - - return text; - } - - module - create_module_from_spirv(const std::vector<char> &source, - size_t pointer_byte_size, - std::string &err) { - const size_t length = source.size() / sizeof(uint32_t); - size_t i = SPIRV_HEADER_WORD_SIZE; // Skip header - - std::string kernel_name; - size_t kernel_nb = 0u; - std::vector<module::argument> args; - - module m; - - std::unordered_map<SpvId, std::string> kernels; - std::unordered_map<SpvId, module::argument> types; - std::unordered_map<SpvId, SpvId> pointer_types; - std::unordered_map<SpvId, unsigned int> constants; - std::unordered_set<SpvId> packed_structures; - std::unordered_map<SpvId, std::vector<SpvFunctionParameterAttribute>> - func_param_attr_map; - - while (i < length) { - const auto inst = &source[i * sizeof(uint32_t)]; - const auto desc_word = get<uint32_t>(inst, 0); - const auto opcode = static_cast<SpvOp>(desc_word & SpvOpCodeMask); - const unsigned int num_operands = desc_word >> SpvWordCountShift; - - switch (opcode) { - case SpvOpEntryPoint: - if (get<SpvExecutionModel>(inst, 1) == SpvExecutionModelKernel) - kernels.emplace(get<SpvId>(inst, 2), - source.data() + (i + 3u) * sizeof(uint32_t)); - break; - - case SpvOpDecorate: { - const auto id = get<SpvId>(inst, 1); - const auto decoration = get<SpvDecoration>(inst, 2); - if (decoration == SpvDecorationCPacked) - packed_structures.emplace(id); - else if (decoration == SpvDecorationFuncParamAttr) { - const auto attribute = - get<SpvFunctionParameterAttribute>(inst, 3u); - func_param_attr_map[id].push_back(attribute); - } - break; - } - - case SpvOpGroupDecorate: { - const auto group_id = get<SpvId>(inst, 1); - if (packed_structures.count(group_id)) { - for (unsigned int i = 2u; i < num_operands; ++i) - packed_structures.emplace(get<SpvId>(inst, i)); - } - const auto func_param_attr_iter = - func_param_attr_map.find(group_id); - if (func_param_attr_iter != func_param_attr_map.end()) { - for (unsigned int i = 2u; i < num_operands; ++i) - func_param_attr_map.emplace(get<SpvId>(inst, i), - func_param_attr_iter->second); - } - break; - } - - case SpvOpConstant: - // We only care about constants that represent the size of arrays. - // If they are passed as argument, they will never be more than - // 4GB-wide, and even if they did, a clover::module::argument size - // is represented by an int. - constants[get<SpvId>(inst, 2)] = get<unsigned int>(inst, 3u); - break; - - case SpvOpTypeInt: // FALLTHROUGH - case SpvOpTypeFloat: { - const auto size = get<uint32_t>(inst, 2) / 8u; - types[get<SpvId>(inst, 1)] = { module::argument::scalar, size, - size, size, - module::argument::zero_ext }; - break; - } - - case SpvOpTypeArray: { - const auto id = get<SpvId>(inst, 1); - const auto type_id = get<SpvId>(inst, 2); - const auto types_iter = types.find(type_id); - if (types_iter == types.end()) - break; - - const auto constant_id = get<SpvId>(inst, 3); - const auto constants_iter = constants.find(constant_id); - if (constants_iter == constants.end()) { - err += "Constant " + std::to_string(constant_id) + - " is missing\n"; - throw build_error(); - } - const auto elem_size = types_iter->second.size; - const auto elem_nbs = constants_iter->second; - const auto size = elem_size * elem_nbs; - types[id] = { module::argument::scalar, size, size, - types_iter->second.target_align, - module::argument::zero_ext }; - break; - } - - case SpvOpTypeStruct: { - const auto id = get<SpvId>(inst, 1); - const bool is_packed = packed_structures.count(id); - - unsigned struct_size = 0u; - unsigned struct_align = 1u; - for (unsigned j = 2u; j < num_operands; ++j) { - const auto type_id = get<SpvId>(inst, j); - const auto types_iter = types.find(type_id); - - // If a type was not found, that means it is not one of the - // types allowed as kernel arguments. And since the module has - // been validated, this means this type is not used for kernel - // arguments, and therefore can be ignored. - if (types_iter == types.end()) - break; - - const auto alignment = is_packed ? 1u - : types_iter->second.target_align; - const auto padding = (-struct_size) & (alignment - 1u); - struct_size += padding + types_iter->second.target_size; - struct_align = std::max(struct_align, alignment); - } - struct_size += (-struct_size) & (struct_align - 1u); - types[id] = { module::argument::scalar, struct_size, struct_size, - struct_align, module::argument::zero_ext }; - break; - } - - case SpvOpTypeVector: { - const auto id = get<SpvId>(inst, 1); - const auto type_id = get<SpvId>(inst, 2); - const auto types_iter = types.find(type_id); - - // If a type was not found, that means it is not one of the - // types allowed as kernel arguments. And since the module has - // been validated, this means this type is not used for kernel - // arguments, and therefore can be ignored. - if (types_iter == types.end()) - break; - - const auto elem_size = types_iter->second.size; - const auto elem_nbs = get<uint32_t>(inst, 3); - const auto size = elem_size * elem_nbs; - types[id] = { module::argument::scalar, size, size, size, - module::argument::zero_ext }; - break; - } - - case SpvOpTypeForwardPointer: // FALLTHROUGH - case SpvOpTypePointer: { - const auto id = get<SpvId>(inst, 1); - const auto storage_class = get<SpvStorageClass>(inst, 2); - // Input means this is for a builtin variable, which can not be - // passed as an argument to a kernel. - if (storage_class == SpvStorageClassInput) - break; - types[id] = { convert_storage_class(storage_class, err), - sizeof(cl_mem), - static_cast<module::size_t>(pointer_byte_size), - static_cast<module::size_t>(pointer_byte_size), - module::argument::zero_ext }; - if (opcode == SpvOpTypePointer) - pointer_types[id] = get<SpvId>(inst, 3); - break; - } - - case SpvOpTypeSampler: - types[get<SpvId>(inst, 1)] = { module::argument::sampler, - sizeof(cl_sampler) }; - break; - - case SpvOpTypeImage: { - const auto id = get<SpvId>(inst, 1); - const auto dim = get<SpvDim>(inst, 3); - const auto access = get<SpvAccessQualifier>(inst, 9); - types[id] = { convert_image_type(id, dim, access, err), - sizeof(cl_mem), sizeof(cl_mem), sizeof(cl_mem), - module::argument::zero_ext }; - break; - } - - case SpvOpTypePipe: // FALLTHROUGH - case SpvOpTypeQueue: { - err += "TypePipe and TypeQueue are valid SPIR-V 1.0 types, but are " - "not available in the currently supported OpenCL C version." - "\n"; - throw build_error(); - } - - case SpvOpFunction: { - const auto kernels_iter = kernels.find(get<SpvId>(inst, 2)); - if (kernels_iter != kernels.end()) - kernel_name = kernels_iter->second; - break; - } - - case SpvOpFunctionParameter: { - if (kernel_name.empty()) - break; - - const auto type_id = get<SpvId>(inst, 1); - auto arg = types.find(type_id)->second; - const auto &func_param_attr_iter = - func_param_attr_map.find(get<SpvId>(inst, 2)); - if (func_param_attr_iter != func_param_attr_map.end()) { - for (auto &i : func_param_attr_iter->second) { - switch (i) { - case SpvFunctionParameterAttributeSext: - arg.ext_type = module::argument::sign_ext; - break; - case SpvFunctionParameterAttributeZext: - arg.ext_type = module::argument::zero_ext; - break; - case SpvFunctionParameterAttributeByVal: { - const SpvId ptr_type_id = - pointer_types.find(type_id)->second; - arg = types.find(ptr_type_id)->second; - break; - } - default: - break; - } - } - } - args.emplace_back(arg); - break; - } - - case SpvOpFunctionEnd: - if (kernel_name.empty()) - break; - m.syms.emplace_back(kernel_name, 0, kernel_nb, args); - ++kernel_nb; - kernel_name.clear(); - args.clear(); - break; - - default: - break; - } - - i += num_operands; - } - - m.secs.push_back(make_text_section(source, - module::section::text_intermediate)); - return m; - } - - bool - check_capabilities(const device &dev, const std::vector<char> &source, - std::string &r_log) { - const size_t length = source.size() / sizeof(uint32_t); - size_t i = SPIRV_HEADER_WORD_SIZE; // Skip header - - while (i < length) { - const auto desc_word = get<uint32_t>(source.data(), i); - const auto opcode = static_cast<SpvOp>(desc_word & SpvOpCodeMask); - const unsigned int num_operands = desc_word >> SpvWordCountShift; - - if (opcode != SpvOpCapability) - break; - - const auto capability = get<SpvCapability>(source.data(), i + 1u); - switch (capability) { - // Mandatory capabilities - case SpvCapabilityAddresses: - case SpvCapabilityFloat16Buffer: - case SpvCapabilityGroups: - case SpvCapabilityInt64: - case SpvCapabilityInt16: - case SpvCapabilityInt8: - case SpvCapabilityKernel: - case SpvCapabilityLinkage: - case SpvCapabilityVector16: - break; - // Optional capabilities - case SpvCapabilityImageBasic: - case SpvCapabilityLiteralSampler: - case SpvCapabilitySampled1D: - case SpvCapabilityImage1D: - case SpvCapabilitySampledBuffer: - case SpvCapabilityImageBuffer: - if (!dev.image_support()) { - r_log += "Capability 'ImageBasic' is not supported.\n"; - return false; - } - break; - case SpvCapabilityFloat64: - if (!dev.has_doubles()) { - r_log += "Capability 'Float64' is not supported.\n"; - return false; - } - break; - // Enabled through extensions - case SpvCapabilityFloat16: - if (!dev.has_halves()) { - r_log += "Capability 'Float16' is not supported.\n"; - return false; - } - break; - case SpvCapabilityInt64Atomics: - if (!dev.has_int64_atomics()) { - r_log += "Capability 'Int64Atomics' is not supported.\n"; - return false; - } - break; - default: - r_log += "Capability '" + std::to_string(capability) + - "' is not supported.\n"; - return false; - } - - i += num_operands; - } - - return true; - } - - bool - check_extensions(const device &dev, const std::vector<char> &source, - std::string &r_log) { - const size_t length = source.size() / sizeof(uint32_t); - size_t i = SPIRV_HEADER_WORD_SIZE; // Skip header - - while (i < length) { - const auto desc_word = get<uint32_t>(source.data(), i); - const auto opcode = static_cast<SpvOp>(desc_word & SpvOpCodeMask); - const unsigned int num_operands = desc_word >> SpvWordCountShift; - - if (opcode == SpvOpCapability) { - i += num_operands; - continue; - } - if (opcode != SpvOpExtension) - break; - - const char *extension = source.data() + (i + 1u) * sizeof(uint32_t); - const std::string device_extensions = dev.supported_extensions(); - const std::string platform_extensions = - dev.platform.supported_extensions(); - if (device_extensions.find(extension) == std::string::npos && - platform_extensions.find(extension) == std::string::npos) { - r_log += "Extension '" + std::string(extension) + - "' is not supported.\n"; - return false; - } - - i += num_operands; - } - - return true; - } - - bool - check_memory_model(const device &dev, const std::vector<char> &source, - std::string &r_log) { - const size_t length = source.size() / sizeof(uint32_t); - size_t i = SPIRV_HEADER_WORD_SIZE; // Skip header - - while (i < length) { - const auto desc_word = get<uint32_t>(source.data(), i); - const auto opcode = static_cast<SpvOp>(desc_word & SpvOpCodeMask); - const unsigned int num_operands = desc_word >> SpvWordCountShift; - - switch (opcode) { - case SpvOpMemoryModel: - switch (get<SpvAddressingModel>(source.data(), i + 1u)) { - case SpvAddressingModelPhysical32: - return dev.address_bits() == 32; - case SpvAddressingModelPhysical64: - return dev.address_bits() == 64; - default: - unreachable("Only Physical32 and Physical64 are valid for OpenCL, and the binary was already validated"); - return false; - } - break; - default: - break; - } - - i += num_operands; - } - - return false; - } - - // Copies the input binary and convert it to the endianness of the host CPU. - std::vector<char> - spirv_to_cpu(const std::vector<char> &binary) - { - const uint32_t first_word = get<uint32_t>(binary.data(), 0u); - if (first_word == SpvMagicNumber) - return binary; - - std::vector<char> cpu_endianness_binary(binary.size()); - for (size_t i = 0; i < (binary.size() / 4u); ++i) { - const uint32_t word = get<uint32_t>(binary.data(), i); - reinterpret_cast<uint32_t *>(cpu_endianness_binary.data())[i] = - util_bswap32(word); - } - - return cpu_endianness_binary; - } - -#ifdef HAVE_CLOVER_SPIRV - std::string - format_validator_msg(spv_message_level_t level, const char * /* source */, - const spv_position_t &position, const char *message) { - std::string level_str; - switch (level) { - case SPV_MSG_FATAL: - level_str = "Fatal"; - break; - case SPV_MSG_INTERNAL_ERROR: - level_str = "Internal error"; - break; - case SPV_MSG_ERROR: - level_str = "Error"; - break; - case SPV_MSG_WARNING: - level_str = "Warning"; - break; - case SPV_MSG_INFO: - level_str = "Info"; - break; - case SPV_MSG_DEBUG: - level_str = "Debug"; - break; - } - return "[" + level_str + "] At word No." + - std::to_string(position.index) + ": \"" + message + "\"\n"; - } - - spv_target_env - convert_opencl_str_to_target_env(const std::string &opencl_version) { - if (opencl_version == "2.2") { - return SPV_ENV_OPENCL_2_2; - } else if (opencl_version == "2.1") { - return SPV_ENV_OPENCL_2_1; - } else if (opencl_version == "2.0") { - return SPV_ENV_OPENCL_2_0; - } else if (opencl_version == "1.2" || - opencl_version == "1.1" || - opencl_version == "1.0") { - // SPIR-V is only defined for OpenCL >= 1.2, however some drivers - // might use it with OpenCL 1.0 and 1.1. - return SPV_ENV_OPENCL_1_2; - } else { - throw build_error("Invalid OpenCL version"); - } - } -#endif - -} - -module -clover::spirv::compile_program(const std::vector<char> &binary, - const device &dev, std::string &r_log) { - std::vector<char> source = spirv_to_cpu(binary); - - if (!is_valid_spirv(source, dev.device_version(), r_log)) - throw build_error(); - - if (!check_capabilities(dev, source, r_log)) - throw build_error(); - if (!check_extensions(dev, source, r_log)) - throw build_error(); - if (!check_memory_model(dev, source, r_log)) - throw build_error(); - - return create_module_from_spirv(source, - dev.address_bits() == 32 ? 4u : 8u, r_log); -} - -module -clover::spirv::link_program(const std::vector<module> &modules, - const device &dev, const std::string &opts, - std::string &r_log) { - std::vector<std::string> options = clover::llvm::tokenize(opts); - - bool create_library = false; - - std::string ignored_options; - for (const std::string &option : options) { - if (option == "-create-library") { - create_library = true; - } else { - ignored_options += "'" + option + "' "; - } - } - if (!ignored_options.empty()) { - r_log += "Ignoring the following link options: " + ignored_options - + "\n"; - } - - spvtools::LinkerOptions linker_options; - linker_options.SetCreateLibrary(create_library); - - module m; - - const auto section_type = create_library ? module::section::text_library : - module::section::text_executable; - - std::vector<const uint32_t *> sections; - sections.reserve(modules.size()); - std::vector<size_t> lengths; - lengths.reserve(modules.size()); - - auto const validator_consumer = [&r_log](spv_message_level_t level, - const char *source, - const spv_position_t &position, - const char *message) { - r_log += format_validator_msg(level, source, position, message); - }; - - for (const auto &mod : modules) { - const auto &msec = find([](const module::section &sec) { - return sec.type == module::section::text_intermediate || - sec.type == module::section::text_library; - }, mod.secs); - - const auto c_il = ((struct pipe_binary_program_header*)msec.data.data())->blob; - const auto length = msec.size; - - sections.push_back(reinterpret_cast<const uint32_t *>(c_il)); - lengths.push_back(length / sizeof(uint32_t)); - } - - std::vector<uint32_t> linked_binary; - - const std::string opencl_version = dev.device_version(); - const spv_target_env target_env = - convert_opencl_str_to_target_env(opencl_version); - - const spvtools::MessageConsumer consumer = validator_consumer; - spvtools::Context context(target_env); - context.SetMessageConsumer(std::move(consumer)); - - if (Link(context, sections.data(), lengths.data(), sections.size(), - &linked_binary, linker_options) != SPV_SUCCESS) - throw error(CL_LINK_PROGRAM_FAILURE); - - std::vector<char> final_binary{ - reinterpret_cast<char *>(linked_binary.data()), - reinterpret_cast<char *>(linked_binary.data() + - linked_binary.size()) }; - if (!is_valid_spirv(final_binary, opencl_version, r_log)) - throw error(CL_LINK_PROGRAM_FAILURE); - - for (const auto &mod : modules) - m.syms.insert(m.syms.end(), mod.syms.begin(), mod.syms.end()); - - m.secs.emplace_back(make_text_section(final_binary, section_type)); - - return m; -} - -bool -clover::spirv::is_valid_spirv(const std::vector<char> &binary, - const std::string &opencl_version, - std::string &r_log) { - auto const validator_consumer = - [&r_log](spv_message_level_t level, const char *source, - const spv_position_t &position, const char *message) { - r_log += format_validator_msg(level, source, position, message); - }; - - const spv_target_env target_env = - convert_opencl_str_to_target_env(opencl_version); - spvtools::SpirvTools spvTool(target_env); - spvTool.SetMessageConsumer(validator_consumer); - - return spvTool.Validate(reinterpret_cast<const uint32_t *>(binary.data()), - binary.size() / 4u); -} - -std::string -clover::spirv::print_module(const std::vector<char> &binary, - const std::string &opencl_version) { - const spv_target_env target_env = - convert_opencl_str_to_target_env(opencl_version); - spvtools::SpirvTools spvTool(target_env); - spv_context spvContext = spvContextCreate(target_env); - if (!spvContext) - return "Failed to create an spv_context for disassembling the module."; - - spv_text disassembly; - spvBinaryToText(spvContext, - reinterpret_cast<const uint32_t *>(binary.data()), - binary.size() / 4u, SPV_BINARY_TO_TEXT_OPTION_NONE, - &disassembly, nullptr); - spvContextDestroy(spvContext); - - const std::string disassemblyStr = disassembly->str; - spvTextDestroy(disassembly); - - return disassemblyStr; -} - -#else -bool -clover::spirv::is_valid_spirv(const std::vector<char> &/*binary*/, - const std::string &/*opencl_version*/, - std::string &/*r_log*/) { - return false; -} - -module -clover::spirv::compile_program(const std::vector<char> &binary, - const device &dev, std::string &r_log) { - r_log += "SPIR-V support in clover is not enabled.\n"; - throw build_error(); -} - -module -clover::spirv::link_program(const std::vector<module> &/*modules*/, - const device &/*dev*/, const std::string &/*opts*/, - std::string &r_log) { - r_log += "SPIR-V support in clover is not enabled.\n"; - throw error(CL_LINKER_NOT_AVAILABLE); -} - -std::string -clover::spirv::print_module(const std::vector<char> &binary, - const std::string &opencl_version) { - return std::string(); -} -#endif diff --git a/src/gallium/state_trackers/clover/spirv/invocation.hpp b/src/gallium/state_trackers/clover/spirv/invocation.hpp deleted file mode 100644 index 472d8c0de71..00000000000 --- a/src/gallium/state_trackers/clover/spirv/invocation.hpp +++ /dev/null @@ -1,56 +0,0 @@ -// -// Copyright 2018 Pierre Moreau -// -// Permission is hereby granted, free of charge, to any person obtaining a -// copy of this software and associated documentation files (the "Software"), -// to deal in the Software without restriction, including without limitation -// the rights to use, copy, modify, merge, publish, distribute, sublicense, -// and/or sell copies of the Software, and to permit persons to whom the -// Software is furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL -// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR -// OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, -// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR -// OTHER DEALINGS IN THE SOFTWARE. -// - -#ifndef CLOVER_SPIRV_INVOCATION_HPP -#define CLOVER_SPIRV_INVOCATION_HPP - -#include "core/context.hpp" -#include "core/module.hpp" -#include "core/program.hpp" - -namespace clover { - namespace spirv { - // Returns whether the given binary is considered valid for the given - // OpenCL version. - // - // It uses SPIRV-Tools validator to do the validation, and potential - // warnings and errors are appended to |r_log|. - bool is_valid_spirv(const std::vector<char> &binary, - const std::string &opencl_version, - std::string &r_log); - - // Creates a clover module out of the given SPIR-V binary. - module compile_program(const std::vector<char> &binary, - const device &dev, std::string &r_log); - - // Combines multiple clover modules into a single one, resolving - // link dependencies between them. - module link_program(const std::vector<module> &modules, const device &dev, - const std::string &opts, std::string &r_log); - - // Returns a textual representation of the given binary. - std::string print_module(const std::vector<char> &binary, - const std::string &opencl_version); - } -} - -#endif diff --git a/src/gallium/state_trackers/clover/util/adaptor.hpp b/src/gallium/state_trackers/clover/util/adaptor.hpp deleted file mode 100644 index e9035968573..00000000000 --- a/src/gallium/state_trackers/clover/util/adaptor.hpp +++ /dev/null @@ -1,183 +0,0 @@ -// -// Copyright 2013 Francisco Jerez -// -// Permission is hereby granted, free of charge, to any person obtaining a -// copy of this software and associated documentation files (the "Software"), -// to deal in the Software without restriction, including without limitation -// the rights to use, copy, modify, merge, publish, distribute, sublicense, -// and/or sell copies of the Software, and to permit persons to whom the -// Software is furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL -// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR -// OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, -// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR -// OTHER DEALINGS IN THE SOFTWARE. -// - -#ifndef CLOVER_UTIL_ADAPTOR_HPP -#define CLOVER_UTIL_ADAPTOR_HPP - -#include <iterator> - -#include "util/tuple.hpp" -#include "util/pointer.hpp" -#include "util/functional.hpp" - -namespace clover { - namespace detail { - /// - /// Implementation of the iterator concept that transforms the - /// value of the source iterators \a Is on dereference by use of - /// a functor \a F. - /// - /// The exact category of the resulting iterator should be the - /// least common denominator of the source iterator categories. - /// - template<typename F, typename... Is> - class iterator_adaptor { - public: - typedef std::forward_iterator_tag iterator_category; - typedef typename std::result_of< - F(typename std::iterator_traits<Is>::reference...) - >::type reference; - typedef typename std::remove_reference<reference>::type value_type; - typedef pseudo_ptr<value_type> pointer; - typedef std::ptrdiff_t difference_type; - - iterator_adaptor() { - } - - iterator_adaptor(F f, std::tuple<Is...> &&its) : - f(f), its(std::move(its)) { - } - - reference - operator*() const { - return tuple::apply(f, tuple::map(derefs(), its)); - } - - iterator_adaptor & - operator++() { - tuple::map(preincs(), its); - return *this; - } - - iterator_adaptor - operator++(int) { - auto jt = *this; - ++*this; - return jt; - } - - bool - operator==(const iterator_adaptor &jt) const { - return its == jt.its; - } - - bool - operator!=(const iterator_adaptor &jt) const { - return its != jt.its; - } - - pointer - operator->() const { - return { **this }; - } - - iterator_adaptor & - operator--() { - tuple::map(predecs(), its); - return *this; - } - - iterator_adaptor - operator--(int) { - auto jt = *this; - --*this; - return jt; - } - - iterator_adaptor & - operator+=(difference_type n) { - tuple::map(advances_by(n), its); - return *this; - } - - iterator_adaptor & - operator-=(difference_type n) { - tuple::map(advances_by(-n), its); - return *this; - } - - iterator_adaptor - operator+(difference_type n) const { - auto jt = *this; - jt += n; - return jt; - } - - iterator_adaptor - operator-(difference_type n) const { - auto jt = *this; - jt -= n; - return jt; - } - - difference_type - operator-(const iterator_adaptor &jt) const { - return std::get<0>(its) - std::get<0>(jt.its); - } - - reference - operator[](difference_type n) const { - return *(*this + n); - } - - bool - operator<(iterator_adaptor &jt) const { - return *this - jt < 0; - } - - bool - operator>(iterator_adaptor &jt) const { - return *this - jt > 0; - } - - bool - operator>=(iterator_adaptor &jt) const { - return !(*this < jt); - } - - bool - operator<=(iterator_adaptor &jt) const { - return !(*this > jt); - } - - protected: - F f; - std::tuple<Is...> its; - }; - - template<typename F, typename... Is> - iterator_adaptor<F, Is...> - operator+(typename iterator_adaptor<F, Is...>::difference_type n, - const iterator_adaptor<F, Is...> &jt) { - return (jt + n); - } - - template<typename F, typename... Is> - iterator_adaptor<F, Is...> - operator-(typename iterator_adaptor<F, Is...>::difference_type n, - const iterator_adaptor<F, Is...> &jt) { - return (jt - n); - } - } -} - -#endif diff --git a/src/gallium/state_trackers/clover/util/algebra.hpp b/src/gallium/state_trackers/clover/util/algebra.hpp deleted file mode 100644 index 43a9d8bbf5f..00000000000 --- a/src/gallium/state_trackers/clover/util/algebra.hpp +++ /dev/null @@ -1,160 +0,0 @@ -// -// Copyright 2013 Francisco Jerez -// -// Permission is hereby granted, free of charge, to any person obtaining a -// copy of this software and associated documentation files (the "Software"), -// to deal in the Software without restriction, including without limitation -// the rights to use, copy, modify, merge, publish, distribute, sublicense, -// and/or sell copies of the Software, and to permit persons to whom the -// Software is furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL -// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR -// OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, -// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR -// OTHER DEALINGS IN THE SOFTWARE. -// - -#ifndef CLOVER_UTIL_ALGEBRA_HPP -#define CLOVER_UTIL_ALGEBRA_HPP - -#include <type_traits> - -#include "util/range.hpp" -#include "util/functional.hpp" - -namespace clover { - /// - /// Class that identifies vectors (in the linear-algebraic sense). - /// - /// There should be a definition of this class for each type that - /// makes sense as vector arithmetic operand. - /// - template<typename V, typename = void> - struct vector_traits; - - /// - /// References of vectors are vectors. - /// - template<typename T> - struct vector_traits<T &, typename vector_traits<T>::enable> { - typedef void enable; - }; - - /// - /// Constant vectors are vectors. - /// - template<typename T> - struct vector_traits<const T, typename vector_traits<T>::enable> { - typedef void enable; - }; - - /// - /// Arrays of arithmetic types are vectors. - /// - template<typename T, std::size_t N> - struct vector_traits<std::array<T, N>, - typename std::enable_if< - std::is_arithmetic<T>::value>::type> { - typedef void enable; - }; - - namespace detail { - template<typename... Ts> - struct are_defined { - typedef void enable; - }; - } - - /// - /// The result of mapping a vector is a vector. - /// - template<typename F, typename... Vs> - struct vector_traits<adaptor_range<F, Vs...>, - typename detail::are_defined< - typename vector_traits<Vs>::enable...>::enable> { - typedef void enable; - }; - - /// - /// Vector sum. - /// - template<typename U, typename V, - typename = typename vector_traits<U>::enable, - typename = typename vector_traits<V>::enable> - adaptor_range<plus, U, V> - operator+(U &&u, V &&v) { - return map(plus(), std::forward<U>(u), std::forward<V>(v)); - } - - /// - /// Vector difference. - /// - template<typename U, typename V, - typename = typename vector_traits<U>::enable, - typename = typename vector_traits<V>::enable> - adaptor_range<minus, U, V> - operator-(U &&u, V &&v) { - return map(minus(), std::forward<U>(u), std::forward<V>(v)); - } - - /// - /// Scalar multiplication. - /// - template<typename U, typename T, - typename = typename vector_traits<U>::enable> - adaptor_range<multiplies_by_t<T>, U> - operator*(U &&u, T &&a) { - return map(multiplies_by<T>(std::forward<T>(a)), std::forward<U>(u)); - } - - /// - /// Scalar multiplication. - /// - template<typename U, typename T, - typename = typename vector_traits<U>::enable> - adaptor_range<multiplies_by_t<T>, U> - operator*(T &&a, U &&u) { - return map(multiplies_by<T>(std::forward<T>(a)), std::forward<U>(u)); - } - - /// - /// Additive inverse. - /// - template<typename U, - typename = typename vector_traits<U>::enable> - adaptor_range<negate, U> - operator-(U &&u) { - return map(negate(), std::forward<U>(u)); - } - - namespace detail { - template<typename U, typename V> - using dot_type = typename std::common_type< - typename std::remove_reference<U>::type::value_type, - typename std::remove_reference<V>::type::value_type - >::type; - } - - /// - /// Dot product of two vectors. - /// - /// It can also do matrix multiplication if \a u or \a v is a - /// vector of vectors. - /// - template<typename U, typename V, - typename = typename vector_traits<U>::enable, - typename = typename vector_traits<V>::enable> - detail::dot_type<U, V> - dot(U &&u, V &&v) { - return fold(plus(), detail::dot_type<U, V>(), - map(multiplies(), u, v)); - } -} - -#endif diff --git a/src/gallium/state_trackers/clover/util/algorithm.hpp b/src/gallium/state_trackers/clover/util/algorithm.hpp deleted file mode 100644 index 1658458ee18..00000000000 --- a/src/gallium/state_trackers/clover/util/algorithm.hpp +++ /dev/null @@ -1,218 +0,0 @@ -// -// Copyright 2013 Francisco Jerez -// -// Permission is hereby granted, free of charge, to any person obtaining a -// copy of this software and associated documentation files (the "Software"), -// to deal in the Software without restriction, including without limitation -// the rights to use, copy, modify, merge, publish, distribute, sublicense, -// and/or sell copies of the Software, and to permit persons to whom the -// Software is furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL -// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR -// OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, -// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR -// OTHER DEALINGS IN THE SOFTWARE. -// - -#ifndef CLOVER_UTIL_ALGORITHM_HPP -#define CLOVER_UTIL_ALGORITHM_HPP - -#include <algorithm> -#include <stdexcept> - -#include "util/range.hpp" -#include "util/functional.hpp" - -namespace clover { - namespace detail { - template<typename R> - using preferred_reference_type = decltype(*std::declval<R>().begin()); - } - - /// - /// Return the first element in a range. - /// - template<typename R> - detail::preferred_reference_type<R> - head(R &&r) { - assert(!r.empty()); - return r.front(); - } - - /// - /// Return all elements in a range but the first. - /// - template<typename R> - slice_range<R> - tail(R &&r) { - assert(!r.empty()); - return { std::forward<R>(r), 1, r.size() }; - } - - /// - /// Return the only element in a range. - /// - template<typename R> - detail::preferred_reference_type<R> - unique(R &&r) { - if (r.size() != 1) - throw std::out_of_range(""); - - return r.front(); - } - - /// - /// Combine a variable number of ranges element-wise in a single - /// range of tuples. - /// - template<typename... Rs> - adaptor_range<zips, Rs...> - zip(Rs &&... rs) { - return map(zips(), std::forward<Rs>(rs)...); - } - - /// - /// Evaluate the elements of a range. - /// - /// Useful because most of the range algorithms evaluate their - /// result lazily. - /// - template<typename R> - void - eval(R &&r) { - for (auto i = r.begin(), e = r.end(); i != e; ++i) - *i; - } - - /// - /// Apply functor \a f element-wise on a variable number of ranges - /// \a rs. - /// - /// The functor \a f should take as many arguments as ranges are - /// provided. - /// - template<typename F, typename... Rs> - void - for_each(F &&f, Rs &&... rs) { - eval(map(std::forward<F>(f), std::forward<Rs>(rs)...)); - } - - /// - /// Copy all elements from range \a r into an output container - /// starting from iterator \a i. - /// - template<typename R, typename I> - void - copy(R &&r, I i) { - for (detail::preferred_reference_type<R> x : r) - *(i++) = x; - } - - /// - /// Reduce the elements of range \a r by applying functor \a f - /// element by element. - /// - /// \a f should take an accumulator value (which is initialized to - /// \a a) and an element value as arguments, and return an updated - /// accumulator value. - /// - /// \returns The final value of the accumulator. - /// - template<typename F, typename A, typename R> - A - fold(F &&f, A a, R &&r) { - for (detail::preferred_reference_type<R> x : r) - a = f(a, x); - - return a; - } - - /// - /// Return how many elements of range \a r are equal to \a x. - /// - template<typename T, typename R> - typename std::remove_reference<R>::type::size_type - count(T &&x, R &&r) { - typename std::remove_reference<R>::type::size_type n = 0; - - for (detail::preferred_reference_type<R> y : r) { - if (x == y) - n++; - } - - return n; - } - - /// - /// Return the first element in range \a r for which predicate \a f - /// evaluates to true. - /// - template<typename F, typename R> - detail::preferred_reference_type<R> - find(F &&f, R &&r) { - for (detail::preferred_reference_type<R> x : r) { - if (f(x)) - return x; - } - - throw std::out_of_range(""); - } - - /// - /// Return true if the element-wise application of predicate \a f - /// on \a rs evaluates to true for all elements. - /// - template<typename F, typename... Rs> - bool - all_of(F &&f, Rs &&... rs) { - for (auto b : map(f, rs...)) { - if (!b) - return false; - } - - return true; - } - - /// - /// Return true if the element-wise application of predicate \a f - /// on \a rs evaluates to true for any element. - /// - template<typename F, typename... Rs> - bool - any_of(F &&f, Rs &&... rs) { - for (auto b : map(f, rs...)) { - if (b) - return true; - } - - return false; - } - - /// - /// Erase elements for which predicate \a f evaluates to true from - /// container \a r. - /// - template<typename F, typename R> - void - erase_if(F &&f, R &&r) { - auto i = r.begin(), e = r.end(); - - for (auto j = r.begin(); j != e; ++j) { - if (!f(*j)) { - if (j != i) - *i = std::move(*j); - ++i; - } - } - - r.erase(i, e); - } -} - -#endif diff --git a/src/gallium/state_trackers/clover/util/factor.hpp b/src/gallium/state_trackers/clover/util/factor.hpp deleted file mode 100644 index 76d3bfe343f..00000000000 --- a/src/gallium/state_trackers/clover/util/factor.hpp +++ /dev/null @@ -1,131 +0,0 @@ -// -// Copyright 2013 Francisco Jerez -// -// Permission is hereby granted, free of charge, to any person obtaining a -// copy of this software and associated documentation files (the "Software"), -// to deal in the Software without restriction, including without limitation -// the rights to use, copy, modify, merge, publish, distribute, sublicense, -// and/or sell copies of the Software, and to permit persons to whom the -// Software is furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL -// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR -// OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, -// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR -// OTHER DEALINGS IN THE SOFTWARE. -// - -#ifndef CLOVER_UTIL_FACTOR_HPP -#define CLOVER_UTIL_FACTOR_HPP - -#include "util/range.hpp" - -namespace clover { - namespace factor { - /// - /// Calculate all prime integer factors of \p x. - /// - /// If \p limit is non-zero, terminate early as soon as enough - /// factors have been collected to reach the product \p limit. - /// - template<typename T> - std::vector<T> - find_integer_prime_factors(T x, T limit = 0) - { - const T max_d = (limit > 0 && limit < x ? limit : x); - const T min_x = x / max_d; - std::vector<T> factors; - - for (T d = 2; d <= max_d && x > min_x; d++) { - if (x % d == 0) { - for (; x % d == 0; x /= d); - factors.push_back(d); - } - } - - return factors; - } - - namespace detail { - /// - /// Walk the power set of prime factors of the n-dimensional - /// integer array \p grid subject to the constraints given by - /// \p limits. - /// - template<typename T> - std::pair<T, std::vector<T>> - next_grid_factor(const std::pair<T, std::vector<T>> &limits, - const std::vector<T> &grid, - const std::vector<std::vector<T>> &factors, - std::pair<T, std::vector<T>> block, - unsigned d = 0, unsigned i = 0) { - if (d >= factors.size()) { - // We're done. - return {}; - - } else if (i >= factors[d].size()) { - // We're done with this grid dimension, try the next. - return next_grid_factor(limits, grid, factors, - std::move(block), d + 1, 0); - - } else { - T f = factors[d][i]; - - // Try the next power of this factor. - block.first *= f; - block.second[d] *= f; - - if (block.first <= limits.first && - block.second[d] <= limits.second[d] && - grid[d] % block.second[d] == 0) { - // We've found a valid grid divisor. - return block; - - } else { - // Overflow, back off to the zeroth power, - while (block.second[d] % f == 0) { - block.second[d] /= f; - block.first /= f; - } - - // ...and carry to the next factor. - return next_grid_factor(limits, grid, factors, - std::move(block), d, i + 1); - } - } - } - } - - /// - /// Find the divisor of the integer array \p grid that gives the - /// highest possible product not greater than \p product_limit - /// subject to the constraints given by \p coord_limit. - /// - template<typename T> - std::vector<T> - find_grid_optimal_factor(T product_limit, - const std::vector<T> &coord_limit, - const std::vector<T> &grid) { - const std::vector<std::vector<T>> factors = - map(find_integer_prime_factors<T>, grid, coord_limit); - const auto limits = std::make_pair(product_limit, coord_limit); - auto best = std::make_pair(T(1), std::vector<T>(grid.size(), T(1))); - - for (auto block = best; - block.first != 0 && best.first != product_limit; - block = detail::next_grid_factor(limits, grid, factors, block)) { - if (block.first > best.first) - best = block; - } - - return best.second; - } - } -} - -#endif diff --git a/src/gallium/state_trackers/clover/util/functional.hpp b/src/gallium/state_trackers/clover/util/functional.hpp deleted file mode 100644 index fc281c5c79a..00000000000 --- a/src/gallium/state_trackers/clover/util/functional.hpp +++ /dev/null @@ -1,419 +0,0 @@ -// -// Copyright 2013 Francisco Jerez -// -// Permission is hereby granted, free of charge, to any person obtaining a -// copy of this software and associated documentation files (the "Software"), -// to deal in the Software without restriction, including without limitation -// the rights to use, copy, modify, merge, publish, distribute, sublicense, -// and/or sell copies of the Software, and to permit persons to whom the -// Software is furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL -// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR -// OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, -// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR -// OTHER DEALINGS IN THE SOFTWARE. -// - -#ifndef CLOVER_UTIL_FUNCTIONAL_HPP -#define CLOVER_UTIL_FUNCTIONAL_HPP - -#include <type_traits> - -namespace clover { - struct identity { - template<typename T> - typename std::remove_reference<T>::type - operator()(T &&x) const { - return x; - } - }; - - struct plus { - template<typename T, typename S> - typename std::common_type<T, S>::type - operator()(T x, S y) const { - return x + y; - } - }; - - struct minus { - template<typename T, typename S> - typename std::common_type<T, S>::type - operator()(T x, S y) const { - return x - y; - } - }; - - struct negate { - template<typename T> - T - operator()(T x) const { - return -x; - } - }; - - struct multiplies { - template<typename T, typename S> - typename std::common_type<T, S>::type - operator()(T x, S y) const { - return x * y; - } - }; - - struct divides { - template<typename T, typename S> - typename std::common_type<T, S>::type - operator()(T x, S y) const { - return x / y; - } - }; - - struct modulus { - template<typename T, typename S> - typename std::common_type<T, S>::type - operator()(T x, S y) const { - return x % y; - } - }; - - struct minimum { - template<typename T> - T - operator()(T x) const { - return x; - } - - template<typename T, typename... Ts> - T - operator()(T x, Ts... xs) const { - T y = minimum()(xs...); - return x < y ? x : y; - } - }; - - struct maximum { - template<typename T> - T - operator()(T x) const { - return x; - } - - template<typename T, typename... Ts> - T - operator()(T x, Ts... xs) const { - T y = maximum()(xs...); - return x < y ? y : x; - } - }; - - struct preincs { - template<typename T> - T & - operator()(T &x) const { - return ++x; - } - }; - - struct predecs { - template<typename T> - T & - operator()(T &x) const { - return --x; - } - }; - - template<typename T> - class multiplies_by_t { - public: - multiplies_by_t(T x) : x(x) { - } - - template<typename S> - typename std::common_type<T, S>::type - operator()(S y) const { - return x * y; - } - - private: - T x; - }; - - template<typename T> - multiplies_by_t<T> - multiplies_by(T x) { - return { x }; - } - - template<typename T> - class preincs_by_t { - public: - preincs_by_t(T n) : n(n) { - } - - template<typename S> - S & - operator()(S &x) const { - return x += n; - } - - private: - T n; - }; - - template<typename T> - preincs_by_t<T> - preincs_by(T n) { - return { n }; - } - - template<typename T> - class predecs_by_t { - public: - predecs_by_t(T n) : n(n) { - } - - template<typename S> - S & - operator()(S &x) const { - return x -= n; - } - - private: - T n; - }; - - template<typename T> - predecs_by_t<T> - predecs_by(T n) { - return { n }; - } - - struct greater { - template<typename T, typename S> - bool - operator()(T x, S y) const { - return x > y; - } - }; - - struct evals { - template<typename T> - auto - operator()(T &&x) const -> decltype(x()) { - return x(); - } - }; - - struct derefs { - template<typename T> - auto - operator()(T &&x) const -> decltype(*x) { - return *x; - } - }; - - struct addresses { - template<typename T> - T * - operator()(T &x) const { - return &x; - } - - template<typename T> - T * - operator()(std::reference_wrapper<T> x) const { - return &x.get(); - } - }; - - struct begins { - template<typename T> - auto - operator()(T &x) const -> decltype(x.begin()) { - return x.begin(); - } - }; - - struct ends { - template<typename T> - auto - operator()(T &x) const -> decltype(x.end()) { - return x.end(); - } - }; - - struct sizes { - template<typename T> - auto - operator()(T &x) const -> decltype(x.size()) { - return x.size(); - } - }; - - template<typename T> - class advances_by_t { - public: - advances_by_t(T n) : n(n) { - } - - template<typename S> - S - operator()(S &&it) const { - std::advance(it, n); - return it; - } - - private: - T n; - }; - - template<typename T> - advances_by_t<T> - advances_by(T n) { - return { n }; - } - - struct zips { - template<typename... Ts> - std::tuple<Ts...> - operator()(Ts &&... xs) const { - return std::tuple<Ts...>(std::forward<Ts>(xs)...); - } - }; - - struct is_zero { - template<typename T> - bool - operator()(const T &x) const { - return x == 0; - } - }; - - struct keys { - template<typename P> - auto - operator()(P &&p) const -> decltype(std::get<0>(std::forward<P>(p))) { - return std::get<0>(std::forward<P>(p)); - } - }; - - struct values { - template<typename P> - auto - operator()(P &&p) const -> decltype(std::get<1>(std::forward<P>(p))) { - return std::get<1>(std::forward<P>(p)); - } - }; - - template<typename T> - class equals_t { - public: - equals_t(T &&x) : x(x) {} - - template<typename S> - bool - operator()(S &&y) const { - return x == y; - } - - private: - T x; - }; - - template<typename T> - equals_t<T> - equals(T &&x) { - return { std::forward<T>(x) }; - } - - class name_equals { - public: - name_equals(const std::string &name) : name(name) { - } - - template<typename T> - bool - operator()(const T &x) const { - return std::string(x.name.begin(), x.name.end()) == name; - } - - private: - const std::string &name; - }; - - class id_equals { - public: - id_equals(const uint32_t id) : id(id) { - } - - template<typename T> - bool - operator()(const T &x) const { - return x.id == id; - } - - private: - const uint32_t id; - }; - - template<typename T> - class key_equals_t { - public: - key_equals_t(T &&x) : x(x) { - } - - template<typename P> - bool - operator()(const P &p) const { - return p.first == x; - } - - private: - T x; - }; - - template<typename T> - key_equals_t<T> - key_equals(T &&x) { - return { std::forward<T>(x) }; - } - - template<typename T> - class type_equals_t { - public: - type_equals_t(T type) : type(type) { - } - - template<typename S> - bool - operator()(const S &x) const { - return x.type == type; - } - - private: - T type; - }; - - template<typename T> - type_equals_t<T> - type_equals(T x) { - return { x }; - } - - struct interval_overlaps { - template<typename T> - bool - operator()(T x0, T x1, T y0, T y1) { - return ((x0 <= y0 && y0 < x1) || - (y0 <= x0 && x0 < y1)); - } - }; -} - -#endif diff --git a/src/gallium/state_trackers/clover/util/lazy.hpp b/src/gallium/state_trackers/clover/util/lazy.hpp deleted file mode 100644 index e32a8f8b1b9..00000000000 --- a/src/gallium/state_trackers/clover/util/lazy.hpp +++ /dev/null @@ -1,161 +0,0 @@ -// -// Copyright 2013 Francisco Jerez -// -// Permission is hereby granted, free of charge, to any person obtaining a -// copy of this software and associated documentation files (the "Software"), -// to deal in the Software without restriction, including without limitation -// the rights to use, copy, modify, merge, publish, distribute, sublicense, -// and/or sell copies of the Software, and to permit persons to whom the -// Software is furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL -// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR -// OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, -// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR -// OTHER DEALINGS IN THE SOFTWARE. -// - -#ifndef CLOVER_UTIL_LAZY_HPP -#define CLOVER_UTIL_LAZY_HPP - -#include <type_traits> -#include <stdexcept> -#include <memory> - -namespace clover { - namespace detail { - template<typename T> - class basic_lazy { - public: - virtual - ~basic_lazy() { - } - - virtual basic_lazy * - clone() const = 0; - - virtual - operator T() const = 0; - }; - - template<typename T, typename F> - class deferred_lazy : public basic_lazy<T> { - public: - template<typename G> - deferred_lazy(G &&f) : f(new F(std::forward<G>(f))) { - } - - virtual basic_lazy<T> * - clone() const { - return new deferred_lazy(*this); - } - - operator T() const { - if (f) { - x = (*f)(); - f = {}; - } - - return x; - } - - private: - mutable std::shared_ptr<F> f; - mutable T x; - }; - - template<typename T> - class strict_lazy : public basic_lazy<T> { - public: - template<typename S> - strict_lazy(S &&x) : x(std::forward<S>(x)) { - } - - virtual basic_lazy<T> * - clone() const { - return new strict_lazy(*this); - } - - operator T() const { - return x; - } - - private: - T x; - }; - } - - /// - /// Object that represents a value of type \a T that is calculated - /// lazily as soon as it is required. - /// - template<typename T> - class lazy { - public: - class undefined_error : std::logic_error { - public: - undefined_error() : std::logic_error("") { - } - }; - - /// - /// Initialize to some fixed value \a x which isn't calculated - /// lazily. - /// - lazy(T x) : obj(new detail::strict_lazy<T>(x)) { - } - - /// - /// Initialize by providing a functor \a f that will calculate - /// the value on-demand. - /// - template<typename F> - lazy(F &&f) : obj(new detail::deferred_lazy< - T, typename std::remove_reference<F>::type - >(std::forward<F>(f))) { - } - - /// - /// Initialize to undefined. - /// - lazy() : lazy([]() { - throw undefined_error(); - return T(); - }) { - } - - lazy(const lazy &other) : obj(obj->clone()) { - } - - lazy(lazy &&other) : obj(NULL) { - std::swap(obj, other.obj); - } - - ~lazy() { - delete obj; - } - - lazy & - operator=(lazy other) { - std::swap(obj, other.obj); - return *this; - } - - /// - /// Evaluate the value. - /// - operator T() const { - return *obj; - } - - private: - detail::basic_lazy<T> *obj; - }; -} - -#endif diff --git a/src/gallium/state_trackers/clover/util/pointer.hpp b/src/gallium/state_trackers/clover/util/pointer.hpp deleted file mode 100644 index 7bb9951aef6..00000000000 --- a/src/gallium/state_trackers/clover/util/pointer.hpp +++ /dev/null @@ -1,284 +0,0 @@ -// -// Copyright 2013 Francisco Jerez -// -// Permission is hereby granted, free of charge, to any person obtaining a -// copy of this software and associated documentation files (the "Software"), -// to deal in the Software without restriction, including without limitation -// the rights to use, copy, modify, merge, publish, distribute, sublicense, -// and/or sell copies of the Software, and to permit persons to whom the -// Software is furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL -// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR -// OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, -// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR -// OTHER DEALINGS IN THE SOFTWARE. -// - -#ifndef CLOVER_UTIL_POINTER_HPP -#define CLOVER_UTIL_POINTER_HPP - -#include <atomic> - -namespace clover { - /// - /// Some helper functions for raw pointer operations - /// - template <class T> - static bool - ptr_is_aligned(const T *ptr, uintptr_t a) noexcept { - assert(a == (a & -a)); - uintptr_t ptr_value = reinterpret_cast<uintptr_t>(ptr); - return (ptr_value & (a - 1)) == 0; - } - - /// - /// Base class for objects that support reference counting. - /// - class ref_counter { - public: - ref_counter(unsigned value = 1) : _ref_count(value) {} - - unsigned - ref_count() const { - return _ref_count; - } - - void - retain() { - _ref_count++; - } - - bool - release() { - return (--_ref_count) == 0; - } - - private: - std::atomic<unsigned> _ref_count; - }; - - /// - /// Simple reference to a clover::ref_counter object. Unlike - /// clover::intrusive_ptr and clover::intrusive_ref, it does nothing - /// special when the reference count drops to zero. - /// - class ref_holder { - public: - ref_holder(ref_counter &o) : p(&o) { - p->retain(); - } - - ref_holder(const ref_holder &ref) : - ref_holder(*ref.p) { - } - - ref_holder(ref_holder &&ref) : - p(ref.p) { - ref.p = NULL; - } - - ~ref_holder() { - if (p) - p->release(); - } - - ref_holder & - operator=(ref_holder ref) { - std::swap(ref.p, p); - return *this; - } - - bool - operator==(const ref_holder &ref) const { - return p == ref.p; - } - - bool - operator!=(const ref_holder &ref) const { - return p != ref.p; - } - - private: - ref_counter *p; - }; - - /// - /// Intrusive smart pointer for objects that implement the - /// clover::ref_counter interface. - /// - template<typename T> - class intrusive_ptr { - public: - intrusive_ptr(T *q = NULL) : p(q) { - if (p) - p->retain(); - } - - intrusive_ptr(const intrusive_ptr &ptr) : - intrusive_ptr(ptr.p) { - } - - intrusive_ptr(intrusive_ptr &&ptr) : - p(ptr.p) { - ptr.p = NULL; - } - - ~intrusive_ptr() { - if (p && p->release()) - delete p; - } - - intrusive_ptr & - operator=(intrusive_ptr ptr) { - std::swap(ptr.p, p); - return *this; - } - - bool - operator==(const intrusive_ptr &ref) const { - return p == ref.p; - } - - bool - operator!=(const intrusive_ptr &ref) const { - return p != ref.p; - } - - T & - operator*() const { - return *p; - } - - T * - operator->() const { - return p; - } - - T * - operator()() const { - return p; - } - - explicit operator bool() const { - return p; - } - - explicit operator T *() const { - return p; - } - - private: - T *p; - }; - - /// - /// Intrusive smart reference for objects that implement the - /// clover::ref_counter interface. - /// - template<typename T> - class intrusive_ref { - public: - intrusive_ref(T &o) : p(&o) { - p->retain(); - } - - intrusive_ref(const intrusive_ref &ref) : - intrusive_ref(*ref.p) { - } - - intrusive_ref(intrusive_ref &&ref) : - p(ref.p) { - ref.p = NULL; - } - - ~intrusive_ref() { - if (p && p->release()) - delete p; - } - - intrusive_ref & - operator=(intrusive_ref ref) { - std::swap(ref.p, p); - return *this; - } - - bool - operator==(const intrusive_ref &ref) const { - return p == ref.p; - } - - bool - operator!=(const intrusive_ref &ref) const { - return p != ref.p; - } - - T & - operator()() const { - return *p; - } - - operator T &() const { - return *p; - } - - private: - T *p; - }; - - /// - /// Initialize a clover::intrusive_ref from a newly created object - /// using the specified constructor arguments. - /// - template<typename T, typename... As> - intrusive_ref<T> - create(As &&... as) { - intrusive_ref<T> ref { *new T(std::forward<As>(as)...) }; - ref().release(); - return ref; - } - - /// - /// Class that implements the usual pointer interface but in fact - /// contains the object it seems to be pointing to. - /// - template<typename T> - class pseudo_ptr { - public: - pseudo_ptr(T x) : x(x) { - } - - pseudo_ptr(const pseudo_ptr &p) : x(p.x) { - } - - pseudo_ptr & - operator=(const pseudo_ptr &p) { - x = p.x; - return *this; - } - - T & - operator*() { - return x; - } - - T * - operator->() { - return &x; - } - - explicit operator bool() const { - return true; - } - - private: - T x; - }; -} - -#endif diff --git a/src/gallium/state_trackers/clover/util/range.hpp b/src/gallium/state_trackers/clover/util/range.hpp deleted file mode 100644 index b082359ee86..00000000000 --- a/src/gallium/state_trackers/clover/util/range.hpp +++ /dev/null @@ -1,419 +0,0 @@ -// -// Copyright 2013 Francisco Jerez -// -// Permission is hereby granted, free of charge, to any person obtaining a -// copy of this software and associated documentation files (the "Software"), -// to deal in the Software without restriction, including without limitation -// the rights to use, copy, modify, merge, publish, distribute, sublicense, -// and/or sell copies of the Software, and to permit persons to whom the -// Software is furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL -// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR -// OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, -// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR -// OTHER DEALINGS IN THE SOFTWARE. -// - -#ifndef CLOVER_UTIL_RANGE_HPP -#define CLOVER_UTIL_RANGE_HPP - -#include <array> -#include <vector> - -#include "util/adaptor.hpp" - -namespace clover { - /// - /// Class that identifies container types where the elements of a - /// range can be stored by the type conversion operator. - /// - /// \a T identifies the range element type. - /// - template<typename T, typename V> - struct range_store_traits; - - template<typename T, typename S> - struct range_store_traits<T, std::vector<S>> { - typedef void enable; - - template<typename R> - static std::vector<S> - create(const R &r) { - return { r.begin(), r.end() }; - } - }; - - template<typename T, typename S, std::size_t N> - struct range_store_traits<T, std::array<S, N>> { - typedef void enable; - - template<typename R> - static std::array<S, N> - create(const R &r) { - std::array<S, N> v; - assert(r.size() == v.size()); - copy(r, v.begin()); - return v; - } - }; - - namespace detail { - /// - /// Common functionality that is shared by other implementations - /// of the container concept. - /// - template<typename R, typename I, typename CI> - class basic_range { - public: - typedef I iterator; - typedef CI const_iterator; - typedef typename std::iterator_traits<iterator>::value_type value_type; - typedef typename std::iterator_traits<iterator>::reference - reference; - typedef typename std::iterator_traits<const_iterator>::reference - const_reference; - typedef typename std::iterator_traits<iterator>::difference_type - difference_type; - typedef std::size_t size_type; - - bool - operator==(const basic_range &r) const { - return *static_cast<const R *>(this) == r; - } - - bool - operator!=(const basic_range &r) const { - return !(*this == r); - } - - iterator - begin() { - return static_cast<R *>(this)->begin(); - } - - iterator - end() { - return static_cast<R *>(this)->end(); - } - - const_iterator - begin() const { - return static_cast<const R *>(this)->begin(); - } - - const_iterator - end() const { - return static_cast<const R *>(this)->end(); - } - - std::reverse_iterator<iterator> - rbegin() { - return { begin() }; - } - - std::reverse_iterator<iterator> - rend() { - return { end() }; - } - - reference - front() { - return *begin(); - } - - reference - back() { - return *(end() - 1); - } - - bool - empty() const { - return begin() == end(); - } - - reference - at(size_type i) { - if (i >= static_cast<const R *>(this)->size()) - throw std::out_of_range(""); - - return begin()[i]; - } - - const_reference - at(size_type i) const { - if (i >= static_cast<const R *>(this)->size()) - throw std::out_of_range(""); - - return begin()[i]; - } - - reference - operator[](size_type i) { - return begin()[i]; - } - - const_reference - operator[](size_type i) const { - return begin()[i]; - } - - template<typename V> - using store_traits = range_store_traits< - typename std::remove_cv<value_type>::type, V - >; - - template<typename V, - typename = typename store_traits<V>::enable> - operator V() const { - return store_traits<V>::create(*static_cast<const R *>(this)); - } - }; - } - - /// - /// Range that contains all elements delimited by an iterator pair - /// (\a i, \a j). Use range() as convenience constructor. - /// - template<typename I> - class iterator_range : public detail::basic_range<iterator_range<I>, I, I> { - public: - typedef detail::basic_range<iterator_range<I>, I, I> super; - - iterator_range() : i(), j() { - } - - iterator_range(I i, I j) : i(i), j(j) { - } - - bool - operator==(const iterator_range &r) const { - return i == r.i && j == r.j; - } - - I - begin() const { - return i; - } - - I - end() const { - return j; - } - - typename super::size_type - size() const { - return end() - begin(); - } - - private: - I i, j; - }; - - namespace detail { - template<typename T> - using preferred_iterator_type = decltype(std::declval<T>().begin()); - } - - /// - /// Range that transforms the contents of a number of source ranges - /// \a os element-wise by using the provided functor \a f. Use - /// map() as convenience constructor. - /// - template<typename F, typename... Os> - class adaptor_range : - public detail::basic_range<adaptor_range<F, Os...>, - detail::iterator_adaptor< - F, detail::preferred_iterator_type<Os>...>, - detail::iterator_adaptor< - F, detail::preferred_iterator_type<const Os>...> - > { - public: - typedef detail::basic_range<adaptor_range<F, Os...>, - detail::iterator_adaptor< - F, detail::preferred_iterator_type<Os>...>, - detail::iterator_adaptor< - F, detail::preferred_iterator_type<const Os>...> - > super; - - template<typename G, typename... Rs> - adaptor_range(G &&f, Rs &&... os) : - f(std::forward<G>(f)), os(std::forward<Rs>(os)...) { - } - - bool - operator==(const adaptor_range &r) const { - return f == r.f && os == r.os; - } - - typename super::iterator - begin() { - return { f, tuple::map(begins(), os) }; - } - - typename super::iterator - end() { - return { f, tuple::map(advances_by(size()), - tuple::map(begins(), os)) }; - } - - typename super::const_iterator - begin() const { - return { f, tuple::map(begins(), os) }; - } - - typename super::const_iterator - end() const { - return { f, tuple::map(advances_by(size()), - tuple::map(begins(), os)) }; - } - - typename super::size_type - size() const { - return tuple::apply(minimum(), tuple::map(sizes(), os)); - } - - private: - F f; - std::tuple<Os...> os; - }; - - /// - /// Range that contains all elements delimited by the index pair - /// (\a i, \a j) in the source range \a r. Use slice() as - /// convenience constructor. - /// - template<typename O> - class slice_range : - public detail::basic_range<slice_range<O>, - detail::preferred_iterator_type<O>, - detail::preferred_iterator_type<const O>> { - public: - typedef detail::basic_range<slice_range<O>, - detail::preferred_iterator_type<O>, - detail::preferred_iterator_type<const O> - > super; - - template<typename R> - slice_range(R &&r, typename super::size_type i, - typename super::size_type j) : - o(std::forward<R>(r)), i(i), j(j) { - } - - bool - operator==(const slice_range &r) const { - return o == r.o && i == r.i && j == r.j; - } - - typename super::iterator - begin() { - return std::next(o.begin(), i); - } - - typename super::iterator - end() { - return std::next(o.begin(), j); - } - - typename super::const_iterator - begin() const { - return std::next(o.begin(), i); - } - - typename super::const_iterator - end() const { - return std::next(o.begin(), j); - } - - typename super::size_type - size() const { - return j - i; - } - - private: - O o; - typename super::size_type i, j; - }; - - /// - /// Create a range from an iterator pair (\a i, \a j). - /// - /// \sa iterator_range. - /// - template<typename T> - iterator_range<T> - range(T i, T j) { - return { i, j }; - } - - /// - /// Create a range of \a n elements starting from iterator \a i. - /// - /// \sa iterator_range. - /// - template<typename T> - iterator_range<T> - range(T i, typename std::iterator_traits<T>::difference_type n) { - return { i, i + n }; - } - - /// - /// Create a range by transforming the contents of a number of - /// source ranges \a rs element-wise using a provided functor \a f. - /// - /// \sa adaptor_range. - /// - template<typename F, typename... Rs> - adaptor_range<F, Rs...> - map(F &&f, Rs &&... rs) { - return { std::forward<F>(f), std::forward<Rs>(rs)... }; - } - - /// - /// Create a range identical to another range \a r. - /// - template<typename R> - adaptor_range<identity, R> - range(R &&r) { - return { identity(), std::forward<R>(r) }; - } - - /// - /// Create a range by taking the elements delimited by the index - /// pair (\a i, \a j) in a source range \a r. - /// - /// \sa slice_range. - /// - template<typename R> - slice_range<R> - slice(R &&r, typename slice_range<R>::size_type i, - typename slice_range<R>::size_type j) { - return { std::forward<R>(r), i, j }; - } - - /// - /// Range that behaves as a vector of references of type \a T. - /// - /// Useful because STL containers cannot contain references to - /// objects as elements. - /// - template<typename T> - class ref_vector : public adaptor_range<derefs, std::vector<T *>> { - public: - ref_vector(std::initializer_list<std::reference_wrapper<T>> il) : - adaptor_range<derefs, std::vector<T *>>(derefs(), map(addresses(), il)) { - } - - template<typename R> - ref_vector(R &&r) : adaptor_range<derefs, std::vector<T *>>( - derefs(), map(addresses(), std::forward<R>(r))) { - } - }; -} - -#endif diff --git a/src/gallium/state_trackers/clover/util/tuple.hpp b/src/gallium/state_trackers/clover/util/tuple.hpp deleted file mode 100644 index bd49684a314..00000000000 --- a/src/gallium/state_trackers/clover/util/tuple.hpp +++ /dev/null @@ -1,117 +0,0 @@ -// -// Copyright 2013 Francisco Jerez -// -// Permission is hereby granted, free of charge, to any person obtaining a -// copy of this software and associated documentation files (the "Software"), -// to deal in the Software without restriction, including without limitation -// the rights to use, copy, modify, merge, publish, distribute, sublicense, -// and/or sell copies of the Software, and to permit persons to whom the -// Software is furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL -// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR -// OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, -// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR -// OTHER DEALINGS IN THE SOFTWARE. -// - -#ifndef CLOVER_UTIL_TUPLE_HPP -#define CLOVER_UTIL_TUPLE_HPP - -#include <tuple> - -namespace clover { - namespace tuple { - /// - /// Static sequence of integers. - /// - template<int... Is> - struct integral_sequence; - - /// - /// Static sequence containing all integers from 0 to N-1. - /// - template<int N, int... Is> - struct enumerate { - typedef typename enumerate<N-1, N-1, Is...>::type - type; - }; - - template<int... Is> - struct enumerate<0, Is...> { - typedef integral_sequence<Is...> type; - }; - - namespace detail { - template<typename F, typename T, - typename E = typename enumerate<std::tuple_size< - typename std::remove_reference<T>::type>::value - >::type> - struct _apply; - - template<typename F, typename T, int... Is> - struct _apply<F, T, integral_sequence<Is...>> { - typedef typename std::remove_reference<F>::type func_type; - typedef decltype( - std::declval<func_type>()(std::get<Is>(std::declval<T &&>())...) - ) value_type; - - static value_type - eval(F &&f, T &&t) { - return f(std::get<Is>(std::forward<T>(t))...); - } - }; - } - - /// - /// Evaluate function \a f with the elements of tuple \a t - /// expanded as arguments. - /// - template<typename F, typename T> - typename detail::_apply<F, T>::value_type - apply(F &&f, T &&t) { - return detail::_apply<F, T>::eval(std::forward<F>(f), - std::forward<T>(t)); - } - - namespace detail { - template<typename F, typename T, - typename E = typename enumerate<std::tuple_size< - typename std::remove_reference<T>::type>::value - >::type> - struct _map; - - template<typename F, typename T, int... Is> - struct _map<F, T, integral_sequence<Is...>> { - typedef typename std::remove_reference<F>::type func_type; - typedef std::tuple< - decltype(std::declval<func_type>()( - std::get<Is>(std::declval<T &&>())))... - > value_type; - - static value_type - eval(F &&f, T &&t) { - return value_type(f(std::get<Is>(std::forward<T>(t)))...); - } - }; - } - - /// - /// Evaluate function \a f on each element of the tuple \a t and - /// return the resulting values as a new tuple. - /// - template<typename F, typename T> - typename detail::_map<F, T>::value_type - map(F &&f, T &&t) { - return detail::_map<F, T>::eval(std::forward<F>(f), - std::forward<T>(t)); - } - } -} - -#endif |