Merge remote-tracking branch 'aosp/upstream-master' into 20180302-merge-android_layers_to_master
Change-Id: I5b213c9c6e83929a921f9f2bae17a98d294745d2
diff --git a/Android.bp b/Android.bp
new file mode 100644
index 0000000..e95bc5d
--- /dev/null
+++ b/Android.bp
@@ -0,0 +1,4 @@
+subdirs = [
+ "libs/cjson",
+ "libs/vkjson",
+]
diff --git a/Android.mk b/Android.mk
new file mode 100644
index 0000000..c948812
--- /dev/null
+++ b/Android.mk
@@ -0,0 +1,2 @@
+# Leave this Android.mk empty, deleting it unmasks
+# invalid Android.mks in subdirectories.
diff --git a/MODULE_LICENSE_APACHE2 b/MODULE_LICENSE_APACHE2
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/MODULE_LICENSE_APACHE2
diff --git a/NOTICE b/NOTICE
new file mode 100644
index 0000000..3c65815
--- /dev/null
+++ b/NOTICE
@@ -0,0 +1,170 @@
+Apache License
+
+Version 2.0, January 2004
+
+http://www.apache.org/licenses/
+
+TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+1. Definitions.
+
+"License" shall mean the terms and conditions for use, reproduction, and distribution as
+defined by Sections 1 through 9 of this document.
+
+"Licensor" shall mean the copyright owner or entity authorized by the copyright owner
+that is granting the License.
+
+"Legal Entity" shall mean the union of the acting entity and all other entities that
+control, are controlled by, or are under common control with that entity. For the
+purposes of this definition, "control" means (i) the power, direct or indirect, to
+cause the direction or management of such entity, whether by contract or otherwise,
+or (ii) ownership of fifty percent (50%) or more of the outstanding shares, or
+(iii) beneficial ownership of such entity.
+
+"You" (or "Your") shall mean an individual or Legal Entity exercising permissions
+granted by this License.
+
+"Source" form shall mean the preferred form for making modifications, including but not
+limited to software source code, documentation source, and configuration files.
+
+"Object" form shall mean any form resulting from mechanical transformation or
+translation of a Source form, including but not limited to compiled object code,
+generated documentation, and conversions to other media types.
+
+"Work" shall mean the work of authorship, whether in Source or Object form, made
+available under the License, as indicated by a copyright notice that is included in or
+attached to the work (an example is provided in the Appendix below).
+
+"Derivative Works" shall mean any work, whether in Source or Object form, that is based
+on (or derived from) the Work and for which the editorial revisions, annotations,
+elaborations, or other modifications represent, as a whole, an original work of
+authorship. For the purposes of this License, Derivative Works shall not include works
+that remain separable from, or merely link (or bind by name) to the interfaces of, the
+Work and Derivative Works thereof.
+
+"Contribution" shall mean any work of authorship, including the original version of the
+Work and any modifications or additions to that Work or Derivative Works thereof, that
+is intentionally submitted to Licensor for inclusion in the Work by the copyright owner
+or by an individual or Legal Entity authorized to submit on behalf of the copyright owner.
+For the purposes of this definition, "submitted" means any form of electronic, verbal,
+or written communication sent to the Licensor or its representatives, including but not
+limited to communication on electronic mailing lists, source code control systems, and
+issue tracking systems that are managed by, or on behalf of, the Licensor for the purpose
+of discussing and improving the Work, but excluding communication that is conspicuously
+marked or otherwise designated in writing by the copyright owner as "Not a Contribution."
+
+"Contributor" shall mean Licensor and any individual or Legal Entity on behalf of whom a
+Contribution has been received by Licensor and subsequently incorporated within the Work.
+
+2. Grant of Copyright License. Subject to the terms and conditions of this License, each
+Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge,
+royalty-free, irrevocable copyright license to reproduce, prepare Derivative Works of,
+publicly display, publicly perform, sublicense, and distribute the Work and such
+Derivative Works in Source or Object form.
+
+3. Grant of Patent License. Subject to the terms and conditions of this License, each
+Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge,
+royalty-free, irrevocable (except as stated in this section) patent license to make,
+have made, use, offer to sell, sell, import, and otherwise transfer the Work, where such
+license applies only to those patent claims licensable by such Contributor that are
+necessarily infringed by their Contribution(s) alone or by combination of their
+Contribution(s) with the Work to which such Contribution(s) was submitted. If You
+institute patent litigation against any entity (including a cross-claim or counterclaim
+in a lawsuit) alleging that the Work or a Contribution incorporated within the Work
+constitutes direct or contributory patent infringement, then any patent licenses granted
+to You under this License for that Work shall terminate as of the date such litigation
+is filed.
+
+4. Redistribution. You may reproduce and distribute copies of the Work or Derivative
+Works thereof in any medium, with or without modifications, and in Source or Object form,
+provided that You meet the following conditions:
+
+You must give any other recipients of the Work or Derivative Works a copy of this
+License; and
+You must cause any modified files to carry prominent notices stating that You changed
+the files; and
+You must retain, in the Source form of any Derivative Works that You distribute, all
+copyright, patent, trademark, and attribution notices from the Source form of the Work,
+excluding those notices that do not pertain to any part of the Derivative Works; and
+If the Work includes a "NOTICE" text file as part of its distribution, then any
+Derivative Works that You distribute must include a readable copy of the attribution
+notices contained within such NOTICE file, excluding those notices that do not pertain
+to any part of the Derivative Works, in at least one of the following places: within a
+NOTICE text file distributed as part of the Derivative Works; within the Source form or
+documentation, if provided along with the Derivative Works; or, within a display
+generated by the Derivative Works, if and wherever such third-party notices normally
+appear. The contents of the NOTICE file are for informational purposes only and do not
+modify the License. You may add Your own attribution notices within Derivative Works
+that You distribute, alongside or as an addendum to the NOTICE text from the Work,
+provided that such additional attribution notices cannot be construed as modifying
+the License.
+
+You may add Your own copyright statement to Your modifications and may provide
+additional or different license terms and conditions for use, reproduction, or
+distribution of Your modifications, or for any such Derivative Works as a whole,
+provided Your use, reproduction, and distribution of the Work otherwise complies with
+the conditions stated in this License.
+
+5. Submission of Contributions. Unless You explicitly state otherwise, any Contribution
+intentionally submitted for inclusion in the Work by You to the Licensor shall be under
+the terms and conditions of this License, without any additional terms or conditions.
+Notwithstanding the above, nothing herein shall supersede or modify the terms of any
+separate license agreement you may have executed with Licensor regarding such
+Contributions.
+
+6. Trademarks. This License does not grant permission to use the trade names,
+trademarks, service marks, or product names of the Licensor, except as required for
+reasonable and customary use in describing the origin of the Work and reproducing the
+content of the NOTICE file.
+
+7. Disclaimer of Warranty. Unless required by applicable law or agreed to in writing,
+Licensor provides the Work (and each Contributor provides its Contributions) on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied,
+ including, without limitation, any warranties or conditions of TITLE, NON-INFRINGEMENT,
+ MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are solely responsible for
+ determining the appropriateness of using or redistributing the Work and assume any
+ risks associated with Your exercise of permissions under this License.
+
+8. Limitation of Liability. In no event and under no legal theory, whether in tort
+(including negligence), contract, or otherwise, unless required by applicable law (such
+as deliberate and grossly negligent acts) or agreed to in writing, shall any Contributor
+be liable to You for damages, including any direct, indirect, special, incidental, or
+consequential damages of any character arising as a result of this License or out of the
+use or inability to use the Work (including but not limited to damages for loss of
+goodwill, work stoppage, computer failure or malfunction, or any and all other
+commercial damages or losses), even if such Contributor has been advised of the
+possibility of such damages.
+
+9. Accepting Warranty or Additional Liability. While redistributing the Work or
+Derivative Works thereof, You may choose to offer, and charge a fee for, acceptance of
+support, warranty, indemnity, or other liability obligations and/or rights consistent
+with this License. However, in accepting such obligations, You may act only on Your own
+behalf and on Your sole responsibility, not on behalf of any other Contributor, and only
+if You agree to indemnify, defend, and hold each Contributor harmless for any liability
+incurred by, or claims asserted against, such Contributor by reason of your accepting
+any such warranty or additional liability.
+
+END OF TERMS AND CONDITIONS
+
+APPENDIX: HOW TO APPLY THE APACHE LICENSE TO YOUR WORK
+To apply the Apache License to your work, attach the following boilerplate notice, with
+the fields enclosed by brackets "[]" replaced with your own identifying information.
+(Don't include the brackets!) The text should be enclosed in the appropriate comment
+syntax for the file format. We also recommend that a file or class name and description
+of purpose be included on the same "printed page" as the copyright notice for easier
+identification within third-party archives.
+
+Copyright [yyyy] [name of copyright owner]
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+
diff --git a/build-android/android-generate.sh b/build-android/android-generate.sh
index 0c0f5e1..4fa5a5c 100755
--- a/build-android/android-generate.sh
+++ b/build-android/android-generate.sh
@@ -59,7 +59,7 @@
echo No spirv-tools git_dir found, generating UUID for external_revision_generator.py
# Ensure uuidgen is installed, this should error if not found
- uuidgen --v
+ type uuidgen
uuidgen > $SPIRV_TOOLS_UUID;
cat $SPIRV_TOOLS_UUID;
diff --git a/build-android/build.py b/build-android/build.py
new file mode 100755
index 0000000..05af005
--- /dev/null
+++ b/build-android/build.py
@@ -0,0 +1,300 @@
+#!/usr/bin/env python
+#
+# Copyright (C) 2015 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+import argparse
+import multiprocessing
+import os
+import shutil
+import subprocess
+import sys
+import time
+
+from subprocess import PIPE, STDOUT
+
+def install_file(file_name, src_dir, dst_dir):
+ src_file = os.path.join(src_dir, file_name)
+ dst_file = os.path.join(dst_dir, file_name)
+
+ print('Copying {} to {}...'.format(src_file, dst_file))
+ if os.path.isdir(src_file):
+ _install_dir(src_file, dst_file)
+ elif os.path.islink(src_file):
+ _install_symlink(src_file, dst_file)
+ else:
+ _install_file(src_file, dst_file)
+
+
+def _install_dir(src_dir, dst_dir):
+ parent_dir = os.path.normpath(os.path.join(dst_dir, '..'))
+ if not os.path.exists(parent_dir):
+ os.makedirs(parent_dir)
+ shutil.copytree(src_dir, dst_dir, symlinks=True)
+
+
+def _install_symlink(src_file, dst_file):
+ dirname = os.path.dirname(dst_file)
+ if not os.path.exists(dirname):
+ os.makedirs(dirname)
+ link_target = os.readlink(src_file)
+ os.symlink(link_target, dst_file)
+
+
+def _install_file(src_file, dst_file):
+ dirname = os.path.dirname(dst_file)
+ if not os.path.exists(dirname):
+ os.makedirs(dirname)
+ # copy2 is just copy followed by copystat (preserves file metadata).
+ shutil.copy2(src_file, dst_file)
+
+THIS_DIR = os.path.realpath(os.path.dirname(__file__))
+
+ALL_ARCHITECTURES = (
+ 'arm',
+ 'arm64',
+ 'mips',
+ 'mips64',
+ 'x86',
+ 'x86_64',
+)
+
+# According to vk_platform.h, armeabi is not supported for Vulkan
+# so remove it from the abis list.
+ALL_ABIS = (
+ 'armeabi-v7a',
+ 'arm64-v8a',
+ 'mips',
+ 'mips64',
+ 'x86',
+ 'x86_64',
+)
+
+def jobs_arg():
+ return '-j{}'.format(multiprocessing.cpu_count() * 2)
+
+def arch_to_abis(arch):
+ return {
+ 'arm': ['armeabi-v7a'],
+ 'arm64': ['arm64-v8a'],
+ 'mips': ['mips'],
+ 'mips64': ['mips64'],
+ 'x86': ['x86'],
+ 'x86_64': ['x86_64'],
+ }[arch]
+
+class ArgParser(argparse.ArgumentParser):
+ def __init__(self):
+ super(ArgParser, self).__init__()
+
+ self.add_argument(
+ '--out-dir', help='Directory to place temporary build files.',
+ type=os.path.realpath, default=os.path.join(THIS_DIR, 'out'))
+
+ self.add_argument(
+ '--arch', choices=ALL_ARCHITECTURES,
+ help='Architectures to build. Builds all if not present.')
+
+ self.add_argument('--installdir', dest='installdir', required=True,
+ help='Installation directory. Required.')
+
+ # The default for --dist-dir has to be handled after parsing all
+ # arguments because the default is derived from --out-dir. This is
+ # handled in run().
+ self.add_argument(
+ '--dist-dir', help='Directory to place the packaged artifact.',
+ type=os.path.realpath)
+
+
+def main():
+ print('THIS_DIR: %s' % THIS_DIR)
+ parser = ArgParser()
+ args = parser.parse_args()
+
+ arches = ALL_ARCHITECTURES
+ if args.arch is not None:
+ arches = [args.arch]
+
+ # Make paths absolute, and ensure directories exist.
+ installdir = os.path.abspath(args.installdir)
+
+ abis = []
+ for arch in arches:
+ abis.extend(arch_to_abis(arch))
+
+ shaderc_path = installdir + '/shaderc/android_test'
+ print('shaderc_path = %s' % shaderc_path)
+
+ ndk_dir = os.path.join(THIS_DIR, '../../../prebuilts/toolchain')
+
+ ndk_build = os.path.join(ndk_dir, 'ndk-build')
+ platforms_root = os.path.join(ndk_dir, 'platforms')
+ toolchains_root = os.path.join(ndk_dir, 'toolchains')
+ build_dir = THIS_DIR
+
+ print('installdir: %s' % installdir)
+ print('ndk_dir: %s' % ndk_dir)
+ print('ndk_build: %s' % ndk_build)
+ print('platforms_root: %s' % platforms_root)
+
+ compiler = 'clang'
+ stl = 'c++_static'
+ obj_out = os.path.join(THIS_DIR, stl, 'obj')
+ lib_out = os.path.join(THIS_DIR, 'jniLibs')
+
+ print('obj_out: %s' % obj_out)
+ print('lib_out: %s' % lib_out)
+
+ print('Constructing shaderc build tree...')
+ shaderc_root_dir = os.path.join(THIS_DIR, '../../shaderc')
+
+ copies = [
+ {
+ 'source_dir': os.path.join(shaderc_root_dir, 'shaderc'),
+ 'dest_dir': 'third_party/shaderc',
+ 'files': [
+ 'Android.mk', 'libshaderc/Android.mk',
+ 'libshaderc_util/Android.mk',
+ 'third_party/Android.mk',
+ 'utils/update_build_version.py',
+ 'CHANGES',
+ ],
+ 'dirs': [
+ 'libshaderc/include', 'libshaderc/src',
+ 'libshaderc_util/include', 'libshaderc_util/src',
+ 'android_test'
+ ],
+ },
+ {
+ 'source_dir': os.path.join(shaderc_root_dir, 'spirv-tools'),
+ 'dest_dir': 'third_party/shaderc/third_party/spirv-tools',
+ 'files': [
+ 'utils/generate_grammar_tables.py',
+ 'utils/generate_language_headers.py',
+ 'utils/generate_registry_tables.py',
+ 'utils/update_build_version.py',
+ 'Android.mk',
+ 'CHANGES',
+ ],
+ 'dirs': ['include', 'source'],
+ },
+ {
+ 'source_dir': os.path.join(shaderc_root_dir, 'spirv-headers'),
+ 'dest_dir':
+ 'third_party/shaderc/third_party/spirv-tools/external/spirv-headers',
+ 'dirs': ['include',],
+ 'files': [
+ 'include/spirv/1.0/spirv.py',
+ 'include/spirv/1.1/spirv.py',
+ 'include/spirv/1.2/spirv.py',
+ ],
+ },
+ {
+ 'source_dir': os.path.join(shaderc_root_dir, 'glslang'),
+ 'dest_dir': 'third_party/shaderc/third_party/glslang',
+ 'files': ['glslang/OSDependent/osinclude.h'],
+ 'dirs': [
+ 'SPIRV',
+ 'OGLCompilersDLL',
+ 'glslang/GenericCodeGen',
+ 'hlsl',
+ 'glslang/Include',
+ 'glslang/MachineIndependent',
+ 'glslang/OSDependent/Unix',
+ 'glslang/Public',
+ ],
+ },
+ ]
+
+ default_ignore_patterns = shutil.ignore_patterns(
+ "*CMakeLists.txt",
+ "*.py",
+ "*test.h",
+ "*test.cc")
+
+ for properties in copies:
+ source_dir = properties['source_dir']
+ dest_dir = os.path.join(installdir, properties['dest_dir'])
+ for d in properties['dirs']:
+ src = os.path.join(source_dir, d)
+ dst = os.path.join(dest_dir, d)
+ print(src, " -> ", dst)
+ shutil.copytree(src, dst,
+ ignore=default_ignore_patterns)
+ for f in properties['files']:
+ print(source_dir, ':', dest_dir, ":", f)
+ # Only copy if the source file exists. That way
+ # we can update this script in anticipation of
+ # source files yet-to-come.
+ if os.path.exists(os.path.join(source_dir, f)):
+ install_file(f, source_dir, dest_dir)
+ else:
+ print(source_dir, ':', dest_dir, ":", f, "SKIPPED")
+
+ print('Constructing Vulkan validation layer source...')
+
+ build_cmd = [
+ 'bash', THIS_DIR + '/android-generate.sh'
+ ]
+ print('Generating generated layers...')
+ subprocess.check_call(build_cmd)
+ print('Generation finished')
+
+ build_cmd = [
+ 'bash', ndk_build, '-C', build_dir,
+ jobs_arg(),
+ 'APP_ABI=' + ' '.join(abis),
+ # Use the prebuilt platforms and toolchains.
+ 'NDK_PLATFORMS_ROOT=' + platforms_root,
+ 'NDK_TOOLCHAINS_ROOT=' + toolchains_root,
+ 'NDK_MODULE_PATH=' + installdir,
+ 'GNUSTL_PREFIX=',
+ 'APP_STL=' + stl,
+ 'NDK_TOOLCHAIN_VERSION=' + compiler,
+
+ # Tell ndk-build where to put the results
+ 'NDK_OUT=' + obj_out,
+ 'NDK_LIBS_OUT=' + lib_out,
+ ]
+
+ print('Building Vulkan validation layers for ABIs:' +
+ ' {}'.format(', '.join(abis)) + "...")
+ print(' '.join(build_cmd))
+
+ subprocess.check_call(build_cmd)
+
+ print('Finished building Vulkan validation layers')
+ out_package = os.path.join(installdir, 'vulkan_validation_layers.zip')
+ os.chdir(lib_out)
+ build_cmd = [
+ 'zip', '-9qr', out_package, "."
+ ]
+
+ print('Packaging Vulkan validation layers')
+ subprocess.check_call(build_cmd)
+ print('Finished Packaging Vulkan validation layers')
+
+ for properties in copies:
+ dest_dir = os.path.join(installdir, properties['dest_dir'])
+ for d in properties['dirs']:
+ dst = os.path.join(dest_dir, d)
+ print('Remove: %s' % dst)
+ shutil.rmtree(dst)
+
+ return 0
+
+
+if __name__ == '__main__':
+ main()
diff --git a/build-android/jni/Android.mk b/build-android/jni/Android.mk
index 2915de1..cbdc8c1 100644
--- a/build-android/jni/Android.mk
+++ b/build-android/jni/Android.mk
@@ -165,8 +165,9 @@
LOCAL_SRC_FILES += $(SRC_DIR)/libs/vkjson/vkjson.cc \
$(SRC_DIR)/libs/vkjson/vkjson_instance.cc \
$(SRC_DIR)/common/vulkan_wrapper.cpp \
- $(SRC_DIR)/loader/cJSON.c
+ $(SRC_DIR)/libs/cjson/cJSON.c
LOCAL_C_INCLUDES += $(LOCAL_PATH)/$(SRC_DIR)/include \
+ $(LOCAL_PATH)/$(SRC_DIR)/libs/cjson/includes \
$(LOCAL_PATH)/$(SRC_DIR)/loader
LOCAL_CPPFLAGS += -std=c++11 -DVK_PROTOTYPES -Wall -Werror -Wno-unused-function -Wno-unused-const-variable
diff --git a/libs/cjson/Android.bp b/libs/cjson/Android.bp
new file mode 100644
index 0000000..6a1600c
--- /dev/null
+++ b/libs/cjson/Android.bp
@@ -0,0 +1,36 @@
+cc_library_static {
+ name: "cjson",
+ clang: true,
+ srcs: [
+ "cJSON.c",
+ ],
+ cflags: [
+ "-Wall",
+ "-Werror",
+ ],
+ local_include_dirs: [
+ "includes",
+ ],
+ export_include_dirs: [
+ "includes",
+ ],
+}
+
+cc_library_static {
+ name: "cjson_ndk",
+ clang: true,
+ srcs: [
+ "cJSON.c",
+ ],
+ cflags: [
+ "-Wall",
+ "-Werror",
+ ],
+ local_include_dirs: [
+ "includes",
+ ],
+ export_include_dirs: [
+ "includes",
+ ],
+ sdk_version: "24",
+}
diff --git a/loader/cJSON.c b/libs/cjson/cJSON.c
similarity index 100%
rename from loader/cJSON.c
rename to libs/cjson/cJSON.c
diff --git a/loader/cJSON.h b/libs/cjson/includes/cJSON.h
similarity index 100%
rename from loader/cJSON.h
rename to libs/cjson/includes/cJSON.h
diff --git a/libs/vkjson/Android.bp b/libs/vkjson/Android.bp
new file mode 100644
index 0000000..1b32e7a
--- /dev/null
+++ b/libs/vkjson/Android.bp
@@ -0,0 +1,52 @@
+cc_library_static {
+ name: "libvkjson",
+ srcs: [
+ "vkjson.cc",
+ "vkjson_instance.cc",
+ ],
+ cflags: [
+ "-Wall",
+ "-Werror",
+ ],
+ cppflags: [
+ "-std=c++11",
+ "-Wno-sign-compare",
+ ],
+ export_include_dirs: [
+ ".",
+ ],
+ whole_static_libs: [
+ "cjson",
+ ],
+ header_libs: [
+ "vulkan_headers",
+ ],
+}
+
+cc_library_static {
+ name: "libvkjson_ndk",
+ clang: true,
+ srcs: [
+ "vkjson.cc",
+ "vkjson_instance.cc",
+ ],
+ cflags: [
+ "-Wall",
+ "-Werror",
+ ],
+ cppflags: [
+ "-std=c++11",
+ "-Wno-sign-compare",
+ ],
+ export_include_dirs: [
+ ".",
+ ],
+ whole_static_libs: [
+ "cjson_ndk",
+ ],
+ header_libs: [
+ "vulkan_headers_ndk",
+ ],
+ sdk_version: "24",
+ stl: "libc++_static",
+}
diff --git a/libs/vkjson/CMakeLists.txt b/libs/vkjson/CMakeLists.txt
index 2e79d91..80357b2 100644
--- a/libs/vkjson/CMakeLists.txt
+++ b/libs/vkjson/CMakeLists.txt
@@ -23,9 +23,10 @@
${CMAKE_CURRENT_SOURCE_DIR}
${CMAKE_CURRENT_SOURCE_DIR}/../../loader
${CMAKE_CURRENT_SOURCE_DIR}/../../include/vulkan
+ ${CMAKE_CURRENT_SOURCE_DIR}/../../libs/cjson/includes
)
-add_library(vkjson STATIC vkjson.cc vkjson_instance.cc ../../loader/cJSON.c)
+add_library(vkjson STATIC vkjson.cc vkjson_instance.cc ../../libs/cjson/cJSON.c)
if(UNIX)
set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wno-sign-compare")
diff --git a/libs/vkjson/vkjson.cc b/libs/vkjson/vkjson.cc
index 177be92..c41a247 100644
--- a/libs/vkjson/vkjson.cc
+++ b/libs/vkjson/vkjson.cc
@@ -34,7 +34,6 @@
#include <utility>
#include <cJSON.h>
-#include <vulkan/vk_sdk_platform.h>
namespace {
@@ -277,6 +276,14 @@
}
template <typename Visitor>
+inline bool Iterate(Visitor* visitor,
+ VkPhysicalDeviceVariablePointerFeaturesKHR* features) {
+ return visitor->Visit("variablePointersStorageBuffer",
+ &features->variablePointersStorageBuffer) &&
+ visitor->Visit("variablePointers", &features->variablePointers);
+}
+
+template <typename Visitor>
inline bool Iterate(Visitor* visitor, VkMemoryType* type) {
return
visitor->Visit("propertyFlags", &type->propertyFlags) &&
@@ -342,6 +349,8 @@
inline bool Iterate(Visitor* visitor, VkJsonDevice* device) {
return visitor->Visit("properties", &device->properties) &&
visitor->Visit("features", &device->features) &&
+ visitor->Visit("variablePointersFeaturesKHR",
+ &device->variable_pointer_features) &&
visitor->Visit("memory", &device->memory) &&
visitor->Visit("queues", &device->queues) &&
visitor->Visit("extensions", &device->extensions) &&
diff --git a/libs/vkjson/vkjson.h b/libs/vkjson/vkjson.h
index b703750..af3b37f 100644
--- a/libs/vkjson/vkjson.h
+++ b/libs/vkjson/vkjson.h
@@ -42,10 +42,13 @@
VkJsonDevice() {
memset(&properties, 0, sizeof(VkPhysicalDeviceProperties));
memset(&features, 0, sizeof(VkPhysicalDeviceFeatures));
+ memset(&variable_pointer_features, 0,
+ sizeof(VkPhysicalDeviceVariablePointerFeaturesKHR));
memset(&memory, 0, sizeof(VkPhysicalDeviceMemoryProperties));
}
VkPhysicalDeviceProperties properties;
VkPhysicalDeviceFeatures features;
+ VkPhysicalDeviceVariablePointerFeaturesKHR variable_pointer_features;
VkPhysicalDeviceMemoryProperties memory;
std::vector<VkQueueFamilyProperties> queues;
std::vector<VkExtensionProperties> extensions;
@@ -65,7 +68,10 @@
VkJsonInstance* instance,
std::string* errors);
-VkJsonDevice VkJsonGetDevice(VkPhysicalDevice device);
+VkJsonDevice VkJsonGetDevice(VkInstance instance,
+ VkPhysicalDevice device,
+ uint32_t instanceExtensionCount,
+ const char* const* instanceExtensions);
std::string VkJsonDeviceToJson(const VkJsonDevice& device);
bool VkJsonDeviceFromJson(const std::string& json,
VkJsonDevice* device,
@@ -81,7 +87,7 @@
typedef VkJsonDevice VkJsonAllProperties;
inline VkJsonAllProperties VkJsonGetAllProperties(
VkPhysicalDevice physicalDevice) {
- return VkJsonGetDevice(physicalDevice);
+ return VkJsonGetDevice(VK_NULL_HANDLE, physicalDevice, 0, nullptr);
}
inline std::string VkJsonAllPropertiesToJson(
const VkJsonAllProperties& properties) {
diff --git a/libs/vkjson/vkjson_instance.cc b/libs/vkjson/vkjson_instance.cc
index 51b5cfa..de61101 100644
--- a/libs/vkjson/vkjson_instance.cc
+++ b/libs/vkjson/vkjson_instance.cc
@@ -24,9 +24,13 @@
#include "vkjson.h"
+#include <algorithm>
#include <utility>
namespace {
+const char* kSupportedInstanceExtensions[] = {
+ "VK_KHR_get_physical_device_properties2"};
+
bool EnumerateExtensions(const char* layer_name,
std::vector<VkExtensionProperties>* extensions) {
VkResult result;
@@ -42,21 +46,39 @@
return true;
}
+bool HasExtension(const char* extension_name,
+ uint32_t count,
+ const char* const* extensions) {
+ return std::find_if(extensions, extensions + count,
+ [extension_name](const char* extension) {
+ return strcmp(extension, extension_name) == 0;
+ }) != extensions + count;
+}
+
+bool HasExtension(const char* extension_name,
+ const std::vector<VkExtensionProperties>& extensions) {
+ return std::find_if(extensions.cbegin(), extensions.cend(),
+ [extension_name](const VkExtensionProperties& extension) {
+ return strcmp(extension.extensionName,
+ extension_name) == 0;
+ }) != extensions.cend();
+}
} // anonymous namespace
-VkJsonDevice VkJsonGetDevice(VkPhysicalDevice physical_device) {
+VkJsonDevice VkJsonGetDevice(VkInstance instance,
+ VkPhysicalDevice physical_device,
+ uint32_t instance_extension_count,
+ const char* const* instance_extensions) {
VkJsonDevice device;
- vkGetPhysicalDeviceProperties(physical_device, &device.properties);
- vkGetPhysicalDeviceFeatures(physical_device, &device.features);
- vkGetPhysicalDeviceMemoryProperties(physical_device, &device.memory);
- uint32_t queue_family_count = 0;
- vkGetPhysicalDeviceQueueFamilyProperties(physical_device, &queue_family_count,
- nullptr);
- if (queue_family_count > 0) {
- device.queues.resize(queue_family_count);
- vkGetPhysicalDeviceQueueFamilyProperties(
- physical_device, &queue_family_count, device.queues.data());
+ PFN_vkGetPhysicalDeviceFeatures2KHR vkpGetPhysicalDeviceFeatures2KHR =
+ nullptr;
+ if (instance != VK_NULL_HANDLE &&
+ HasExtension("VK_KHR_get_physical_device_properties2",
+ instance_extension_count, instance_extensions)) {
+ vkpGetPhysicalDeviceFeatures2KHR =
+ reinterpret_cast<PFN_vkGetPhysicalDeviceFeatures2KHR>(
+ vkGetInstanceProcAddr(instance, "vkGetPhysicalDeviceFeatures2KHR"));
}
// Only device extensions.
@@ -78,6 +100,36 @@
device.layers.data());
}
+ vkGetPhysicalDeviceProperties(physical_device, &device.properties);
+ if (HasExtension("VK_KHR_get_physical_device_properties2",
+ instance_extension_count, instance_extensions)) {
+ VkPhysicalDeviceFeatures2KHR features = {
+ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FEATURES_2_KHR,
+ nullptr,
+ {} // features
+ };
+ if (HasExtension("VK_KHR_variable_pointers", device.extensions)) {
+ device.variable_pointer_features.sType =
+ VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VARIABLE_POINTER_FEATURES_KHR;
+ device.variable_pointer_features.pNext = features.pNext;
+ features.pNext = &device.variable_pointer_features;
+ }
+ vkpGetPhysicalDeviceFeatures2KHR(physical_device, &features);
+ device.features = features.features;
+ } else {
+ vkGetPhysicalDeviceFeatures(physical_device, &device.features);
+ }
+ vkGetPhysicalDeviceMemoryProperties(physical_device, &device.memory);
+
+ uint32_t queue_family_count = 0;
+ vkGetPhysicalDeviceQueueFamilyProperties(physical_device, &queue_family_count,
+ nullptr);
+ if (queue_family_count > 0) {
+ device.queues.resize(queue_family_count);
+ vkGetPhysicalDeviceQueueFamilyProperties(
+ physical_device, &queue_family_count, device.queues.data());
+ }
+
VkFormatProperties format_properties = {};
for (VkFormat format = VK_FORMAT_R4G4_UNORM_PACK8;
format <= VK_FORMAT_END_RANGE;
@@ -119,6 +171,12 @@
if (!EnumerateExtensions(nullptr, &instance.extensions))
return VkJsonInstance();
+ std::vector<const char*> instance_extensions;
+ for (const auto extension : kSupportedInstanceExtensions) {
+ if (HasExtension(extension, instance.extensions))
+ instance_extensions.push_back(extension);
+ }
+
const VkApplicationInfo app_info = {VK_STRUCTURE_TYPE_APPLICATION_INFO,
nullptr,
"vkjson_info",
@@ -133,8 +191,8 @@
&app_info,
0,
nullptr,
- 0,
- nullptr};
+ static_cast<uint32_t>(instance_extensions.size()),
+ instance_extensions.data()};
VkInstance vkinstance;
result = vkCreateInstance(&instance_info, nullptr, &vkinstance);
if (result != VK_SUCCESS)
@@ -155,7 +213,9 @@
instance.devices.reserve(devices.size());
for (auto device : devices)
- instance.devices.emplace_back(VkJsonGetDevice(device));
+ instance.devices.emplace_back(VkJsonGetDevice(vkinstance, device,
+ instance_extensions.size(),
+ instance_extensions.data()));
vkDestroyInstance(vkinstance, nullptr);
return instance;
diff --git a/loader/CMakeLists.txt b/loader/CMakeLists.txt
index 779ebbd..9c0f7ea 100644
--- a/loader/CMakeLists.txt
+++ b/loader/CMakeLists.txt
@@ -78,8 +78,8 @@
debug_report.c
debug_report.h
gpa_helper.h
- cJSON.c
- cJSON.h
+ ../libs/cjson/includes/cJSON.h
+ ../libs/cjson/cJSON.c
murmurhash.c
murmurhash.h
)