/*
 * Copyright 2016 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.
 */

package android.graphics.cts;

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;
import static org.junit.Assume.assumeTrue;

import android.content.pm.FeatureInfo;
import android.content.pm.PackageManager;
import android.util.Log;

import androidx.test.InstrumentationRegistry;
import androidx.test.filters.SmallTest;
import androidx.test.runner.AndroidJUnit4;

import com.android.compatibility.common.util.CddTest;
import com.android.compatibility.common.util.PropertyUtil;

import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;

/**
 * Test that the Vulkan loader is present, supports the required extensions, and that system
 * features accurately indicate the capabilities of the Vulkan driver if one exists.
 */
@SmallTest
@RunWith(AndroidJUnit4.class)
public class VulkanFeaturesTest {

    static {
        System.loadLibrary("ctsgraphics_jni");
    }

    private static final String TAG = VulkanFeaturesTest.class.getSimpleName();
    private static final boolean DEBUG = false;

    // Require patch version 3 for Vulkan 1.0: It was the first publicly available version,
    // and there was an important bugfix relative to 1.0.2.
    private static final int VULKAN_1_0 = 0x00400003; // 1.0.3
    private static final int VULKAN_1_1 = 0x00401000; // 1.1.0
    private static final int VULKAN_1_2 = 0x00402000; // 1.2.0
    private static final int VULKAN_1_3 = 0x00403000; // 1.3.0

    private static final String VK_ANDROID_EXTERNAL_MEMORY_ANDROID_HARDWARE_BUFFER_EXTENSION_NAME =
            "VK_ANDROID_external_memory_android_hardware_buffer";
    private static final int VK_ANDROID_EXTERNAL_MEMORY_ANDROID_HARDWARE_BUFFER_SPEC_VERSION = 2;
    private static final int VK_EXTERNAL_FENCE_HANDLE_TYPE_SYNC_FD_BIT = 0x8;
    private static final int VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_SYNC_FD_BIT = 0x10;
    private static final int VK_PHYSICAL_DEVICE_TYPE_CPU = 4;

    private static final int API_LEVEL_BEFORE_ANDROID_HARDWARE_BUFFER_REQ = 28;

    private PackageManager mPm;
    private FeatureInfo mVulkanHardwareLevel = null;
    private FeatureInfo mVulkanHardwareVersion = null;
    private FeatureInfo mVulkanHardwareCompute = null;
    private JSONObject mVkJSON = null;
    private JSONObject mVulkanDevices[];
    private JSONObject mBestDevice = null;

    @Before
    public void setup() throws Throwable {
        mPm = InstrumentationRegistry.getTargetContext().getPackageManager();
        FeatureInfo features[] = mPm.getSystemAvailableFeatures();
        if (features != null) {
            for (FeatureInfo feature : features) {
                if (PackageManager.FEATURE_VULKAN_HARDWARE_LEVEL.equals(feature.name)) {
                    mVulkanHardwareLevel = feature;
                    if (DEBUG) {
                        Log.d(TAG, feature.name + "=" + feature.version);
                    }
                } else if (PackageManager.FEATURE_VULKAN_HARDWARE_VERSION.equals(feature.name)) {
                    mVulkanHardwareVersion = feature;
                    if (DEBUG) {
                        Log.d(TAG, feature.name + "=0x" + Integer.toHexString(feature.version));
                    }
                } else if (PackageManager.FEATURE_VULKAN_HARDWARE_COMPUTE.equals(feature.name)) {
                    mVulkanHardwareCompute = feature;
                    if (DEBUG) {
                        Log.d(TAG, feature.name + "=" + feature.version);
                    }
                }
            }
        }

        mVkJSON = new JSONObject(nativeGetVkJSON());
        mVulkanDevices = getVulkanDevices(mVkJSON);
        mBestDevice = getBestDevice();
    }
    @CddTest(requirement = "7.1.4.2/C-1-1,C-2-1")
    @Test
    public void testVulkanHardwareFeatures() throws JSONException {
        if (DEBUG) {
            Log.d(TAG, "Inspecting " + mVulkanDevices.length + " devices");
        }
        if (mVulkanDevices.length == 0) {
            assertNull("System feature " + PackageManager.FEATURE_VULKAN_HARDWARE_LEVEL +
                       " is supported, but no Vulkan physical devices are available",
                       mVulkanHardwareLevel);
            assertNull("System feature " + PackageManager.FEATURE_VULKAN_HARDWARE_VERSION +
                       " is supported, but no Vulkan physical devices are available",
                       mVulkanHardwareLevel);
            assertNull("System feature " + PackageManager.FEATURE_VULKAN_HARDWARE_COMPUTE +
                       " is supported, but no Vulkan physical devices are available",
                       mVulkanHardwareCompute);
            return;
        }

        if (hasOnlyCpuDevice()) {
            return;
        }

        assertNotNull("Vulkan physical devices are available, but system feature " +
                      PackageManager.FEATURE_VULKAN_HARDWARE_LEVEL + " is not supported",
                      mVulkanHardwareLevel);
        assertNotNull("Vulkan physical devices are available, but system feature " +
                      PackageManager.FEATURE_VULKAN_HARDWARE_VERSION + " is not supported",
                      mVulkanHardwareVersion);
        if (mVulkanHardwareLevel == null || mVulkanHardwareVersion == null) {
            return;
        }

        assertTrue("System feature " + PackageManager.FEATURE_VULKAN_HARDWARE_LEVEL +
                   " version " + mVulkanHardwareLevel.version + " is not one of the defined " +
                   " versions [0..1]",
                   mVulkanHardwareLevel.version >= 0 && mVulkanHardwareLevel.version <= 1);
        assertTrue("System feature " + PackageManager.FEATURE_VULKAN_HARDWARE_VERSION +
                   " version 0x" + Integer.toHexString(mVulkanHardwareVersion.version) + " is not" +
                   " one of the versions allowed",
                   isHardwareVersionAllowed(mVulkanHardwareVersion.version));
        if (mVulkanHardwareCompute != null) {
            assertTrue("System feature " + PackageManager.FEATURE_VULKAN_HARDWARE_COMPUTE +
                       " version " + mVulkanHardwareCompute.version +
                       " is not one of the versions allowed",
                       mVulkanHardwareCompute.version == 0);
        }

        int bestDeviceLevel = determineHardwareLevel(mBestDevice);
        int bestComputeLevel = determineHardwareCompute(mBestDevice);
        int bestDeviceVersion = determineHardwareVersion(mBestDevice);

        assertEquals("System feature " + PackageManager.FEATURE_VULKAN_HARDWARE_LEVEL +
            " version " + mVulkanHardwareLevel.version + " doesn't match best physical device " +
            " hardware level " + bestDeviceLevel,
            bestDeviceLevel, mVulkanHardwareLevel.version);
        assertTrue(
            "System feature " + PackageManager.FEATURE_VULKAN_HARDWARE_VERSION +
            " version 0x" + Integer.toHexString(mVulkanHardwareVersion.version) +
            " isn't close enough (same major and minor version, less or equal patch version)" +
            " to best physical device version 0x" + Integer.toHexString(bestDeviceVersion),
            isVersionCompatible(bestDeviceVersion, mVulkanHardwareVersion.version));
        if (mVulkanHardwareCompute == null) {
            assertEquals("System feature " + PackageManager.FEATURE_VULKAN_HARDWARE_COMPUTE +
                " not present, but required features are supported",
                bestComputeLevel, -1);
        } else {
            assertEquals("System feature " + PackageManager.FEATURE_VULKAN_HARDWARE_COMPUTE +
                " version " + mVulkanHardwareCompute.version +
                " doesn't match best physical device (version: " + bestComputeLevel + ")",
                bestComputeLevel, mVulkanHardwareCompute.version);
        }
    }

    @CddTest(requirement = "7.1.4.2/C-3-1")
    @Test
    public void testVulkan1_1Requirements() throws JSONException {
        if (mVulkanHardwareVersion == null || mVulkanHardwareVersion.version < VULKAN_1_1
                || !PropertyUtil.isVendorApiLevelNewerThan(
                        API_LEVEL_BEFORE_ANDROID_HARDWARE_BUFFER_REQ)) {
            return;
        }
        assertTrue("Devices with Vulkan 1.1 must support sampler YCbCr conversion",
                mBestDevice.getJSONObject("samplerYcbcrConversionFeatures")
                           .getInt("samplerYcbcrConversion") != 0);

        if (hasOnlyCpuDevice()) {
            return;
        }
        assertTrue("Devices with Vulkan 1.1 must support " +
                VK_ANDROID_EXTERNAL_MEMORY_ANDROID_HARDWARE_BUFFER_EXTENSION_NAME +
                " (version >= " + VK_ANDROID_EXTERNAL_MEMORY_ANDROID_HARDWARE_BUFFER_SPEC_VERSION +
                ")",
                hasDeviceExtension(mBestDevice,
                    VK_ANDROID_EXTERNAL_MEMORY_ANDROID_HARDWARE_BUFFER_EXTENSION_NAME,
                    VK_ANDROID_EXTERNAL_MEMORY_ANDROID_HARDWARE_BUFFER_SPEC_VERSION));
        assertTrue("Devices with Vulkan 1.1 must support SYNC_FD external semaphores",
                hasHandleType(mBestDevice.getJSONArray("externalSemaphoreProperties"),
                    VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_SYNC_FD_BIT,
                    "externalSemaphoreFeatures", 0x3 /* importable + exportable */));
        assertTrue("Devices with Vulkan 1.1 must support SYNC_FD external fences",
                hasHandleType(mBestDevice.getJSONArray("externalFenceProperties"),
                    VK_EXTERNAL_FENCE_HANDLE_TYPE_SYNC_FD_BIT,
                    "externalFenceFeatures", 0x3 /* importable + exportable */));
    }

    @CddTest(requirement = "7.1.4.2/C-1-7")
    @Test
    public void testVulkanRequiredExtensions() throws JSONException {
        assumeTrue("Skipping because Vulkan is not supported", mVulkanDevices.length > 0);

        assertVulkanInstanceExtension("VK_KHR_surface", 25);
        assertVulkanInstanceExtension("VK_KHR_android_surface", 6);
        assertVulkanDeviceExtension("VK_KHR_swapchain", 68);
        assertVulkanDeviceExtension("VK_KHR_incremental_present", 1);
    }

    @CddTest(requirement = "7.9.2/C-1-5")
    @Test
    public void testVulkanVersionForVrHighPerformance() {
        if (!mPm.hasSystemFeature(PackageManager.FEATURE_VR_MODE_HIGH_PERFORMANCE))
            return;
        assertTrue(
            "VR high-performance devices must support Vulkan 1.0 with Hardware Level 0, " +
            "but this device does not.",
            mVulkanHardwareVersion != null && mVulkanHardwareVersion.version >= VULKAN_1_0 &&
            mVulkanHardwareLevel != null && mVulkanHardwareLevel.version >= 0);
    }

    @CddTest(requirement = "7.1.4.2/C-1-11")
    @Test
    public void testVulkanBlockedExtensions() throws JSONException {
        assertNoVulkanDeviceExtension("VK_KHR_performance_query");
        assertNoVulkanDeviceExtension("VK_KHR_video_queue");
        assertNoVulkanDeviceExtension("VK_KHR_video_decode_queue");
        assertNoVulkanDeviceExtension("VK_KHR_video_encode_queue");
    }

    @CddTest(requirement = "7.1.4.2")
    @Test
    public void testVulkanVariantSupport() throws JSONException {
        int expectedVariant = 0x0;
        int actualVariant = (mVulkanHardwareVersion.version >> 29) & 0x7;
        assertEquals(expectedVariant, actualVariant);
    }

    private JSONObject getBestDevice() throws JSONException {
        JSONObject bestDevice = null;
        int bestDeviceLevel = -1;
        int bestComputeLevel = -1;
        int bestDeviceVersion = -1;
        for (JSONObject device : mVulkanDevices) {
            int level = determineHardwareLevel(device);
            int compute = determineHardwareCompute(device);
            int version = determineHardwareVersion(device);
            if (DEBUG) {
                Log.d(TAG, device.getJSONObject("properties").getString("deviceName") +
                    ": level=" + level + " compute=" + compute +
                    " version=0x" + Integer.toHexString(version));
            }
            if (level >= bestDeviceLevel && compute >= bestComputeLevel &&
                    version >= bestDeviceVersion) {
                bestDevice = device;
                bestDeviceLevel = level;
                bestComputeLevel = compute;
                bestDeviceVersion = version;
            }
        }
        return bestDevice;
    }

    private boolean hasOnlyCpuDevice() throws JSONException {
        for (JSONObject device : mVulkanDevices) {
            if (device.getJSONObject("properties").getInt("deviceType")
                    != VK_PHYSICAL_DEVICE_TYPE_CPU) {
                return false;
            }
        }
        return true;
    }

    private int determineHardwareLevel(JSONObject device) throws JSONException {
        JSONObject features = device.getJSONObject("features");
        boolean textureCompressionETC2 = features.getInt("textureCompressionETC2") != 0;
        boolean fullDrawIndexUint32 = features.getInt("fullDrawIndexUint32") != 0;
        boolean imageCubeArray = features.getInt("imageCubeArray") != 0;
        boolean independentBlend = features.getInt("independentBlend") != 0;
        boolean geometryShader = features.getInt("geometryShader") != 0;
        boolean tessellationShader = features.getInt("tessellationShader") != 0;
        boolean sampleRateShading = features.getInt("sampleRateShading") != 0;
        boolean textureCompressionASTC_LDR = features.getInt("textureCompressionASTC_LDR") != 0;
        boolean fragmentStoresAndAtomics = features.getInt("fragmentStoresAndAtomics") != 0;
        boolean shaderImageGatherExtended = features.getInt("shaderImageGatherExtended") != 0;
        boolean shaderUniformBufferArrayDynamicIndexing = features.getInt("shaderUniformBufferArrayDynamicIndexing") != 0;
        boolean shaderSampledImageArrayDynamicIndexing = features.getInt("shaderSampledImageArrayDynamicIndexing") != 0;
        if (!textureCompressionETC2) {
            return -1;
        }
        if (!fullDrawIndexUint32 ||
            !imageCubeArray ||
            !independentBlend ||
            !geometryShader ||
            !tessellationShader ||
            !sampleRateShading ||
            !textureCompressionASTC_LDR ||
            !fragmentStoresAndAtomics ||
            !shaderImageGatherExtended ||
            !shaderUniformBufferArrayDynamicIndexing ||
            !shaderSampledImageArrayDynamicIndexing) {
            return 0;
        }
        return 1;
    }

    private int determineHardwareCompute(JSONObject device) throws JSONException {
        boolean variablePointers = false;
        try {
            variablePointers = device.getJSONObject("variablePointerFeatures")
                                             .getInt("variablePointers") != 0;
        } catch (JSONException exp) {
            try {
                variablePointers = device.getJSONObject("VK_KHR_variable_pointers")
                                                 .getJSONObject("variablePointerFeaturesKHR")
                                                 .getInt("variablePointers") != 0;
            }  catch (JSONException exp2) {
                variablePointers = false;
            }
        }
        JSONObject limits = device.getJSONObject("properties").getJSONObject("limits");
        int maxPerStageDescriptorStorageBuffers = limits.getInt("maxPerStageDescriptorStorageBuffers");
        if (DEBUG) {
            Log.d(TAG, device.getJSONObject("properties").getString("deviceName") +
                ": variablePointers=" + variablePointers +
                " maxPerStageDescriptorStorageBuffers=" + maxPerStageDescriptorStorageBuffers);
        }
        if (!variablePointers || maxPerStageDescriptorStorageBuffers < 16)
            return -1;
        return 0;
    }

    private int determineHardwareVersion(JSONObject device) throws JSONException {
        return device.getJSONObject("properties").getInt("apiVersion");
    }

    private boolean isVersionCompatible(int expected, int actual) {
        int expectedVariant = (expected >> 29) & 0x7;
        int expectedMajor   = (expected >> 22) & 0x7F;
        int expectedMinor   = (expected >> 12) & 0x3FF;
        int expectedPatch   = (expected >>  0) & 0xFFF;
        int actualVariant = (actual >> 29) & 0x7;
        int actualMajor   = (actual >> 22) & 0x7F;
        int actualMinor   = (actual >> 12) & 0x3FF;
        int actualPatch   = (actual >>  0) & 0xFFF;
        return (actualVariant == expectedVariant)
            && (actualMajor == expectedMajor)
            && (actualMinor == expectedMinor)
            && (actualPatch <= expectedPatch);
    }

    private boolean isHardwareVersionAllowed(int actual) {
        // Limit which system feature hardware versions are allowed. If a new major/minor version
        // is released, we don't want devices claiming support for it until tests for the new
        // version are available. And only claiming support for a base patch level per major/minor
        // pair reduces fragmentation seen by developers. Patch-level changes are supposed to be
        // forwards and backwards compatible; if a developer *really* needs to alter behavior based
        // on the patch version, they can do so at runtime, but must be able to handle previous
        // patch versions.
        final int[] ALLOWED_HARDWARE_VERSIONS = {
            VULKAN_1_0,
            VULKAN_1_1,
            VULKAN_1_2,
            VULKAN_1_3,
        };
        for (int expected : ALLOWED_HARDWARE_VERSIONS) {
            if (actual == expected) {
                return true;
            }
        }
        return false;
    }

    private void assertVulkanDeviceExtension(final String name, final int minVersion)
            throws JSONException {
        assertTrue(
                String.format(
                        "Devices with Vulkan must support device extension %s (version >= %d)",
                        name,
                        minVersion),
                hasDeviceExtension(mBestDevice, name, minVersion));
    }

    private void assertNoVulkanDeviceExtension(final String name)
            throws JSONException {
        for (JSONObject device : mVulkanDevices) {
            assertTrue(
                    String.format("Devices must not support Vulkan device extension %s", name),
                    !hasDeviceExtension(device, name, 0));
        }
    }

    private void assertVulkanInstanceExtension(final String name, final int minVersion)
            throws JSONException {
        assertTrue(
                String.format(
                        "Devices with Vulkan must support instance extension %s (version >= %d)",
                        name,
                        minVersion),
                hasInstanceExtension(name, minVersion));
    }

    private static boolean hasDeviceExtension(
            final JSONObject device,
            final String name,
            final int minVersion) throws JSONException {
        final JSONArray deviceExtensions = device.getJSONArray("extensions");
        return hasExtension(deviceExtensions, name, minVersion);
    }

    private boolean hasInstanceExtension(
            final String name,
            final int minVersion) throws JSONException {
        // Instance extensions are in the top-level vkjson object.
        final JSONArray instanceExtensions = mVkJSON.getJSONArray("extensions");
        return hasExtension(instanceExtensions, name, minVersion);
    }

    private static boolean hasExtension(
            final JSONArray extensions,
            final String name,
            final int minVersion) throws JSONException {
        for (int i = 0; i < extensions.length(); i++) {
            JSONObject ext = extensions.getJSONObject(i);
            if (ext.getString("extensionName").equals(name) &&
                    ext.getInt("specVersion") >= minVersion)
                return true;
        }
        return false;
    }

    private boolean hasHandleType(JSONArray handleTypes, int type,
            String featuresName, int requiredFeatures) throws JSONException {
        for (int i = 0; i < handleTypes.length(); i++) {
            JSONArray typeRecord = handleTypes.getJSONArray(i);
            if (typeRecord.getInt(0) == type) {
                JSONObject typeInfo = typeRecord.getJSONObject(1);
                if ((typeInfo.getInt(featuresName) & requiredFeatures) == requiredFeatures)
                    return true;
            }
        }
        return false;
    }

    private static native String nativeGetVkJSON();

    private static JSONObject[] getVulkanDevices(final JSONObject vkJSON) throws JSONException {
        JSONArray devicesArray = vkJSON.getJSONArray("devices");
        JSONObject[] devices = new JSONObject[devicesArray.length()];
        for (int i = 0; i < devicesArray.length(); i++) {
            devices[i] = devicesArray.getJSONObject(i);
        }
        return devices;
    }
}
