/*
 * 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.
 *
 * Authors:
 *   Courtney Goeltzenleuchter <courtney@lunarg.com>
 */

#include "xglrenderframework.h"

XglRenderFramework::XglRenderFramework() :
    m_cmdBuffer( XGL_NULL_HANDLE ),
    m_stateRaster( XGL_NULL_HANDLE ),
    m_colorBlend( XGL_NULL_HANDLE ),
    m_stateViewport( XGL_NULL_HANDLE ),
    m_stateDepthStencil( XGL_NULL_HANDLE ),
    m_width( 256.0 ),                   // default window width
    m_height( 256.0 ),                  // default window height
    m_render_target_fmt( XGL_FMT_R8G8B8A8_UNORM ),
    m_depth_stencil_fmt( XGL_FMT_UNDEFINED ),
    m_depth_clear_color( 1.0 ),
    m_stencil_clear_color( 0 )
{

    // clear the back buffer to dark grey
    m_clear_color.color.rawColor[0] = 64;
    m_clear_color.color.rawColor[1] = 64;
    m_clear_color.color.rawColor[2] = 64;
    m_clear_color.color.rawColor[3] = 0;
    m_clear_color.useRawValue = true;
}

XglRenderFramework::~XglRenderFramework()
{

}

void XglRenderFramework::InitFramework()
{
    XGL_RESULT err;

    err = xglCreateInstance(&app_info, NULL, &this->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 = new XglDevice(0, objs[0]);
    m_device->get_device_queue();

    m_depthStencil = new XglDepthStencilObj();
}

void XglRenderFramework::ShutdownFramework()
{
    if (m_colorBlend) xglDestroyObject(m_colorBlend);
    if (m_stateDepthStencil) xglDestroyObject(m_stateDepthStencil);
    if (m_stateRaster) xglDestroyObject(m_stateRaster);
    if (m_cmdBuffer) xglDestroyObject(m_cmdBuffer);
    if (m_framebuffer) xglDestroyObject(m_framebuffer);
    if (m_renderPass) xglDestroyObject(m_renderPass);

    if (m_stateViewport) {
        xglDestroyObject(m_stateViewport);
    }
    while (!m_renderTargets.empty()) {
        xglDestroyObject(m_renderTargets.back()->targetView());
        xglBindObjectMemory(m_renderTargets.back()->image(), 0, XGL_NULL_HANDLE, 0);
        xglDestroyObject(m_renderTargets.back()->image());
        xglFreeMemory(m_renderTargets.back()->memory());
        m_renderTargets.pop_back();
    }

    delete m_depthStencil;

    // reset the driver
    delete m_device;
    xglDestroyInstance(this->inst);
}

void XglRenderFramework::InitState()
{
    XGL_RESULT err;

    m_render_target_fmt = XGL_FMT_B8G8R8A8_UNORM;

    // create a raster state (solid, back-face culling)
    XGL_DYNAMIC_RS_STATE_CREATE_INFO raster = {};
    raster.sType = XGL_STRUCTURE_TYPE_DYNAMIC_RS_STATE_CREATE_INFO;
    raster.pointSize = 1.0;

    err = xglCreateDynamicRasterState( device(), &raster, &m_stateRaster );
    ASSERT_XGL_SUCCESS(err);

    XGL_DYNAMIC_CB_STATE_CREATE_INFO blend = {};
    blend.sType = XGL_STRUCTURE_TYPE_DYNAMIC_CB_STATE_CREATE_INFO;
    err = xglCreateDynamicColorBlendState(device(), &blend, &m_colorBlend);
    ASSERT_XGL_SUCCESS( err );

    XGL_DYNAMIC_DS_STATE_CREATE_INFO depthStencil = {};
    depthStencil.sType = XGL_STRUCTURE_TYPE_DYNAMIC_DS_STATE_CREATE_INFO;
    depthStencil.minDepth = 0.f;
    depthStencil.maxDepth = 1.f;
    depthStencil.stencilFrontRef = 0;
    depthStencil.stencilBackRef = 0;

    err = xglCreateDynamicDepthStencilState( device(), &depthStencil, &m_stateDepthStencil );
    ASSERT_XGL_SUCCESS( err );

    XGL_CMD_BUFFER_CREATE_INFO cmdInfo = {};

    cmdInfo.sType = XGL_STRUCTURE_TYPE_CMD_BUFFER_CREATE_INFO;
    cmdInfo.queueNodeIndex = m_device->graphics_queue_node_index_;

    err = xglCreateCommandBuffer(device(), &cmdInfo, &m_cmdBuffer);
    ASSERT_XGL_SUCCESS(err) << "xglCreateCommandBuffer failed";
}

void XglRenderFramework::InitViewport(float width, float height)
{
    XGL_RESULT err;

    XGL_VIEWPORT viewport;
    XGL_RECT scissor;

    XGL_DYNAMIC_VP_STATE_CREATE_INFO viewportCreate = {};
    viewportCreate.sType = XGL_STRUCTURE_TYPE_DYNAMIC_VP_STATE_CREATE_INFO;
    viewportCreate.viewportAndScissorCount         = 1;
    viewport.originX  = 0;
    viewport.originY  = 0;
    viewport.width    = 1.f * width;
    viewport.height   = 1.f * height;
    viewport.minDepth = 0.f;
    viewport.maxDepth = 1.f;
    scissor.extent.width = width;
    scissor.extent.height = height;
    scissor.offset.x = 0;
    scissor.offset.y = 0;
    viewportCreate.pViewports = &viewport;
    viewportCreate.pScissors = &scissor;

    err = xglCreateDynamicViewportState( device(), &viewportCreate, &m_stateViewport );
    ASSERT_XGL_SUCCESS( err );
    m_width = width;
    m_height = height;
}

void XglRenderFramework::InitViewport()
{
    InitViewport(m_width, m_height);
}
void XglRenderFramework::InitRenderTarget()
{

    InitRenderTarget(1);
}

void XglRenderFramework::InitRenderTarget(uint32_t targets)
{
    InitRenderTarget(targets, NULL);
}

void XglRenderFramework::InitRenderTarget(XGL_DEPTH_STENCIL_BIND_INFO *dsBinding)
{
    InitRenderTarget(1, dsBinding);
}

void XglRenderFramework::InitRenderTarget(uint32_t targets, XGL_DEPTH_STENCIL_BIND_INFO *dsBinding)
{
    std::vector<XGL_ATTACHMENT_LOAD_OP> load_ops;
    std::vector<XGL_ATTACHMENT_STORE_OP> store_ops;
    std::vector<XGL_CLEAR_COLOR> clear_colors;

    uint32_t i;

    for (i = 0; i < targets; i++) {
        XglImage *img = new XglImage(m_device);
        img->init(m_width, m_height, m_render_target_fmt,
                XGL_IMAGE_USAGE_SHADER_ACCESS_WRITE_BIT |
                XGL_IMAGE_USAGE_COLOR_ATTACHMENT_BIT);
        m_colorBindings[i].view  = img->targetView();
        m_colorBindings[i].layout = XGL_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
        m_renderTargets.push_back(img);
        load_ops.push_back(XGL_ATTACHMENT_LOAD_OP_LOAD);
        store_ops.push_back(XGL_ATTACHMENT_STORE_OP_STORE);
        clear_colors.push_back(m_clear_color);
    }
      // Create Framebuffer and RenderPass with color attachments and any depth/stencil attachment
    XGL_FRAMEBUFFER_CREATE_INFO fb_info = {};
    fb_info.sType = XGL_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO;
    fb_info.pNext = NULL;
    fb_info.colorAttachmentCount = m_renderTargets.size();
    fb_info.pColorAttachments = m_colorBindings;
    fb_info.pDepthStencilAttachment = dsBinding;
    fb_info.sampleCount = 1;
    fb_info.width = (uint32_t)m_width;
    fb_info.height = (uint32_t)m_height;
    fb_info.layers = 1;

    xglCreateFramebuffer(device(), &fb_info, &m_framebuffer);

    XGL_RENDER_PASS_CREATE_INFO rp_info = {};
    rp_info.sType = XGL_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO;
    rp_info.renderArea.extent.width = m_width;
    rp_info.renderArea.extent.height = m_height;

    rp_info.colorAttachmentCount = m_renderTargets.size();
    rp_info.pColorFormats = &m_render_target_fmt;
    rp_info.pColorLayouts = &m_colorBindings[0].layout;
    rp_info.pColorLoadOps = &load_ops[0];
    rp_info.pColorStoreOps = &store_ops[0];
    rp_info.pColorLoadClearValues = &clear_colors[0];
    rp_info.depthStencilFormat = m_depth_stencil_fmt;
    if (dsBinding) {
        rp_info.depthStencilLayout = dsBinding->layout;
    }
    rp_info.depthLoadOp = XGL_ATTACHMENT_LOAD_OP_LOAD;
    rp_info.depthLoadClearValue = m_depth_clear_color;
    rp_info.depthStoreOp = XGL_ATTACHMENT_STORE_OP_STORE;
    rp_info.stencilLoadOp = XGL_ATTACHMENT_LOAD_OP_LOAD;
    rp_info.stencilLoadClearValue = m_stencil_clear_color;
    rp_info.stencilStoreOp = XGL_ATTACHMENT_STORE_OP_STORE;
    xglCreateRenderPass(device(), &rp_info, &m_renderPass);
}



XglDevice::XglDevice(uint32_t id, XGL_PHYSICAL_GPU obj) :
    xgl_testing::Device(obj), id(id)
{
    init();

    props = gpu().properties();
    queue_props = &gpu().queue_properties()[0];
}

void XglDevice::get_device_queue()
{
    ASSERT_NE(true, graphics_queues().empty());
    m_queue = graphics_queues()[0]->obj();
}

XglDescriptorSetObj::XglDescriptorSetObj(XglDevice *device)
{
    m_device = device;
    m_nextSlot = 0;

}

XglDescriptorSetObj::~XglDescriptorSetObj()
{
    delete m_set;
}

int XglDescriptorSetObj::AppendDummy()
{
    /* request a descriptor but do not update it */
    XGL_DESCRIPTOR_TYPE_COUNT tc = {};
    tc.type = XGL_DESCRIPTOR_TYPE_RAW_BUFFER;
    tc.count = 1;
    m_type_counts.push_back(tc);

    return m_nextSlot++;
}

int XglDescriptorSetObj::AppendBuffer(XGL_DESCRIPTOR_TYPE type, XglConstantBufferObj *constantBuffer)
{
    XGL_DESCRIPTOR_TYPE_COUNT tc = {};
    tc.type = type;
    tc.count = 1;
    m_type_counts.push_back(tc);

    m_bufferInfo.push_back(&constantBuffer->m_bufferViewInfo);

    m_updateBuffers.push_back(xgl_testing::DescriptorSet::update(type, m_nextSlot, 1,
                (const XGL_BUFFER_VIEW_ATTACH_INFO **) NULL));

    return m_nextSlot++;
}

int XglDescriptorSetObj::AppendSamplerTexture( XglSamplerObj* sampler, XglTextureObj* texture)
{
    XGL_DESCRIPTOR_TYPE_COUNT tc = {};
    tc.type = XGL_DESCRIPTOR_TYPE_SAMPLER_TEXTURE;
    tc.count = 1;
    m_type_counts.push_back(tc);

    XGL_SAMPLER_IMAGE_VIEW_INFO tmp = {};
    tmp.pSampler = sampler->obj();
    tmp.pImageView = &texture->m_textureViewInfo;
    m_samplerTextureInfo.push_back(tmp);

    m_updateSamplerTextures.push_back(xgl_testing::DescriptorSet::update(m_nextSlot, 1,
                (const XGL_SAMPLER_IMAGE_VIEW_INFO *) NULL));

    return m_nextSlot++;
}

XGL_DESCRIPTOR_SET_LAYOUT XglDescriptorSetObj::GetLayout()
{
    return m_layout.obj();
}

XGL_DESCRIPTOR_SET XglDescriptorSetObj::GetDescriptorSetHandle()
{
    return m_set->obj();
}

void XglDescriptorSetObj::CreateXGLDescriptorSet(XglCommandBufferObj *cmdBuffer)
{
    // create XGL_DESCRIPTOR_POOL
    XGL_DESCRIPTOR_POOL_CREATE_INFO pool = {};
    pool.sType = XGL_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO;
    pool.count = m_type_counts.size();
    pool.pTypeCount = &m_type_counts[0];
    init(*m_device, XGL_DESCRIPTOR_POOL_USAGE_ONE_SHOT, 1, pool);

    // create XGL_DESCRIPTOR_SET_LAYOUT
    vector<XGL_DESCRIPTOR_SET_LAYOUT_CREATE_INFO> layout;
    layout.resize(m_type_counts.size());
    for (int i = 0; i < m_type_counts.size(); i++) {
        layout[i].sType = XGL_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO;
        layout[i].descriptorType = m_type_counts[i].type;
        layout[i].count = m_type_counts[i].count;
        layout[i].stageFlags = XGL_SHADER_STAGE_FLAGS_ALL;
        layout[i].immutableSampler = XGL_NULL_HANDLE;

        if (i < m_type_counts.size() - 1)
            layout[i].pNext = &layout[i + 1];
        else
            layout[i].pNext = NULL;
    }

    m_layout.init(*m_device, 0, layout[0]);

    // create XGL_DESCRIPTOR_SET
    m_set = alloc_sets(XGL_DESCRIPTOR_SET_USAGE_STATIC, m_layout);

    // build the update chain
    for (int i = 0; i < m_updateBuffers.size(); i++) {
        m_updateBuffers[i].pBufferViews = &m_bufferInfo[i];

        if (i < m_updateBuffers.size() - 1)
            m_updateBuffers[i].pNext = &m_updateBuffers[i + 1];
        else if (m_updateSamplerTextures.empty())
            m_updateBuffers[i].pNext = NULL;
        else
            m_updateBuffers[i].pNext = &m_updateSamplerTextures[0];
    }
    for (int i = 0; i < m_updateSamplerTextures.size(); i++) {
        m_updateSamplerTextures[i].pSamplerImageViews = &m_samplerTextureInfo[i];

        if (i < m_updateSamplerTextures.size() - 1)
            m_updateSamplerTextures[i].pNext = &m_updateSamplerTextures[i + 1];
        else
            m_updateSamplerTextures[i].pNext = NULL;
    }
    const void *chain = (!m_updateBuffers.empty()) ? (const void *) &m_updateBuffers[0] :
                        (!m_updateSamplerTextures.empty()) ? (const void *) &m_updateSamplerTextures[0] :
                        NULL;

    // do the updates
    m_device->begin_descriptor_pool_update(XGL_DESCRIPTOR_UPDATE_MODE_FASTEST);
    clear_sets(*m_set);
    m_set->update(chain);
    m_device->end_descriptor_pool_update(*cmdBuffer);
}

XglImage::XglImage(XglDevice *dev)
{
    m_device = dev;
    m_imageInfo.view = XGL_NULL_HANDLE;
    m_imageInfo.layout = XGL_IMAGE_LAYOUT_GENERAL;
}

static bool IsCompatible(XGL_FLAGS usage, XGL_FLAGS features)
{
    if ((usage & XGL_IMAGE_USAGE_SHADER_ACCESS_READ_BIT) &&
            !(features & XGL_FORMAT_IMAGE_SHADER_READ_BIT))
        return false;
    if ((usage & XGL_IMAGE_USAGE_SHADER_ACCESS_WRITE_BIT) &&
            !(features & XGL_FORMAT_IMAGE_SHADER_WRITE_BIT))
        return false;
    return true;
}

void XglImage::init(uint32_t w, uint32_t h,
               XGL_FORMAT fmt, XGL_FLAGS usage,
               XGL_IMAGE_TILING requested_tiling)
{
    uint32_t mipCount;
    XGL_FORMAT_PROPERTIES image_fmt;
    XGL_IMAGE_TILING tiling;
    XGL_RESULT err;
    size_t size;

    mipCount = 0;

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

    size = sizeof(image_fmt);
    err = xglGetFormatInfo(m_device->obj(), fmt,
        XGL_INFO_TYPE_FORMAT_PROPERTIES,
        &size, &image_fmt);
    ASSERT_XGL_SUCCESS(err);

    if (requested_tiling == XGL_LINEAR_TILING) {
        if (IsCompatible(usage, image_fmt.linearTilingFeatures)) {
            tiling = XGL_LINEAR_TILING;
        } else if (IsCompatible(usage, image_fmt.optimalTilingFeatures)) {
            tiling = XGL_OPTIMAL_TILING;
        } else {
            ASSERT_TRUE(false) << "Error: Cannot find requested tiling configuration";
        }
    } else if (IsCompatible(usage, image_fmt.optimalTilingFeatures)) {
        tiling = XGL_OPTIMAL_TILING;
    } else if (IsCompatible(usage, image_fmt.linearTilingFeatures)) {
        tiling = XGL_LINEAR_TILING;
    } else {
         ASSERT_TRUE(false) << "Error: Cannot find requested tiling configuration";
    }

    XGL_IMAGE_CREATE_INFO imageCreateInfo = xgl_testing::Image::create_info();
    imageCreateInfo.imageType = XGL_IMAGE_2D;
    imageCreateInfo.format = fmt;
    imageCreateInfo.extent.width = w;
    imageCreateInfo.extent.height = h;
    imageCreateInfo.mipLevels = mipCount;
    imageCreateInfo.tiling = tiling;

    imageCreateInfo.usage = usage;

    xgl_testing::Image::init(*m_device, imageCreateInfo);

    m_imageInfo.layout = XGL_IMAGE_LAYOUT_GENERAL;
}

XGL_RESULT XglImage::MapMemory(void** ptr)
{
    *ptr = map();
    return (*ptr) ? XGL_SUCCESS : XGL_ERROR_UNKNOWN;
}

XGL_RESULT XglImage::UnmapMemory()
{
    unmap();
    return XGL_SUCCESS;
}

XGL_RESULT XglImage::CopyImage(XglImage &fromImage)
{
    XGL_RESULT err;

    XGL_CMD_BUFFER cmd_buf;
    XGL_CMD_BUFFER_CREATE_INFO  cmd_buf_create_info = {};
    cmd_buf_create_info.sType = XGL_STRUCTURE_TYPE_CMD_BUFFER_CREATE_INFO;
    cmd_buf_create_info.pNext = NULL;
    cmd_buf_create_info.queueNodeIndex = m_device->graphics_queue_node_index_;
    cmd_buf_create_info.flags = 0;

    err = xglCreateCommandBuffer(m_device->device(), &cmd_buf_create_info, &cmd_buf);
    assert(!err);

    /* Copy staging texture to usable texture */
    XGL_CMD_BUFFER_BEGIN_INFO cmd_buf_begin_info = {};
    cmd_buf_begin_info.sType = XGL_STRUCTURE_TYPE_CMD_BUFFER_BEGIN_INFO;
    cmd_buf_begin_info.pNext = NULL;
    cmd_buf_begin_info.flags = 0;

    err = xglResetCommandBuffer(cmd_buf);
    assert(!err);

    err = xglBeginCommandBuffer(cmd_buf, &cmd_buf_begin_info);
    assert(!err);

    XGL_IMAGE_MEMORY_BARRIER image_memory_barrier = {};
    image_memory_barrier.sType = XGL_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER;
    image_memory_barrier.pNext = NULL;
    image_memory_barrier.outputMask = XGL_MEMORY_OUTPUT_COPY_BIT;
    image_memory_barrier.inputMask = XGL_MEMORY_INPUT_SHADER_READ_BIT | XGL_MEMORY_INPUT_COPY_BIT;
    image_memory_barrier.oldLayout = fromImage.layout();
    image_memory_barrier.newLayout = XGL_IMAGE_LAYOUT_TRANSFER_SOURCE_OPTIMAL;
    image_memory_barrier.image = fromImage.obj();
    image_memory_barrier.subresourceRange.aspect = XGL_IMAGE_ASPECT_COLOR;
    image_memory_barrier.subresourceRange.baseMipLevel = 0;
    image_memory_barrier.subresourceRange.mipLevels = 1;
    image_memory_barrier.subresourceRange.baseArraySlice = 0;
    image_memory_barrier.subresourceRange.arraySize = 0;

    XGL_IMAGE_MEMORY_BARRIER *pmemory_barrier = &image_memory_barrier;

    XGL_PIPE_EVENT pipe_events[] = { XGL_PIPE_EVENT_GPU_COMMANDS_COMPLETE };
    XGL_PIPELINE_BARRIER pipeline_barrier;
    pipeline_barrier.sType = XGL_STRUCTURE_TYPE_PIPELINE_BARRIER;
    pipeline_barrier.pNext = NULL;
    pipeline_barrier.eventCount = 1;
    pipeline_barrier.pEvents = pipe_events;
    pipeline_barrier.waitEvent = XGL_WAIT_EVENT_TOP_OF_PIPE;
    pipeline_barrier.memBarrierCount = 1;
    pipeline_barrier.ppMemBarriers = (const void **)&pmemory_barrier;

    // write barrier to the command buffer
    xglCmdPipelineBarrier(cmd_buf, &pipeline_barrier);

    image_memory_barrier.sType = XGL_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER;
    image_memory_barrier.pNext = NULL;
    image_memory_barrier.outputMask = XGL_MEMORY_OUTPUT_COPY_BIT;
    image_memory_barrier.inputMask = XGL_MEMORY_INPUT_SHADER_READ_BIT | XGL_MEMORY_INPUT_COPY_BIT;
    image_memory_barrier.oldLayout = this->layout();
    image_memory_barrier.newLayout = XGL_IMAGE_LAYOUT_TRANSFER_DESTINATION_OPTIMAL;
    image_memory_barrier.image = this->obj();
    image_memory_barrier.subresourceRange.aspect = XGL_IMAGE_ASPECT_COLOR;
    image_memory_barrier.subresourceRange.baseMipLevel = 0;
    image_memory_barrier.subresourceRange.mipLevels = 1;
    image_memory_barrier.subresourceRange.baseArraySlice = 0;
    image_memory_barrier.subresourceRange.arraySize = 0;

    pipeline_barrier.sType = XGL_STRUCTURE_TYPE_PIPELINE_BARRIER;
    pipeline_barrier.pNext = NULL;
    pipeline_barrier.eventCount = 1;
    pipeline_barrier.pEvents = pipe_events;
    pipeline_barrier.waitEvent = XGL_WAIT_EVENT_TOP_OF_PIPE;
    pipeline_barrier.memBarrierCount = 1;
    pipeline_barrier.ppMemBarriers = (const void **)&pmemory_barrier;

    // write barrier to the command buffer
    xglCmdPipelineBarrier(cmd_buf, &pipeline_barrier);

    XGL_IMAGE_COPY copy_region = {};
    copy_region.srcSubresource.aspect = XGL_IMAGE_ASPECT_COLOR;
    copy_region.srcSubresource.arraySlice = 0;
    copy_region.srcSubresource.mipLevel = 0;
    copy_region.srcOffset.x = 0;
    copy_region.srcOffset.y = 0;
    copy_region.srcOffset.z = 0;
    copy_region.destSubresource.aspect = XGL_IMAGE_ASPECT_COLOR;
    copy_region.destSubresource.arraySlice = 0;
    copy_region.destSubresource.mipLevel = 0;
    copy_region.destOffset.x = 0;
    copy_region.destOffset.y = 0;
    copy_region.destOffset.z = 0;
    copy_region.extent = fromImage.extent();

    xglCmdCopyImage(cmd_buf, fromImage.obj(), fromImage.layout(),
                    obj(), XGL_IMAGE_LAYOUT_TRANSFER_DESTINATION_OPTIMAL,
                    1, &copy_region);

    image_memory_barrier.sType = XGL_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER;
    image_memory_barrier.pNext = NULL;
    image_memory_barrier.outputMask = XGL_MEMORY_OUTPUT_COPY_BIT;
    image_memory_barrier.inputMask = XGL_MEMORY_INPUT_SHADER_READ_BIT | XGL_MEMORY_INPUT_COPY_BIT;
    image_memory_barrier.oldLayout = XGL_IMAGE_LAYOUT_TRANSFER_SOURCE_OPTIMAL;
    image_memory_barrier.newLayout = fromImage.layout();
    image_memory_barrier.image = fromImage.obj();
    image_memory_barrier.subresourceRange.aspect = XGL_IMAGE_ASPECT_COLOR;
    image_memory_barrier.subresourceRange.baseMipLevel = 0;
    image_memory_barrier.subresourceRange.mipLevels = 1;
    image_memory_barrier.subresourceRange.baseArraySlice = 0;
    image_memory_barrier.subresourceRange.arraySize = 0;

    pipeline_barrier.sType = XGL_STRUCTURE_TYPE_PIPELINE_BARRIER;
    pipeline_barrier.pNext = NULL;
    pipeline_barrier.eventCount = 1;
    pipeline_barrier.pEvents = pipe_events;
    pipeline_barrier.waitEvent = XGL_WAIT_EVENT_TOP_OF_PIPE;
    pipeline_barrier.memBarrierCount = 1;
    pipeline_barrier.ppMemBarriers = (const void **)&pmemory_barrier;

    // write barrier to the command buffer
    xglCmdPipelineBarrier(cmd_buf, &pipeline_barrier);

    image_memory_barrier.sType = XGL_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER;
    image_memory_barrier.pNext = NULL;
    image_memory_barrier.outputMask = XGL_MEMORY_OUTPUT_COPY_BIT;
    image_memory_barrier.inputMask = XGL_MEMORY_INPUT_SHADER_READ_BIT | XGL_MEMORY_INPUT_COPY_BIT;
    image_memory_barrier.oldLayout = XGL_IMAGE_LAYOUT_TRANSFER_DESTINATION_OPTIMAL;
    image_memory_barrier.newLayout = this->layout();
    image_memory_barrier.image = this->obj();
    image_memory_barrier.subresourceRange.aspect = XGL_IMAGE_ASPECT_COLOR;
    image_memory_barrier.subresourceRange.baseMipLevel = 0;
    image_memory_barrier.subresourceRange.mipLevels = 1;
    image_memory_barrier.subresourceRange.baseArraySlice = 0;
    image_memory_barrier.subresourceRange.arraySize = 0;

    pipeline_barrier.sType = XGL_STRUCTURE_TYPE_PIPELINE_BARRIER;
    pipeline_barrier.pNext = NULL;
    pipeline_barrier.eventCount = 1;
    pipeline_barrier.pEvents = pipe_events;
    pipeline_barrier.waitEvent = XGL_WAIT_EVENT_TOP_OF_PIPE;
    pipeline_barrier.memBarrierCount = 1;
    pipeline_barrier.ppMemBarriers = (const void **)&pmemory_barrier;

    // write barrier to the command buffer
    xglCmdPipelineBarrier(cmd_buf, &pipeline_barrier);

    err = xglEndCommandBuffer(cmd_buf);
    assert(!err);

    const XGL_CMD_BUFFER cmd_bufs[] = { cmd_buf };
    XGL_MEMORY_REF mem_refs[16];
    uint32_t num_refs = 0;
    const std::vector<XGL_GPU_MEMORY> from_mems = fromImage.memories();
    const std::vector<XGL_GPU_MEMORY> to_mems = memories();

    for (uint32_t j = 0; j < from_mems.size(); j++) {
        mem_refs[num_refs].flags = XGL_MEMORY_REF_READ_ONLY_BIT;
        mem_refs[num_refs].mem = from_mems[j];
        num_refs++;
        assert(num_refs < 16);
    }

    for (uint32_t j = 0; j < to_mems.size(); j++) {
        mem_refs[num_refs].flags = XGL_MEMORY_REF_READ_ONLY_BIT;
        mem_refs[num_refs].mem = to_mems[j];
        num_refs++;
        assert(num_refs < 16);
    }

    err = xglQueueSubmit(m_device->m_queue, 1, cmd_bufs,
                         num_refs, mem_refs, XGL_NULL_HANDLE);
    assert(!err);

    err = xglQueueWaitIdle(m_device->m_queue);
    assert(!err);

    xglDestroyObject(cmd_buf);

    return XGL_SUCCESS;
}

XglTextureObj::XglTextureObj(XglDevice *device, uint32_t *colors)
    :XglImage(device)
{
    m_device = device;
    const XGL_FORMAT tex_format = XGL_FMT_B8G8R8A8_UNORM;
    uint32_t tex_colors[2] = { 0xffff0000, 0xff00ff00 };
    void *data;
    int32_t x, y;
    XglImage stagingImage(device);

    stagingImage.init(16, 16, tex_format, 0, XGL_LINEAR_TILING);
    XGL_SUBRESOURCE_LAYOUT layout = stagingImage.subresource_layout(subresource(XGL_IMAGE_ASPECT_COLOR, 0, 0));

    if (colors == NULL)
        colors = tex_colors;

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

    m_textureViewInfo.sType = XGL_STRUCTURE_TYPE_IMAGE_VIEW_ATTACH_INFO;

    XGL_IMAGE_VIEW_CREATE_INFO view = {};
    view.sType = XGL_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO;
    view.pNext = NULL;
    view.image = XGL_NULL_HANDLE;
    view.viewType = XGL_IMAGE_VIEW_2D;
    view.format = tex_format;
    view.channels.r = XGL_CHANNEL_SWIZZLE_R;
    view.channels.g = XGL_CHANNEL_SWIZZLE_G;
    view.channels.b = XGL_CHANNEL_SWIZZLE_B;
    view.channels.a = XGL_CHANNEL_SWIZZLE_A;
    view.subresourceRange.aspect = XGL_IMAGE_ASPECT_COLOR;
    view.subresourceRange.baseMipLevel = 0;
    view.subresourceRange.mipLevels = 1;
    view.subresourceRange.baseArraySlice = 0;
    view.subresourceRange.arraySize = 1;
    view.minLod = 0.0f;

    /* create image */
    init(16, 16, tex_format, XGL_IMAGE_USAGE_SHADER_ACCESS_READ_BIT, XGL_OPTIMAL_TILING);

    /* create image view */
    view.image = obj();
    m_textureView.init(*m_device, view);
    m_textureViewInfo.view = m_textureView.obj();

    data = stagingImage.map();

    for (y = 0; y < extent().height; y++) {
        uint32_t *row = (uint32_t *) ((char *) data + layout.rowPitch * y);
        for (x = 0; x < extent().width; x++)
            row[x] = colors[(x & 1) ^ (y & 1)];
    }
    stagingImage.unmap();
    XglImage::CopyImage(stagingImage);
}

XglSamplerObj::XglSamplerObj(XglDevice *device)
{
    m_device = device;

    XGL_SAMPLER_CREATE_INFO samplerCreateInfo;
    memset(&samplerCreateInfo,0,sizeof(samplerCreateInfo));
    samplerCreateInfo.sType = XGL_STRUCTURE_TYPE_SAMPLER_CREATE_INFO;
    samplerCreateInfo.magFilter = XGL_TEX_FILTER_NEAREST;
    samplerCreateInfo.minFilter = XGL_TEX_FILTER_NEAREST;
    samplerCreateInfo.mipMode = XGL_TEX_MIPMAP_BASE;
    samplerCreateInfo.addressU = XGL_TEX_ADDRESS_WRAP;
    samplerCreateInfo.addressV = XGL_TEX_ADDRESS_WRAP;
    samplerCreateInfo.addressW = XGL_TEX_ADDRESS_WRAP;
    samplerCreateInfo.mipLodBias = 0.0;
    samplerCreateInfo.maxAnisotropy = 0.0;
    samplerCreateInfo.compareFunc = XGL_COMPARE_NEVER;
    samplerCreateInfo.minLod = 0.0;
    samplerCreateInfo.maxLod = 0.0;
    samplerCreateInfo.borderColorType = XGL_BORDER_COLOR_OPAQUE_WHITE;

    init(*m_device, samplerCreateInfo);
}

/*
 * Basic ConstantBuffer constructor. Then use create methods to fill in the details.
 */
XglConstantBufferObj::XglConstantBufferObj(XglDevice *device)
{
    m_device = device;
    m_commandBuffer = 0;

    memset(&m_bufferViewInfo,0,sizeof(m_bufferViewInfo));
}

XglConstantBufferObj::~XglConstantBufferObj()
{
    if (m_commandBuffer) {
        delete m_commandBuffer;
    }
}

XglConstantBufferObj::XglConstantBufferObj(XglDevice *device, int constantCount, int constantSize, const void* data)
{
    m_device = device;
    m_commandBuffer = 0;

    memset(&m_bufferViewInfo,0,sizeof(m_bufferViewInfo));
    m_numVertices = constantCount;
    m_stride = constantSize;

    const size_t allocationSize = constantCount * constantSize;
    init(*m_device, allocationSize);

    void *pData = map();
    memcpy(pData, data, allocationSize);
    unmap();

    // set up the buffer view for the constant buffer
    XGL_BUFFER_VIEW_CREATE_INFO view_info = {};
    view_info.sType = XGL_STRUCTURE_TYPE_BUFFER_VIEW_CREATE_INFO;
    view_info.buffer = obj();
    view_info.viewType = XGL_BUFFER_VIEW_RAW;
    view_info.offset = 0;
    view_info.range  = allocationSize;
    m_bufferView.init(*m_device, view_info);

    this->m_bufferViewInfo.sType = XGL_STRUCTURE_TYPE_BUFFER_VIEW_ATTACH_INFO;
    this->m_bufferViewInfo.view = m_bufferView.obj();
}

void XglConstantBufferObj::Bind(XGL_CMD_BUFFER cmdBuffer, XGL_GPU_SIZE offset, uint32_t binding)
{
    xglCmdBindVertexBuffer(cmdBuffer, obj(), offset, binding);
}


void XglConstantBufferObj::BufferMemoryBarrier(
        XGL_FLAGS outputMask /*=
            XGL_MEMORY_OUTPUT_CPU_WRITE_BIT |
            XGL_MEMORY_OUTPUT_SHADER_WRITE_BIT |
            XGL_MEMORY_OUTPUT_COLOR_ATTACHMENT_BIT |
            XGL_MEMORY_OUTPUT_DEPTH_STENCIL_ATTACHMENT_BIT |
            XGL_MEMORY_OUTPUT_COPY_BIT*/,
        XGL_FLAGS inputMask /*=
            XGL_MEMORY_INPUT_CPU_READ_BIT |
            XGL_MEMORY_INPUT_INDIRECT_COMMAND_BIT |
            XGL_MEMORY_INPUT_INDEX_FETCH_BIT |
            XGL_MEMORY_INPUT_VERTEX_ATTRIBUTE_FETCH_BIT |
            XGL_MEMORY_INPUT_UNIFORM_READ_BIT |
            XGL_MEMORY_INPUT_SHADER_READ_BIT |
            XGL_MEMORY_INPUT_COLOR_ATTACHMENT_BIT |
            XGL_MEMORY_INPUT_DEPTH_STENCIL_ATTACHMENT_BIT |
            XGL_MEMORY_INPUT_COPY_BIT*/)
{
    XGL_RESULT err = XGL_SUCCESS;

    if (!m_commandBuffer)
    {
        m_fence.init(*m_device, xgl_testing::Fence::create_info(0));

        m_commandBuffer = new XglCommandBufferObj(m_device);

    }
    else
    {
        m_device->wait(m_fence);
    }

    // open the command buffer
    XGL_CMD_BUFFER_BEGIN_INFO cmd_buf_info = {};
    cmd_buf_info.sType = XGL_STRUCTURE_TYPE_CMD_BUFFER_BEGIN_INFO;
    cmd_buf_info.pNext = NULL;
    cmd_buf_info.flags = 0;

    err = m_commandBuffer->BeginCommandBuffer(&cmd_buf_info);
    ASSERT_XGL_SUCCESS(err);

    XGL_BUFFER_MEMORY_BARRIER memory_barrier =
        buffer_memory_barrier(outputMask, inputMask, 0, m_numVertices * m_stride);
    XGL_BUFFER_MEMORY_BARRIER *pmemory_barrier = &memory_barrier;

    XGL_PIPE_EVENT set_events[] = { XGL_PIPE_EVENT_GPU_COMMANDS_COMPLETE };
    XGL_PIPELINE_BARRIER pipeline_barrier = {};
    pipeline_barrier.sType = XGL_STRUCTURE_TYPE_PIPELINE_BARRIER;
    pipeline_barrier.eventCount = 1;
    pipeline_barrier.pEvents = set_events;
    pipeline_barrier.waitEvent = XGL_WAIT_EVENT_TOP_OF_PIPE;
    pipeline_barrier.memBarrierCount = 1;
    pipeline_barrier.ppMemBarriers = (const void **)&pmemory_barrier;

    // write barrier to the command buffer
    m_commandBuffer->PipelineBarrier(&pipeline_barrier);

    // finish recording the command buffer
    err = m_commandBuffer->EndCommandBuffer();
    ASSERT_XGL_SUCCESS(err);

    uint32_t     numMemRefs=1;
    XGL_MEMORY_REF memRefs;
    // this command buffer only uses the vertex buffer memory
    memRefs.flags = 0;
    memRefs.mem = memories()[0];

    // submit the command buffer to the universal queue
    XGL_CMD_BUFFER bufferArray[1];
    bufferArray[0] = m_commandBuffer->GetBufferHandle();
    err = xglQueueSubmit( m_device->m_queue, 1, bufferArray, numMemRefs, &memRefs, m_fence.obj() );
    ASSERT_XGL_SUCCESS(err);
}

XglIndexBufferObj::XglIndexBufferObj(XglDevice *device)
    : XglConstantBufferObj(device)
{

}

void XglIndexBufferObj::CreateAndInitBuffer(int numIndexes, XGL_INDEX_TYPE indexType, const void* data)
{
    XGL_FORMAT viewFormat;

    m_numVertices = numIndexes;
    m_indexType = indexType;
    switch (indexType) {
    case XGL_INDEX_8:
        m_stride = 1;
        viewFormat = XGL_FMT_R8_UINT;
        break;
    case XGL_INDEX_16:
        m_stride = 2;
        viewFormat = XGL_FMT_R16_UINT;
        break;
    case XGL_INDEX_32:
        m_stride = 4;
        viewFormat = XGL_FMT_R32_UINT;
        break;
    default:
        assert(!"unknown index type");
        break;
    }

    const size_t allocationSize = numIndexes * m_stride;
    init(*m_device, allocationSize);

    void *pData = map();
    memcpy(pData, data, allocationSize);
    unmap();

    // set up the buffer view for the constant buffer
    XGL_BUFFER_VIEW_CREATE_INFO view_info = {};
    view_info.sType = XGL_STRUCTURE_TYPE_BUFFER_VIEW_CREATE_INFO;
    view_info.buffer = obj();
    view_info.viewType = XGL_BUFFER_VIEW_TYPED;
    view_info.format = viewFormat;
    view_info.offset = 0;
    view_info.range  = allocationSize;
    m_bufferView.init(*m_device, view_info);

    this->m_bufferViewInfo.sType = XGL_STRUCTURE_TYPE_BUFFER_VIEW_ATTACH_INFO;
    this->m_bufferViewInfo.view = m_bufferView.obj();
}

void XglIndexBufferObj::Bind(XGL_CMD_BUFFER cmdBuffer, XGL_GPU_SIZE offset)
{
    xglCmdBindIndexBuffer(cmdBuffer, obj(), offset, m_indexType);
}

XGL_INDEX_TYPE XglIndexBufferObj::GetIndexType()
{
    return m_indexType;
}

XGL_PIPELINE_SHADER_STAGE_CREATE_INFO* XglShaderObj::GetStageCreateInfo()
{
    XGL_PIPELINE_SHADER_STAGE_CREATE_INFO *stageInfo = (XGL_PIPELINE_SHADER_STAGE_CREATE_INFO*) calloc( 1,sizeof(XGL_PIPELINE_SHADER_STAGE_CREATE_INFO) );
    stageInfo->sType = XGL_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO;
    stageInfo->shader.stage = m_stage;
    stageInfo->shader.shader = obj();
    stageInfo->shader.linkConstBufferCount = 0;
    stageInfo->shader.pLinkConstBufferInfo = XGL_NULL_HANDLE;

    return stageInfo;
}

XglShaderObj::XglShaderObj(XglDevice *device, const char * shader_code, XGL_PIPELINE_SHADER_STAGE stage, XglRenderFramework *framework)
{
    XGL_RESULT err = XGL_SUCCESS;
    std::vector<unsigned int> spv;
    XGL_SHADER_CREATE_INFO createInfo;
    size_t shader_len;

    m_stage = stage;
    m_device = device;

    createInfo.sType = XGL_STRUCTURE_TYPE_SHADER_CREATE_INFO;
    createInfo.pNext = NULL;

    if (!framework->m_use_spv) {

        shader_len = strlen(shader_code);
        createInfo.codeSize = 3 * sizeof(uint32_t) + shader_len + 1;
        createInfo.pCode = malloc(createInfo.codeSize);
        createInfo.flags = 0;

        /* try version 0 first: XGL_PIPELINE_SHADER_STAGE followed by GLSL */
        ((uint32_t *) createInfo.pCode)[0] = ICD_SPV_MAGIC;
        ((uint32_t *) createInfo.pCode)[1] = 0;
        ((uint32_t *) createInfo.pCode)[2] = stage;
        memcpy(((uint32_t *) createInfo.pCode + 3), shader_code, shader_len + 1);

        err = init_try(*m_device, createInfo);
    }

    if (framework->m_use_spv || err) {
        std::vector<unsigned int> spv;
        err = XGL_SUCCESS;

        // Use Reference GLSL to SPV compiler
        framework->GLSLtoSPV(stage, shader_code, spv);
        createInfo.pCode = spv.data();
        createInfo.codeSize = spv.size() * sizeof(unsigned int);
        createInfo.flags = 0;

        init(*m_device, createInfo);
    }
}

XglPipelineObj::XglPipelineObj(XglDevice *device)
{
    m_device = device;
    m_vi_state.attributeCount = m_vi_state.bindingCount = 0;
    m_vertexBufferCount = 0;

    m_ia_state.sType = XGL_STRUCTURE_TYPE_PIPELINE_IA_STATE_CREATE_INFO;
    m_ia_state.pNext = XGL_NULL_HANDLE;
    m_ia_state.topology = XGL_TOPOLOGY_TRIANGLE_LIST;
    m_ia_state.disableVertexReuse = XGL_FALSE;
    m_ia_state.primitiveRestartEnable = XGL_FALSE;
    m_ia_state.primitiveRestartIndex = 0;

    m_rs_state.sType = XGL_STRUCTURE_TYPE_PIPELINE_RS_STATE_CREATE_INFO;
    m_rs_state.pNext = &m_ia_state;
    m_rs_state.depthClipEnable = XGL_FALSE;
    m_rs_state.rasterizerDiscardEnable = XGL_FALSE;
    m_rs_state.programPointSize = XGL_FALSE;
    m_rs_state.pointOrigin = XGL_COORDINATE_ORIGIN_UPPER_LEFT;
    m_rs_state.provokingVertex = XGL_PROVOKING_VERTEX_LAST;
    m_rs_state.fillMode = XGL_FILL_SOLID;
    m_rs_state.cullMode = XGL_CULL_NONE;
    m_rs_state.frontFace = XGL_FRONT_FACE_CCW;

    memset(&m_cb_state,0,sizeof(m_cb_state));
    m_cb_state.sType = XGL_STRUCTURE_TYPE_PIPELINE_CB_STATE_CREATE_INFO;
    m_cb_state.pNext = &m_rs_state;
    m_cb_state.alphaToCoverageEnable = XGL_FALSE;
    m_cb_state.logicOp = XGL_LOGIC_OP_COPY;

    m_ms_state.pNext = &m_cb_state;
    m_ms_state.sType = XGL_STRUCTURE_TYPE_PIPELINE_MS_STATE_CREATE_INFO;
    m_ms_state.multisampleEnable = XGL_FALSE;
    m_ms_state.sampleMask = 1;                // Do we have to specify MSAA even just to disable it?
    m_ms_state.samples = 1;
    m_ms_state.minSampleShading = 0;
    m_ms_state.sampleShadingEnable = 0;

    m_ds_state.sType = XGL_STRUCTURE_TYPE_PIPELINE_DS_STATE_CREATE_INFO;
    m_ds_state.pNext = &m_ms_state,
    m_ds_state.format = XGL_FMT_D32_SFLOAT;
    m_ds_state.depthTestEnable      = XGL_FALSE;
    m_ds_state.depthWriteEnable     = XGL_FALSE;
    m_ds_state.depthBoundsEnable    = XGL_FALSE;
    m_ds_state.depthFunc = XGL_COMPARE_LESS_EQUAL;
    m_ds_state.back.stencilDepthFailOp = XGL_STENCIL_OP_KEEP;
    m_ds_state.back.stencilFailOp = XGL_STENCIL_OP_KEEP;
    m_ds_state.back.stencilPassOp = XGL_STENCIL_OP_KEEP;
    m_ds_state.back.stencilFunc = XGL_COMPARE_ALWAYS;
    m_ds_state.stencilTestEnable = XGL_FALSE;
    m_ds_state.front = m_ds_state.back;

    XGL_PIPELINE_CB_ATTACHMENT_STATE att = {};
    att.blendEnable = XGL_FALSE;
    att.format = XGL_FMT_B8G8R8A8_UNORM;
    att.channelWriteMask = 0xf;
    AddColorAttachment(0, &att);

};

void XglPipelineObj::AddShader(XglShaderObj* shader)
{
    m_shaderObjs.push_back(shader);
}

void XglPipelineObj::AddVertexInputAttribs(XGL_VERTEX_INPUT_ATTRIBUTE_DESCRIPTION* vi_attrib, int count)
{
    m_vi_state.pVertexAttributeDescriptions = vi_attrib;
    m_vi_state.attributeCount = count;
}

void XglPipelineObj::AddVertexInputBindings(XGL_VERTEX_INPUT_BINDING_DESCRIPTION* vi_binding, int count)
{
    m_vi_state.pVertexBindingDescriptions = vi_binding;
    m_vi_state.bindingCount = count;
}

void XglPipelineObj::AddVertexDataBuffer(XglConstantBufferObj* vertexDataBuffer, int binding)
{
    m_vertexBufferObjs.push_back(vertexDataBuffer);
    m_vertexBufferBindings.push_back(binding);
    m_vertexBufferCount++;
}

void XglPipelineObj::AddColorAttachment(uint32_t binding, const XGL_PIPELINE_CB_ATTACHMENT_STATE *att)
{
    if (binding+1 > m_colorAttachments.size())
    {
        m_colorAttachments.resize(binding+1);
    }
    m_colorAttachments[binding] = *att;
}

void XglPipelineObj::SetDepthStencil(XGL_PIPELINE_DS_STATE_CREATE_INFO *ds_state)
{
    m_ds_state.format = ds_state->format;
    m_ds_state.depthTestEnable = ds_state->depthTestEnable;
    m_ds_state.depthWriteEnable = ds_state->depthWriteEnable;
    m_ds_state.depthBoundsEnable = ds_state->depthBoundsEnable;
    m_ds_state.depthFunc = ds_state->depthFunc;
    m_ds_state.stencilTestEnable = ds_state->stencilTestEnable;
    m_ds_state.back = ds_state->back;
    m_ds_state.front = ds_state->front;
}

void XglPipelineObj::CreateXGLPipeline(XglDescriptorSetObj *descriptorSet)
{
    void* head_ptr = &m_ds_state;
    XGL_GRAPHICS_PIPELINE_CREATE_INFO info = {};

    XGL_PIPELINE_SHADER_STAGE_CREATE_INFO* shaderCreateInfo;

    for (int i=0; i<m_shaderObjs.size(); i++)
    {
        shaderCreateInfo = m_shaderObjs[i]->GetStageCreateInfo();
        shaderCreateInfo->pNext = head_ptr;
        head_ptr = shaderCreateInfo;
    }

    if (m_vi_state.attributeCount && m_vi_state.bindingCount)
    {
        m_vi_state.sType = XGL_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_CREATE_INFO;
        m_vi_state.pNext = head_ptr;
        head_ptr = &m_vi_state;
    }

    info.sType = XGL_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO;
    info.pNext = head_ptr;
    info.flags = 0;
    info.lastSetLayout = descriptorSet->GetLayout();

    m_cb_state.attachmentCount = m_colorAttachments.size();
    m_cb_state.pAttachments = &m_colorAttachments[0];

    init(*m_device, info);
}

XGL_PIPELINE XglPipelineObj::GetPipelineHandle()
{
    return obj();
}

void XglPipelineObj::BindPipelineCommandBuffer(XGL_CMD_BUFFER m_cmdBuffer, XglDescriptorSetObj *descriptorSet)
{
    void* head_ptr = &m_ds_state;
    XGL_GRAPHICS_PIPELINE_CREATE_INFO info = {};

    XGL_PIPELINE_SHADER_STAGE_CREATE_INFO* shaderCreateInfo;

    for (int i=0; i<m_shaderObjs.size(); i++)
    {
        shaderCreateInfo = m_shaderObjs[i]->GetStageCreateInfo();
        shaderCreateInfo->pNext = head_ptr;
        head_ptr = shaderCreateInfo;
    }

    if (m_vi_state.attributeCount && m_vi_state.bindingCount)
    {
        m_vi_state.sType = XGL_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_CREATE_INFO;
        m_vi_state.pNext = head_ptr;
        head_ptr = &m_vi_state;
    }

    info.sType = XGL_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO;
    info.pNext = head_ptr;
    info.flags = 0;
    info.lastSetLayout = descriptorSet->GetLayout();

    init(*m_device, info);

    xglCmdBindPipeline( m_cmdBuffer, XGL_PIPELINE_BIND_POINT_GRAPHICS, obj() );


    for (int i=0; i < m_vertexBufferCount; i++)
    {
        m_vertexBufferObjs[i]->Bind(m_cmdBuffer, 0,  m_vertexBufferBindings[i]);
    }
}

XglMemoryRefManager::XglMemoryRefManager() {

}

void XglMemoryRefManager::AddMemoryRef(xgl_testing::Object *xglObject) {
    const std::vector<XGL_GPU_MEMORY> mems = xglObject->memories();
    for (size_t i = 0; i < mems.size(); i++) {
        m_bufferObjs.push_back(mems[i]);
    }
}

void XglMemoryRefManager::AddMemoryRef(XGL_GPU_MEMORY *mem, uint32_t refCount) {
    for (size_t i = 0; i < refCount; i++) {
        m_bufferObjs.push_back(mem[i]);
    }
}

void XglMemoryRefManager::AddRTMemoryRefs(vector<XglImage*>images, uint32_t rtCount) {
    for (uint32_t i = 0; i < rtCount; i++) {
        const std::vector<XGL_GPU_MEMORY> mems = images[i]->memories();
        if (!mems.empty())
            m_bufferObjs.push_back(mems[0]);
    }
}

XGL_MEMORY_REF* XglMemoryRefManager::GetMemoryRefList() {

    XGL_MEMORY_REF *localRefs;
    uint32_t       numRefs=m_bufferObjs.size();

    if (numRefs <= 0)
        return NULL;

    localRefs = (XGL_MEMORY_REF*) malloc( numRefs * sizeof(XGL_MEMORY_REF) );
    for (int i=0; i<numRefs; i++)
    {
        localRefs[i].flags = 0;
        localRefs[i].mem = m_bufferObjs[i];
    }
    return localRefs;
}
int XglMemoryRefManager::GetNumRefs() {
    return m_bufferObjs.size();
}

XglCommandBufferObj::XglCommandBufferObj(XglDevice *device)
    : xgl_testing::CmdBuffer(*device, xgl_testing::CmdBuffer::create_info(device->graphics_queue_node_index_))
{
    m_device = device;
}

XGL_CMD_BUFFER XglCommandBufferObj::GetBufferHandle()
{
    return obj();
}

XGL_RESULT XglCommandBufferObj::BeginCommandBuffer(XGL_CMD_BUFFER_BEGIN_INFO *pInfo)
{
    begin(pInfo);
    return XGL_SUCCESS;
}

XGL_RESULT XglCommandBufferObj::BeginCommandBuffer(XGL_RENDER_PASS renderpass_obj, XGL_FRAMEBUFFER framebuffer_obj)
{
    begin(renderpass_obj, framebuffer_obj);
    return XGL_SUCCESS;
}

XGL_RESULT XglCommandBufferObj::BeginCommandBuffer()
{
    begin();
    return XGL_SUCCESS;
}

XGL_RESULT XglCommandBufferObj::EndCommandBuffer()
{
    end();
    return XGL_SUCCESS;
}

void XglCommandBufferObj::PipelineBarrier(XGL_PIPELINE_BARRIER *barrierPtr)
{
    xglCmdPipelineBarrier(obj(), barrierPtr);
}

void XglCommandBufferObj::ClearAllBuffers(XGL_CLEAR_COLOR clear_color, float depth_clear_color, uint32_t stencil_clear_color,
                                          XGL_DEPTH_STENCIL_BIND_INFO *depthStencilBinding, XGL_IMAGE depthStencilImage)
{
    uint32_t i;
    const XGL_FLAGS output_mask =
        XGL_MEMORY_OUTPUT_CPU_WRITE_BIT |
        XGL_MEMORY_OUTPUT_SHADER_WRITE_BIT |
        XGL_MEMORY_OUTPUT_COLOR_ATTACHMENT_BIT |
        XGL_MEMORY_OUTPUT_DEPTH_STENCIL_ATTACHMENT_BIT |
        XGL_MEMORY_OUTPUT_COPY_BIT;
    const XGL_FLAGS input_mask = 0;

    // whatever we want to do, we do it to the whole buffer
    XGL_IMAGE_SUBRESOURCE_RANGE srRange = {};
    srRange.aspect = XGL_IMAGE_ASPECT_COLOR;
    srRange.baseMipLevel = 0;
    srRange.mipLevels = XGL_LAST_MIP_OR_SLICE;
    srRange.baseArraySlice = 0;
    srRange.arraySize = XGL_LAST_MIP_OR_SLICE;

    XGL_IMAGE_MEMORY_BARRIER memory_barrier = {};
    memory_barrier.sType = XGL_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER;
    memory_barrier.outputMask = output_mask;
    memory_barrier.inputMask = input_mask;
    memory_barrier.newLayout = XGL_IMAGE_LAYOUT_CLEAR_OPTIMAL;
    memory_barrier.subresourceRange = srRange;
    XGL_IMAGE_MEMORY_BARRIER *pmemory_barrier = &memory_barrier;

    XGL_PIPE_EVENT set_events[] = { XGL_PIPE_EVENT_GPU_COMMANDS_COMPLETE };
    XGL_PIPELINE_BARRIER pipeline_barrier = {};
    pipeline_barrier.sType = XGL_STRUCTURE_TYPE_PIPELINE_BARRIER;
    pipeline_barrier.eventCount = 1;
    pipeline_barrier.pEvents = set_events;
    pipeline_barrier.waitEvent = XGL_WAIT_EVENT_TOP_OF_PIPE;
    pipeline_barrier.memBarrierCount = 1;
    pipeline_barrier.ppMemBarriers = (const void **)&pmemory_barrier;

    for (i = 0; i < m_renderTargets.size(); i++) {
        memory_barrier.image = m_renderTargets[i]->image();
        memory_barrier.oldLayout = m_renderTargets[i]->layout();
        xglCmdPipelineBarrier( obj(), &pipeline_barrier);
        m_renderTargets[i]->layout(memory_barrier.newLayout);

        xglCmdClearColorImage(obj(),
               m_renderTargets[i]->image(), XGL_IMAGE_LAYOUT_CLEAR_OPTIMAL,
               clear_color, 1, &srRange );
    }

    if (depthStencilImage)
    {
        XGL_IMAGE_SUBRESOURCE_RANGE dsRange = {};
        dsRange.aspect = XGL_IMAGE_ASPECT_DEPTH;
        dsRange.baseMipLevel = 0;
        dsRange.mipLevels = XGL_LAST_MIP_OR_SLICE;
        dsRange.baseArraySlice = 0;
        dsRange.arraySize = XGL_LAST_MIP_OR_SLICE;

        // prepare the depth buffer for clear

        memory_barrier.oldLayout = depthStencilBinding->layout;
        memory_barrier.newLayout = XGL_IMAGE_LAYOUT_CLEAR_OPTIMAL;
        memory_barrier.image = depthStencilImage;
        memory_barrier.subresourceRange = dsRange;

        xglCmdPipelineBarrier( obj(), &pipeline_barrier);
        depthStencilBinding->layout = memory_barrier.newLayout;

        xglCmdClearDepthStencil(obj(),
                                depthStencilImage, XGL_IMAGE_LAYOUT_CLEAR_OPTIMAL,
                                depth_clear_color,  stencil_clear_color,
                                1, &dsRange);

        // prepare depth buffer for rendering
        memory_barrier.image = depthStencilImage;
        memory_barrier.oldLayout = XGL_IMAGE_LAYOUT_CLEAR_OPTIMAL;
        memory_barrier.newLayout = depthStencilBinding->layout;
        memory_barrier.subresourceRange = dsRange;
        xglCmdPipelineBarrier( obj(), &pipeline_barrier);
        depthStencilBinding->layout = memory_barrier.newLayout;
    }
}

void XglCommandBufferObj::PrepareAttachments()
{
    uint32_t i;
    const XGL_FLAGS output_mask =
        XGL_MEMORY_OUTPUT_CPU_WRITE_BIT |
        XGL_MEMORY_OUTPUT_SHADER_WRITE_BIT |
        XGL_MEMORY_OUTPUT_COLOR_ATTACHMENT_BIT |
        XGL_MEMORY_OUTPUT_DEPTH_STENCIL_ATTACHMENT_BIT |
        XGL_MEMORY_OUTPUT_COPY_BIT;
    const XGL_FLAGS input_mask =
        XGL_MEMORY_INPUT_CPU_READ_BIT |
        XGL_MEMORY_INPUT_INDIRECT_COMMAND_BIT |
        XGL_MEMORY_INPUT_INDEX_FETCH_BIT |
        XGL_MEMORY_INPUT_VERTEX_ATTRIBUTE_FETCH_BIT |
        XGL_MEMORY_INPUT_UNIFORM_READ_BIT |
        XGL_MEMORY_INPUT_SHADER_READ_BIT |
        XGL_MEMORY_INPUT_COLOR_ATTACHMENT_BIT |
        XGL_MEMORY_INPUT_DEPTH_STENCIL_ATTACHMENT_BIT |
        XGL_MEMORY_INPUT_COPY_BIT;

    XGL_IMAGE_SUBRESOURCE_RANGE srRange = {};
    srRange.aspect = XGL_IMAGE_ASPECT_COLOR;
    srRange.baseMipLevel = 0;
    srRange.mipLevels = XGL_LAST_MIP_OR_SLICE;
    srRange.baseArraySlice = 0;
    srRange.arraySize = XGL_LAST_MIP_OR_SLICE;

    XGL_IMAGE_MEMORY_BARRIER memory_barrier = {};
    memory_barrier.sType = XGL_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER;
    memory_barrier.outputMask = output_mask;
    memory_barrier.inputMask = input_mask;
    memory_barrier.newLayout = XGL_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
    memory_barrier.subresourceRange = srRange;
    XGL_IMAGE_MEMORY_BARRIER *pmemory_barrier = &memory_barrier;

    XGL_PIPE_EVENT set_events[] = { XGL_PIPE_EVENT_GPU_COMMANDS_COMPLETE };
    XGL_PIPELINE_BARRIER pipeline_barrier = {};
    pipeline_barrier.sType = XGL_STRUCTURE_TYPE_PIPELINE_BARRIER;
    pipeline_barrier.eventCount = 1;
    pipeline_barrier.pEvents = set_events;
    pipeline_barrier.waitEvent = XGL_WAIT_EVENT_TOP_OF_PIPE;
    pipeline_barrier.memBarrierCount = 1;
    pipeline_barrier.ppMemBarriers = (const void **)&pmemory_barrier;

    for(i=0; i<m_renderTargets.size(); i++)
    {
        memory_barrier.image = m_renderTargets[i]->image();
        memory_barrier.oldLayout = m_renderTargets[i]->layout();
        xglCmdPipelineBarrier( obj(), &pipeline_barrier);
        m_renderTargets[i]->layout(memory_barrier.newLayout);
    }
}

void XglCommandBufferObj::BeginRenderPass(XGL_RENDER_PASS renderpass, XGL_FRAMEBUFFER framebuffer)
{
    XGL_RENDER_PASS_BEGIN rp_begin = {
        renderpass,
        framebuffer,
    };

    xglCmdBeginRenderPass( obj(), &rp_begin);
}

void XglCommandBufferObj::EndRenderPass(XGL_RENDER_PASS renderpass)
{
    xglCmdEndRenderPass( obj(), renderpass);
}

void XglCommandBufferObj::BindStateObject(XGL_STATE_BIND_POINT stateBindPoint, XGL_DYNAMIC_STATE_OBJECT stateObject)
{
    xglCmdBindDynamicStateObject( obj(), stateBindPoint, stateObject);
}

void XglCommandBufferObj::AddRenderTarget(XglImage *renderTarget)
{
    m_renderTargets.push_back(renderTarget);
}

void XglCommandBufferObj::DrawIndexed(uint32_t firstIndex, uint32_t indexCount, int32_t vertexOffset, uint32_t firstInstance, uint32_t instanceCount)
{
    xglCmdDrawIndexed(obj(), firstIndex, indexCount, vertexOffset, firstInstance, instanceCount);
}

void XglCommandBufferObj::Draw(uint32_t firstVertex, uint32_t vertexCount, uint32_t firstInstance, uint32_t instanceCount)
{
    xglCmdDraw(obj(), firstVertex, vertexCount, firstInstance, instanceCount);
}

void XglCommandBufferObj::QueueCommandBuffer(XGL_MEMORY_REF *memRefs, uint32_t numMemRefs)
{
    XGL_RESULT err = XGL_SUCCESS;

    // submit the command buffer to the universal queue
    err = xglQueueSubmit( m_device->m_queue, 1, &obj(), numMemRefs, memRefs, NULL );
    ASSERT_XGL_SUCCESS( err );

    err = xglQueueWaitIdle( m_device->m_queue );
    ASSERT_XGL_SUCCESS( err );

    // Wait for work to finish before cleaning up.
    xglDeviceWaitIdle(m_device->device());

}
void XglCommandBufferObj::BindPipeline(XGL_PIPELINE pipeline)
{
        xglCmdBindPipeline( obj(), XGL_PIPELINE_BIND_POINT_GRAPHICS, pipeline );
}

void XglCommandBufferObj::BindDescriptorSet(XGL_DESCRIPTOR_SET descriptorSet)
{
    // bind pipeline, vertex buffer (descriptor set) and WVP (dynamic buffer view)
    xglCmdBindDescriptorSet(obj(), XGL_PIPELINE_BIND_POINT_GRAPHICS, descriptorSet, NULL );
}
void XglCommandBufferObj::BindIndexBuffer(XglIndexBufferObj *indexBuffer, uint32_t offset)
{
    xglCmdBindIndexBuffer(obj(), indexBuffer->obj(), offset, indexBuffer->GetIndexType());
}
void XglCommandBufferObj::BindVertexBuffer(XglConstantBufferObj *vertexBuffer, uint32_t offset, uint32_t binding)
{
    xglCmdBindVertexBuffer(obj(), vertexBuffer->obj(), offset, binding);
}
XglDepthStencilObj::XglDepthStencilObj()
{
    m_initialized = false;
}
bool XglDepthStencilObj::Initialized()
{
    return m_initialized;
}

XGL_DEPTH_STENCIL_BIND_INFO* XglDepthStencilObj::BindInfo()
{
    return &m_depthStencilBindInfo;
}

void XglDepthStencilObj::Init(XglDevice *device, int32_t width, int32_t height)
{
    XGL_IMAGE_CREATE_INFO image_info;
    XGL_DEPTH_STENCIL_VIEW_CREATE_INFO view_info;

    m_device = device;
    m_initialized = true;
    m_depth_stencil_fmt = XGL_FMT_D16_UNORM;

    image_info.sType = XGL_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
    image_info.pNext = NULL;
    image_info.imageType = XGL_IMAGE_2D;
    image_info.format = m_depth_stencil_fmt;
    image_info.extent.width = width;
    image_info.extent.height = height;
    image_info.extent.depth = 1;
    image_info.mipLevels = 1;
    image_info.arraySize = 1;
    image_info.samples = 1;
    image_info.tiling = XGL_OPTIMAL_TILING;
    image_info.usage = XGL_IMAGE_USAGE_DEPTH_STENCIL_BIT;
    image_info.flags = 0;
    init(*m_device, image_info);

    view_info.sType = XGL_STRUCTURE_TYPE_DEPTH_STENCIL_VIEW_CREATE_INFO;
    view_info.pNext = NULL;
    view_info.image = XGL_NULL_HANDLE;
    view_info.mipLevel = 0;
    view_info.baseArraySlice = 0;
    view_info.arraySize = 1;
    view_info.flags = 0;
    view_info.image = obj();
    m_depthStencilView.init(*m_device, view_info);

    m_depthStencilBindInfo.view = m_depthStencilView.obj();
    m_depthStencilBindInfo.layout = XGL_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL;
}
