tests: Add gpu class
diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt
index d6bcf0e..80b8c9c 100644
--- a/tests/CMakeLists.txt
+++ b/tests/CMakeLists.txt
@@ -3,7 +3,7 @@
     )
 
 SET(COMMON_CPP
-   testobject.cpp
+   xglgpu.cpp
    )
 
 include_directories("${PROJECT_SOURCE_DIR}/tests/gtest-1.7.0/include")
@@ -15,7 +15,7 @@
 add_executable(xglQueue xglQueue.c ${COMMON})
 add_executable(xglEvent xglEvent.c ${COMMON})
 add_executable(xglQuery xglQuery.c ${COMMON})
-add_executable(xglinit init.cpp)
+add_executable(xglinit init.cpp ${COMMON_CPP})
 set_target_properties(xglinit
    PROPERTIES
    COMPILE_DEFINITIONS "GTEST_LINKED_AS_SHARED_LIBRARY=1")
diff --git a/tests/test_common.h b/tests/test_common.h
new file mode 100644
index 0000000..fd9e235
--- /dev/null
+++ b/tests/test_common.h
@@ -0,0 +1,65 @@
+#ifndef TEST_COMMON_H
+#define TEST_COMMON_H
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <stdbool.h>
+#include <string.h>
+#include <assert.h>
+
+#include <xgl.h>
+
+#include "gtest/gtest.h"
+
+#define ASSERT_XGL_SUCCESS(err) ASSERT_EQ(XGL_SUCCESS, err) << xgl_result_string(err)
+
+static const char *xgl_result_string(XGL_RESULT err)
+{
+    switch (err) {
+#define STR(r) case r: return #r
+    STR(XGL_SUCCESS);
+    STR(XGL_UNSUPPORTED);
+    STR(XGL_NOT_READY);
+    STR(XGL_TIMEOUT);
+    STR(XGL_EVENT_SET);
+    STR(XGL_EVENT_RESET);
+    STR(XGL_ERROR_UNKNOWN);
+    STR(XGL_ERROR_UNAVAILABLE);
+    STR(XGL_ERROR_INITIALIZATION_FAILED);
+    STR(XGL_ERROR_OUT_OF_MEMORY);
+    STR(XGL_ERROR_OUT_OF_GPU_MEMORY);
+    STR(XGL_ERROR_DEVICE_ALREADY_CREATED);
+    STR(XGL_ERROR_DEVICE_LOST);
+    STR(XGL_ERROR_INVALID_POINTER);
+    STR(XGL_ERROR_INVALID_VALUE);
+    STR(XGL_ERROR_INVALID_HANDLE);
+    STR(XGL_ERROR_INVALID_ORDINAL);
+    STR(XGL_ERROR_INVALID_MEMORY_SIZE);
+    STR(XGL_ERROR_INVALID_EXTENSION);
+    STR(XGL_ERROR_INVALID_FLAGS);
+    STR(XGL_ERROR_INVALID_ALIGNMENT);
+    STR(XGL_ERROR_INVALID_FORMAT);
+    STR(XGL_ERROR_INVALID_IMAGE);
+    STR(XGL_ERROR_INVALID_DESCRIPTOR_SET_DATA);
+    STR(XGL_ERROR_INVALID_QUEUE_TYPE);
+    STR(XGL_ERROR_INVALID_OBJECT_TYPE);
+    STR(XGL_ERROR_UNSUPPORTED_SHADER_IL_VERSION);
+    STR(XGL_ERROR_BAD_SHADER_CODE);
+    STR(XGL_ERROR_BAD_PIPELINE_DATA);
+    STR(XGL_ERROR_TOO_MANY_MEMORY_REFERENCES);
+    STR(XGL_ERROR_NOT_MAPPABLE);
+    STR(XGL_ERROR_MEMORY_MAP_FAILED);
+    STR(XGL_ERROR_MEMORY_UNMAP_FAILED);
+    STR(XGL_ERROR_INCOMPATIBLE_DEVICE);
+    STR(XGL_ERROR_INCOMPATIBLE_DRIVER);
+    STR(XGL_ERROR_INCOMPLETE_COMMAND_BUFFER);
+    STR(XGL_ERROR_BUILDING_COMMAND_BUFFER);
+    STR(XGL_ERROR_MEMORY_NOT_BOUND);
+    STR(XGL_ERROR_INCOMPATIBLE_QUEUE);
+    STR(XGL_ERROR_NOT_SHAREABLE);
+#undef STR
+    default: return "UNKNOWN_RESULT";
+    }
+}
+
+#endif // TEST_COMMON_H
diff --git a/tests/xglgpu.cpp b/tests/xglgpu.cpp
new file mode 100644
index 0000000..17d31b0
--- /dev/null
+++ b/tests/xglgpu.cpp
@@ -0,0 +1,168 @@
+#include "xglgpu.h"
+
+#define ARRAY_SIZE(a) (sizeof(a) / sizeof(a[0]))
+
+XglGpu::XglGpu(XGL_UINT id, XGL_PHYSICAL_GPU obj)
+{
+    this->id = id;
+    this->gpuObj = obj;
+    this->extension_count = 0;
+    this->heap_count = 0;
+    this->queue_count = 0;
+
+    this->init_gpu();
+    this->init_extensions();
+    this->init_device();
+    this->init_formats();
+}
+
+void XglGpu::init_gpu()
+{
+    int i;
+    XGL_RESULT err;
+    XGL_SIZE size;
+
+    err = xglGetGpuInfo(this->gpuObj,
+                        XGL_INFO_TYPE_PHYSICAL_GPU_PROPERTIES,
+                        &size, &this->props);
+    ASSERT_XGL_SUCCESS(err);
+    ASSERT_EQ(size, sizeof(this->props));
+
+    err = xglGetGpuInfo(this->gpuObj,
+                        XGL_INFO_TYPE_PHYSICAL_GPU_PERFORMANCE,
+                        &size, &this->perf);
+    ASSERT_XGL_SUCCESS(err);
+    ASSERT_EQ(size, sizeof(this->perf));
+
+    /* get queue count */
+    err = xglGetGpuInfo(this->gpuObj,
+                        XGL_INFO_TYPE_PHYSICAL_GPU_QUEUE_PROPERTIES,
+                        &size, NULL);
+    ASSERT_XGL_SUCCESS(err);
+    this->queue_count = size / sizeof(this->queue_props[0]);
+    ASSERT_EQ(this->queue_count*sizeof(this->queue_props[0]), size) << "invalid GPU_QUEUE_PROPERTIES size";
+
+    this->queue_props = new XGL_PHYSICAL_GPU_QUEUE_PROPERTIES [this->queue_count];
+    ASSERT_TRUE(NULL != this->queue_props) << "Out of memory";
+
+    err = xglGetGpuInfo(this->gpuObj,
+                        XGL_INFO_TYPE_PHYSICAL_GPU_QUEUE_PROPERTIES,
+                        &size, this->queue_props);
+    ASSERT_XGL_SUCCESS(err);
+    ASSERT_EQ(this->queue_count*sizeof(this->queue_props[0]), size) << "invalid GPU_QUEUE_PROPERTIES size";
+
+    /* set up queue requests */
+    // this->queue_reqs = malloc(sizeof(*this->queue_reqs) * this->queue_count);
+    this->queue_reqs = new XGL_DEVICE_QUEUE_CREATE_INFO [this->queue_count];
+    ASSERT_TRUE(NULL != this->queue_reqs) << "Out of memory";
+
+    for (i = 0; i < this->queue_count; i++) {
+        this->queue_reqs[i].queueNodeIndex = i;
+        this->queue_reqs[i].queueCount = this->queue_props[i].queueCount;
+    }
+
+    err = xglGetGpuInfo(this->gpuObj,
+                        XGL_INFO_TYPE_PHYSICAL_GPU_MEMORY_PROPERTIES,
+                        &size, &this->memory_props);
+    ASSERT_XGL_SUCCESS(err);
+    ASSERT_EQ(size, sizeof(this->memory_props));
+}
+
+void XglGpu::init_extensions()
+{
+    XGL_RESULT err;
+    XGL_UINT i;
+
+    static const XGL_CHAR *known_extensions[] = {
+        (const XGL_CHAR *) "some_extension",
+    };
+    this->extension_count = 0;
+
+    for (i = 0; i < ARRAY_SIZE(known_extensions); i++) {
+        err = xglGetExtensionSupport(this->gpuObj, known_extensions[i]);
+        if (!err)
+            this->extension_count++;
+    }
+
+    if (this->extension_count == 0) {
+        return;
+    }
+
+    this->extensions = new const XGL_CHAR *[this->extension_count];
+
+    ASSERT_TRUE(NULL != this->extensions) << "Out of memory";
+
+    this->extension_count = 0;
+    for (i = 0; i < ARRAY_SIZE(known_extensions); i++) {
+        err = xglGetExtensionSupport(this->gpuObj, known_extensions[i]);
+        if (!err)
+            this->extensions[this->extension_count++] = known_extensions[i];
+    }
+}
+
+void XglGpu::init_device()
+{
+    XGL_DEVICE_CREATE_INFO info = {};
+    XGL_RESULT err;
+    XGL_SIZE size;
+    XGL_UINT i;
+
+    info.sType = XGL_STRUCTURE_TYPE_DEVICE_CREATE_INFO,
+    info.maxValidationLevel = XGL_VALIDATION_LEVEL_END_RANGE;
+    info.flags = XGL_DEVICE_CREATE_VALIDATION_BIT;
+
+    /* request all queues */
+    info.queueRecordCount = this->queue_count;
+    info.pRequestedQueues = this->queue_reqs;
+
+    /* enable all extensions */
+    info.extensionCount = this->extension_count;
+    info.ppEnabledExtensionNames = this->extensions;
+
+    err = xglCreateDevice(this->gpuObj, &info, &this->devObj);
+    ASSERT_XGL_SUCCESS(err);
+
+    err = xglGetMemoryHeapCount(this->devObj, &this->heap_count);
+    ASSERT_XGL_SUCCESS(err);
+
+    this->heap_props = new XGL_MEMORY_HEAP_PROPERTIES [this->heap_count];
+//            malloc(sizeof(dev->heap_props[0]) * dev->heap_count);
+    ASSERT_TRUE(NULL != this->heap_props) << "Out of memory";
+
+    for (i = 0; i < this->heap_count; i++) {
+        err = xglGetMemoryHeapInfo(this->devObj, i,
+                                   XGL_INFO_TYPE_MEMORY_HEAP_PROPERTIES,
+                                   &size, &this->heap_props[i]);
+        ASSERT_XGL_SUCCESS(err);
+        ASSERT_EQ(size, sizeof(this->heap_props[0]));
+    }
+}
+
+void XglGpu::init_formats()
+{
+    XGL_CHANNEL_FORMAT ch;
+    XGL_NUM_FORMAT num;
+
+    for (int chInt = XGL_CH_FMT_UNDEFINED; chInt < XGL_MAX_CH_FMT; chInt++) {
+        for (int numInt = 0; numInt < XGL_MAX_NUM_FMT; numInt++) {
+            XGL_FORMAT fmt = {};
+            XGL_RESULT err;
+            XGL_SIZE size;
+
+            fmt.channelFormat = static_cast<XGL_CHANNEL_FORMAT>(chInt);
+            fmt.numericFormat = static_cast<XGL_NUM_FORMAT>(numInt);
+
+            err = xglGetFormatInfo(this->devObj, fmt,
+                                   XGL_INFO_TYPE_FORMAT_PROPERTIES,
+                                   &size, &this->format_props[ch][num]);
+            if (err) {
+                memset(&this->format_props[ch][num], 0,
+                       sizeof(this->format_props[ch][num]));
+            }
+            else if (size != sizeof(this->format_props[ch][num])) {
+                ASSERT_EQ(size, sizeof(this->format_props[ch][num])) << "Incorrect data size";
+            }
+        }
+    }
+}
+
diff --git a/tests/xglgpu.h b/tests/xglgpu.h
new file mode 100644
index 0000000..8fcc210
--- /dev/null
+++ b/tests/xglgpu.h
@@ -0,0 +1,49 @@
+#ifndef XGLGPU_H
+#define XGLGPU_H
+
+#include "test_common.h"
+
+#include <xgl.h>
+
+#define MAX_GPUS 8
+
+#define MAX_QUEUE_TYPES 5
+
+class XglGpu
+{
+public:
+    XglGpu(XGL_UINT id, XGL_PHYSICAL_GPU gpuObj);
+    void init_gpu();
+    void init_extensions();
+    void init_device();
+    void init_formats();
+
+private:
+    XGL_UINT id;
+    XGL_PHYSICAL_GPU gpuObj;
+
+    XGL_PHYSICAL_GPU_PROPERTIES props;
+    XGL_PHYSICAL_GPU_PERFORMANCE perf;
+
+    XGL_UINT queue_count;
+    XGL_PHYSICAL_GPU_QUEUE_PROPERTIES *queue_props;
+    XGL_DEVICE_QUEUE_CREATE_INFO *queue_reqs;
+
+    XGL_PHYSICAL_GPU_MEMORY_PROPERTIES memory_props;
+
+    XGL_UINT extension_count;
+    const XGL_CHAR **extensions;
+
+    // Device info
+    // struct app_dev dev;
+    XGL_DEVICE devObj;
+
+    XGL_UINT heap_count;
+    XGL_MEMORY_HEAP_PROPERTIES *heap_props;
+    XGL_QUEUE queues[MAX_QUEUE_TYPES];
+
+    XGL_FORMAT_PROPERTIES format_props[XGL_MAX_CH_FMT][XGL_MAX_NUM_FMT];
+
+};
+
+#endif // XGLGPU_H