intel: add intel_rmap for shader resource mapping
It will be used to parse XGL_DESCRIPTOR_SET_MAPPING and
XGL_DYNAMIC_MEMORY_VIEW_SLOT_INFO.
diff --git a/icd/intel/pipeline_rmap.c b/icd/intel/pipeline_rmap.c
new file mode 100644
index 0000000..123a6f1
--- /dev/null
+++ b/icd/intel/pipeline_rmap.c
@@ -0,0 +1,253 @@
+/*
+ * XGL
+ *
+ * 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.
+ */
+
+#include "pipeline_priv.h"
+
+static struct intel_rmap_slot *rmap_get_slot(struct intel_rmap *rmap,
+ XGL_DESCRIPTOR_SET_SLOT_TYPE type,
+ XGL_UINT index)
+{
+ const XGL_UINT resource_offset = rmap->rt_count;
+ const XGL_UINT uav_offset = resource_offset + rmap->resource_count;
+ const XGL_UINT sampler_offset = uav_offset + rmap->uav_count;
+ struct intel_rmap_slot *slot;
+
+ switch (type) {
+ case XGL_SLOT_UNUSED:
+ slot = NULL;
+ break;
+ case XGL_SLOT_SHADER_RESOURCE:
+ slot = &rmap->slots[resource_offset + index];
+ break;
+ case XGL_SLOT_SHADER_UAV:
+ slot = &rmap->slots[uav_offset + index];
+ break;
+ case XGL_SLOT_SHADER_SAMPLER:
+ slot = &rmap->slots[sampler_offset + index];
+ break;
+ default:
+ assert(!"unknown rmap slot type");
+ slot = NULL;
+ break;
+ }
+
+ return slot;
+}
+
+static bool rmap_init_slots_with_path(struct intel_rmap *rmap,
+ const XGL_DESCRIPTOR_SET_MAPPING *mapping,
+ XGL_UINT *nest_path,
+ XGL_UINT nest_level)
+{
+ XGL_UINT i;
+
+ for (i = 0; i < mapping->descriptorCount; i++) {
+ const XGL_DESCRIPTOR_SLOT_INFO *info = &mapping->pDescriptorInfo[i];
+ struct intel_rmap_slot *slot;
+
+ if (info->slotObjectType == XGL_SLOT_NEXT_DESCRIPTOR_SET) {
+ nest_path[nest_level] = i;
+ if (!rmap_init_slots_with_path(rmap, info->pNextLevelSet,
+ nest_path, nest_level + 1))
+ return false;
+
+ continue;
+ }
+
+ slot = rmap_get_slot(rmap, info->slotObjectType,
+ info->shaderEntityIndex);
+ if (!slot)
+ continue;
+
+ assert(!slot->path_len);
+ slot->path_len = nest_level + 1;
+
+ if (nest_level) {
+ slot->u.path = icd_alloc(sizeof(slot->u.path[0]) *
+ slot->path_len, 0, XGL_SYSTEM_ALLOC_INTERNAL);
+ if (!slot->u.path) {
+ slot->path_len = 0;
+ return false;
+ }
+
+ memcpy(slot->u.path, nest_path,
+ sizeof(slot->u.path[0]) * nest_level);
+ slot->u.path[nest_level] = i;
+ } else {
+ slot->u.index = i;
+ }
+ }
+
+ return true;
+}
+
+static bool rmap_init_slots(struct intel_rmap *rmap,
+ const XGL_DESCRIPTOR_SET_MAPPING *mapping,
+ XGL_UINT depth)
+{
+ XGL_UINT *nest_path;
+ bool ok;
+
+ if (depth) {
+ nest_path = icd_alloc(sizeof(nest_path[0]) * depth,
+ 0, XGL_SYSTEM_ALLOC_INTERNAL_TEMP);
+ if (!nest_path)
+ return false;
+ } else {
+ nest_path = NULL;
+ }
+
+ ok = rmap_init_slots_with_path(rmap, mapping, nest_path, 0);
+
+ if (nest_path)
+ icd_free(nest_path);
+
+ return ok;
+}
+
+static void rmap_update_count(struct intel_rmap *rmap,
+ XGL_DESCRIPTOR_SET_SLOT_TYPE type,
+ XGL_UINT index)
+{
+ switch (type) {
+ case XGL_SLOT_UNUSED:
+ break;
+ case XGL_SLOT_SHADER_RESOURCE:
+ if (rmap->resource_count < index + 1)
+ rmap->resource_count = index + 1;
+ break;
+ case XGL_SLOT_SHADER_UAV:
+ if (rmap->uav_count < index + 1)
+ rmap->uav_count = index + 1;
+ break;
+ case XGL_SLOT_SHADER_SAMPLER:
+ if (rmap->sampler_count < index + 1)
+ rmap->sampler_count = index + 1;
+ break;
+ default:
+ assert(!"unknown rmap slot type");
+ break;
+ }
+}
+
+static XGL_UINT rmap_init_counts(struct intel_rmap *rmap,
+ const XGL_DESCRIPTOR_SET_MAPPING *mapping)
+{
+ XGL_UINT depth = 0;
+ XGL_UINT i;
+
+ for (i = 0; i < mapping->descriptorCount; i++) {
+ const XGL_DESCRIPTOR_SLOT_INFO *info = &mapping->pDescriptorInfo[i];
+
+ if (info->slotObjectType == XGL_SLOT_NEXT_DESCRIPTOR_SET) {
+ const XGL_UINT d = rmap_init_counts(rmap,
+ info->pNextLevelSet);
+ if (depth < d + 1)
+ depth = d + 1;
+
+ continue;
+ }
+
+ rmap_update_count(rmap, info->slotObjectType,
+ info->shaderEntityIndex);
+ }
+
+ return depth;
+}
+
+struct intel_rmap *intel_rmap_create(struct intel_dev *dev,
+ const XGL_DESCRIPTOR_SET_MAPPING *mapping,
+ const XGL_DYNAMIC_MEMORY_VIEW_SLOT_INFO *dyn,
+ XGL_UINT rt_count)
+{
+ struct intel_rmap *rmap;
+ struct intel_rmap_slot *slot;
+ XGL_UINT depth, rt;
+
+ rmap = icd_alloc(sizeof(*rmap), 0, XGL_SYSTEM_ALLOC_INTERNAL);
+ if (!rmap)
+ return NULL;
+
+ memset(rmap, 0, sizeof(*rmap));
+
+ depth = rmap_init_counts(rmap, mapping);
+
+ /* add RTs and the dynamic memory view */
+ rmap_update_count(rmap, dyn->slotObjectType, dyn->shaderEntityIndex);
+ rmap->rt_count = rt_count;
+
+ rmap->slot_count = rmap->rt_count + rmap->resource_count +
+ rmap->uav_count + rmap->sampler_count;
+
+ rmap->slots = icd_alloc(sizeof(rmap->slots[0]) * rmap->slot_count,
+ 0, XGL_SYSTEM_ALLOC_INTERNAL);
+ if (!rmap->slots) {
+ icd_free(rmap);
+ return NULL;
+ }
+
+ memset(rmap->slots, 0, sizeof(rmap->slots[0]) * rmap->slot_count);
+
+ if (!rmap_init_slots(rmap, mapping, depth)) {
+ intel_rmap_destroy(rmap);
+ return NULL;
+ }
+
+ /* add RTs and the dynamic memory view */
+ slot = rmap_get_slot(rmap, dyn->slotObjectType, dyn->shaderEntityIndex);
+ if (slot) {
+ slot->path_len = INTEL_RMAP_SLOT_DYN;
+ slot->u.index = 0;
+ }
+ for (rt = 0; rt < rmap->rt_count; rt++) {
+ slot = &rmap->slots[rt];
+ slot->path_len = INTEL_RMAP_SLOT_RT;
+ slot->u.index = rt;
+ }
+
+ return rmap;
+}
+
+void intel_rmap_destroy(struct intel_rmap *rmap)
+{
+ XGL_UINT i;
+
+ for (i = 0; i < rmap->slot_count; i++) {
+ struct intel_rmap_slot *slot = &rmap->slots[i];
+
+ switch (slot->path_len) {
+ case 0:
+ case 1:
+ case INTEL_RMAP_SLOT_RT:
+ case INTEL_RMAP_SLOT_DYN:
+ break;
+ default:
+ icd_free(slot->u.path);
+ break;
+ }
+ }
+
+ icd_free(rmap->slots);
+ icd_free(rmap);
+}