Home | History | Annotate | Download | only in deviceinfo
      1 /*
      2  * Copyright 2016 The Android Open Source Project
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  *      http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13  * See the License for the specific language governing permissions and
     14  * limitations under the License.
     15  */
     16 
     17 package com.android.cts.deviceinfo;
     18 
     19 import com.android.compatibility.common.deviceinfo.DeviceInfo;
     20 import com.android.compatibility.common.util.DeviceInfoStore;
     21 
     22 import org.json.JSONArray;
     23 import org.json.JSONException;
     24 import org.json.JSONObject;
     25 
     26 /**
     27  * Vulkan info collector.
     28  *
     29  * This collector gathers a VkJSONInstance representing the Vulkan capabilities of the Android
     30  * device, and translates it into a DeviceInfoStore. The goal is to be as faithful to the original
     31  * VkJSON as possible, so that the DeviceInfo can later be turned back into VkJSON without loss,
     32  * while still allow complex queries against the DeviceInfo database.
     33  *
     34  * We inherit some design decisions from VkJSON, and there are a few places were translation isn't
     35  * perfect:
     36  *
     37  * - Most JSON implementations handle JSON Numbers as doubles (64-bit floating point), which can't
     38  *   faithfully transfer 64-bit integers. So Vulkan uint64_t and VkDeviceSize values are encoded as
     39  *   Strings containing the hexadecimal representation of the value (with "0x" prefix).
     40  *
     41  * - Vulkan enum values are represented as Numbers. This is most convenient for processing, though
     42  *   isn't very human-readable. Pretty-printing these as strings is left for other tools.
     43  *
     44  * - For implementation convenience, VkJSON represents VkBool32 values as JSON Numbers (0/1). This
     45  *   collector converts them to JSON Boolean values (false/true).
     46  *
     47  * - DeviceInfoStore doesn't allow arrays of non-uniform or non-primitive types. VkJSON stores
     48  *   format capabilities as an array of formats, where each format is an array containing a number
     49  *   (the format enum value) and an object (the format properties). Since DeviceInfoStore doesn't
     50  *   allow array-of-array, we instead store formats as an array of uniform structs, So instead of
     51  *       [[3, {
     52  *           "linearTilingFeatures": 0,
     53  *           "optimalTilingFeatures": 5121,
     54  *           "bufferFeatures": 0
     55  *       }]]
     56  *   the format with enum value "3" will be represented as
     57  *       {
     58  *           "id": 3,
     59  *           "linear_tiling_features": 0,
     60  *           "optimal_tiling_features": 5121,
     61  *           "buffer_features": 0
     62  *       }
     63  *
     64  * - Device layers are deprecated, but instance layers can still add device extensions. VkJSON
     65  *   doesn't yet include device extensions provided by layers, though. So VulkanDeviceInfo omits
     66  *   device layers altogether. Eventually VkJSON and VulkanDeviceInfo should report device layers
     67  *   and their extensions the same way instance layers and their extensions are reported.
     68  *
     69  * - VkJSON uses the original Vulkan field names, while VulkanDeviceInfo follows the DeviceInfo
     70  *   naming convention. So VkJSON fields named like "sparseProperties" will be converted to names
     71  *   like "sparse_properties".
     72  */
     73 public final class VulkanDeviceInfo extends DeviceInfo {
     74 
     75     private static final String KEY_ALPHA_TO_ONE = "alphaToOne";
     76     private static final String KEY_API_VERSION = "apiVersion";
     77     private static final String KEY_BUFFER_FEATURES = "bufferFeatures";
     78     private static final String KEY_BUFFER_IMAGE_GRANULARITY = "bufferImageGranularity";
     79     private static final String KEY_DEPTH = "depth";
     80     private static final String KEY_DEPTH_BIAS_CLAMP = "depthBiasClamp";
     81     private static final String KEY_DEPTH_BOUNDS = "depthBounds";
     82     private static final String KEY_DEPTH_CLAMP = "depthClamp";
     83     private static final String KEY_DESCRIPTION = "description";
     84     private static final String KEY_DEVICE_ID = "deviceID";
     85     private static final String KEY_DEVICE_NAME = "deviceName";
     86     private static final String KEY_DEVICE_TYPE = "deviceType";
     87     private static final String KEY_DEVICES = "devices";
     88     private static final String KEY_DISCRETE_QUEUE_PRIORITIES = "discreteQueuePriorities";
     89     private static final String KEY_DRAW_INDIRECT_FIRST_INSTANCE = "drawIndirectFirstInstance";
     90     private static final String KEY_DRIVER_VERSION = "driverVersion";
     91     private static final String KEY_DUAL_SRC_BLEND = "dualSrcBlend";
     92     private static final String KEY_EXTENSION_NAME = "extensionName";
     93     private static final String KEY_EXTENSIONS = "extensions";
     94     private static final String KEY_FEATURES = "features";
     95     private static final String KEY_FILL_MODE_NON_SOLID = "fillModeNonSolid";
     96     private static final String KEY_FLAGS = "flags";
     97     private static final String KEY_FORMATS = "formats";
     98     private static final String KEY_FRAGMENT_STORES_AND_ATOMICS = "fragmentStoresAndAtomics";
     99     private static final String KEY_FRAMEBUFFER_COLOR_SAMPLE_COUNTS = "framebufferColorSampleCounts";
    100     private static final String KEY_FRAMEBUFFER_DEPTH_SAMPLE_COUNTS = "framebufferDepthSampleCounts";
    101     private static final String KEY_FRAMEBUFFER_NO_ATTACHMENTS_SAMPLE_COUNTS = "framebufferNoAttachmentsSampleCounts";
    102     private static final String KEY_FRAMEBUFFER_STENCIL_SAMPLE_COUNTS = "framebufferStencilSampleCounts";
    103     private static final String KEY_FULL_DRAW_INDEX_UINT32 = "fullDrawIndexUint32";
    104     private static final String KEY_GEOMETRY_SHADER = "geometryShader";
    105     private static final String KEY_HEAP_INDEX = "heapIndex";
    106     private static final String KEY_HEIGHT = "height";
    107     private static final String KEY_IMAGE_CUBE_ARRAY = "imageCubeArray";
    108     private static final String KEY_IMPLEMENTATION_VERSION = "implementationVersion";
    109     private static final String KEY_INDEPENDENT_BLEND = "independentBlend";
    110     private static final String KEY_INHERITED_QUERIES = "inheritedQueries";
    111     private static final String KEY_LARGE_POINTS = "largePoints";
    112     private static final String KEY_LAYER_NAME = "layerName";
    113     private static final String KEY_LAYERS = "layers";
    114     private static final String KEY_LIMITS = "limits";
    115     private static final String KEY_LINE_WIDTH_GRANULARITY = "lineWidthGranularity";
    116     private static final String KEY_LINE_WIDTH_RANGE = "lineWidthRange";
    117     private static final String KEY_LINEAR_TILING_FEATURES = "linearTilingFeatures";
    118     private static final String KEY_LOGIC_OP = "logicOp";
    119     private static final String KEY_MAX_BOUND_DESCRIPTOR_SETS = "maxBoundDescriptorSets";
    120     private static final String KEY_MAX_CLIP_DISTANCES = "maxClipDistances";
    121     private static final String KEY_MAX_COLOR_ATTACHMENTS = "maxColorAttachments";
    122     private static final String KEY_MAX_COMBINED_CLIP_AND_CULL_DISTANCES = "maxCombinedClipAndCullDistances";
    123     private static final String KEY_MAX_COMPUTE_SHARED_MEMORY_SIZE = "maxComputeSharedMemorySize";
    124     private static final String KEY_MAX_COMPUTE_WORK_GROUP_COUNT = "maxComputeWorkGroupCount";
    125     private static final String KEY_MAX_COMPUTE_WORK_GROUP_INVOCATIONS = "maxComputeWorkGroupInvocations";
    126     private static final String KEY_MAX_COMPUTE_WORK_GROUP_SIZE = "maxComputeWorkGroupSize";
    127     private static final String KEY_MAX_CULL_DISTANCES = "maxCullDistances";
    128     private static final String KEY_MAX_DESCRIPTOR_SET_INPUT_ATTACHMENTS = "maxDescriptorSetInputAttachments";
    129     private static final String KEY_MAX_DESCRIPTOR_SET_SAMPLED_IMAGES = "maxDescriptorSetSampledImages";
    130     private static final String KEY_MAX_DESCRIPTOR_SET_SAMPLERS = "maxDescriptorSetSamplers";
    131     private static final String KEY_MAX_DESCRIPTOR_SET_STORAGE_BUFFERS = "maxDescriptorSetStorageBuffers";
    132     private static final String KEY_MAX_DESCRIPTOR_SET_STORAGE_BUFFERS_DYNAMIC = "maxDescriptorSetStorageBuffersDynamic";
    133     private static final String KEY_MAX_DESCRIPTOR_SET_STORAGE_IMAGES = "maxDescriptorSetStorageImages";
    134     private static final String KEY_MAX_DESCRIPTOR_SET_UNIFORM_BUFFERS = "maxDescriptorSetUniformBuffers";
    135     private static final String KEY_MAX_DESCRIPTOR_SET_UNIFORM_BUFFERS_DYNAMIC = "maxDescriptorSetUniformBuffersDynamic";
    136     private static final String KEY_MAX_DRAW_INDEXED_INDEX_VALUE = "maxDrawIndexedIndexValue";
    137     private static final String KEY_MAX_DRAW_INDIRECT_COUNT = "maxDrawIndirectCount";
    138     private static final String KEY_MAX_FRAGMENT_COMBINED_OUTPUT_RESOURCES = "maxFragmentCombinedOutputResources";
    139     private static final String KEY_MAX_FRAGMENT_DUAL_SRC_ATTACHMENTS = "maxFragmentDualSrcAttachments";
    140     private static final String KEY_MAX_FRAGMENT_INPUT_COMPONENTS = "maxFragmentInputComponents";
    141     private static final String KEY_MAX_FRAGMENT_OUTPUT_ATTACHMENTS = "maxFragmentOutputAttachments";
    142     private static final String KEY_MAX_FRAMEBUFFER_HEIGHT = "maxFramebufferHeight";
    143     private static final String KEY_MAX_FRAMEBUFFER_LAYERS = "maxFramebufferLayers";
    144     private static final String KEY_MAX_FRAMEBUFFER_WIDTH = "maxFramebufferWidth";
    145     private static final String KEY_MAX_GEOMETRY_INPUT_COMPONENTS = "maxGeometryInputComponents";
    146     private static final String KEY_MAX_GEOMETRY_OUTPUT_COMPONENTS = "maxGeometryOutputComponents";
    147     private static final String KEY_MAX_GEOMETRY_OUTPUT_VERTICES = "maxGeometryOutputVertices";
    148     private static final String KEY_MAX_GEOMETRY_SHADER_INVOCATIONS = "maxGeometryShaderInvocations";
    149     private static final String KEY_MAX_GEOMETRY_TOTAL_OUTPUT_COMPONENTS = "maxGeometryTotalOutputComponents";
    150     private static final String KEY_MAX_IMAGE_ARRAY_LAYERS = "maxImageArrayLayers";
    151     private static final String KEY_MAX_IMAGE_DIMENSION_1D = "maxImageDimension1D";
    152     private static final String KEY_MAX_IMAGE_DIMENSION_2D = "maxImageDimension2D";
    153     private static final String KEY_MAX_IMAGE_DIMENSION_3D = "maxImageDimension3D";
    154     private static final String KEY_MAX_IMAGE_DIMENSION_CUBE = "maxImageDimensionCube";
    155     private static final String KEY_MAX_INTERPOLATION_OFFSET = "maxInterpolationOffset";
    156     private static final String KEY_MAX_MEMORY_ALLOCATION_COUNT = "maxMemoryAllocationCount";
    157     private static final String KEY_MAX_PER_STAGE_DESCRIPTOR_INPUT_ATTACHMENTS = "maxPerStageDescriptorInputAttachments";
    158     private static final String KEY_MAX_PER_STAGE_DESCRIPTOR_SAMPLED_IMAGES = "maxPerStageDescriptorSampledImages";
    159     private static final String KEY_MAX_PER_STAGE_DESCRIPTOR_SAMPLERS = "maxPerStageDescriptorSamplers";
    160     private static final String KEY_MAX_PER_STAGE_DESCRIPTOR_STORAGE_BUFFERS = "maxPerStageDescriptorStorageBuffers";
    161     private static final String KEY_MAX_PER_STAGE_DESCRIPTOR_STORAGE_IMAGES = "maxPerStageDescriptorStorageImages";
    162     private static final String KEY_MAX_PER_STAGE_DESCRIPTOR_UNIFORM_BUFFERS = "maxPerStageDescriptorUniformBuffers";
    163     private static final String KEY_MAX_PER_STAGE_RESOURCES = "maxPerStageResources";
    164     private static final String KEY_MAX_PUSH_CONSTANTS_SIZE = "maxPushConstantsSize";
    165     private static final String KEY_MAX_SAMPLE_MASK_WORDS = "maxSampleMaskWords";
    166     private static final String KEY_MAX_SAMPLER_ALLOCATION_COUNT = "maxSamplerAllocationCount";
    167     private static final String KEY_MAX_SAMPLER_ANISOTROPY = "maxSamplerAnisotropy";
    168     private static final String KEY_MAX_SAMPLER_LOD_BIAS = "maxSamplerLodBias";
    169     private static final String KEY_MAX_STORAGE_BUFFER_RANGE = "maxStorageBufferRange";
    170     private static final String KEY_MAX_TESSELLATION_CONTROL_PER_PATCH_OUTPUT_COMPONENTS = "maxTessellationControlPerPatchOutputComponents";
    171     private static final String KEY_MAX_TESSELLATION_CONTROL_PER_VERTEX_INPUT_COMPONENTS = "maxTessellationControlPerVertexInputComponents";
    172     private static final String KEY_MAX_TESSELLATION_CONTROL_PER_VERTEX_OUTPUT_COMPONENTS = "maxTessellationControlPerVertexOutputComponents";
    173     private static final String KEY_MAX_TESSELLATION_CONTROL_TOTAL_OUTPUT_COMPONENTS = "maxTessellationControlTotalOutputComponents";
    174     private static final String KEY_MAX_TESSELLATION_EVALUATION_INPUT_COMPONENTS = "maxTessellationEvaluationInputComponents";
    175     private static final String KEY_MAX_TESSELLATION_EVALUATION_OUTPUT_COMPONENTS = "maxTessellationEvaluationOutputComponents";
    176     private static final String KEY_MAX_TESSELLATION_GENERATION_LEVEL = "maxTessellationGenerationLevel";
    177     private static final String KEY_MAX_TESSELLATION_PATCH_SIZE = "maxTessellationPatchSize";
    178     private static final String KEY_MAX_TEXEL_BUFFER_ELEMENTS = "maxTexelBufferElements";
    179     private static final String KEY_MAX_TEXEL_GATHER_OFFSET = "maxTexelGatherOffset";
    180     private static final String KEY_MAX_TEXEL_OFFSET = "maxTexelOffset";
    181     private static final String KEY_MAX_UNIFORM_BUFFER_RANGE = "maxUniformBufferRange";
    182     private static final String KEY_MAX_VERTEX_INPUT_ATTRIBUTE_OFFSET = "maxVertexInputAttributeOffset";
    183     private static final String KEY_MAX_VERTEX_INPUT_ATTRIBUTES = "maxVertexInputAttributes";
    184     private static final String KEY_MAX_VERTEX_INPUT_BINDING_STRIDE = "maxVertexInputBindingStride";
    185     private static final String KEY_MAX_VERTEX_INPUT_BINDINGS = "maxVertexInputBindings";
    186     private static final String KEY_MAX_VERTEX_OUTPUT_COMPONENTS = "maxVertexOutputComponents";
    187     private static final String KEY_MAX_VIEWPORT_DIMENSIONS = "maxViewportDimensions";
    188     private static final String KEY_MAX_VIEWPORTS = "maxViewports";
    189     private static final String KEY_MEMORY = "memory";
    190     private static final String KEY_MEMORY_HEAP_COUNT = "memoryHeapCount";
    191     private static final String KEY_MEMORY_HEAPS = "memoryHeaps";
    192     private static final String KEY_MEMORY_TYPE_COUNT = "memoryTypeCount";
    193     private static final String KEY_MEMORY_TYPES = "memoryTypes";
    194     private static final String KEY_MIN_IMAGE_TRANSFER_GRANULARITY = "minImageTransferGranularity";
    195     private static final String KEY_MIN_INTERPOLATION_OFFSET = "minInterpolationOffset";
    196     private static final String KEY_MIN_MEMORY_MAP_ALIGNMENT = "minMemoryMapAlignment";
    197     private static final String KEY_MIN_STORAGE_BUFFER_OFFSET_ALIGNMENT = "minStorageBufferOffsetAlignment";
    198     private static final String KEY_MIN_TEXEL_BUFFER_OFFSET_ALIGNMENT = "minTexelBufferOffsetAlignment";
    199     private static final String KEY_MIN_TEXEL_GATHER_OFFSET = "minTexelGatherOffset";
    200     private static final String KEY_MIN_TEXEL_OFFSET = "minTexelOffset";
    201     private static final String KEY_MIN_UNIFORM_BUFFER_OFFSET_ALIGNMENT = "minUniformBufferOffsetAlignment";
    202     private static final String KEY_MIPMAP_PRECISION_BITS = "mipmapPrecisionBits";
    203     private static final String KEY_MULTI_DRAW_INDIRECT = "multiDrawIndirect";
    204     private static final String KEY_MULTI_VIEWPORT = "multiViewport";
    205     private static final String KEY_NON_COHERENT_ATOM_SIZE = "nonCoherentAtomSize";
    206     private static final String KEY_OCCLUSION_QUERY_PRECISE = "occlusionQueryPrecise";
    207     private static final String KEY_OPTIMAL_BUFFER_COPY_OFFSET_ALIGNMENT = "optimalBufferCopyOffsetAlignment";
    208     private static final String KEY_OPTIMAL_BUFFER_COPY_ROW_PITCH_ALIGNMENT = "optimalBufferCopyRowPitchAlignment";
    209     private static final String KEY_OPTIMAL_TILING_FEATURES = "optimalTilingFeatures";
    210     private static final String KEY_PIPELINE_CACHE_UUID = "pipelineCacheUUID";
    211     private static final String KEY_PIPELINE_STATISTICS_QUERY = "pipelineStatisticsQuery";
    212     private static final String KEY_POINT_SIZE_GRANULARITY = "pointSizeGranularity";
    213     private static final String KEY_POINT_SIZE_RANGE = "pointSizeRange";
    214     private static final String KEY_PROPERTIES = "properties";
    215     private static final String KEY_PROPERTY_FLAGS = "propertyFlags";
    216     private static final String KEY_QUEUE_COUNT = "queueCount";
    217     private static final String KEY_QUEUE_FLAGS = "queueFlags";
    218     private static final String KEY_QUEUES = "queues";
    219     private static final String KEY_RESIDENCY_ALIGNED_MIP_SIZE = "residencyAlignedMipSize";
    220     private static final String KEY_RESIDENCY_NON_RESIDENT_STRICT = "residencyNonResidentStrict";
    221     private static final String KEY_RESIDENCY_STANDARD_2D_BLOCK_SHAPE = "residencyStandard2DBlockShape";
    222     private static final String KEY_RESIDENCY_STANDARD_2D_MULTISAMPLE_BLOCK_SHAPE = "residencyStandard2DMultisampleBlockShape";
    223     private static final String KEY_RESIDENCY_STANDARD_3D_BLOCK_SHAPE = "residencyStandard3DBlockShape";
    224     private static final String KEY_ROBUST_BUFFER_ACCESS = "robustBufferAccess";
    225     private static final String KEY_SAMPLE_RATE_SHADING = "sampleRateShading";
    226     private static final String KEY_SAMPLED_IMAGE_COLOR_SAMPLE_COUNTS = "sampledImageColorSampleCounts";
    227     private static final String KEY_SAMPLED_IMAGE_DEPTH_SAMPLE_COUNTS = "sampledImageDepthSampleCounts";
    228     private static final String KEY_SAMPLED_IMAGE_INTEGER_SAMPLE_COUNTS = "sampledImageIntegerSampleCounts";
    229     private static final String KEY_SAMPLED_IMAGE_STENCIL_SAMPLE_COUNTS = "sampledImageStencilSampleCounts";
    230     private static final String KEY_SAMPLER_ANISOTROPY = "samplerAnisotropy";
    231     private static final String KEY_SHADER_CLIP_DISTANCE = "shaderClipDistance";
    232     private static final String KEY_SHADER_CULL_DISTANCE = "shaderCullDistance";
    233     private static final String KEY_SHADER_FLOAT64 = "shaderFloat64";
    234     private static final String KEY_SHADER_IMAGE_GATHER_EXTENDED = "shaderImageGatherExtended";
    235     private static final String KEY_SHADER_INT16 = "shaderInt16";
    236     private static final String KEY_SHADER_INT64 = "shaderInt64";
    237     private static final String KEY_SHADER_RESOURCE_MIN_LOD = "shaderResourceMinLod";
    238     private static final String KEY_SHADER_RESOURCE_RESIDENCY = "shaderResourceResidency";
    239     private static final String KEY_SHADER_SAMPLED_IMAGE_ARRAY_DYNAMIC_INDEXING = "shaderSampledImageArrayDynamicIndexing";
    240     private static final String KEY_SHADER_STORAGE_BUFFER_ARRAY_DYNAMIC_INDEXING = "shaderStorageBufferArrayDynamicIndexing";
    241     private static final String KEY_SHADER_STORAGE_IMAGE_ARRAY_DYNAMIC_INDEXING = "shaderStorageImageArrayDynamicIndexing";
    242     private static final String KEY_SHADER_STORAGE_IMAGE_EXTENDED_FORMATS = "shaderStorageImageExtendedFormats";
    243     private static final String KEY_SHADER_STORAGE_IMAGE_MULTISAMPLE = "shaderStorageImageMultisample";
    244     private static final String KEY_SHADER_STORAGE_IMAGE_READ_WITHOUT_FORMAT = "shaderStorageImageReadWithoutFormat";
    245     private static final String KEY_SHADER_STORAGE_IMAGE_WRITE_WITHOUT_FORMAT = "shaderStorageImageWriteWithoutFormat";
    246     private static final String KEY_SHADER_TESSELLATION_AND_GEOMETRY_POINT_SIZE = "shaderTessellationAndGeometryPointSize";
    247     private static final String KEY_SHADER_UNIFORM_BUFFER_ARRAY_DYNAMIC_INDEXING = "shaderUniformBufferArrayDynamicIndexing";
    248     private static final String KEY_SIZE = "size";
    249     private static final String KEY_SPARSE_ADDRESS_SPACE_SIZE = "sparseAddressSpaceSize";
    250     private static final String KEY_SPARSE_BINDING = "sparseBinding";
    251     private static final String KEY_SPARSE_PROPERTIES = "sparseProperties";
    252     private static final String KEY_SPARSE_RESIDENCY_16_SAMPLES = "sparseResidency16Samples";
    253     private static final String KEY_SPARSE_RESIDENCY_2_SAMPLES = "sparseResidency2Samples";
    254     private static final String KEY_SPARSE_RESIDENCY_4_SAMPLES = "sparseResidency4Samples";
    255     private static final String KEY_SPARSE_RESIDENCY_8_SAMPLES = "sparseResidency8Samples";
    256     private static final String KEY_SPARSE_RESIDENCY_ALIASED = "sparseResidencyAliased";
    257     private static final String KEY_SPARSE_RESIDENCY_BUFFER = "sparseResidencyBuffer";
    258     private static final String KEY_SPARSE_RESIDENCY_IMAGE_2D = "sparseResidencyImage2D";
    259     private static final String KEY_SPARSE_RESIDENCY_IMAGE_3D = "sparseResidencyImage3D";
    260     private static final String KEY_SPEC_VERSION = "specVersion";
    261     private static final String KEY_STANDARD_SAMPLE_LOCATIONS = "standardSampleLocations";
    262     private static final String KEY_STORAGE_IMAGE_SAMPLE_COUNTS = "storageImageSampleCounts";
    263     private static final String KEY_STRICT_LINES = "strictLines";
    264     private static final String KEY_SUB_PIXEL_INTERPOLATION_OFFSET_BITS = "subPixelInterpolationOffsetBits";
    265     private static final String KEY_SUB_PIXEL_PRECISION_BITS = "subPixelPrecisionBits";
    266     private static final String KEY_SUB_TEXEL_PRECISION_BITS = "subTexelPrecisionBits";
    267     private static final String KEY_TESSELLATION_SHADER = "tessellationShader";
    268     private static final String KEY_TEXTURE_COMPRESSION_ASTC_LDR = "textureCompressionASTC_LDR";
    269     private static final String KEY_TEXTURE_COMPRESSION_BC = "textureCompressionBC";
    270     private static final String KEY_TEXTURE_COMPRESSION_ETC2 = "textureCompressionETC2";
    271     private static final String KEY_TIMESTAMP_COMPUTE_AND_GRAPHICS = "timestampComputeAndGraphics";
    272     private static final String KEY_TIMESTAMP_PERIOD = "timestampPeriod";
    273     private static final String KEY_TIMESTAMP_VALID_BITS = "timestampValidBits";
    274     private static final String KEY_VARIABLE_MULTISAMPLE_RATE = "variableMultisampleRate";
    275     private static final String KEY_VENDOR_ID = "vendorID";
    276     private static final String KEY_VERTEX_PIPELINE_STORES_AND_ATOMICS = "vertexPipelineStoresAndAtomics";
    277     private static final String KEY_VIEWPORT_BOUNDS_RANGE = "viewportBoundsRange";
    278     private static final String KEY_VIEWPORT_SUB_PIXEL_BITS = "viewportSubPixelBits";
    279     private static final String KEY_WIDE_LINES = "wideLines";
    280     private static final String KEY_WIDTH = "width";
    281 
    282     static {
    283         System.loadLibrary("ctsdeviceinfo");
    284     }
    285 
    286     @Override
    287     protected void collectDeviceInfo(DeviceInfoStore store) throws Exception {
    288         try {
    289             JSONObject instance = new JSONObject(nativeGetVkJSON());
    290             emitLayers(store, instance);
    291             emitExtensions(store, instance);
    292             emitDevices(store, instance);
    293         } catch (JSONException e) {
    294             e.printStackTrace();
    295             throw new RuntimeException(e);
    296         }
    297     }
    298 
    299     private static void emitDevices(DeviceInfoStore store, JSONObject parent)
    300             throws Exception {
    301         JSONArray devices = parent.getJSONArray(KEY_DEVICES);
    302         store.startArray(convertName(KEY_DEVICES));
    303         for (int deviceIdx = 0; deviceIdx < devices.length(); deviceIdx++) {
    304             JSONObject device = devices.getJSONObject(deviceIdx);
    305             store.startGroup();
    306             {
    307                 JSONObject properties = device.getJSONObject(KEY_PROPERTIES);
    308                 store.startGroup(convertName(KEY_PROPERTIES));
    309                 {
    310                     emitLong(store, properties, KEY_API_VERSION);
    311                     emitLong(store, properties, KEY_DRIVER_VERSION);
    312                     emitLong(store, properties, KEY_VENDOR_ID);
    313                     emitLong(store, properties, KEY_DEVICE_ID);
    314                     emitLong(store, properties, KEY_DEVICE_TYPE);
    315                     emitString(store, properties, KEY_DEVICE_NAME);
    316                     emitLongArray(store, properties, KEY_PIPELINE_CACHE_UUID);
    317 
    318                     JSONObject limits = properties.getJSONObject(KEY_LIMITS);
    319                     store.startGroup(convertName(KEY_LIMITS));
    320                     {
    321                         emitLong(store, limits, KEY_MAX_IMAGE_DIMENSION_1D);
    322                         emitLong(store, limits, KEY_MAX_IMAGE_DIMENSION_2D);
    323                         emitLong(store, limits, KEY_MAX_IMAGE_DIMENSION_3D);
    324                         emitLong(store, limits, KEY_MAX_IMAGE_DIMENSION_CUBE);
    325                         emitLong(store, limits, KEY_MAX_IMAGE_ARRAY_LAYERS);
    326                         emitLong(store, limits, KEY_MAX_TEXEL_BUFFER_ELEMENTS);
    327                         emitLong(store, limits, KEY_MAX_UNIFORM_BUFFER_RANGE);
    328                         emitLong(store, limits, KEY_MAX_STORAGE_BUFFER_RANGE);
    329                         emitLong(store, limits, KEY_MAX_PUSH_CONSTANTS_SIZE);
    330                         emitLong(store, limits, KEY_MAX_MEMORY_ALLOCATION_COUNT);
    331                         emitLong(store, limits, KEY_MAX_SAMPLER_ALLOCATION_COUNT);
    332                         emitString(store, limits, KEY_BUFFER_IMAGE_GRANULARITY);
    333                         emitString(store, limits, KEY_SPARSE_ADDRESS_SPACE_SIZE);
    334                         emitLong(store, limits, KEY_MAX_BOUND_DESCRIPTOR_SETS);
    335                         emitLong(store, limits, KEY_MAX_PER_STAGE_DESCRIPTOR_SAMPLERS);
    336                         emitLong(store, limits, KEY_MAX_PER_STAGE_DESCRIPTOR_UNIFORM_BUFFERS);
    337                         emitLong(store, limits, KEY_MAX_PER_STAGE_DESCRIPTOR_STORAGE_BUFFERS);
    338                         emitLong(store, limits, KEY_MAX_PER_STAGE_DESCRIPTOR_SAMPLED_IMAGES);
    339                         emitLong(store, limits, KEY_MAX_PER_STAGE_DESCRIPTOR_STORAGE_IMAGES);
    340                         emitLong(store, limits, KEY_MAX_PER_STAGE_DESCRIPTOR_INPUT_ATTACHMENTS);
    341                         emitLong(store, limits, KEY_MAX_PER_STAGE_RESOURCES);
    342                         emitLong(store, limits, KEY_MAX_DESCRIPTOR_SET_SAMPLERS);
    343                         emitLong(store, limits, KEY_MAX_DESCRIPTOR_SET_UNIFORM_BUFFERS);
    344                         emitLong(store, limits, KEY_MAX_DESCRIPTOR_SET_UNIFORM_BUFFERS_DYNAMIC);
    345                         emitLong(store, limits, KEY_MAX_DESCRIPTOR_SET_STORAGE_BUFFERS);
    346                         emitLong(store, limits, KEY_MAX_DESCRIPTOR_SET_STORAGE_BUFFERS_DYNAMIC);
    347                         emitLong(store, limits, KEY_MAX_DESCRIPTOR_SET_SAMPLED_IMAGES);
    348                         emitLong(store, limits, KEY_MAX_DESCRIPTOR_SET_STORAGE_IMAGES);
    349                         emitLong(store, limits, KEY_MAX_DESCRIPTOR_SET_INPUT_ATTACHMENTS);
    350                         emitLong(store, limits, KEY_MAX_VERTEX_INPUT_ATTRIBUTES);
    351                         emitLong(store, limits, KEY_MAX_VERTEX_INPUT_BINDINGS);
    352                         emitLong(store, limits, KEY_MAX_VERTEX_INPUT_ATTRIBUTE_OFFSET);
    353                         emitLong(store, limits, KEY_MAX_VERTEX_INPUT_BINDING_STRIDE);
    354                         emitLong(store, limits, KEY_MAX_VERTEX_OUTPUT_COMPONENTS);
    355                         emitLong(store, limits, KEY_MAX_TESSELLATION_GENERATION_LEVEL);
    356                         emitLong(store, limits, KEY_MAX_TESSELLATION_PATCH_SIZE);
    357                         emitLong(store, limits, KEY_MAX_TESSELLATION_CONTROL_PER_VERTEX_INPUT_COMPONENTS);
    358                         emitLong(store, limits, KEY_MAX_TESSELLATION_CONTROL_PER_VERTEX_OUTPUT_COMPONENTS);
    359                         emitLong(store, limits, KEY_MAX_TESSELLATION_CONTROL_PER_PATCH_OUTPUT_COMPONENTS);
    360                         emitLong(store, limits, KEY_MAX_TESSELLATION_CONTROL_TOTAL_OUTPUT_COMPONENTS);
    361                         emitLong(store, limits, KEY_MAX_TESSELLATION_EVALUATION_INPUT_COMPONENTS);
    362                         emitLong(store, limits, KEY_MAX_TESSELLATION_EVALUATION_OUTPUT_COMPONENTS);
    363                         emitLong(store, limits, KEY_MAX_GEOMETRY_SHADER_INVOCATIONS);
    364                         emitLong(store, limits, KEY_MAX_GEOMETRY_INPUT_COMPONENTS);
    365                         emitLong(store, limits, KEY_MAX_GEOMETRY_OUTPUT_COMPONENTS);
    366                         emitLong(store, limits, KEY_MAX_GEOMETRY_OUTPUT_VERTICES);
    367                         emitLong(store, limits, KEY_MAX_GEOMETRY_TOTAL_OUTPUT_COMPONENTS);
    368                         emitLong(store, limits, KEY_MAX_FRAGMENT_INPUT_COMPONENTS);
    369                         emitLong(store, limits, KEY_MAX_FRAGMENT_OUTPUT_ATTACHMENTS);
    370                         emitLong(store, limits, KEY_MAX_FRAGMENT_DUAL_SRC_ATTACHMENTS);
    371                         emitLong(store, limits, KEY_MAX_FRAGMENT_COMBINED_OUTPUT_RESOURCES);
    372                         emitLong(store, limits, KEY_MAX_COMPUTE_SHARED_MEMORY_SIZE);
    373                         emitLongArray(store, limits, KEY_MAX_COMPUTE_WORK_GROUP_COUNT);
    374                         emitLong(store, limits, KEY_MAX_COMPUTE_WORK_GROUP_INVOCATIONS);
    375                         emitLongArray(store, limits, KEY_MAX_COMPUTE_WORK_GROUP_SIZE);
    376                         emitLong(store, limits, KEY_SUB_PIXEL_PRECISION_BITS);
    377                         emitLong(store, limits, KEY_SUB_TEXEL_PRECISION_BITS);
    378                         emitLong(store, limits, KEY_MIPMAP_PRECISION_BITS);
    379                         emitLong(store, limits, KEY_MAX_DRAW_INDEXED_INDEX_VALUE);
    380                         emitLong(store, limits, KEY_MAX_DRAW_INDIRECT_COUNT);
    381                         emitDouble(store, limits, KEY_MAX_SAMPLER_LOD_BIAS);
    382                         emitDouble(store, limits, KEY_MAX_SAMPLER_ANISOTROPY);
    383                         emitLong(store, limits, KEY_MAX_VIEWPORTS);
    384                         emitLongArray(store, limits, KEY_MAX_VIEWPORT_DIMENSIONS);
    385                         emitDoubleArray(store, limits, KEY_VIEWPORT_BOUNDS_RANGE);
    386                         emitLong(store, limits, KEY_VIEWPORT_SUB_PIXEL_BITS);
    387                         emitString(store, limits, KEY_MIN_MEMORY_MAP_ALIGNMENT);
    388                         emitString(store, limits, KEY_MIN_TEXEL_BUFFER_OFFSET_ALIGNMENT);
    389                         emitString(store, limits, KEY_MIN_UNIFORM_BUFFER_OFFSET_ALIGNMENT);
    390                         emitString(store, limits, KEY_MIN_STORAGE_BUFFER_OFFSET_ALIGNMENT);
    391                         emitLong(store, limits, KEY_MIN_TEXEL_OFFSET);
    392                         emitLong(store, limits, KEY_MAX_TEXEL_OFFSET);
    393                         emitLong(store, limits, KEY_MIN_TEXEL_GATHER_OFFSET);
    394                         emitLong(store, limits, KEY_MAX_TEXEL_GATHER_OFFSET);
    395                         emitDouble(store, limits, KEY_MIN_INTERPOLATION_OFFSET);
    396                         emitDouble(store, limits, KEY_MAX_INTERPOLATION_OFFSET);
    397                         emitLong(store, limits, KEY_SUB_PIXEL_INTERPOLATION_OFFSET_BITS);
    398                         emitLong(store, limits, KEY_MAX_FRAMEBUFFER_WIDTH);
    399                         emitLong(store, limits, KEY_MAX_FRAMEBUFFER_HEIGHT);
    400                         emitLong(store, limits, KEY_MAX_FRAMEBUFFER_LAYERS);
    401                         emitLong(store, limits, KEY_FRAMEBUFFER_COLOR_SAMPLE_COUNTS);
    402                         emitLong(store, limits, KEY_FRAMEBUFFER_DEPTH_SAMPLE_COUNTS);
    403                         emitLong(store, limits, KEY_FRAMEBUFFER_STENCIL_SAMPLE_COUNTS);
    404                         emitLong(store, limits, KEY_FRAMEBUFFER_NO_ATTACHMENTS_SAMPLE_COUNTS);
    405                         emitLong(store, limits, KEY_MAX_COLOR_ATTACHMENTS);
    406                         emitLong(store, limits, KEY_SAMPLED_IMAGE_COLOR_SAMPLE_COUNTS);
    407                         emitLong(store, limits, KEY_SAMPLED_IMAGE_INTEGER_SAMPLE_COUNTS);
    408                         emitLong(store, limits, KEY_SAMPLED_IMAGE_DEPTH_SAMPLE_COUNTS);
    409                         emitLong(store, limits, KEY_SAMPLED_IMAGE_STENCIL_SAMPLE_COUNTS);
    410                         emitLong(store, limits, KEY_STORAGE_IMAGE_SAMPLE_COUNTS);
    411                         emitLong(store, limits, KEY_MAX_SAMPLE_MASK_WORDS);
    412                         emitBoolean(store, limits, KEY_TIMESTAMP_COMPUTE_AND_GRAPHICS);
    413                         emitDouble(store, limits, KEY_TIMESTAMP_PERIOD);
    414                         emitLong(store, limits, KEY_MAX_CLIP_DISTANCES);
    415                         emitLong(store, limits, KEY_MAX_CULL_DISTANCES);
    416                         emitLong(store, limits, KEY_MAX_COMBINED_CLIP_AND_CULL_DISTANCES);
    417                         emitLong(store, limits, KEY_DISCRETE_QUEUE_PRIORITIES);
    418                         emitDoubleArray(store, limits, KEY_POINT_SIZE_RANGE);
    419                         emitDoubleArray(store, limits, KEY_LINE_WIDTH_RANGE);
    420                         emitDouble(store, limits, KEY_POINT_SIZE_GRANULARITY);
    421                         emitDouble(store, limits, KEY_LINE_WIDTH_GRANULARITY);
    422                         emitBoolean(store, limits, KEY_STRICT_LINES);
    423                         emitBoolean(store, limits, KEY_STANDARD_SAMPLE_LOCATIONS);
    424                         emitString(store, limits, KEY_OPTIMAL_BUFFER_COPY_OFFSET_ALIGNMENT);
    425                         emitString(store, limits, KEY_OPTIMAL_BUFFER_COPY_ROW_PITCH_ALIGNMENT);
    426                         emitString(store, limits, KEY_NON_COHERENT_ATOM_SIZE);
    427                     }
    428                     store.endGroup();
    429 
    430                     JSONObject sparse = properties.getJSONObject(KEY_SPARSE_PROPERTIES);
    431                     store.startGroup(convertName(KEY_SPARSE_PROPERTIES));
    432                     {
    433                         emitBoolean(store, sparse, KEY_RESIDENCY_STANDARD_2D_BLOCK_SHAPE);
    434                         emitBoolean(store, sparse, KEY_RESIDENCY_STANDARD_2D_MULTISAMPLE_BLOCK_SHAPE);
    435                         emitBoolean(store, sparse, KEY_RESIDENCY_STANDARD_3D_BLOCK_SHAPE);
    436                         emitBoolean(store, sparse, KEY_RESIDENCY_ALIGNED_MIP_SIZE);
    437                         emitBoolean(store, sparse, KEY_RESIDENCY_NON_RESIDENT_STRICT);
    438                     }
    439                     store.endGroup();
    440                 }
    441                 store.endGroup();
    442 
    443                 JSONObject features = device.getJSONObject(KEY_FEATURES);
    444                 store.startGroup(convertName(KEY_FEATURES));
    445                 {
    446                     emitBoolean(store, features, KEY_ROBUST_BUFFER_ACCESS);
    447                     emitBoolean(store, features, KEY_FULL_DRAW_INDEX_UINT32);
    448                     emitBoolean(store, features, KEY_IMAGE_CUBE_ARRAY);
    449                     emitBoolean(store, features, KEY_INDEPENDENT_BLEND);
    450                     emitBoolean(store, features, KEY_GEOMETRY_SHADER);
    451                     emitBoolean(store, features, KEY_TESSELLATION_SHADER);
    452                     emitBoolean(store, features, KEY_SAMPLE_RATE_SHADING);
    453                     emitBoolean(store, features, KEY_DUAL_SRC_BLEND);
    454                     emitBoolean(store, features, KEY_LOGIC_OP);
    455                     emitBoolean(store, features, KEY_MULTI_DRAW_INDIRECT);
    456                     emitBoolean(store, features, KEY_DRAW_INDIRECT_FIRST_INSTANCE);
    457                     emitBoolean(store, features, KEY_DEPTH_CLAMP);
    458                     emitBoolean(store, features, KEY_DEPTH_BIAS_CLAMP);
    459                     emitBoolean(store, features, KEY_FILL_MODE_NON_SOLID);
    460                     emitBoolean(store, features, KEY_DEPTH_BOUNDS);
    461                     emitBoolean(store, features, KEY_WIDE_LINES);
    462                     emitBoolean(store, features, KEY_LARGE_POINTS);
    463                     emitBoolean(store, features, KEY_ALPHA_TO_ONE);
    464                     emitBoolean(store, features, KEY_MULTI_VIEWPORT);
    465                     emitBoolean(store, features, KEY_SAMPLER_ANISOTROPY);
    466                     emitBoolean(store, features, KEY_TEXTURE_COMPRESSION_ETC2);
    467                     emitBoolean(store, features, KEY_TEXTURE_COMPRESSION_ASTC_LDR);
    468                     emitBoolean(store, features, KEY_TEXTURE_COMPRESSION_BC);
    469                     emitBoolean(store, features, KEY_OCCLUSION_QUERY_PRECISE);
    470                     emitBoolean(store, features, KEY_PIPELINE_STATISTICS_QUERY);
    471                     emitBoolean(store, features, KEY_VERTEX_PIPELINE_STORES_AND_ATOMICS);
    472                     emitBoolean(store, features, KEY_FRAGMENT_STORES_AND_ATOMICS);
    473                     emitBoolean(store, features, KEY_SHADER_TESSELLATION_AND_GEOMETRY_POINT_SIZE);
    474                     emitBoolean(store, features, KEY_SHADER_IMAGE_GATHER_EXTENDED);
    475                     emitBoolean(store, features, KEY_SHADER_STORAGE_IMAGE_EXTENDED_FORMATS);
    476                     emitBoolean(store, features, KEY_SHADER_STORAGE_IMAGE_MULTISAMPLE);
    477                     emitBoolean(store, features, KEY_SHADER_STORAGE_IMAGE_READ_WITHOUT_FORMAT);
    478                     emitBoolean(store, features, KEY_SHADER_STORAGE_IMAGE_WRITE_WITHOUT_FORMAT);
    479                     emitBoolean(store, features, KEY_SHADER_UNIFORM_BUFFER_ARRAY_DYNAMIC_INDEXING);
    480                     emitBoolean(store, features, KEY_SHADER_SAMPLED_IMAGE_ARRAY_DYNAMIC_INDEXING);
    481                     emitBoolean(store, features, KEY_SHADER_STORAGE_BUFFER_ARRAY_DYNAMIC_INDEXING);
    482                     emitBoolean(store, features, KEY_SHADER_STORAGE_IMAGE_ARRAY_DYNAMIC_INDEXING);
    483                     emitBoolean(store, features, KEY_SHADER_CLIP_DISTANCE);
    484                     emitBoolean(store, features, KEY_SHADER_CULL_DISTANCE);
    485                     emitBoolean(store, features, KEY_SHADER_FLOAT64);
    486                     emitBoolean(store, features, KEY_SHADER_INT64);
    487                     emitBoolean(store, features, KEY_SHADER_INT16);
    488                     emitBoolean(store, features, KEY_SHADER_RESOURCE_RESIDENCY);
    489                     emitBoolean(store, features, KEY_SHADER_RESOURCE_MIN_LOD);
    490                     emitBoolean(store, features, KEY_SPARSE_BINDING);
    491                     emitBoolean(store, features, KEY_SPARSE_RESIDENCY_BUFFER);
    492                     emitBoolean(store, features, KEY_SPARSE_RESIDENCY_IMAGE_2D);
    493                     emitBoolean(store, features, KEY_SPARSE_RESIDENCY_IMAGE_3D);
    494                     emitBoolean(store, features, KEY_SPARSE_RESIDENCY_2_SAMPLES);
    495                     emitBoolean(store, features, KEY_SPARSE_RESIDENCY_4_SAMPLES);
    496                     emitBoolean(store, features, KEY_SPARSE_RESIDENCY_8_SAMPLES);
    497                     emitBoolean(store, features, KEY_SPARSE_RESIDENCY_16_SAMPLES);
    498                     emitBoolean(store, features, KEY_SPARSE_RESIDENCY_ALIASED);
    499                     emitBoolean(store, features, KEY_VARIABLE_MULTISAMPLE_RATE);
    500                     emitBoolean(store, features, KEY_INHERITED_QUERIES);
    501                 }
    502                 store.endGroup();
    503 
    504                 JSONObject memory = device.getJSONObject(KEY_MEMORY);
    505                 store.startGroup(convertName(KEY_MEMORY));
    506                 {
    507                     emitLong(store, memory, KEY_MEMORY_TYPE_COUNT);
    508                     JSONArray memoryTypes = memory.getJSONArray(KEY_MEMORY_TYPES);
    509                     store.startArray(convertName(KEY_MEMORY_TYPES));
    510                     for (int memoryTypeIdx = 0; memoryTypeIdx < memoryTypes.length();
    511                             memoryTypeIdx++) {
    512                         JSONObject memoryType = memoryTypes.getJSONObject(memoryTypeIdx);
    513                         store.startGroup();
    514                         {
    515                             emitLong(store, memoryType, KEY_PROPERTY_FLAGS);
    516                             emitLong(store, memoryType, KEY_HEAP_INDEX);
    517                         }
    518                         store.endGroup();
    519                     }
    520                     store.endArray();
    521 
    522                     emitLong(store, memory, KEY_MEMORY_HEAP_COUNT);
    523                     JSONArray memoryHeaps = memory.getJSONArray(KEY_MEMORY_HEAPS);
    524                     store.startArray(convertName(KEY_MEMORY_HEAPS));
    525                     for (int memoryHeapIdx = 0; memoryHeapIdx < memoryHeaps.length();
    526                             memoryHeapIdx++) {
    527                         JSONObject memoryHeap = memoryHeaps.getJSONObject(memoryHeapIdx);
    528                         store.startGroup();
    529                         {
    530                             emitString(store, memoryHeap, KEY_SIZE);
    531                             emitLong(store, memoryHeap, KEY_FLAGS);
    532                         }
    533                         store.endGroup();
    534                     }
    535                     store.endArray();
    536                 }
    537                 store.endGroup();
    538 
    539                 JSONArray queues = device.getJSONArray(KEY_QUEUES);
    540                 store.startArray(convertName(KEY_QUEUES));
    541                 for (int queueIdx = 0; queueIdx < queues.length(); queueIdx++) {
    542                     JSONObject queue = queues.getJSONObject(queueIdx);
    543                     store.startGroup();
    544                     {
    545                         emitLong(store, queue, KEY_QUEUE_FLAGS);
    546                         emitLong(store, queue, KEY_QUEUE_COUNT);
    547                         emitLong(store, queue, KEY_TIMESTAMP_VALID_BITS);
    548                         JSONObject extent = queue.getJSONObject(KEY_MIN_IMAGE_TRANSFER_GRANULARITY);
    549                         store.startGroup(convertName(KEY_MIN_IMAGE_TRANSFER_GRANULARITY));
    550                         {
    551                             emitLong(store, extent, KEY_WIDTH);
    552                             emitLong(store, extent, KEY_HEIGHT);
    553                             emitLong(store, extent, KEY_DEPTH);
    554                         }
    555                         store.endGroup();
    556                     }
    557                     store.endGroup();
    558                 }
    559                 store.endArray();
    560 
    561                 // Skip layers for now. VkJSON doesn't yet include device layer extensions, so
    562                 // this is entirely redundant with the instance extension information.
    563                 // emitLayers(store, device);
    564                 store.startArray(convertName(KEY_LAYERS));
    565                 store.endArray();
    566 
    567                 emitExtensions(store, device);
    568 
    569                 JSONArray formats = device.getJSONArray(KEY_FORMATS);
    570                 // Note: Earlier code used field named 'formats' with different data structure.
    571                 // In order to have the mix of old and new data, we cannot reuse that name.
    572                 store.startArray("supported_formats");
    573                 for (int formatIdx = 0; formatIdx < formats.length(); formatIdx++) {
    574                     JSONArray formatPair = formats.getJSONArray(formatIdx);
    575                     JSONObject formatProperties = formatPair.getJSONObject(1);
    576                     store.startGroup();
    577                     {
    578                         store.addResult("format", (long)formatPair.getInt(0));
    579                         emitLong(store, formatProperties, KEY_LINEAR_TILING_FEATURES);
    580                         emitLong(store, formatProperties, KEY_OPTIMAL_TILING_FEATURES);
    581                         emitLong(store, formatProperties, KEY_BUFFER_FEATURES);
    582                     }
    583                     store.endGroup();
    584                 }
    585                 store.endArray();
    586             }
    587             store.endGroup();
    588         }
    589         store.endArray();
    590     }
    591 
    592     private static void emitLayers(DeviceInfoStore store, JSONObject parent)
    593             throws Exception {
    594         JSONArray layers = parent.getJSONArray(KEY_LAYERS);
    595         store.startArray(convertName(KEY_LAYERS));
    596         for (int i = 0; i < layers.length(); i++) {
    597             JSONObject layer = layers.getJSONObject(i);
    598             store.startGroup();
    599             {
    600                 JSONObject properties = layer.getJSONObject(KEY_PROPERTIES);
    601                 store.startGroup(convertName(KEY_PROPERTIES));
    602                 {
    603                     emitString(store, properties, KEY_LAYER_NAME);
    604                     emitLong(store, properties, KEY_SPEC_VERSION);
    605                     emitLong(store, properties, KEY_IMPLEMENTATION_VERSION);
    606                     emitString(store, properties, KEY_DESCRIPTION);
    607                 }
    608                 store.endGroup();
    609                 emitExtensions(store, layer);
    610             }
    611             store.endGroup();
    612         }
    613         store.endArray();
    614     }
    615 
    616     private static void emitExtensions(DeviceInfoStore store, JSONObject parent)
    617             throws Exception {
    618         JSONArray extensions = parent.getJSONArray(KEY_EXTENSIONS);
    619         store.startArray(convertName(KEY_EXTENSIONS));
    620         for (int i = 0; i < extensions.length(); i++) {
    621             JSONObject extension = extensions.getJSONObject(i);
    622             store.startGroup();
    623             {
    624                 emitString(store, extension, KEY_EXTENSION_NAME);
    625                 emitLong(store, extension, KEY_SPEC_VERSION);
    626             }
    627             store.endGroup();
    628         }
    629         store.endArray();
    630     }
    631 
    632     private static void emitBoolean(DeviceInfoStore store, JSONObject parent, String name)
    633             throws Exception {
    634         store.addResult(convertName(name), parent.getInt(name) != 0 ? true : false);
    635     }
    636 
    637     private static void emitLong(DeviceInfoStore store, JSONObject parent, String name)
    638             throws Exception {
    639         store.addResult(convertName(name), parent.getLong(name));
    640     }
    641 
    642     private static void emitDouble(DeviceInfoStore store, JSONObject parent, String name)
    643             throws Exception {
    644         store.addResult(convertName(name), parent.getDouble(name));
    645     }
    646 
    647     private static void emitString(DeviceInfoStore store, JSONObject parent, String name)
    648             throws Exception {
    649         store.addResult(convertName(name), parent.getString(name));
    650     }
    651 
    652     private static void emitLongArray(DeviceInfoStore store, JSONObject parent, String name)
    653             throws Exception {
    654         JSONArray jsonArray = parent.getJSONArray(name);
    655         long[] array = new long[jsonArray.length()];
    656         for (int i = 0; i < jsonArray.length(); i++) {
    657             array[i] = jsonArray.getLong(i);
    658         }
    659         store.addArrayResult(convertName(name), array);
    660     }
    661 
    662     private static void emitDoubleArray(DeviceInfoStore store, JSONObject parent, String name)
    663             throws Exception {
    664         JSONArray jsonArray = parent.getJSONArray(name);
    665         double[] array = new double[jsonArray.length()];
    666         for (int i = 0; i < jsonArray.length(); i++) {
    667             array[i] = jsonArray.getDouble(i);
    668         }
    669         store.addArrayResult(convertName(name), array);
    670     }
    671 
    672     private static String convertName(String name) {
    673         // This translation could be done algorithmically, but in this case being able to
    674         // code-search for both the original and converted names is more important.
    675         switch (name) {
    676             case KEY_ALPHA_TO_ONE: return "alpha_to_one";
    677             case KEY_API_VERSION: return "api_version";
    678             case KEY_BUFFER_FEATURES: return "buffer_features";
    679             case KEY_BUFFER_IMAGE_GRANULARITY: return "buffer_image_granularity";
    680             case KEY_DEPTH: return "depth";
    681             case KEY_DEPTH_BIAS_CLAMP: return "depth_bias_clamp";
    682             case KEY_DEPTH_BOUNDS: return "depth_bounds";
    683             case KEY_DEPTH_CLAMP: return "depth_clamp";
    684             case KEY_DESCRIPTION: return "description";
    685             case KEY_DEVICE_ID: return "device_id";
    686             case KEY_DEVICE_NAME: return "device_name";
    687             case KEY_DEVICE_TYPE: return "device_type";
    688             case KEY_DEVICES: return "devices";
    689             case KEY_DISCRETE_QUEUE_PRIORITIES: return "discrete_queue_priorities";
    690             case KEY_DRAW_INDIRECT_FIRST_INSTANCE: return "draw_indirect_first_instance";
    691             case KEY_DRIVER_VERSION: return "driver_version";
    692             case KEY_DUAL_SRC_BLEND: return "dual_src_blend";
    693             case KEY_EXTENSION_NAME: return "extension_name";
    694             case KEY_EXTENSIONS: return "extensions";
    695             case KEY_FEATURES: return "features";
    696             case KEY_FILL_MODE_NON_SOLID: return "fill_mode_non_solid";
    697             case KEY_FLAGS: return "flags";
    698             case KEY_FORMATS: return "formats";
    699             case KEY_FRAGMENT_STORES_AND_ATOMICS: return "fragment_stores_and_atomics";
    700             case KEY_FRAMEBUFFER_COLOR_SAMPLE_COUNTS: return "framebuffer_color_sample_counts";
    701             case KEY_FRAMEBUFFER_DEPTH_SAMPLE_COUNTS: return "framebuffer_depth_sample_counts";
    702             case KEY_FRAMEBUFFER_NO_ATTACHMENTS_SAMPLE_COUNTS: return "framebuffer_no_attachments_sample_counts";
    703             case KEY_FRAMEBUFFER_STENCIL_SAMPLE_COUNTS: return "framebuffer_stencil_sample_counts";
    704             case KEY_FULL_DRAW_INDEX_UINT32: return "full_draw_index_uint32";
    705             case KEY_GEOMETRY_SHADER: return "geometry_shader";
    706             case KEY_HEAP_INDEX: return "heap_index";
    707             case KEY_HEIGHT: return "height";
    708             case KEY_IMAGE_CUBE_ARRAY: return "image_cube_array";
    709             case KEY_IMPLEMENTATION_VERSION: return "implementation_version";
    710             case KEY_INDEPENDENT_BLEND: return "independent_blend";
    711             case KEY_INHERITED_QUERIES: return "inherited_queries";
    712             case KEY_LARGE_POINTS: return "large_points";
    713             case KEY_LAYER_NAME: return "layer_name";
    714             case KEY_LAYERS: return "layers";
    715             case KEY_LIMITS: return "limits";
    716             case KEY_LINE_WIDTH_GRANULARITY: return "line_width_granularity";
    717             case KEY_LINE_WIDTH_RANGE: return "line_width_range";
    718             case KEY_LINEAR_TILING_FEATURES: return "linear_tiling_features";
    719             case KEY_LOGIC_OP: return "logic_op";
    720             case KEY_MAX_BOUND_DESCRIPTOR_SETS: return "max_bound_descriptor_sets";
    721             case KEY_MAX_CLIP_DISTANCES: return "max_clip_distances";
    722             case KEY_MAX_COLOR_ATTACHMENTS: return "max_color_attachments";
    723             case KEY_MAX_COMBINED_CLIP_AND_CULL_DISTANCES: return "max_combined_clip_and_cull_distances";
    724             case KEY_MAX_COMPUTE_SHARED_MEMORY_SIZE: return "max_compute_shared_memory_size";
    725             case KEY_MAX_COMPUTE_WORK_GROUP_COUNT: return "max_compute_work_group_count";
    726             case KEY_MAX_COMPUTE_WORK_GROUP_INVOCATIONS: return "max_compute_work_group_invocations";
    727             case KEY_MAX_COMPUTE_WORK_GROUP_SIZE: return "max_compute_work_group_size";
    728             case KEY_MAX_CULL_DISTANCES: return "max_cull_distances";
    729             case KEY_MAX_DESCRIPTOR_SET_INPUT_ATTACHMENTS: return "max_descriptor_set_input_attachments";
    730             case KEY_MAX_DESCRIPTOR_SET_SAMPLED_IMAGES: return "max_descriptor_set_sampled_images";
    731             case KEY_MAX_DESCRIPTOR_SET_SAMPLERS: return "max_descriptor_set_samplers";
    732             case KEY_MAX_DESCRIPTOR_SET_STORAGE_BUFFERS: return "max_descriptor_set_storage_buffers";
    733             case KEY_MAX_DESCRIPTOR_SET_STORAGE_BUFFERS_DYNAMIC: return "max_descriptor_set_storage_buffers_dynamic";
    734             case KEY_MAX_DESCRIPTOR_SET_STORAGE_IMAGES: return "max_descriptor_set_storage_images";
    735             case KEY_MAX_DESCRIPTOR_SET_UNIFORM_BUFFERS: return "max_descriptor_set_uniform_buffers";
    736             case KEY_MAX_DESCRIPTOR_SET_UNIFORM_BUFFERS_DYNAMIC: return "max_descriptor_set_uniform_buffers_dynamic";
    737             case KEY_MAX_DRAW_INDEXED_INDEX_VALUE: return "max_draw_indexed_index_value";
    738             case KEY_MAX_DRAW_INDIRECT_COUNT: return "max_draw_indirect_count";
    739             case KEY_MAX_FRAGMENT_COMBINED_OUTPUT_RESOURCES: return "max_fragment_combined_output_resources";
    740             case KEY_MAX_FRAGMENT_DUAL_SRC_ATTACHMENTS: return "max_fragment_dual_src_attachments";
    741             case KEY_MAX_FRAGMENT_INPUT_COMPONENTS: return "max_fragment_input_components";
    742             case KEY_MAX_FRAGMENT_OUTPUT_ATTACHMENTS: return "max_fragment_output_attachments";
    743             case KEY_MAX_FRAMEBUFFER_HEIGHT: return "max_framebuffer_height";
    744             case KEY_MAX_FRAMEBUFFER_LAYERS: return "max_framebuffer_layers";
    745             case KEY_MAX_FRAMEBUFFER_WIDTH: return "max_framebuffer_width";
    746             case KEY_MAX_GEOMETRY_INPUT_COMPONENTS: return "max_geometry_input_components";
    747             case KEY_MAX_GEOMETRY_OUTPUT_COMPONENTS: return "max_geometry_output_components";
    748             case KEY_MAX_GEOMETRY_OUTPUT_VERTICES: return "max_geometry_output_vertices";
    749             case KEY_MAX_GEOMETRY_SHADER_INVOCATIONS: return "max_geometry_shader_invocations";
    750             case KEY_MAX_GEOMETRY_TOTAL_OUTPUT_COMPONENTS: return "max_geometry_total_output_components";
    751             case KEY_MAX_IMAGE_ARRAY_LAYERS: return "max_image_array_layers";
    752             case KEY_MAX_IMAGE_DIMENSION_1D: return "max_image_dimension_1d";
    753             case KEY_MAX_IMAGE_DIMENSION_2D: return "max_image_dimension_2d";
    754             case KEY_MAX_IMAGE_DIMENSION_3D: return "max_image_dimension_3d";
    755             case KEY_MAX_IMAGE_DIMENSION_CUBE: return "max_image_dimension_cube";
    756             case KEY_MAX_INTERPOLATION_OFFSET: return "max_interpolation_offset";
    757             case KEY_MAX_MEMORY_ALLOCATION_COUNT: return "max_memory_allocation_count";
    758             case KEY_MAX_PER_STAGE_DESCRIPTOR_INPUT_ATTACHMENTS: return "max_per_stage_descriptor_input_attachments";
    759             case KEY_MAX_PER_STAGE_DESCRIPTOR_SAMPLED_IMAGES: return "max_per_stage_descriptor_sampled_images";
    760             case KEY_MAX_PER_STAGE_DESCRIPTOR_SAMPLERS: return "max_per_stage_descriptor_samplers";
    761             case KEY_MAX_PER_STAGE_DESCRIPTOR_STORAGE_BUFFERS: return "max_per_stage_descriptor_storage_buffers";
    762             case KEY_MAX_PER_STAGE_DESCRIPTOR_STORAGE_IMAGES: return "max_per_stage_descriptor_storage_images";
    763             case KEY_MAX_PER_STAGE_DESCRIPTOR_UNIFORM_BUFFERS: return "max_per_stage_descriptor_uniform_buffers";
    764             case KEY_MAX_PER_STAGE_RESOURCES: return "max_per_stage_resources";
    765             case KEY_MAX_PUSH_CONSTANTS_SIZE: return "max_push_constants_size";
    766             case KEY_MAX_SAMPLE_MASK_WORDS: return "max_sample_mask_words";
    767             case KEY_MAX_SAMPLER_ALLOCATION_COUNT: return "max_sampler_allocation_count";
    768             case KEY_MAX_SAMPLER_ANISOTROPY: return "max_sampler_anisotropy";
    769             case KEY_MAX_SAMPLER_LOD_BIAS: return "max_sampler_lod_bias";
    770             case KEY_MAX_STORAGE_BUFFER_RANGE: return "max_storage_buffer_range";
    771             case KEY_MAX_TESSELLATION_CONTROL_PER_PATCH_OUTPUT_COMPONENTS: return "max_tessellation_control_per_patch_output_components";
    772             case KEY_MAX_TESSELLATION_CONTROL_PER_VERTEX_INPUT_COMPONENTS: return "max_tessellation_control_per_vertex_input_components";
    773             case KEY_MAX_TESSELLATION_CONTROL_PER_VERTEX_OUTPUT_COMPONENTS: return "max_tessellation_control_per_vertex_output_components";
    774             case KEY_MAX_TESSELLATION_CONTROL_TOTAL_OUTPUT_COMPONENTS: return "max_tessellation_control_total_output_components";
    775             case KEY_MAX_TESSELLATION_EVALUATION_INPUT_COMPONENTS: return "max_tessellation_evaluation_input_components";
    776             case KEY_MAX_TESSELLATION_EVALUATION_OUTPUT_COMPONENTS: return "max_tessellation_evaluation_output_components";
    777             case KEY_MAX_TESSELLATION_GENERATION_LEVEL: return "max_tessellation_generation_level";
    778             case KEY_MAX_TESSELLATION_PATCH_SIZE: return "max_tessellation_patch_size";
    779             case KEY_MAX_TEXEL_BUFFER_ELEMENTS: return "max_texel_buffer_elements";
    780             case KEY_MAX_TEXEL_GATHER_OFFSET: return "max_texel_gather_offset";
    781             case KEY_MAX_TEXEL_OFFSET: return "max_texel_offset";
    782             case KEY_MAX_UNIFORM_BUFFER_RANGE: return "max_uniform_buffer_range";
    783             case KEY_MAX_VERTEX_INPUT_ATTRIBUTE_OFFSET: return "max_vertex_input_attribute_offset";
    784             case KEY_MAX_VERTEX_INPUT_ATTRIBUTES: return "max_vertex_input_attributes";
    785             case KEY_MAX_VERTEX_INPUT_BINDING_STRIDE: return "max_vertex_input_binding_stride";
    786             case KEY_MAX_VERTEX_INPUT_BINDINGS: return "max_vertex_input_bindings";
    787             case KEY_MAX_VERTEX_OUTPUT_COMPONENTS: return "max_vertex_output_components";
    788             case KEY_MAX_VIEWPORT_DIMENSIONS: return "max_viewport_dimensions";
    789             case KEY_MAX_VIEWPORTS: return "max_viewports";
    790             case KEY_MEMORY: return "memory";
    791             case KEY_MEMORY_HEAP_COUNT: return "memory_heap_count";
    792             case KEY_MEMORY_HEAPS: return "memory_heaps";
    793             case KEY_MEMORY_TYPE_COUNT: return "memory_type_count";
    794             case KEY_MEMORY_TYPES: return "memory_types";
    795             case KEY_MIN_IMAGE_TRANSFER_GRANULARITY: return "min_image_transfer_granularity";
    796             case KEY_MIN_INTERPOLATION_OFFSET: return "min_interpolation_offset";
    797             case KEY_MIN_MEMORY_MAP_ALIGNMENT: return "min_memory_map_alignment";
    798             case KEY_MIN_STORAGE_BUFFER_OFFSET_ALIGNMENT: return "min_storage_buffer_offset_alignment";
    799             case KEY_MIN_TEXEL_BUFFER_OFFSET_ALIGNMENT: return "min_texel_buffer_offset_alignment";
    800             case KEY_MIN_TEXEL_GATHER_OFFSET: return "min_texel_gather_offset";
    801             case KEY_MIN_TEXEL_OFFSET: return "min_texel_offset";
    802             case KEY_MIN_UNIFORM_BUFFER_OFFSET_ALIGNMENT: return "min_uniform_buffer_offset_alignment";
    803             case KEY_MIPMAP_PRECISION_BITS: return "mipmap_precision_bits";
    804             case KEY_MULTI_DRAW_INDIRECT: return "multi_draw_indirect";
    805             case KEY_MULTI_VIEWPORT: return "multi_viewport";
    806             case KEY_NON_COHERENT_ATOM_SIZE: return "non_coherent_atom_size";
    807             case KEY_OCCLUSION_QUERY_PRECISE: return "occlusion_query_precise";
    808             case KEY_OPTIMAL_BUFFER_COPY_OFFSET_ALIGNMENT: return "optimal_buffer_copy_offset_alignment";
    809             case KEY_OPTIMAL_BUFFER_COPY_ROW_PITCH_ALIGNMENT: return "optimal_buffer_copy_row_pitch_alignment";
    810             case KEY_OPTIMAL_TILING_FEATURES: return "optimal_tiling_features";
    811             case KEY_PIPELINE_CACHE_UUID: return "pipeline_cache_uuid";
    812             case KEY_PIPELINE_STATISTICS_QUERY: return "pipeline_statistics_query";
    813             case KEY_POINT_SIZE_GRANULARITY: return "point_size_granularity";
    814             case KEY_POINT_SIZE_RANGE: return "point_size_range";
    815             case KEY_PROPERTIES: return "properties";
    816             case KEY_PROPERTY_FLAGS: return "property_flags";
    817             case KEY_QUEUE_COUNT: return "queue_count";
    818             case KEY_QUEUE_FLAGS: return "queue_flags";
    819             case KEY_QUEUES: return "queues";
    820             case KEY_RESIDENCY_ALIGNED_MIP_SIZE: return "residency_aligned_mip_size";
    821             case KEY_RESIDENCY_NON_RESIDENT_STRICT: return "residency_non_resident_strict";
    822             case KEY_RESIDENCY_STANDARD_2D_BLOCK_SHAPE: return "residency_standard_2d_block_shape";
    823             case KEY_RESIDENCY_STANDARD_2D_MULTISAMPLE_BLOCK_SHAPE: return "residency_standard_2d_multisample_block_shape";
    824             case KEY_RESIDENCY_STANDARD_3D_BLOCK_SHAPE: return "residency_standard_3d_block_shape";
    825             case KEY_ROBUST_BUFFER_ACCESS: return "robust_buffer_access";
    826             case KEY_SAMPLE_RATE_SHADING: return "sample_rate_shading";
    827             case KEY_SAMPLED_IMAGE_COLOR_SAMPLE_COUNTS: return "sampled_image_color_sample_counts";
    828             case KEY_SAMPLED_IMAGE_DEPTH_SAMPLE_COUNTS: return "sampled_image_depth_sample_counts";
    829             case KEY_SAMPLED_IMAGE_INTEGER_SAMPLE_COUNTS: return "sampled_image_integer_sample_counts";
    830             case KEY_SAMPLED_IMAGE_STENCIL_SAMPLE_COUNTS: return "sampled_image_stencil_sample_counts";
    831             case KEY_SAMPLER_ANISOTROPY: return "sampler_anisotropy";
    832             case KEY_SHADER_CLIP_DISTANCE: return "shader_clip_distance";
    833             case KEY_SHADER_CULL_DISTANCE: return "shader_cull_distance";
    834             case KEY_SHADER_FLOAT64: return "shader_float64";
    835             case KEY_SHADER_IMAGE_GATHER_EXTENDED: return "shader_image_gather_extended";
    836             case KEY_SHADER_INT16: return "shader_int16";
    837             case KEY_SHADER_INT64: return "shader_int64";
    838             case KEY_SHADER_RESOURCE_MIN_LOD: return "shader_resource_min_lod";
    839             case KEY_SHADER_RESOURCE_RESIDENCY: return "shader_resource_residency";
    840             case KEY_SHADER_SAMPLED_IMAGE_ARRAY_DYNAMIC_INDEXING: return "shader_sampled_image_array_dynamic_indexing";
    841             case KEY_SHADER_STORAGE_BUFFER_ARRAY_DYNAMIC_INDEXING: return "shader_storage_buffer_array_dynamic_indexing";
    842             case KEY_SHADER_STORAGE_IMAGE_ARRAY_DYNAMIC_INDEXING: return "shader_storage_image_array_dynamic_indexing";
    843             case KEY_SHADER_STORAGE_IMAGE_EXTENDED_FORMATS: return "shader_storage_image_extended_formats";
    844             case KEY_SHADER_STORAGE_IMAGE_MULTISAMPLE: return "shader_storage_image_multisample";
    845             case KEY_SHADER_STORAGE_IMAGE_READ_WITHOUT_FORMAT: return "shader_storage_image_read_without_format";
    846             case KEY_SHADER_STORAGE_IMAGE_WRITE_WITHOUT_FORMAT: return "shader_storage_image_write_without_format";
    847             case KEY_SHADER_TESSELLATION_AND_GEOMETRY_POINT_SIZE: return "shader_tessellation_and_geometry_point_size";
    848             case KEY_SHADER_UNIFORM_BUFFER_ARRAY_DYNAMIC_INDEXING: return "shader_uniform_buffer_array_dynamic_indexing";
    849             case KEY_SIZE: return "size";
    850             case KEY_SPARSE_ADDRESS_SPACE_SIZE: return "sparse_address_space_size";
    851             case KEY_SPARSE_BINDING: return "sparse_binding";
    852             case KEY_SPARSE_PROPERTIES: return "sparse_properties";
    853             case KEY_SPARSE_RESIDENCY_16_SAMPLES: return "sparse_residency_16_samples";
    854             case KEY_SPARSE_RESIDENCY_2_SAMPLES: return "sparse_residency_2_samples";
    855             case KEY_SPARSE_RESIDENCY_4_SAMPLES: return "sparse_residency_4_samples";
    856             case KEY_SPARSE_RESIDENCY_8_SAMPLES: return "sparse_residency_8_samples";
    857             case KEY_SPARSE_RESIDENCY_ALIASED: return "sparse_residency_aliased";
    858             case KEY_SPARSE_RESIDENCY_BUFFER: return "sparse_residency_buffer";
    859             case KEY_SPARSE_RESIDENCY_IMAGE_2D: return "sparse_residency_image_2d";
    860             case KEY_SPARSE_RESIDENCY_IMAGE_3D: return "sparse_residency_image_3d";
    861             case KEY_SPEC_VERSION: return "spec_version";
    862             case KEY_STANDARD_SAMPLE_LOCATIONS: return "standard_sample_locations";
    863             case KEY_STORAGE_IMAGE_SAMPLE_COUNTS: return "storage_image_sample_counts";
    864             case KEY_STRICT_LINES: return "strict_lines";
    865             case KEY_SUB_PIXEL_INTERPOLATION_OFFSET_BITS: return "sub_pixel_interpolation_offset_bits";
    866             case KEY_SUB_PIXEL_PRECISION_BITS: return "sub_pixel_precision_bits";
    867             case KEY_SUB_TEXEL_PRECISION_BITS: return "sub_texel_precision_bits";
    868             case KEY_TESSELLATION_SHADER: return "tessellation_shader";
    869             case KEY_TEXTURE_COMPRESSION_ASTC_LDR: return "texture_compression_astc_ldr";
    870             case KEY_TEXTURE_COMPRESSION_BC: return "texture_compression_bc";
    871             case KEY_TEXTURE_COMPRESSION_ETC2: return "texture_compression_etc2";
    872             case KEY_TIMESTAMP_COMPUTE_AND_GRAPHICS: return "timestamp_compute_and_graphics";
    873             case KEY_TIMESTAMP_PERIOD: return "timestamp_period";
    874             case KEY_TIMESTAMP_VALID_BITS: return "timestamp_valid_bits";
    875             case KEY_VARIABLE_MULTISAMPLE_RATE: return "variable_multisample_rate";
    876             case KEY_VENDOR_ID: return "vendor_id";
    877             case KEY_VERTEX_PIPELINE_STORES_AND_ATOMICS: return "vertex_pipeline_stores_and_atomics";
    878             case KEY_VIEWPORT_BOUNDS_RANGE: return "viewport_bounds_range";
    879             case KEY_VIEWPORT_SUB_PIXEL_BITS: return "viewport_sub_pixel_bits";
    880             case KEY_WIDE_LINES: return "wide_lines";
    881             case KEY_WIDTH: return "width";
    882             default: throw new RuntimeException("unknown key name: " + name);
    883         }
    884     }
    885 
    886     private static native String nativeGetVkJSON();
    887 
    888 }
    889