// Copyright 2005, Google Inc.
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
//     * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
//     * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
//     * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.


//  XGL tests
//
//  Copyright (C) 2014 LunarG, Inc.
//
//  Permission is hereby granted, free of charge, to any person obtaining a
//  copy of this software and associated documentation files (the "Software"),
//  to deal in the Software without restriction, including without limitation
//  the rights to use, copy, modify, merge, publish, distribute, sublicense,
//  and/or sell copies of the Software, and to permit persons to whom the
//  Software is furnished to do so, subject to the following conditions:
//
//  The above copyright notice and this permission notice shall be included
//  in all copies or substantial portions of the Software.
//
//  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
//  IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
//  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
//  THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
//  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
//  FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
//  DEALINGS IN THE SOFTWARE.


// Verify XGL driver initialization

#include <stdlib.h>
#include <stdio.h>
#include <stdbool.h>
#include <string.h>

#include <xgl.h>
#include "gtest-1.7.0/include/gtest/gtest.h"

#include "xgltestbinding.h"
#include "test_common.h"
#include "icd-spv.h"

class XglTest : public ::testing::Test {
public:
    void CreateImageTest();
    void CreateCommandBufferTest();
    void CreatePipelineTest();
    void CreateShaderTest();
    void CreateShader(XGL_SHADER *pshader);

    XGL_DEVICE device() {return m_device->obj();}

protected:
    XGL_APPLICATION_INFO app_info;
    XGL_INSTANCE inst;
    XGL_PHYSICAL_GPU objs[XGL_MAX_PHYSICAL_GPUS];
    uint32_t gpu_count;

    uint32_t m_device_id;
    xgl_testing::Device *m_device;
    XGL_PHYSICAL_GPU_PROPERTIES props;
    std::vector<XGL_PHYSICAL_GPU_QUEUE_PROPERTIES> queue_props;
    uint32_t graphics_queue_node_index;

    virtual void SetUp() {
        XGL_RESULT err;
        int i;

        this->app_info.sType = XGL_STRUCTURE_TYPE_APPLICATION_INFO;
        this->app_info.pNext = NULL;
        this->app_info.pAppName = "base";
        this->app_info.appVersion = 1;
        this->app_info.pEngineName = "unittest";
        this->app_info.engineVersion = 1;
        this->app_info.apiVersion = XGL_API_VERSION;

        err = xglCreateInstance(&app_info, NULL, &inst);
        ASSERT_XGL_SUCCESS(err);
        err = xglEnumerateGpus(inst, XGL_MAX_PHYSICAL_GPUS, &this->gpu_count,
                               objs);
        ASSERT_XGL_SUCCESS(err);
        ASSERT_GE(this->gpu_count, 1) << "No GPU available";

        m_device_id = 0;
        this->m_device = new xgl_testing::Device(objs[m_device_id]);
        this->m_device->init();

        props = m_device->gpu().properties();

        queue_props = this->m_device->gpu().queue_properties();
        for (i = 0; i < queue_props.size(); i++) {
            if (queue_props[i].queueFlags & XGL_QUEUE_GRAPHICS_BIT) {
                graphics_queue_node_index = i;
                break;
            }
        }
        ASSERT_LT(i, queue_props.size()) << "Could not find a Queue with Graphics support";
    }

    virtual void TearDown() {
        xglDestroyInstance(inst);
    }
};

TEST(Initialization, xglEnumerateGpus) {
    XGL_APPLICATION_INFO app_info = {};
    XGL_INSTANCE inst;
    XGL_PHYSICAL_GPU objs[XGL_MAX_PHYSICAL_GPUS];
    uint32_t gpu_count;
    XGL_RESULT err;
    xgl_testing::PhysicalGpu *gpu;
    char *layers[16];
    size_t layer_count;
    char layer_buf[16][256];

    app_info.sType = XGL_STRUCTURE_TYPE_APPLICATION_INFO;
    app_info.pNext = NULL;
    app_info.pAppName = "base";
    app_info.appVersion = 1;
    app_info.pEngineName = "unittest";
    app_info.engineVersion = 1;
    app_info.apiVersion = XGL_API_VERSION;

    err = xglCreateInstance(&app_info, NULL, &inst);
    ASSERT_XGL_SUCCESS(err);
    err = xglEnumerateGpus(inst, XGL_MAX_PHYSICAL_GPUS, &gpu_count, objs);
    ASSERT_XGL_SUCCESS(err);
    ASSERT_GE(gpu_count, 1) << "No GPU available";

    for (int i = 0; i < 16; i++)
        layers[i] = &layer_buf[i][0];
    err = xglEnumerateLayers(objs[0], 16, 256, &layer_count, (char * const *) layers, NULL);
    ASSERT_XGL_SUCCESS(err);
    for (int i = 0; i < layer_count; i++) {
        printf("Enumerated layers: %s ", layers[i]);
    }
    printf("\n");

    // TODO: Iterate over all GPUs
    gpu = new xgl_testing::PhysicalGpu(objs[0]);
    delete gpu;

    // TODO: Verify destroy functions
    err = xglDestroyInstance(inst);
    ASSERT_XGL_SUCCESS(err);
}

TEST_F(XglTest, AllocMemory) {
    XGL_RESULT err;
    XGL_MEMORY_ALLOC_INFO alloc_info = {};
    XGL_GPU_MEMORY gpu_mem;
    uint8_t *pData;

    alloc_info.sType = XGL_STRUCTURE_TYPE_MEMORY_ALLOC_INFO;
    alloc_info.allocationSize = 1024 * 1024; // 1MB
    alloc_info.memProps = XGL_MEMORY_PROPERTY_SHAREABLE_BIT |
                          XGL_MEMORY_PROPERTY_CPU_VISIBLE_BIT;
    alloc_info.memType = XGL_MEMORY_TYPE_OTHER;


    // TODO: Try variety of memory priorities
    alloc_info.memPriority = XGL_MEMORY_PRIORITY_NORMAL;

    err = xglAllocMemory(device(), &alloc_info, &gpu_mem);
    ASSERT_XGL_SUCCESS(err);

    err = xglMapMemory(gpu_mem, 0, (void **) &pData);
    ASSERT_XGL_SUCCESS(err);

    memset(pData, 0x55, alloc_info.allocationSize);
    EXPECT_EQ(0x55, pData[0]) << "Memory read not same a write";

    err = xglUnmapMemory(gpu_mem);
    ASSERT_XGL_SUCCESS(err);

    err = xglFreeMemory(gpu_mem);
    ASSERT_XGL_SUCCESS(err);
}

TEST_F(XglTest, Event) {
    XGL_EVENT_CREATE_INFO event_info;
    XGL_EVENT event;
    XGL_MEMORY_REQUIREMENTS mem_req;
    size_t data_size = sizeof(mem_req);
    XGL_RESULT err;

    //        typedef struct _XGL_EVENT_CREATE_INFO
    //        {
    //            XGL_STRUCTURE_TYPE                      sType;      // Must be XGL_STRUCTURE_TYPE_EVENT_CREATE_INFO
    //            const void*                             pNext;      // Pointer to next structure
    //            XGL_FLAGS                               flags;      // Reserved
    //        } XGL_EVENT_CREATE_INFO;
    memset(&event_info, 0, sizeof(event_info));
    event_info.sType = XGL_STRUCTURE_TYPE_EVENT_CREATE_INFO;

    err = xglCreateEvent(device(), &event_info, &event);
    ASSERT_XGL_SUCCESS(err);

    err = xglGetObjectInfo(event, XGL_INFO_TYPE_MEMORY_REQUIREMENTS,
                           &data_size, &mem_req);
    ASSERT_XGL_SUCCESS(err);

    //        XGL_RESULT XGLAPI xglAllocMemory(
    //            XGL_DEVICE                                  device,
    //            const XGL_MEMORY_ALLOC_INFO*                pAllocInfo,
    //            XGL_GPU_MEMORY*                             pMem);
    XGL_MEMORY_ALLOC_INFO mem_info;
    XGL_GPU_MEMORY event_mem;

    ASSERT_NE(0, mem_req.size) << "xglGetObjectInfo (Event): Failed - expect events to require memory";

    memset(&mem_info, 0, sizeof(mem_info));
    mem_info.sType = XGL_STRUCTURE_TYPE_MEMORY_ALLOC_INFO;
    mem_info.allocationSize = mem_req.size;
    mem_info.memProps = XGL_MEMORY_PROPERTY_SHAREABLE_BIT;
    mem_info.memPriority = XGL_MEMORY_PRIORITY_NORMAL;
    mem_info.memType = XGL_MEMORY_TYPE_OTHER;
    err = xglAllocMemory(device(), &mem_info, &event_mem);
    ASSERT_XGL_SUCCESS(err);

    err = xglBindObjectMemory(event, 0, event_mem, 0);
    ASSERT_XGL_SUCCESS(err);

    err = xglResetEvent(event);
    ASSERT_XGL_SUCCESS(err);

    err = xglGetEventStatus(event);
    ASSERT_EQ(XGL_EVENT_RESET, err);

    err = xglSetEvent(event);
    ASSERT_XGL_SUCCESS(err);

    err = xglGetEventStatus(event);
    ASSERT_EQ(XGL_EVENT_SET, err);

    // TODO: Test actual synchronization with command buffer event.

    // All done with event memory, clean up
    err = xglBindObjectMemory(event, 0, XGL_NULL_HANDLE, 0);
    ASSERT_XGL_SUCCESS(err);

    err = xglDestroyObject(event);
    ASSERT_XGL_SUCCESS(err);
}

TEST_F(XglTest, Fence) {
    XGL_RESULT err;
    XGL_FENCE_CREATE_INFO fence_info;
    XGL_FENCE fence;

    memset(&fence_info, 0, sizeof(fence_info));

    //            typedef struct _XGL_FENCE_CREATE_INFO
    //            {
    //                XGL_STRUCTURE_TYPE                      sType;      // Must be XGL_STRUCTURE_TYPE_FENCE_CREATE_INFO
    //                const void*                             pNext;      // Pointer to next structure
    //                XGL_FLAGS                               flags;      // Reserved
    fence_info.sType = XGL_STRUCTURE_TYPE_FENCE_CREATE_INFO;

    err = xglCreateFence(device(), &fence_info, &fence);
    ASSERT_XGL_SUCCESS(err);

    err = xglGetFenceStatus(fence);
    // We've not submitted this fence on a command buffer so should get
    // XGL_ERROR_UNAVAILABLE
    EXPECT_EQ(XGL_ERROR_UNAVAILABLE, err);

    // Test glxWaitForFences
    //        XGL_RESULT XGLAPI xglWaitForFences(
    //            XGL_DEVICE                                  device,
    //            uint32_t                                    fenceCount,
    //            const XGL_FENCE*                            pFences,
    //            bool32_t                                    waitAll,
    //            uint64_t                                    timeout);
    err = xglWaitForFences(device(), 1, &fence, XGL_TRUE, 0);
    EXPECT_EQ(XGL_ERROR_UNAVAILABLE, err);

    // TODO: Attached to command buffer and test GetFenceStatus
    // TODO: Add some commands and submit the command buffer

    err = xglDestroyObject(fence);
    ASSERT_XGL_SUCCESS(err);

}

#define MAX_QUERY_SLOTS 10

TEST_F(XglTest, Query) {
    XGL_QUERY_POOL_CREATE_INFO query_info;
    XGL_QUERY_POOL query_pool;
    size_t data_size;
    XGL_MEMORY_REQUIREMENTS mem_req;
    size_t query_result_size;
    uint32_t *query_result_data;
    XGL_RESULT err;

    //        typedef enum _XGL_QUERY_TYPE
    //        {
    //            XGL_QUERY_OCCLUSION                                     = 0x00000000,
    //            XGL_QUERY_PIPELINE_STATISTICS                           = 0x00000001,

    //            XGL_QUERY_TYPE_BEGIN_RANGE                              = XGL_QUERY_OCCLUSION,
    //            XGL_QUERY_TYPE_END_RANGE                                = XGL_QUERY_PIPELINE_STATISTICS,
    //            XGL_NUM_QUERY_TYPE                                      = (XGL_QUERY_TYPE_END_RANGE - XGL_QUERY_TYPE_BEGIN_RANGE + 1),
    //            XGL_MAX_ENUM(_XGL_QUERY_TYPE)
    //        } XGL_QUERY_TYPE;

    //        typedef struct _XGL_QUERY_POOL_CREATE_INFO
    //        {
    //            XGL_STRUCTURE_TYPE                      sType;      // Must be XGL_STRUCTURE_TYPE_QUERY_POOL_CREATE_INFO
    //            const void*                             pNext;      // Pointer to next structure
    //            XGL_QUERY_TYPE                          queryType;
    //            uint32_t                                slots;
    //        } XGL_QUERY_POOL_CREATE_INFO;

    memset(&query_info, 0, sizeof(query_info));
    query_info.sType = XGL_STRUCTURE_TYPE_QUERY_POOL_CREATE_INFO;
    query_info.queryType = XGL_QUERY_OCCLUSION;
    query_info.slots = MAX_QUERY_SLOTS;

    //        XGL_RESULT XGLAPI xglCreateQueryPool(
    //            XGL_DEVICE                                  device,
    //            const XGL_QUERY_POOL_CREATE_INFO*           pCreateInfo,
    //            XGL_QUERY_POOL*                             pQueryPool);

    err = xglCreateQueryPool(device(), &query_info, &query_pool);
    ASSERT_XGL_SUCCESS(err);

    data_size = sizeof(mem_req);
    err = xglGetObjectInfo(query_pool, XGL_INFO_TYPE_MEMORY_REQUIREMENTS,
                           &data_size, &mem_req);
    ASSERT_XGL_SUCCESS(err);
    ASSERT_NE(0, data_size) << "Invalid data_size";

    //        XGL_RESULT XGLAPI xglAllocMemory(
    //            XGL_DEVICE                                  device,
    //            const XGL_MEMORY_ALLOC_INFO*                pAllocInfo,
    //            XGL_GPU_MEMORY*                             pMem);
    XGL_MEMORY_ALLOC_INFO mem_info;
    XGL_GPU_MEMORY query_mem;

    memset(&mem_info, 0, sizeof(mem_info));
    mem_info.sType = XGL_STRUCTURE_TYPE_MEMORY_ALLOC_INFO;
    // TODO: Is a simple multiple all that's needed here?
    mem_info.allocationSize = mem_req.size * MAX_QUERY_SLOTS;
    mem_info.memProps = XGL_MEMORY_PROPERTY_SHAREABLE_BIT;
    mem_info.memType = XGL_MEMORY_TYPE_OTHER;
    mem_info.memPriority = XGL_MEMORY_PRIORITY_NORMAL;
    // TODO: Should this be pinned? Or maybe a separate test with pinned.
    err = xglAllocMemory(device(), &mem_info, &query_mem);
    ASSERT_XGL_SUCCESS(err);

    err = xglBindObjectMemory(query_pool, 0, query_mem, 0);
    ASSERT_XGL_SUCCESS(err);

    // TODO: Test actual synchronization with command buffer event.
    // TODO: Create command buffer
    // TODO: xglCmdResetQueryPool
    // TODO: xglCmdBeginQuery
    // TODO: commands
    // TOOD: xglCmdEndQuery

    err = xglGetQueryPoolResults(query_pool, 0, MAX_QUERY_SLOTS,
                                 &query_result_size, XGL_NULL_HANDLE);
    ASSERT_XGL_SUCCESS(err);

    if (query_result_size > 0) {
        query_result_data = new uint32_t [query_result_size];
        err = xglGetQueryPoolResults(query_pool, 0, MAX_QUERY_SLOTS,
                                     &query_result_size, query_result_data);
        ASSERT_XGL_SUCCESS(err);

        // TODO: Test Query result data.

    }

    // All done with QueryPool memory, clean up
    err = xglBindObjectMemory(query_pool, 0, XGL_NULL_HANDLE, 0);
    ASSERT_XGL_SUCCESS(err);

    err = xglDestroyObject(query_pool);
    ASSERT_XGL_SUCCESS(err);
}

void getQueue(xgl_testing::Device *device, uint32_t queue_node_index, const char *qname)
{
    int que_idx;
    XGL_RESULT err;
    XGL_QUEUE queue;

    const XGL_PHYSICAL_GPU_QUEUE_PROPERTIES props = device->gpu().queue_properties()[queue_node_index];
    for (que_idx = 0; que_idx < props.queueCount; que_idx++) {
        err = xglGetDeviceQueue(device->obj(), queue_node_index, que_idx, &queue);
        ASSERT_EQ(XGL_SUCCESS, err) << "xglGetDeviceQueue: " << qname << " queue #" << que_idx << ": Failed with error: " << xgl_result_string(err);
    }
}


void print_queue_info(xgl_testing::Device *device, uint32_t queue_node_index)
{
    uint32_t que_idx;
    XGL_PHYSICAL_GPU_QUEUE_PROPERTIES queue_props;
    XGL_PHYSICAL_GPU_PROPERTIES props;

    props = device->gpu().properties();
    queue_props = device->gpu().queue_properties()[queue_node_index];
    ASSERT_NE(0, queue_props.queueCount) << "No Queues available at Node Index #" << queue_node_index << " GPU: " << props.gpuName;

//            XGL_RESULT XGLAPI xglGetDeviceQueue(
//                XGL_DEVICE                                  device,
//                uint32_t                                    queueNodeIndex,
//                uint32_t                                    queueIndex,
//                XGL_QUEUE*                                  pQueue);
    /*
     * queue handles are retrieved from the device by calling
     * xglGetDeviceQueue() with a queue node index and a requested logical
     * queue ID. The queue node index is the index into the array of
     * XGL_PHYSICAL_GPU_QUEUE_PROPERTIES returned by GetGpuInfo. Each
     * queue node index has different attributes specified by the XGL_QUEUE_FLAGS property.
     * The logical queue ID is a sequential number starting from zero
     * and referencing up to the number of queues supported of that node index
     * at device creation.
     */

    for (que_idx = 0; que_idx < queue_props.queueCount; que_idx++) {

//                typedef enum _XGL_QUEUE_FLAGS
//                {
//                    XGL_QUEUE_GRAPHICS_BIT                                  = 0x00000001,   // Queue supports graphics operations
//                    XGL_QUEUE_COMPUTE_BIT                                   = 0x00000002,   // Queue supports compute operations
//                    XGL_QUEUE_DMA_BIT                                       = 0x00000004,   // Queue supports DMA operations
//                    XGL_QUEUE_EXTENDED_BIT                                  = 0x80000000    // Extended queue
//                } XGL_QUEUE_FLAGS;

        if (queue_props.queueFlags & XGL_QUEUE_GRAPHICS_BIT) {
            getQueue(device, queue_node_index, "Graphics");
        }

        if (queue_props.queueFlags & XGL_QUEUE_COMPUTE_BIT) {
            getQueue(device, queue_node_index, "Compute");
        }

        if (queue_props.queueFlags & XGL_QUEUE_DMA_BIT) {
            getQueue(device, queue_node_index, "DMA");
        }

        // TODO: What do we do about EXTENDED_BIT?

        /* Guide: pg 34:
         * The queue objects cannot be destroyed explicitly by an application
         * and are automatically destroyed when the associated device is destroyed.
         * Once the device is destroyed, attempting to use a queue results in
         * undefined behavior.
         */
    }
}

TEST_F(XglTest, Queue)
{
    uint32_t i;

    for (i = 0; i < m_device->gpu().queue_properties().size(); i++) {
        print_queue_info(m_device, i);
    }
}


void XglTest::CreateImageTest()
{
    XGL_RESULT err;
    XGL_IMAGE image;
    uint32_t w, h, mipCount;
    size_t size;
    XGL_FORMAT fmt;
    XGL_FORMAT_PROPERTIES image_fmt;
    size_t data_size;

    w =512;
    h = 256;
    mipCount = 0;

    uint32_t _w = w;
    uint32_t _h = h;
    while( ( _w > 0 ) || ( _h > 0 ) )
    {
        _w >>= 1;
        _h >>= 1;
        mipCount++;
    }

    fmt = XGL_FMT_R8G8B8A8_UINT;
    // TODO: Pick known good format rather than just expect common format
    /*
     * XXX: What should happen if given NULL HANDLE for the pData argument?
     * We're not requesting XGL_INFO_TYPE_MEMORY_REQUIREMENTS so there is
     * an expectation that pData is a valid pointer.
     * However, why include a returned size value? That implies that the
     * amount of data may vary and that doesn't work well for using a
     * fixed structure.
     */

    size = sizeof(image_fmt);
    err = xglGetFormatInfo(device(), fmt,
                           XGL_INFO_TYPE_FORMAT_PROPERTIES,
                           &size, &image_fmt);
    ASSERT_XGL_SUCCESS(err);

//    typedef struct _XGL_IMAGE_CREATE_INFO
//    {
//        XGL_STRUCTURE_TYPE                      sType;                      // Must be XGL_STRUCTURE_TYPE_IMAGE_CREATE_INFO
//        const void*                             pNext;                      // Pointer to next structure.
//        XGL_IMAGE_TYPE                          imageType;
//        XGL_FORMAT                              format;
//        XGL_EXTENT3D                            extent;
//        uint32_t                                mipLevels;
//        uint32_t                                arraySize;
//        uint32_t                                samples;
//        XGL_IMAGE_TILING                        tiling;
//        XGL_FLAGS                               usage;                      // XGL_IMAGE_USAGE_FLAGS
//        XGL_FLAGS                               flags;                      // XGL_IMAGE_CREATE_FLAGS
//    } XGL_IMAGE_CREATE_INFO;


    XGL_IMAGE_CREATE_INFO imageCreateInfo = {};
    imageCreateInfo.sType = XGL_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
    imageCreateInfo.imageType = XGL_IMAGE_2D;
    imageCreateInfo.format = fmt;
    imageCreateInfo.arraySize = 1;
    imageCreateInfo.extent.width = w;
    imageCreateInfo.extent.height = h;
    imageCreateInfo.extent.depth = 1;
    imageCreateInfo.mipLevels = mipCount;
    imageCreateInfo.samples = 1;
    imageCreateInfo.tiling = XGL_LINEAR_TILING;

// Image usage flags
//    typedef enum _XGL_IMAGE_USAGE_FLAGS
//    {
//        XGL_IMAGE_USAGE_SHADER_ACCESS_READ_BIT                  = 0x00000001,
//        XGL_IMAGE_USAGE_SHADER_ACCESS_WRITE_BIT                 = 0x00000002,
//        XGL_IMAGE_USAGE_COLOR_ATTACHMENT_BIT                    = 0x00000004,
//        XGL_IMAGE_USAGE_DEPTH_STENCIL_BIT                       = 0x00000008,
//    } XGL_IMAGE_USAGE_FLAGS;
    imageCreateInfo.usage = XGL_IMAGE_USAGE_SHADER_ACCESS_WRITE_BIT | XGL_IMAGE_USAGE_COLOR_ATTACHMENT_BIT;

//    XGL_RESULT XGLAPI xglCreateImage(
//        XGL_DEVICE                                  device,
//        const XGL_IMAGE_CREATE_INFO*                pCreateInfo,
//        XGL_IMAGE*                                  pImage);
    err = xglCreateImage(device(), &imageCreateInfo, &image);
    ASSERT_XGL_SUCCESS(err);

    // Verify image resources
//    XGL_RESULT XGLAPI xglGetImageSubresourceInfo(
//        XGL_IMAGE                                   image,
//        const XGL_IMAGE_SUBRESOURCE*                pSubresource,
//        XGL_SUBRESOURCE_INFO_TYPE                   infoType,
//        size_t*                                     pDataSize,
//        void*                                       pData);
//    typedef struct _XGL_SUBRESOURCE_LAYOUT
//    {
//        XGL_GPU_SIZE                            offset;                 // Specified in bytes
//        XGL_GPU_SIZE                            size;                   // Specified in bytes
//        XGL_GPU_SIZE                            rowPitch;               // Specified in bytes
//        XGL_GPU_SIZE                            depthPitch;             // Specified in bytes
//    } XGL_SUBRESOURCE_LAYOUT;

//    typedef struct _XGL_IMAGE_SUBRESOURCE
//    {
//        XGL_IMAGE_ASPECT                        aspect;
//        uint32_t                                mipLevel;
//        uint32_t                                arraySlice;
//    } XGL_IMAGE_SUBRESOURCE;
//    typedef enum _XGL_SUBRESOURCE_INFO_TYPE
//    {
//        // Info type for xglGetImageSubresourceInfo()
//        XGL_INFO_TYPE_SUBRESOURCE_LAYOUT                        = 0x00000000,

//        XGL_MAX_ENUM(_XGL_SUBRESOURCE_INFO_TYPE)
//    } XGL_SUBRESOURCE_INFO_TYPE;
    XGL_IMAGE_SUBRESOURCE subresource = {};
    subresource.aspect = XGL_IMAGE_ASPECT_COLOR;
    subresource.arraySlice = 0;

    _w = w;
    _h = h;
    while( ( _w > 0 ) || ( _h > 0 ) )
    {
        XGL_SUBRESOURCE_LAYOUT layout = {};
        data_size = sizeof(layout);
        err = xglGetImageSubresourceInfo(image, &subresource, XGL_INFO_TYPE_SUBRESOURCE_LAYOUT,
                                         &data_size, &layout);
        ASSERT_XGL_SUCCESS(err);
        ASSERT_EQ(sizeof(XGL_SUBRESOURCE_LAYOUT), data_size) << "Invalid structure (XGL_SUBRESOURCE_LAYOUT) size";

        // TODO: 4 should be replaced with pixel size for given format
        EXPECT_LE(_w * 4, layout.rowPitch) << "Pitch does not match expected image pitch";
        _w >>= 1;
        _h >>= 1;

        subresource.mipLevel++;
    }

    XGL_MEMORY_ALLOC_IMAGE_INFO img_alloc = {
        .sType = XGL_STRUCTURE_TYPE_MEMORY_ALLOC_IMAGE_INFO,
        .pNext = NULL,

    };
    XGL_MEMORY_REQUIREMENTS mem_req;
    XGL_IMAGE_MEMORY_REQUIREMENTS img_reqs;
    size_t img_reqs_size = sizeof(XGL_IMAGE_MEMORY_REQUIREMENTS);
    data_size = sizeof(mem_req);
    err = xglGetObjectInfo(image, XGL_INFO_TYPE_MEMORY_REQUIREMENTS,
                           &data_size, &mem_req);
    ASSERT_XGL_SUCCESS(err);
    ASSERT_EQ(data_size, sizeof(mem_req));
    ASSERT_NE(0, mem_req.size) << "xglGetObjectInfo (Event): Failed - expect images to require memory";
    err = xglGetObjectInfo(image, XGL_INFO_TYPE_IMAGE_MEMORY_REQUIREMENTS,
                           &img_reqs_size, &img_reqs);
    ASSERT_XGL_SUCCESS(err);
    ASSERT_EQ(img_reqs_size, sizeof(XGL_IMAGE_MEMORY_REQUIREMENTS));
    img_alloc.usage = img_reqs.usage;
    img_alloc.formatClass = img_reqs.formatClass;
    img_alloc.samples = img_reqs.samples;
    //        XGL_RESULT XGLAPI xglAllocMemory(
    //            XGL_DEVICE                                  device,
    //            const XGL_MEMORY_ALLOC_INFO*                pAllocInfo,
    //            XGL_GPU_MEMORY*                             pMem);
    XGL_MEMORY_ALLOC_INFO mem_info = {};
    XGL_GPU_MEMORY image_mem;

    mem_info.sType = XGL_STRUCTURE_TYPE_MEMORY_ALLOC_INFO;
    mem_info.pNext = &img_alloc;
    mem_info.allocationSize = mem_req.size;
    mem_info.memProps = XGL_MEMORY_PROPERTY_SHAREABLE_BIT;
    mem_info.memType = XGL_MEMORY_TYPE_IMAGE;
    mem_info.memPriority = XGL_MEMORY_PRIORITY_NORMAL;
    err = xglAllocMemory(device(), &mem_info, &image_mem);
    ASSERT_XGL_SUCCESS(err);

    err = xglBindObjectMemory(image, 0, image_mem, 0);
    ASSERT_XGL_SUCCESS(err);

//    typedef struct _XGL_IMAGE_VIEW_CREATE_INFO
//    {
//        XGL_STRUCTURE_TYPE                      sType;                  // Must be XGL_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO
//        const void*                             pNext;                  // Pointer to next structure
//        XGL_IMAGE                               image;
//        XGL_IMAGE_VIEW_TYPE                     viewType;
//        XGL_FORMAT                              format;
//        XGL_CHANNEL_MAPPING                     channels;
//        XGL_IMAGE_SUBRESOURCE_RANGE             subresourceRange;
//        float                                   minLod;
//    } XGL_IMAGE_VIEW_CREATE_INFO;
    XGL_IMAGE_VIEW_CREATE_INFO viewInfo = {};
    XGL_IMAGE_VIEW view;
    viewInfo.sType = XGL_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO;
    viewInfo.image = image;
    viewInfo.viewType = XGL_IMAGE_VIEW_2D;
    viewInfo.format = fmt;

    viewInfo.channels.r = XGL_CHANNEL_SWIZZLE_R;
    viewInfo.channels.g = XGL_CHANNEL_SWIZZLE_G;
    viewInfo.channels.b = XGL_CHANNEL_SWIZZLE_B;
    viewInfo.channels.a = XGL_CHANNEL_SWIZZLE_A;

    viewInfo.subresourceRange.baseArraySlice = 0;
    viewInfo.subresourceRange.arraySize = 1;
    viewInfo.subresourceRange.baseMipLevel = 0;
    viewInfo.subresourceRange.mipLevels = 1;
    viewInfo.subresourceRange.aspect = XGL_IMAGE_ASPECT_COLOR;

//    XGL_RESULT XGLAPI xglCreateImageView(
//        XGL_DEVICE                                  device,
//        const XGL_IMAGE_VIEW_CREATE_INFO*           pCreateInfo,
//        XGL_IMAGE_VIEW*                             pView);

    err = xglCreateImageView(device(), &viewInfo, &view);
    ASSERT_XGL_SUCCESS(err) << "xglCreateImageView failed";

    // TODO: Test image memory.

    // All done with image memory, clean up
    ASSERT_XGL_SUCCESS(xglBindObjectMemory(image, 0, XGL_NULL_HANDLE, 0));

    ASSERT_XGL_SUCCESS(xglFreeMemory(image_mem));

    ASSERT_XGL_SUCCESS(xglDestroyObject(image));
}

TEST_F(XglTest, CreateImage) {
    CreateImageTest();
}

void XglTest::CreateCommandBufferTest()
{
    XGL_RESULT err;
    XGL_CMD_BUFFER_CREATE_INFO info = {};
    XGL_CMD_BUFFER cmdBuffer;

//    typedef struct _XGL_CMD_BUFFER_CREATE_INFO
//    {
//        XGL_STRUCTURE_TYPE                      sType;      // Must be XGL_STRUCTURE_TYPE_CMD_BUFFER_CREATE_INFO
//        const void*                             pNext;
//        XGL_QUEUE_TYPE                          queueType;
//        XGL_FLAGS                               flags;
//    } XGL_CMD_BUFFER_CREATE_INFO;

    info.sType = XGL_STRUCTURE_TYPE_CMD_BUFFER_CREATE_INFO;
    info.queueNodeIndex = graphics_queue_node_index;
    err = xglCreateCommandBuffer(device(), &info, &cmdBuffer);
    ASSERT_XGL_SUCCESS(err) << "xglCreateCommandBuffer failed";

    ASSERT_XGL_SUCCESS(xglDestroyObject(cmdBuffer));
}

TEST_F(XglTest, TestComandBuffer) {
    CreateCommandBufferTest();
}

void XglTest::CreateShader(XGL_SHADER *pshader)
{
    void *code;
    uint32_t codeSize;
    struct icd_spv_header *pSPV;
    XGL_RESULT err;

    codeSize = sizeof(struct icd_spv_header) + 100;
    code = malloc(codeSize);
    ASSERT_TRUE(NULL != code) << "malloc failed!";

    memset(code, 0, codeSize);

    // Indicate that this is SPV data.
    pSPV = (struct icd_spv_header *) code;
    pSPV->magic = ICD_SPV_MAGIC;
    pSPV->version = ICD_SPV_VERSION;

//    typedef struct _XGL_SHADER_CREATE_INFO
//    {
//        XGL_STRUCTURE_TYPE                      sType;              // Must be XGL_STRUCTURE_TYPE_SHADER_CREATE_INFO
//        const void*                             pNext;              // Pointer to next structure
//        size_t                                  codeSize;           // Specified in bytes
//        const void*                             pCode;
//        XGL_FLAGS                               flags;              // Reserved
//    } XGL_SHADER_CREATE_INFO;

    XGL_SHADER_CREATE_INFO createInfo;
    XGL_SHADER shader;

    createInfo.sType = XGL_STRUCTURE_TYPE_SHADER_CREATE_INFO;
    createInfo.pNext = NULL;
    createInfo.pCode = code;
    createInfo.codeSize = codeSize;
    createInfo.flags = 0;
    err = xglCreateShader(device(), &createInfo, &shader);
    ASSERT_XGL_SUCCESS(err);

    *pshader = shader;
}

int main(int argc, char **argv) {
    ::testing::InitGoogleTest(&argc, argv);
    xgl_testing::set_error_callback(test_error_callback);
    return RUN_ALL_TESTS();
}
