binding: introduce XGL_DESCRIPTOR_SET_LAYOUT_CHAIN

Replace a chain of XGL_DESCRIPTOR_SET_LAYOUT by
XGL_DESCRIPTOR_SET_LAYOUT_CHAIN.  The change also drops
stageFlags/pSetBindPoints, and affects xglUpdateDescriptors().

xglCmdBindDescriptorSet() is not updated yet by this commit, which makes it
impossible to bind multiple sets.

The change also encourages the use of arrays of resources, which we do not
support.

v2: fix a typo in intel_desc_set_update_samplers() that prevents it from
working (olv)
diff --git a/include/xgl.h b/include/xgl.h
index 3b9362f..78c0faa 100644
--- a/include/xgl.h
+++ b/include/xgl.h
@@ -72,6 +72,7 @@
 XGL_DEFINE_SUBCLASS_HANDLE(XGL_SAMPLER, XGL_OBJECT)
 XGL_DEFINE_SUBCLASS_HANDLE(XGL_DESCRIPTOR_SET, XGL_OBJECT)
 XGL_DEFINE_SUBCLASS_HANDLE(XGL_DESCRIPTOR_SET_LAYOUT, XGL_OBJECT)
+XGL_DEFINE_SUBCLASS_HANDLE(XGL_DESCRIPTOR_SET_LAYOUT_CHAIN, XGL_OBJECT)
 XGL_DEFINE_SUBCLASS_HANDLE(XGL_DESCRIPTOR_POOL, XGL_OBJECT)
 XGL_DEFINE_SUBCLASS_HANDLE(XGL_DYNAMIC_STATE_OBJECT, XGL_OBJECT)
 XGL_DEFINE_SUBCLASS_HANDLE(XGL_DYNAMIC_VP_STATE_OBJECT, XGL_DYNAMIC_STATE_OBJECT)
@@ -1523,24 +1524,26 @@
 {
     XGL_STRUCTURE_TYPE                      sType;                      // Must be XGL_STRUCTURE_TYPE_UPDATE_SAMPLERS
     const void*                             pNext;                      // Pointer to next structure
-    uint32_t                                index;
-    uint32_t                                count;
+    uint32_t                                binding;                    // Binding of the sampler (array)
+    uint32_t                                arrayIndex;                 // First element of the array to update or zero otherwise
+    uint32_t                                count;                      // Number of elements to update
     const XGL_SAMPLER*                      pSamplers;
 } XGL_UPDATE_SAMPLERS;
 
 typedef struct _XGL_SAMPLER_IMAGE_VIEW_INFO
 {
-    XGL_SAMPLER                             pSampler;
+    XGL_SAMPLER                             sampler;
     const XGL_IMAGE_VIEW_ATTACH_INFO*       pImageView;
 } XGL_SAMPLER_IMAGE_VIEW_INFO;
 
 typedef struct _XGL_UPDATE_SAMPLER_TEXTURES
 {
-    XGL_STRUCTURE_TYPE                       sType;                     // Must be XGL_STRUCTURE_TYPE_UPDATE_SAMPLER_TEXTURES
-    const void*                              pNext;                     // Pointer to next structure
-    uint32_t                                 index;
-    uint32_t                                 count;
-    const XGL_SAMPLER_IMAGE_VIEW_INFO*       pSamplerImageViews;
+    XGL_STRUCTURE_TYPE                      sType;                      // Must be XGL_STRUCTURE_TYPE_UPDATE_SAMPLER_TEXTURES
+    const void*                             pNext;                      // Pointer to next structure
+    uint32_t                                binding;                    // Binding of the combined texture sampler (array)
+    uint32_t                                arrayIndex;                 // First element of the array to update or zero otherwise
+    uint32_t                                count;                      // Number of elements to update
+    const XGL_SAMPLER_IMAGE_VIEW_INFO*      pSamplerImageViews;
 } XGL_UPDATE_SAMPLER_TEXTURES;
 
 typedef struct _XGL_UPDATE_IMAGES
@@ -1548,9 +1551,10 @@
     XGL_STRUCTURE_TYPE                       sType;                     // Must be XGL_STRUCTURE_TYPE_UPDATE_IMAGES
     const void*                              pNext;                     // Pointer to next structure
     XGL_DESCRIPTOR_TYPE                      descriptorType;
-    uint32_t                                 index;
-    uint32_t                                 count;
-    const XGL_IMAGE_VIEW_ATTACH_INFO* const* pImageViews;
+    uint32_t                                 binding;                   // Binding of the image (array)
+    uint32_t                                 arrayIndex;                // First element of the array to update or zero otherwise
+    uint32_t                                 count;                     // Number of elements to update
+    const XGL_IMAGE_VIEW_ATTACH_INFO*        pImageViews;
 } XGL_UPDATE_IMAGES;
 
 typedef struct _XGL_UPDATE_BUFFERS
@@ -1558,9 +1562,10 @@
     XGL_STRUCTURE_TYPE                        sType;                    // Must be XGL_STRUCTURE_TYPE_UPDATE_BUFFERS
     const void*                               pNext;                    // Pointer to next structure
     XGL_DESCRIPTOR_TYPE                       descriptorType;
-    uint32_t                                  index;
-    uint32_t                                  count;
-    const XGL_BUFFER_VIEW_ATTACH_INFO* const* pBufferViews;
+    uint32_t                                  binding;                  // Binding of the buffer (array)
+    uint32_t                                  arrayIndex;               // First element of the array to update or zero otherwise
+    uint32_t                                  count;                    // Number of elements to update
+    const XGL_BUFFER_VIEW_ATTACH_INFO*        pBufferViews;
 } XGL_UPDATE_BUFFERS;
 
 typedef struct _XGL_UPDATE_AS_COPY
@@ -1569,7 +1574,8 @@
     const void*                             pNext;                      // Pointer to next structure
     XGL_DESCRIPTOR_TYPE                     descriptorType;
     XGL_DESCRIPTOR_SET                      descriptorSet;
-    uint32_t                                descriptorIndex;
+    uint32_t                                binding;
+    uint32_t                                arrayElement;
     uint32_t                                count;
 } XGL_UPDATE_AS_COPY;
 
@@ -1878,7 +1884,12 @@
     const void*                             pNext;      // Pointer to next structure
     XGL_PIPELINE_SHADER                     cs;
     XGL_FLAGS                               flags;      // XGL_PIPELINE_CREATE_FLAGS
-    XGL_DESCRIPTOR_SET_LAYOUT               lastSetLayout;
+    XGL_DESCRIPTOR_SET_LAYOUT_CHAIN         setLayoutChain;
+    // For local size fields zero is treated an invalid value
+    uint32_t                                localSizeX;
+    uint32_t                                localSizeY;
+    uint32_t                                localSizeZ;
+
 } XGL_COMPUTE_PIPELINE_CREATE_INFO;
 
 typedef struct _XGL_VERTEX_INPUT_BINDING_DESCRIPTION
@@ -2020,7 +2031,7 @@
     XGL_STRUCTURE_TYPE                      sType;      // Must be XGL_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO
     const void*                             pNext;      // Pointer to next structure
     XGL_FLAGS                               flags;      // XGL_PIPELINE_CREATE_FLAGS
-    XGL_DESCRIPTOR_SET_LAYOUT               lastSetLayout;
+    XGL_DESCRIPTOR_SET_LAYOUT_CHAIN         pSetLayoutChain;
 } XGL_GRAPHICS_PIPELINE_CREATE_INFO;
 
 typedef struct _XGL_SAMPLER_CREATE_INFO
@@ -2306,14 +2317,15 @@
 typedef XGL_RESULT (XGLAPI *xglLoadPipelineType)(XGL_DEVICE device, size_t dataSize, const void* pData, XGL_PIPELINE* pPipeline);
 typedef XGL_RESULT (XGLAPI *xglLoadPipelineDerivativeType)(XGL_DEVICE device, size_t dataSize, const void* pData, XGL_PIPELINE basePipeline, XGL_PIPELINE* pPipeline);
 typedef XGL_RESULT (XGLAPI *xglCreateSamplerType)(XGL_DEVICE device, const XGL_SAMPLER_CREATE_INFO* pCreateInfo, XGL_SAMPLER* pSampler);
-typedef XGL_RESULT (XGLAPI *xglCreateDescriptorSetLayoutType)(XGL_DEVICE device, XGL_FLAGS stageFlags, const uint32_t* pSetBindPoints, XGL_DESCRIPTOR_SET_LAYOUT priorSetLayout, const XGL_DESCRIPTOR_SET_LAYOUT_CREATE_INFO* pCreateInfo, XGL_DESCRIPTOR_SET_LAYOUT* pSetLayout);
+typedef XGL_RESULT (XGLAPI *xglCreateDescriptorSetLayoutType)(XGL_DEVICE device, const XGL_DESCRIPTOR_SET_LAYOUT_CREATE_INFO* pCreateInfo, XGL_DESCRIPTOR_SET_LAYOUT* pSetLayout);
+typedef XGL_RESULT (XGLAPI *xglCreateDescriptorSetLayoutChainType)(XGL_DEVICE device, uint32_t setLayoutArrayCount, const XGL_DESCRIPTOR_SET_LAYOUT* pSetLayoutArray, XGL_DESCRIPTOR_SET_LAYOUT_CHAIN* pLayoutChain);
 typedef XGL_RESULT (XGLAPI *xglBeginDescriptorPoolUpdateType)(XGL_DEVICE device, XGL_DESCRIPTOR_UPDATE_MODE updateMode);
 typedef XGL_RESULT (XGLAPI *xglEndDescriptorPoolUpdateType)(XGL_DEVICE device, XGL_CMD_BUFFER cmd);
 typedef XGL_RESULT (XGLAPI *xglCreateDescriptorPoolType)(XGL_DEVICE device, XGL_DESCRIPTOR_POOL_USAGE poolUsage, uint32_t maxSets, const XGL_DESCRIPTOR_POOL_CREATE_INFO* pCreateInfo, XGL_DESCRIPTOR_POOL* pDescriptorPool);
 typedef XGL_RESULT (XGLAPI *xglResetDescriptorPoolType)(XGL_DESCRIPTOR_POOL descriptorPool);
 typedef XGL_RESULT (XGLAPI *xglAllocDescriptorSetsType)(XGL_DESCRIPTOR_POOL descriptorPool, XGL_DESCRIPTOR_SET_USAGE setUsage, uint32_t count, const XGL_DESCRIPTOR_SET_LAYOUT* pSetLayouts, XGL_DESCRIPTOR_SET* pDescriptorSets, uint32_t* pCount);
 typedef void       (XGLAPI *xglClearDescriptorSetsType)(XGL_DESCRIPTOR_POOL descriptorPool, uint32_t count, const XGL_DESCRIPTOR_SET* pDescriptorSets);
-typedef void       (XGLAPI *xglUpdateDescriptorsType)(XGL_DESCRIPTOR_SET descriptorSet, const void* pUpdateChain);
+typedef void       (XGLAPI *xglUpdateDescriptorsType)(XGL_DESCRIPTOR_SET descriptorSet, uint32_t updateCount, const void** ppUpdateArray);
 typedef XGL_RESULT (XGLAPI *xglCreateDynamicViewportStateType)(XGL_DEVICE device, const XGL_DYNAMIC_VP_STATE_CREATE_INFO* pCreateInfo, XGL_DYNAMIC_VP_STATE_OBJECT* pState);
 typedef XGL_RESULT (XGLAPI *xglCreateDynamicRasterStateType)(XGL_DEVICE device, const XGL_DYNAMIC_RS_STATE_CREATE_INFO* pCreateInfo, XGL_DYNAMIC_RS_STATE_OBJECT* pState);
 typedef XGL_RESULT (XGLAPI *xglCreateDynamicColorBlendStateType)(XGL_DEVICE device, const XGL_DYNAMIC_CB_STATE_CREATE_INFO* pCreateInfo, XGL_DYNAMIC_CB_STATE_OBJECT* pState);
@@ -2699,12 +2711,15 @@
 
 XGL_RESULT XGLAPI xglCreateDescriptorSetLayout(
     XGL_DEVICE                                   device,
-    XGL_FLAGS                                    stageFlags,            // XGL_SHADER_STAGE_FLAGS
-    const uint32_t*                              pSetBindPoints,
-    XGL_DESCRIPTOR_SET_LAYOUT                    priorSetLayout,
     const XGL_DESCRIPTOR_SET_LAYOUT_CREATE_INFO* pCreateInfo,
     XGL_DESCRIPTOR_SET_LAYOUT*                   pSetLayout);
 
+XGL_RESULT XGLAPI xglCreateDescriptorSetLayoutChain(
+    XGL_DEVICE                                   device,
+    uint32_t                                     setLayoutArrayCount,
+    const XGL_DESCRIPTOR_SET_LAYOUT*             pSetLayoutArray,
+    XGL_DESCRIPTOR_SET_LAYOUT_CHAIN*             pLayoutChain);
+
 XGL_RESULT XGLAPI xglBeginDescriptorPoolUpdate(
     XGL_DEVICE                                   device,
     XGL_DESCRIPTOR_UPDATE_MODE                   updateMode);
@@ -2738,7 +2753,8 @@
 
 void XGLAPI xglUpdateDescriptors(
     XGL_DESCRIPTOR_SET                           descriptorSet,
-    const void*                                  pUpdateChain);
+    uint32_t                                     updateCount,
+    const void**                                 ppUpdateArray);
 
 // State object functions
 
diff --git a/include/xglDbg.h b/include/xglDbg.h
index 7e655e6..41b4b3b 100644
--- a/include/xglDbg.h
+++ b/include/xglDbg.h
@@ -91,6 +91,7 @@
     XGL_DBG_OBJECT_BUFFER,
     XGL_DBG_OBJECT_BUFFER_VIEW,
     XGL_DBG_OBJECT_DESCRIPTOR_SET_LAYOUT,
+    XGL_DBG_OBJECT_DESCRIPTOR_SET_LAYOUT_CHAIN,
     XGL_DBG_OBJECT_DESCRIPTOR_POOL,
 
     XGL_DBG_OBJECT_TYPE_BEGIN_RANGE = XGL_DBG_OBJECT_UNKNOWN,
diff --git a/include/xglLayer.h b/include/xglLayer.h
index e4c145a..98e5253 100644
--- a/include/xglLayer.h
+++ b/include/xglLayer.h
@@ -86,6 +86,7 @@
     xglLoadPipelineDerivativeType LoadPipelineDerivative;
     xglCreateSamplerType CreateSampler;
     xglCreateDescriptorSetLayoutType CreateDescriptorSetLayout;
+    xglCreateDescriptorSetLayoutChainType CreateDescriptorSetLayoutChain;
     xglBeginDescriptorPoolUpdateType BeginDescriptorPoolUpdate;
     xglEndDescriptorPoolUpdateType EndDescriptorPoolUpdate;
     xglCreateDescriptorPoolType CreateDescriptorPool;
diff --git a/tests/xglrenderframework.cpp b/tests/xglrenderframework.cpp
index 3c011fa..005ef71 100644
--- a/tests/xglrenderframework.cpp
+++ b/tests/xglrenderframework.cpp
@@ -290,10 +290,8 @@
     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));
+    m_updateBuffers.push_back(xgl_testing::DescriptorSet::update(type,
+                m_nextSlot, 0, 1, &constantBuffer->m_bufferViewInfo));
 
     return m_nextSlot++;
 }
@@ -306,19 +304,19 @@
     m_type_counts.push_back(tc);
 
     XGL_SAMPLER_IMAGE_VIEW_INFO tmp = {};
-    tmp.pSampler = sampler->obj();
+    tmp.sampler = sampler->obj();
     tmp.pImageView = &texture->m_textureViewInfo;
     m_samplerTextureInfo.push_back(tmp);
 
-    m_updateSamplerTextures.push_back(xgl_testing::DescriptorSet::update(m_nextSlot, 1,
+    m_updateSamplerTextures.push_back(xgl_testing::DescriptorSet::update(m_nextSlot, 0, 1,
                 (const XGL_SAMPLER_IMAGE_VIEW_INFO *) NULL));
 
     return m_nextSlot++;
 }
 
-XGL_DESCRIPTOR_SET_LAYOUT XglDescriptorSetObj::GetLayout()
+XGL_DESCRIPTOR_SET_LAYOUT_CHAIN XglDescriptorSetObj::GetLayoutChain()
 {
-    return m_layout.obj();
+    return m_layout_chain.obj();
 }
 
 XGL_DESCRIPTOR_SET XglDescriptorSetObj::GetDescriptorSetHandle()
@@ -351,38 +349,30 @@
     layout.count = bindings.size();
     layout.pBinding = &bindings[0];
 
-    m_layout.init(*m_device, 0, layout);
+    m_layout.init(*m_device, layout);
+
+    vector<const xgl_testing::DescriptorSetLayout *> layouts;
+    layouts.push_back(&m_layout);
+    m_layout_chain.init(*m_device, layouts);
 
     // 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];
+    // build the update array
+    vector<const void *> update_array;
 
-        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_updateBuffers.size(); i++) {
+        update_array.push_back(&m_updateBuffers[i]);
     }
     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;
+        update_array.push_back(&m_updateSamplerTextures[i]);
     }
-    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_set->update(update_array);
     m_device->end_descriptor_pool_update(*cmdBuffer);
 }
 
@@ -1106,7 +1096,7 @@
     info.sType = XGL_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO;
     info.pNext = head_ptr;
     info.flags = 0;
-    info.lastSetLayout = descriptorSet->GetLayout();
+    info.pSetLayoutChain = descriptorSet->GetLayoutChain();
 
     m_cb_state.attachmentCount = m_colorAttachments.size();
     m_cb_state.pAttachments = &m_colorAttachments[0];
@@ -1143,7 +1133,7 @@
     info.sType = XGL_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO;
     info.pNext = head_ptr;
     info.flags = 0;
-    info.lastSetLayout = descriptorSet->GetLayout();
+    info.pSetLayoutChain = descriptorSet->GetLayoutChain();
 
     init(*m_device, info);
 
diff --git a/tests/xglrenderframework.h b/tests/xglrenderframework.h
index 1c8da22..5b92c5d 100644
--- a/tests/xglrenderframework.h
+++ b/tests/xglrenderframework.h
@@ -319,20 +319,20 @@
     void CreateXGLDescriptorSet(XglCommandBufferObj *cmdBuffer);
 
     XGL_DESCRIPTOR_SET GetDescriptorSetHandle();
-    XGL_DESCRIPTOR_SET_LAYOUT GetLayout();
+    XGL_DESCRIPTOR_SET_LAYOUT_CHAIN GetLayoutChain();
 
 protected:
     XglDevice                           *m_device;
     vector<XGL_DESCRIPTOR_TYPE_COUNT>    m_type_counts;
     int                                  m_nextSlot;
 
-    vector<const XGL_BUFFER_VIEW_ATTACH_INFO *> m_bufferInfo;
     vector<XGL_UPDATE_BUFFERS>           m_updateBuffers;
 
     vector<XGL_SAMPLER_IMAGE_VIEW_INFO>  m_samplerTextureInfo;
     vector<XGL_UPDATE_SAMPLER_TEXTURES>  m_updateSamplerTextures;
 
     xgl_testing::DescriptorSetLayout     m_layout;
+    xgl_testing::DescriptorSetLayoutChain m_layout_chain;
     xgl_testing::DescriptorSet          *m_set;
 };
 
diff --git a/tests/xgltestbinding.cpp b/tests/xgltestbinding.cpp
index 57b1cdc..ae313cb 100644
--- a/tests/xgltestbinding.cpp
+++ b/tests/xgltestbinding.cpp
@@ -819,25 +819,22 @@
     alloc_memory(dev);
 }
 
-void DescriptorSetLayout::init(const Device &dev, XGL_FLAGS stage_mask,
-                               const std::vector<uint32_t> &bind_points,
-                               const DescriptorSetLayout &prior_layout,
-                               const XGL_DESCRIPTOR_SET_LAYOUT_CREATE_INFO &info)
+void DescriptorSetLayout::init(const Device &dev, const XGL_DESCRIPTOR_SET_LAYOUT_CREATE_INFO &info)
 {
-    DERIVED_OBJECT_INIT(xglCreateDescriptorSetLayout, dev.obj(), stage_mask,
-            &bind_points[0], prior_layout.obj(), &info);
+    DERIVED_OBJECT_INIT(xglCreateDescriptorSetLayout, dev.obj(), &info);
     alloc_memory(dev);
 }
 
-void DescriptorSetLayout::init(const Device &dev, uint32_t bind_point,
-                               const DescriptorSetLayout &prior_layout,
-                               const XGL_DESCRIPTOR_SET_LAYOUT_CREATE_INFO &info)
+void DescriptorSetLayoutChain::init(const Device &dev, const std::vector<const DescriptorSetLayout *> &layouts)
 {
-    init(dev, XGL_SHADER_STAGE_FLAGS_ALL, std::vector<uint32_t>(1, bind_point), prior_layout, info);
+    const std::vector<XGL_DESCRIPTOR_SET_LAYOUT> layout_objs = make_objects<XGL_DESCRIPTOR_SET_LAYOUT>(layouts);
+
+    DERIVED_OBJECT_INIT(xglCreateDescriptorSetLayoutChain, dev.obj(), layout_objs.size(), &layout_objs[0]);
+    alloc_memory(dev);
 }
 
 void DescriptorPool::init(const Device &dev, XGL_DESCRIPTOR_POOL_USAGE usage,
-                            uint32_t max_sets, const XGL_DESCRIPTOR_POOL_CREATE_INFO &info)
+                          uint32_t max_sets, const XGL_DESCRIPTOR_POOL_CREATE_INFO &info)
 {
     DERIVED_OBJECT_INIT(xglCreateDescriptorPool, dev.obj(), usage, max_sets, &info);
     alloc_memory(dev);
@@ -888,9 +885,9 @@
     xglClearDescriptorSets(obj(), set_objs.size(), &set_objs[0]);
 }
 
-void DescriptorSet::update(const void *update_chain)
+void DescriptorSet::update(const std::vector<const void *> &update_array)
 {
-    xglUpdateDescriptors(obj(), update_chain);
+    xglUpdateDescriptors(obj(), update_array.size(), const_cast<const void **>(&update_array[0]));
 }
 
 void DynamicVpStateObject::init(const Device &dev, const XGL_DYNAMIC_VP_STATE_CREATE_INFO &info)
diff --git a/tests/xgltestbinding.h b/tests/xgltestbinding.h
index d07c413..2f6535e 100644
--- a/tests/xgltestbinding.h
+++ b/tests/xgltestbinding.h
@@ -54,6 +54,7 @@
 class PipelineDelta;
 class Sampler;
 class DescriptorSetLayout;
+class DescriptorSetLayoutChain;
 class DescriptorSetPool;
 class DescriptorSet;
 class DynamicVpStateObject;
@@ -500,15 +501,13 @@
 class DescriptorSetLayout : public DerivedObject<XGL_DESCRIPTOR_SET_LAYOUT, Object> {
 public:
     // xglCreateDescriptorSetLayout()
-    void init(const Device &dev, XGL_FLAGS stage_mask,
-              const std::vector<uint32_t> &bind_points,
-              const DescriptorSetLayout &prior_layout,
-              const XGL_DESCRIPTOR_SET_LAYOUT_CREATE_INFO &info);
-    void init(const Device &dev, uint32_t bind_point,
-              const DescriptorSetLayout &prior_layout,
-              const XGL_DESCRIPTOR_SET_LAYOUT_CREATE_INFO &info);
-    void init(const Device &dev, uint32_t bind_point,
-              const XGL_DESCRIPTOR_SET_LAYOUT_CREATE_INFO &info) { init(dev, bind_point, DescriptorSetLayout(), info); }
+    void init(const Device &dev, const XGL_DESCRIPTOR_SET_LAYOUT_CREATE_INFO &info);
+};
+
+class DescriptorSetLayoutChain : public DerivedObject<XGL_DESCRIPTOR_SET_LAYOUT_CHAIN, Object> {
+public:
+    // xglCreateDescriptorSetLayoutChain()
+    void init(const Device &dev, const std::vector<const DescriptorSetLayout *> &layouts);
 };
 
 class DescriptorPool : public DerivedObject<XGL_DESCRIPTOR_POOL, Object> {
@@ -535,21 +534,21 @@
     explicit DescriptorSet(XGL_DESCRIPTOR_SET set) : DerivedObject(set) {}
 
     // xglUpdateDescriptors()
-    void update(const void *update_chain);
+    void update(const std::vector<const void *> &update_array);
 
-    static XGL_UPDATE_SAMPLERS update(uint32_t index, uint32_t count, const XGL_SAMPLER *samplers);
-    static XGL_UPDATE_SAMPLERS update(uint32_t index, const std::vector<XGL_SAMPLER> &samplers);
+    static XGL_UPDATE_SAMPLERS update(uint32_t binding, uint32_t index, uint32_t count, const XGL_SAMPLER *samplers);
+    static XGL_UPDATE_SAMPLERS update(uint32_t binding, uint32_t index, const std::vector<XGL_SAMPLER> &samplers);
 
-    static XGL_UPDATE_SAMPLER_TEXTURES update(uint32_t index, uint32_t count, const XGL_SAMPLER_IMAGE_VIEW_INFO *textures);
-    static XGL_UPDATE_SAMPLER_TEXTURES update(uint32_t index, const std::vector<XGL_SAMPLER_IMAGE_VIEW_INFO> &textures);
+    static XGL_UPDATE_SAMPLER_TEXTURES update(uint32_t binding, uint32_t index, uint32_t count, const XGL_SAMPLER_IMAGE_VIEW_INFO *textures);
+    static XGL_UPDATE_SAMPLER_TEXTURES update(uint32_t binding, uint32_t index, const std::vector<XGL_SAMPLER_IMAGE_VIEW_INFO> &textures);
 
-    static XGL_UPDATE_IMAGES update(XGL_DESCRIPTOR_TYPE type, uint32_t index, uint32_t count, const XGL_IMAGE_VIEW_ATTACH_INFO * const *views);
-    static XGL_UPDATE_IMAGES update(XGL_DESCRIPTOR_TYPE type, uint32_t index, const std::vector<const XGL_IMAGE_VIEW_ATTACH_INFO *> &views);
+    static XGL_UPDATE_IMAGES update(XGL_DESCRIPTOR_TYPE type, uint32_t binding, uint32_t index, uint32_t count, const XGL_IMAGE_VIEW_ATTACH_INFO *views);
+    static XGL_UPDATE_IMAGES update(XGL_DESCRIPTOR_TYPE type, uint32_t binding, uint32_t index, const std::vector<XGL_IMAGE_VIEW_ATTACH_INFO> &views);
 
-    static XGL_UPDATE_BUFFERS update(XGL_DESCRIPTOR_TYPE type, uint32_t index, uint32_t count, const XGL_BUFFER_VIEW_ATTACH_INFO * const *views);
-    static XGL_UPDATE_BUFFERS update(XGL_DESCRIPTOR_TYPE type, uint32_t index, const std::vector<const XGL_BUFFER_VIEW_ATTACH_INFO *> &views);
+    static XGL_UPDATE_BUFFERS update(XGL_DESCRIPTOR_TYPE type, uint32_t binding, uint32_t index, uint32_t count, const XGL_BUFFER_VIEW_ATTACH_INFO *views);
+    static XGL_UPDATE_BUFFERS update(XGL_DESCRIPTOR_TYPE type, uint32_t binding, uint32_t index, const std::vector<XGL_BUFFER_VIEW_ATTACH_INFO> &views);
 
-    static XGL_UPDATE_AS_COPY update(XGL_DESCRIPTOR_TYPE type, uint32_t index, uint32_t count, const DescriptorSet &set);
+    static XGL_UPDATE_AS_COPY update(XGL_DESCRIPTOR_TYPE type, uint32_t binding, uint32_t index, uint32_t count, const DescriptorSet &set);
 
     static XGL_BUFFER_VIEW_ATTACH_INFO attach_info(const BufferView &view);
     static XGL_IMAGE_VIEW_ATTACH_INFO attach_info(const ImageView &view, XGL_IMAGE_LAYOUT layout);
@@ -787,78 +786,83 @@
     return info;
 }
 
-inline XGL_UPDATE_SAMPLERS DescriptorSet::update(uint32_t index, uint32_t count, const XGL_SAMPLER *samplers)
+inline XGL_UPDATE_SAMPLERS DescriptorSet::update(uint32_t binding, uint32_t index, uint32_t count, const XGL_SAMPLER *samplers)
 {
     XGL_UPDATE_SAMPLERS info = {};
     info.sType = XGL_STRUCTURE_TYPE_UPDATE_SAMPLERS;
-    info.index = index;
+    info.binding = binding;
+    info.arrayIndex = index;
     info.count = count;
     info.pSamplers = samplers;
     return info;
 }
 
-inline XGL_UPDATE_SAMPLERS DescriptorSet::update(uint32_t index, const std::vector<XGL_SAMPLER> &samplers)
+inline XGL_UPDATE_SAMPLERS DescriptorSet::update(uint32_t binding, uint32_t index, const std::vector<XGL_SAMPLER> &samplers)
 {
-    return update(index, samplers.size(), &samplers[0]);
+    return update(binding, index, samplers.size(), &samplers[0]);
 }
 
-inline XGL_UPDATE_SAMPLER_TEXTURES DescriptorSet::update(uint32_t index, uint32_t count, const XGL_SAMPLER_IMAGE_VIEW_INFO *textures)
+inline XGL_UPDATE_SAMPLER_TEXTURES DescriptorSet::update(uint32_t binding, uint32_t index, uint32_t count, const XGL_SAMPLER_IMAGE_VIEW_INFO *textures)
 {
     XGL_UPDATE_SAMPLER_TEXTURES info = {};
     info.sType = XGL_STRUCTURE_TYPE_UPDATE_SAMPLER_TEXTURES;
-    info.index = index;
+    info.binding = binding;
+    info.arrayIndex = index;
     info.count = count;
     info.pSamplerImageViews = textures;
     return info;
 }
 
-inline XGL_UPDATE_SAMPLER_TEXTURES DescriptorSet::update(uint32_t index, const std::vector<XGL_SAMPLER_IMAGE_VIEW_INFO> &textures)
+inline XGL_UPDATE_SAMPLER_TEXTURES DescriptorSet::update(uint32_t binding, uint32_t index, const std::vector<XGL_SAMPLER_IMAGE_VIEW_INFO> &textures)
 {
-    return update(index, textures.size(), &textures[0]);
+    return update(binding, index, textures.size(), &textures[0]);
 }
 
-inline XGL_UPDATE_IMAGES DescriptorSet::update(XGL_DESCRIPTOR_TYPE type, uint32_t index, uint32_t count,
-                                               const XGL_IMAGE_VIEW_ATTACH_INFO * const *views)
+inline XGL_UPDATE_IMAGES DescriptorSet::update(XGL_DESCRIPTOR_TYPE type, uint32_t binding, uint32_t index, uint32_t count,
+                                               const XGL_IMAGE_VIEW_ATTACH_INFO *views)
 {
     XGL_UPDATE_IMAGES info = {};
     info.sType = XGL_STRUCTURE_TYPE_UPDATE_IMAGES;
     info.descriptorType = type;
-    info.index = index;
+    info.binding = binding;
+    info.arrayIndex = index;
     info.count = count;
     info.pImageViews = views;
     return info;
 }
 
-inline XGL_UPDATE_IMAGES DescriptorSet::update(XGL_DESCRIPTOR_TYPE type, uint32_t index,
-                                               const std::vector<const XGL_IMAGE_VIEW_ATTACH_INFO *> &views)
+inline XGL_UPDATE_IMAGES DescriptorSet::update(XGL_DESCRIPTOR_TYPE type, uint32_t binding, uint32_t index,
+                                               const std::vector<XGL_IMAGE_VIEW_ATTACH_INFO> &views)
 {
-    return update(type, index, views.size(), &views[0]);
+    return update(type, binding, index, views.size(), &views[0]);
 }
 
-inline XGL_UPDATE_BUFFERS DescriptorSet::update(XGL_DESCRIPTOR_TYPE type, uint32_t index, uint32_t count,
-                                                const XGL_BUFFER_VIEW_ATTACH_INFO * const *views)
+inline XGL_UPDATE_BUFFERS DescriptorSet::update(XGL_DESCRIPTOR_TYPE type, uint32_t binding, uint32_t index, uint32_t count,
+                                                const XGL_BUFFER_VIEW_ATTACH_INFO *views)
 {
     XGL_UPDATE_BUFFERS info = {};
     info.sType = XGL_STRUCTURE_TYPE_UPDATE_BUFFERS;
     info.descriptorType = type;
-    info.index = index;
+    info.binding = binding;
+    info.arrayIndex = index;
     info.count = count;
     info.pBufferViews = views;
     return info;
 }
 
-inline XGL_UPDATE_BUFFERS DescriptorSet::update(XGL_DESCRIPTOR_TYPE type, uint32_t index,
-                                                const std::vector<const XGL_BUFFER_VIEW_ATTACH_INFO *> &views)
+inline XGL_UPDATE_BUFFERS DescriptorSet::update(XGL_DESCRIPTOR_TYPE type, uint32_t binding, uint32_t index,
+                                                const std::vector<XGL_BUFFER_VIEW_ATTACH_INFO> &views)
 {
-    return update(type, index, views.size(), &views[0]);
+    return update(type, binding, index, views.size(), &views[0]);
 }
 
-inline XGL_UPDATE_AS_COPY DescriptorSet::update(XGL_DESCRIPTOR_TYPE type, uint32_t index, uint32_t count, const DescriptorSet &set)
+inline XGL_UPDATE_AS_COPY DescriptorSet::update(XGL_DESCRIPTOR_TYPE type, uint32_t binding, uint32_t index, uint32_t count, const DescriptorSet &set)
 {
     XGL_UPDATE_AS_COPY info = {};
     info.sType = XGL_STRUCTURE_TYPE_UPDATE_AS_COPY;
     info.descriptorType = type;
-    info.descriptorIndex = index; // whose index?
+    info.binding = binding;
+    info.arrayElement = index;
     info.count = count;
     info.descriptorSet = set.obj();
     return info;
diff --git a/xgl.py b/xgl.py
index cd7eb00..f9c6d44 100644
--- a/xgl.py
+++ b/xgl.py
@@ -201,6 +201,7 @@
         "XGL_SAMPLER",
         "XGL_DESCRIPTOR_SET",
         "XGL_DESCRIPTOR_SET_LAYOUT",
+        "XGL_DESCRIPTOR_SET_LAYOUT_CHAIN",
         "XGL_DESCRIPTOR_POOL",
         "XGL_DYNAMIC_STATE_OBJECT",
         "XGL_DYNAMIC_VP_STATE_OBJECT",
@@ -511,12 +512,15 @@
 
         Proto("XGL_RESULT", "CreateDescriptorSetLayout",
             [Param("XGL_DEVICE", "device"),
-             Param("XGL_FLAGS", "stageFlags"),
-             Param("const uint32_t*", "pSetBindPoints"),
-             Param("XGL_DESCRIPTOR_SET_LAYOUT", "priorSetLayout"),
              Param("const XGL_DESCRIPTOR_SET_LAYOUT_CREATE_INFO*", "pCreateInfo"),
              Param("XGL_DESCRIPTOR_SET_LAYOUT*", "pSetLayout")]),
 
+        Proto("XGL_RESULT", "CreateDescriptorSetLayoutChain",
+            [Param("XGL_DEVICE", "device"),
+             Param("uint32_t", "setLayoutArrayCount"),
+             Param("const XGL_DESCRIPTOR_SET_LAYOUT*", "pSetLayoutArray"),
+             Param("XGL_DESCRIPTOR_SET_LAYOUT_CHAIN*", "pLayoutChain")]),
+
         Proto("XGL_RESULT", "BeginDescriptorPoolUpdate",
             [Param("XGL_DEVICE", "device"),
              Param("XGL_DESCRIPTOR_UPDATE_MODE", "updateMode")]),
@@ -550,7 +554,8 @@
 
         Proto("void", "UpdateDescriptors",
             [Param("XGL_DESCRIPTOR_SET", "descriptorSet"),
-             Param("const void*", "pUpdateChain")]),
+             Param("uint32_t", "updateCount"),
+             Param("const void**", "ppUpdateArray")]),
 
         Proto("XGL_RESULT", "CreateDynamicViewportState",
             [Param("XGL_DEVICE", "device"),