blob: dc4dbbacfde9f309b722fb20f394cbb8b8276afb [file] [log] [blame]
Chia-I Wu1f7540b2014-08-22 13:56:18 +08001/*
2 * XGL
3 *
4 * Copyright (C) 2014 LunarG, Inc.
5 *
6 * Permission is hereby granted, free of charge, to any person obtaining a
7 * copy of this software and associated documentation files (the "Software"),
8 * to deal in the Software without restriction, including without limitation
9 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
10 * and/or sell copies of the Software, and to permit persons to whom the
11 * Software is furnished to do so, subject to the following conditions:
12 *
13 * The above copyright notice and this permission notice shall be included
14 * in all copies or substantial portions of the Software.
15 *
16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
19 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
21 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
22 * DEALINGS IN THE SOFTWARE.
Chia-I Wu44e42362014-09-02 08:32:09 +080023 *
24 * Authors:
25 * Chia-I Wu <olv@lunarg.com>
Chia-I Wu1f7540b2014-08-22 13:56:18 +080026 */
27
28#include "pipeline_priv.h"
29
30static struct intel_rmap_slot *rmap_get_slot(struct intel_rmap *rmap,
31 XGL_DESCRIPTOR_SET_SLOT_TYPE type,
32 XGL_UINT index)
33{
34 const XGL_UINT resource_offset = rmap->rt_count;
35 const XGL_UINT uav_offset = resource_offset + rmap->resource_count;
36 const XGL_UINT sampler_offset = uav_offset + rmap->uav_count;
37 struct intel_rmap_slot *slot;
38
39 switch (type) {
40 case XGL_SLOT_UNUSED:
41 slot = NULL;
42 break;
43 case XGL_SLOT_SHADER_RESOURCE:
44 slot = &rmap->slots[resource_offset + index];
45 break;
46 case XGL_SLOT_SHADER_UAV:
47 slot = &rmap->slots[uav_offset + index];
48 break;
49 case XGL_SLOT_SHADER_SAMPLER:
50 slot = &rmap->slots[sampler_offset + index];
51 break;
52 default:
53 assert(!"unknown rmap slot type");
54 slot = NULL;
55 break;
56 }
57
58 return slot;
59}
60
61static bool rmap_init_slots_with_path(struct intel_rmap *rmap,
62 const XGL_DESCRIPTOR_SET_MAPPING *mapping,
63 XGL_UINT *nest_path,
64 XGL_UINT nest_level)
65{
66 XGL_UINT i;
67
68 for (i = 0; i < mapping->descriptorCount; i++) {
69 const XGL_DESCRIPTOR_SLOT_INFO *info = &mapping->pDescriptorInfo[i];
70 struct intel_rmap_slot *slot;
71
72 if (info->slotObjectType == XGL_SLOT_NEXT_DESCRIPTOR_SET) {
73 nest_path[nest_level] = i;
74 if (!rmap_init_slots_with_path(rmap, info->pNextLevelSet,
75 nest_path, nest_level + 1))
76 return false;
77
78 continue;
79 }
80
81 slot = rmap_get_slot(rmap, info->slotObjectType,
82 info->shaderEntityIndex);
83 if (!slot)
84 continue;
85
86 assert(!slot->path_len);
87 slot->path_len = nest_level + 1;
88
89 if (nest_level) {
90 slot->u.path = icd_alloc(sizeof(slot->u.path[0]) *
91 slot->path_len, 0, XGL_SYSTEM_ALLOC_INTERNAL);
92 if (!slot->u.path) {
93 slot->path_len = 0;
94 return false;
95 }
96
97 memcpy(slot->u.path, nest_path,
98 sizeof(slot->u.path[0]) * nest_level);
99 slot->u.path[nest_level] = i;
100 } else {
101 slot->u.index = i;
102 }
103 }
104
105 return true;
106}
107
108static bool rmap_init_slots(struct intel_rmap *rmap,
109 const XGL_DESCRIPTOR_SET_MAPPING *mapping,
110 XGL_UINT depth)
111{
112 XGL_UINT *nest_path;
113 bool ok;
114
115 if (depth) {
116 nest_path = icd_alloc(sizeof(nest_path[0]) * depth,
117 0, XGL_SYSTEM_ALLOC_INTERNAL_TEMP);
118 if (!nest_path)
119 return false;
120 } else {
121 nest_path = NULL;
122 }
123
124 ok = rmap_init_slots_with_path(rmap, mapping, nest_path, 0);
125
126 if (nest_path)
127 icd_free(nest_path);
128
129 return ok;
130}
131
132static void rmap_update_count(struct intel_rmap *rmap,
133 XGL_DESCRIPTOR_SET_SLOT_TYPE type,
134 XGL_UINT index)
135{
136 switch (type) {
137 case XGL_SLOT_UNUSED:
138 break;
139 case XGL_SLOT_SHADER_RESOURCE:
140 if (rmap->resource_count < index + 1)
141 rmap->resource_count = index + 1;
142 break;
143 case XGL_SLOT_SHADER_UAV:
144 if (rmap->uav_count < index + 1)
145 rmap->uav_count = index + 1;
146 break;
147 case XGL_SLOT_SHADER_SAMPLER:
148 if (rmap->sampler_count < index + 1)
149 rmap->sampler_count = index + 1;
150 break;
151 default:
152 assert(!"unknown rmap slot type");
153 break;
154 }
155}
156
157static XGL_UINT rmap_init_counts(struct intel_rmap *rmap,
158 const XGL_DESCRIPTOR_SET_MAPPING *mapping)
159{
160 XGL_UINT depth = 0;
161 XGL_UINT i;
162
163 for (i = 0; i < mapping->descriptorCount; i++) {
164 const XGL_DESCRIPTOR_SLOT_INFO *info = &mapping->pDescriptorInfo[i];
165
166 if (info->slotObjectType == XGL_SLOT_NEXT_DESCRIPTOR_SET) {
167 const XGL_UINT d = rmap_init_counts(rmap,
168 info->pNextLevelSet);
169 if (depth < d + 1)
170 depth = d + 1;
171
172 continue;
173 }
174
175 rmap_update_count(rmap, info->slotObjectType,
176 info->shaderEntityIndex);
177 }
178
179 return depth;
180}
181
182struct intel_rmap *intel_rmap_create(struct intel_dev *dev,
183 const XGL_DESCRIPTOR_SET_MAPPING *mapping,
184 const XGL_DYNAMIC_MEMORY_VIEW_SLOT_INFO *dyn,
185 XGL_UINT rt_count)
186{
187 struct intel_rmap *rmap;
188 struct intel_rmap_slot *slot;
189 XGL_UINT depth, rt;
190
191 rmap = icd_alloc(sizeof(*rmap), 0, XGL_SYSTEM_ALLOC_INTERNAL);
192 if (!rmap)
193 return NULL;
194
195 memset(rmap, 0, sizeof(*rmap));
196
197 depth = rmap_init_counts(rmap, mapping);
198
199 /* add RTs and the dynamic memory view */
200 rmap_update_count(rmap, dyn->slotObjectType, dyn->shaderEntityIndex);
201 rmap->rt_count = rt_count;
202
203 rmap->slot_count = rmap->rt_count + rmap->resource_count +
204 rmap->uav_count + rmap->sampler_count;
205
206 rmap->slots = icd_alloc(sizeof(rmap->slots[0]) * rmap->slot_count,
207 0, XGL_SYSTEM_ALLOC_INTERNAL);
208 if (!rmap->slots) {
209 icd_free(rmap);
210 return NULL;
211 }
212
213 memset(rmap->slots, 0, sizeof(rmap->slots[0]) * rmap->slot_count);
214
215 if (!rmap_init_slots(rmap, mapping, depth)) {
216 intel_rmap_destroy(rmap);
217 return NULL;
218 }
219
220 /* add RTs and the dynamic memory view */
221 slot = rmap_get_slot(rmap, dyn->slotObjectType, dyn->shaderEntityIndex);
222 if (slot) {
223 slot->path_len = INTEL_RMAP_SLOT_DYN;
224 slot->u.index = 0;
225 }
226 for (rt = 0; rt < rmap->rt_count; rt++) {
227 slot = &rmap->slots[rt];
228 slot->path_len = INTEL_RMAP_SLOT_RT;
229 slot->u.index = rt;
230 }
231
232 return rmap;
233}
234
235void intel_rmap_destroy(struct intel_rmap *rmap)
236{
237 XGL_UINT i;
238
239 for (i = 0; i < rmap->slot_count; i++) {
240 struct intel_rmap_slot *slot = &rmap->slots[i];
241
242 switch (slot->path_len) {
243 case 0:
244 case 1:
245 case INTEL_RMAP_SLOT_RT:
246 case INTEL_RMAP_SLOT_DYN:
247 break;
248 default:
249 icd_free(slot->u.path);
250 break;
251 }
252 }
253
254 icd_free(rmap->slots);
255 icd_free(rmap);
256}