blob: ea461f452251e01dcf7b8230c9eac23ba68fe134 [file] [log] [blame]
Chia-I Wue54854a2014-08-05 10:23:50 +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.
23 */
24
25#include "kmd/winsys.h"
26#include "dispatch_tables.h"
27#include "gpu.h"
Chia-I Wue09b5362014-08-07 09:25:14 +080028#include "queue.h"
Chia-I Wue54854a2014-08-05 10:23:50 +080029#include "dev.h"
30
Chia-I Wue54854a2014-08-05 10:23:50 +080031static struct intel_dev_dbg *dev_dbg_create(const XGL_DEVICE_CREATE_INFO *info)
32{
33 struct intel_dev_dbg *dbg;
34
35 dbg = icd_alloc(sizeof(*dbg), 0, XGL_SYSTEM_ALLOC_DEBUG);
36 if (!dbg)
37 return NULL;
38
39 memset(dbg, 0, sizeof(*dbg));
40
41 if (!intel_base_dbg_init(&dbg->base, XGL_DBG_OBJECT_DEVICE,
42 info, sizeof(*info))) {
43 icd_free(dbg);
44 return NULL;
45 }
46
47 return dbg;
48}
49
50static void dev_dbg_destroy(struct intel_dev_dbg *dbg)
51{
52 struct intel_dev_dbg_msg_filter *filter;
53
54 filter = dbg->filters;
55 while (filter) {
56 struct intel_dev_dbg_msg_filter *next = filter->next;
57 icd_free(filter);
58 filter = next;
59 }
60
61 intel_base_dbg_cleanup(&dbg->base);
62 icd_free(dbg);
63}
64
65static XGL_RESULT dev_create_queues(struct intel_dev *dev,
66 const XGL_DEVICE_QUEUE_CREATE_INFO *queues,
67 XGL_UINT count)
68{
69 XGL_UINT i;
70
71 if (!count)
72 return XGL_ERROR_INVALID_POINTER;
73
74 for (i = 0; i < count; i++) {
75 const XGL_DEVICE_QUEUE_CREATE_INFO *q = &queues[i];
76 XGL_RESULT ret = XGL_SUCCESS;
77
Chia-I Wu9ae59c12014-08-07 10:08:49 +080078 if (q->queueNodeIndex < INTEL_GPU_ENGINE_COUNT &&
79 q->queueCount == 1 && !dev->queues[q->queueNodeIndex]) {
80 ret = intel_queue_create(dev, q->queueNodeIndex,
81 &dev->queues[q->queueNodeIndex]);
Chia-I Wue54854a2014-08-05 10:23:50 +080082 }
83 else {
Chia-I Wu9ae59c12014-08-07 10:08:49 +080084 ret = XGL_ERROR_INVALID_POINTER;
Chia-I Wue54854a2014-08-05 10:23:50 +080085 }
86
87 if (ret != XGL_SUCCESS) {
88 XGL_UINT j;
89 for (j = 0; j < i; j++)
Chia-I Wue09b5362014-08-07 09:25:14 +080090 intel_queue_destroy(dev->queues[j]);
Chia-I Wue54854a2014-08-05 10:23:50 +080091
92 return ret;
93 }
94 }
95
96 return XGL_SUCCESS;
97}
98
99XGL_RESULT intel_dev_create(struct intel_gpu *gpu,
100 const XGL_DEVICE_CREATE_INFO *info,
101 struct intel_dev **dev_ret)
102{
103 const struct icd_dispatch_table *dispatch;
104 struct intel_dev_dbg *dbg;
105 struct intel_dev *dev;
106 XGL_RESULT ret;
107
108 if (info->extensionCount)
109 return XGL_ERROR_INVALID_EXTENSION;
110
111 if (gpu->fd >= 0)
112 return XGL_ERROR_DEVICE_ALREADY_CREATED;
113
114 dev = icd_alloc(sizeof(*dev), 0, XGL_SYSTEM_ALLOC_API_OBJECT);
115 if (!dev)
116 return XGL_ERROR_OUT_OF_MEMORY;
117
118 memset(dev, 0, sizeof(*dev));
119 dev->gpu = gpu;
120
121 ret = intel_gpu_open(gpu);
122 if (ret != XGL_SUCCESS) {
123 intel_dev_destroy(dev);
124 return ret;
125 }
126
127 dev->winsys = intel_winsys_create_for_fd(gpu->fd);
128 if (!dev->winsys) {
129 icd_log(XGL_DBG_MSG_ERROR, XGL_VALIDATION_LEVEL_0, XGL_NULL_HANDLE,
130 0, 0, "failed to create device winsys for %s", gpu->path);
131 intel_dev_destroy(dev);
132 return XGL_ERROR_UNKNOWN;
133 }
134
135 ret = dev_create_queues(dev, info->pRequestedQueues,
136 info->queueRecordCount);
137 if (ret != XGL_SUCCESS) {
138 intel_dev_destroy(dev);
139 return ret;
140 }
141
142 if (info->flags & XGL_DEVICE_CREATE_VALIDATION_BIT) {
143 dispatch = &intel_debug_dispatch_table;
144 dbg = dev_dbg_create(info);
145
146 if (!dbg) {
147 icd_log(XGL_DBG_MSG_ERROR, XGL_VALIDATION_LEVEL_0,
148 XGL_NULL_HANDLE, 0, 0,
149 "failed to create device debug layer for %s", gpu->path);
150 return XGL_ERROR_OUT_OF_MEMORY;
151 }
152 } else {
153 dispatch = &intel_normal_dispatch_table;
154 dbg = NULL;
155 }
156
157 dev->base.dispatch = dispatch;
158 dev->base.dbg = &dbg->base;
Chia-I Wu26f0bd02014-08-07 10:38:40 +0800159 dev->base.get_info = intel_base_get_info;
Chia-I Wue54854a2014-08-05 10:23:50 +0800160
161 *dev_ret = dev;
162
163 return XGL_SUCCESS;
164}
165
166void intel_dev_destroy(struct intel_dev *dev)
167{
168 XGL_UINT i;
169
170 if (dev->base.dbg)
171 dev_dbg_destroy((struct intel_dev_dbg *) dev->base.dbg);
172
173 for (i = 0; i < ARRAY_SIZE(dev->queues); i++) {
174 if (dev->queues[i])
Chia-I Wue09b5362014-08-07 09:25:14 +0800175 intel_queue_destroy(dev->queues[i]);
Chia-I Wue54854a2014-08-05 10:23:50 +0800176 }
177
178 if (dev->winsys)
179 intel_winsys_destroy(dev->winsys);
180
181 if (dev->gpu->fd >= 0)
182 intel_gpu_close(dev->gpu);
183
184 icd_free(dev);
185}
186
187void intel_dev_get_heap_props(const struct intel_dev *dev,
188 XGL_MEMORY_HEAP_PROPERTIES *props)
189{
190 props->structSize = sizeof(XGL_MEMORY_HEAP_PROPERTIES);
191
192 props->heapMemoryType = XGL_HEAP_MEMORY_LOCAL;
193
194 props->heapSize = 0xffffffff; /* TODO system memory size */
195
196 props->pageSize = 4096;
197 props->flags = XGL_MEMORY_HEAP_CPU_VISIBLE_BIT |
198 XGL_MEMORY_HEAP_CPU_GPU_COHERENT_BIT |
199 XGL_MEMORY_HEAP_CPU_WRITE_COMBINED_BIT |
200 XGL_MEMORY_HEAP_HOLDS_PINNED_BIT |
201 XGL_MEMORY_HEAP_SHAREABLE_BIT;
202
203 props->gpuReadPerfRating = 100.0f;
204 props->gpuWritePerfRating = 100.0f;
205 props->cpuReadPerfRating = 10.0f;
206 props->cpuWritePerfRating = 80.0f;
207}
208
209XGL_RESULT intel_dev_add_msg_filter(struct intel_dev *dev,
210 XGL_INT msg_code,
211 XGL_DBG_MSG_FILTER filter)
212{
213 struct intel_dev_dbg *dbg = intel_dev_dbg(dev);
214 struct intel_dev_dbg_msg_filter *f = dbg->filters;
215
216 assert(filter != XGL_DBG_MSG_FILTER_NONE);
217
218 while (f) {
219 if (f->msg_code == msg_code)
220 break;
221 f = f->next;
222 }
223
224 if (f) {
225 if (f->filter != filter) {
226 f->filter = filter;
227 f->triggered = false;
228 }
229 } else {
230 f = icd_alloc(sizeof(*f), 0, XGL_SYSTEM_ALLOC_DEBUG);
231 if (!f)
232 return XGL_ERROR_OUT_OF_MEMORY;
233
234 f->msg_code = msg_code;
235 f->filter = filter;
236 f->triggered = false;
237
238 f->next = dbg->filters;
239 dbg->filters = f;
240 }
241
242 return XGL_SUCCESS;
243}
244
245void intel_dev_remove_msg_filter(struct intel_dev *dev,
246 XGL_INT msg_code)
247{
248 struct intel_dev_dbg *dbg = intel_dev_dbg(dev);
249 struct intel_dev_dbg_msg_filter *f = dbg->filters, *prev = NULL;
250
251 while (f) {
252 if (f->msg_code == msg_code) {
253 if (prev)
254 prev->next = f->next;
255 else
256 dbg->filters = f->next;
257
258 icd_free(f);
259 break;
260 }
261
262 prev = f;
263 f = f->next;
264 }
265}
Chia-I Wua207aba2014-08-05 15:13:37 +0800266
267XGL_RESULT XGLAPI intelCreateDevice(
268 XGL_PHYSICAL_GPU gpu_,
269 const XGL_DEVICE_CREATE_INFO* pCreateInfo,
270 XGL_DEVICE* pDevice)
271{
272 struct intel_gpu *gpu = intel_gpu(gpu_);
273
274 return intel_dev_create(gpu, pCreateInfo, (struct intel_dev **) pDevice);
275}
276
277XGL_RESULT XGLAPI intelDestroyDevice(
278 XGL_DEVICE device)
279{
280 struct intel_dev *dev = intel_dev(device);
281
282 intel_dev_destroy(dev);
283
284 return XGL_SUCCESS;
285}
286
287XGL_RESULT XGLAPI intelGetMemoryHeapCount(
288 XGL_DEVICE device,
289 XGL_UINT* pCount)
290{
291 *pCount = 1;
292 return XGL_SUCCESS;
293}
294
295XGL_RESULT XGLAPI intelGetMemoryHeapInfo(
296 XGL_DEVICE device,
297 XGL_UINT heapId,
298 XGL_MEMORY_HEAP_INFO_TYPE infoType,
299 XGL_SIZE* pDataSize,
300 XGL_VOID* pData)
301{
302 struct intel_dev *dev = intel_dev(device);
303
304 intel_dev_get_heap_props(dev, pData);
305 *pDataSize = sizeof(XGL_MEMORY_HEAP_PROPERTIES);
306
307 return XGL_SUCCESS;
308}
Chia-I Wu49dbee82014-08-06 12:48:47 +0800309
310XGL_RESULT XGLAPI intelGetDeviceQueue(
311 XGL_DEVICE device,
312 XGL_QUEUE_TYPE queueType,
313 XGL_UINT queueIndex,
314 XGL_QUEUE* pQueue)
315{
316 struct intel_dev *dev = intel_dev(device);
317
318 switch (queueType) {
319 case XGL_QUEUE_TYPE_GRAPHICS:
320 case XGL_QUEUE_TYPE_COMPUTE:
321 if (queueIndex > 0)
322 return XGL_ERROR_UNAVAILABLE;
323 *pQueue = dev->queues[INTEL_GPU_ENGINE_3D];
324 return XGL_SUCCESS;
325 case XGL_QUEUE_TYPE_DMA:
326 default:
327 return XGL_ERROR_UNAVAILABLE;
328 }
329}
330
Chia-I Wu49dbee82014-08-06 12:48:47 +0800331XGL_RESULT XGLAPI intelDeviceWaitIdle(
332 XGL_DEVICE device)
333{
334 struct intel_dev *dev = intel_dev(device);
335 XGL_RESULT ret = XGL_SUCCESS;
336 XGL_UINT i;
337
338 for (i = 0; i < ARRAY_SIZE(dev->queues); i++) {
339 if (dev->queues[i]) {
Chia-I Wue09b5362014-08-07 09:25:14 +0800340 const XGL_RESULT r = intel_queue_wait(dev->queues[i], -1);
Chia-I Wu49dbee82014-08-06 12:48:47 +0800341 if (r != XGL_SUCCESS)
342 ret = r;
343 }
344 }
345
346 return ret;
347}