blob: ebcc473ca478b1a49699d07c54ff042dcc3795e2 [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
Chia-I Wu82d3d8b2014-08-09 13:07:44 +080025#include <stdarg.h>
Chia-I Wue54854a2014-08-05 10:23:50 +080026#include "kmd/winsys.h"
27#include "dispatch_tables.h"
28#include "gpu.h"
Chia-I Wue09b5362014-08-07 09:25:14 +080029#include "queue.h"
Chia-I Wue54854a2014-08-05 10:23:50 +080030#include "dev.h"
31
Chia-I Wue54854a2014-08-05 10:23:50 +080032static XGL_RESULT dev_create_queues(struct intel_dev *dev,
33 const XGL_DEVICE_QUEUE_CREATE_INFO *queues,
34 XGL_UINT count)
35{
36 XGL_UINT i;
37
38 if (!count)
39 return XGL_ERROR_INVALID_POINTER;
40
41 for (i = 0; i < count; i++) {
42 const XGL_DEVICE_QUEUE_CREATE_INFO *q = &queues[i];
43 XGL_RESULT ret = XGL_SUCCESS;
44
Chia-I Wu9ae59c12014-08-07 10:08:49 +080045 if (q->queueNodeIndex < INTEL_GPU_ENGINE_COUNT &&
46 q->queueCount == 1 && !dev->queues[q->queueNodeIndex]) {
47 ret = intel_queue_create(dev, q->queueNodeIndex,
48 &dev->queues[q->queueNodeIndex]);
Chia-I Wue54854a2014-08-05 10:23:50 +080049 }
50 else {
Chia-I Wu9ae59c12014-08-07 10:08:49 +080051 ret = XGL_ERROR_INVALID_POINTER;
Chia-I Wue54854a2014-08-05 10:23:50 +080052 }
53
54 if (ret != XGL_SUCCESS) {
55 XGL_UINT j;
56 for (j = 0; j < i; j++)
Chia-I Wue09b5362014-08-07 09:25:14 +080057 intel_queue_destroy(dev->queues[j]);
Chia-I Wue54854a2014-08-05 10:23:50 +080058
59 return ret;
60 }
61 }
62
63 return XGL_SUCCESS;
64}
65
66XGL_RESULT intel_dev_create(struct intel_gpu *gpu,
67 const XGL_DEVICE_CREATE_INFO *info,
68 struct intel_dev **dev_ret)
69{
Chia-I Wue54854a2014-08-05 10:23:50 +080070 struct intel_dev *dev;
71 XGL_RESULT ret;
72
73 if (info->extensionCount)
74 return XGL_ERROR_INVALID_EXTENSION;
75
76 if (gpu->fd >= 0)
77 return XGL_ERROR_DEVICE_ALREADY_CREATED;
78
Chia-I Wubbf2c932014-08-07 12:20:08 +080079 dev = (struct intel_dev *) intel_base_create(sizeof(*dev),
80 info->flags & XGL_DEVICE_CREATE_VALIDATION_BIT,
81 XGL_DBG_OBJECT_DEVICE, info, sizeof(struct intel_dev_dbg));
Chia-I Wue54854a2014-08-05 10:23:50 +080082 if (!dev)
83 return XGL_ERROR_OUT_OF_MEMORY;
84
Chia-I Wue54854a2014-08-05 10:23:50 +080085 dev->gpu = gpu;
86
87 ret = intel_gpu_open(gpu);
88 if (ret != XGL_SUCCESS) {
89 intel_dev_destroy(dev);
90 return ret;
91 }
92
93 dev->winsys = intel_winsys_create_for_fd(gpu->fd);
94 if (!dev->winsys) {
95 icd_log(XGL_DBG_MSG_ERROR, XGL_VALIDATION_LEVEL_0, XGL_NULL_HANDLE,
96 0, 0, "failed to create device winsys for %s", gpu->path);
97 intel_dev_destroy(dev);
98 return XGL_ERROR_UNKNOWN;
99 }
100
101 ret = dev_create_queues(dev, info->pRequestedQueues,
102 info->queueRecordCount);
103 if (ret != XGL_SUCCESS) {
104 intel_dev_destroy(dev);
105 return ret;
106 }
107
Chia-I Wue54854a2014-08-05 10:23:50 +0800108 *dev_ret = dev;
109
110 return XGL_SUCCESS;
111}
112
Chia-I Wubbf2c932014-08-07 12:20:08 +0800113static void dev_clear_msg_filters(struct intel_dev *dev)
114{
115 struct intel_dev_dbg *dbg = intel_dev_dbg(dev);
116 struct intel_dev_dbg_msg_filter *filter;
117
118 filter = dbg->filters;
119 while (filter) {
120 struct intel_dev_dbg_msg_filter *next = filter->next;
121 icd_free(filter);
122 filter = next;
123 }
124
125 dbg->filters = NULL;
126}
127
Chia-I Wue54854a2014-08-05 10:23:50 +0800128void intel_dev_destroy(struct intel_dev *dev)
129{
130 XGL_UINT i;
131
132 if (dev->base.dbg)
Chia-I Wubbf2c932014-08-07 12:20:08 +0800133 dev_clear_msg_filters(dev);
Chia-I Wue54854a2014-08-05 10:23:50 +0800134
135 for (i = 0; i < ARRAY_SIZE(dev->queues); i++) {
136 if (dev->queues[i])
Chia-I Wue09b5362014-08-07 09:25:14 +0800137 intel_queue_destroy(dev->queues[i]);
Chia-I Wue54854a2014-08-05 10:23:50 +0800138 }
139
140 if (dev->winsys)
141 intel_winsys_destroy(dev->winsys);
142
143 if (dev->gpu->fd >= 0)
144 intel_gpu_close(dev->gpu);
145
Chia-I Wubbf2c932014-08-07 12:20:08 +0800146 intel_base_destroy(&dev->base);
Chia-I Wue54854a2014-08-05 10:23:50 +0800147}
148
149void intel_dev_get_heap_props(const struct intel_dev *dev,
150 XGL_MEMORY_HEAP_PROPERTIES *props)
151{
152 props->structSize = sizeof(XGL_MEMORY_HEAP_PROPERTIES);
153
154 props->heapMemoryType = XGL_HEAP_MEMORY_LOCAL;
155
156 props->heapSize = 0xffffffff; /* TODO system memory size */
157
158 props->pageSize = 4096;
159 props->flags = XGL_MEMORY_HEAP_CPU_VISIBLE_BIT |
160 XGL_MEMORY_HEAP_CPU_GPU_COHERENT_BIT |
161 XGL_MEMORY_HEAP_CPU_WRITE_COMBINED_BIT |
162 XGL_MEMORY_HEAP_HOLDS_PINNED_BIT |
163 XGL_MEMORY_HEAP_SHAREABLE_BIT;
164
165 props->gpuReadPerfRating = 100.0f;
166 props->gpuWritePerfRating = 100.0f;
167 props->cpuReadPerfRating = 10.0f;
168 props->cpuWritePerfRating = 80.0f;
169}
170
171XGL_RESULT intel_dev_add_msg_filter(struct intel_dev *dev,
172 XGL_INT msg_code,
173 XGL_DBG_MSG_FILTER filter)
174{
175 struct intel_dev_dbg *dbg = intel_dev_dbg(dev);
176 struct intel_dev_dbg_msg_filter *f = dbg->filters;
177
178 assert(filter != XGL_DBG_MSG_FILTER_NONE);
179
180 while (f) {
181 if (f->msg_code == msg_code)
182 break;
183 f = f->next;
184 }
185
186 if (f) {
187 if (f->filter != filter) {
188 f->filter = filter;
189 f->triggered = false;
190 }
191 } else {
192 f = icd_alloc(sizeof(*f), 0, XGL_SYSTEM_ALLOC_DEBUG);
193 if (!f)
194 return XGL_ERROR_OUT_OF_MEMORY;
195
196 f->msg_code = msg_code;
197 f->filter = filter;
198 f->triggered = false;
199
200 f->next = dbg->filters;
201 dbg->filters = f;
202 }
203
204 return XGL_SUCCESS;
205}
206
207void intel_dev_remove_msg_filter(struct intel_dev *dev,
208 XGL_INT msg_code)
209{
210 struct intel_dev_dbg *dbg = intel_dev_dbg(dev);
211 struct intel_dev_dbg_msg_filter *f = dbg->filters, *prev = NULL;
212
213 while (f) {
214 if (f->msg_code == msg_code) {
215 if (prev)
216 prev->next = f->next;
217 else
218 dbg->filters = f->next;
219
220 icd_free(f);
221 break;
222 }
223
224 prev = f;
225 f = f->next;
226 }
227}
Chia-I Wua207aba2014-08-05 15:13:37 +0800228
Chia-I Wu82d3d8b2014-08-09 13:07:44 +0800229static bool dev_filter_msg(struct intel_dev *dev,
230 XGL_INT msg_code)
231{
232 struct intel_dev_dbg *dbg = intel_dev_dbg(dev);
233 struct intel_dev_dbg_msg_filter *filter;
234
235 if (!dbg)
236 return false;
237
238 filter = dbg->filters;
239 while (filter) {
240 if (filter->msg_code != msg_code) {
241 filter = filter->next;
242 continue;
243 }
244
245 if (filter->filter == XGL_DBG_MSG_FILTER_ALL)
246 return true;
247
248 if (filter->filter == XGL_DBG_MSG_FILTER_REPEATED &&
249 filter->triggered)
250 return true;
251
252 filter->triggered = true;
253 break;
254 }
255
256 return false;
257}
258
259void intel_dev_log(struct intel_dev *dev,
260 XGL_DBG_MSG_TYPE msg_type,
261 XGL_VALIDATION_LEVEL validation_level,
262 XGL_BASE_OBJECT src_object,
263 XGL_SIZE location,
264 XGL_INT msg_code,
265 const char *format, ...)
266{
267 va_list ap;
268
269 if (dev_filter_msg(dev, msg_code))
270 return;
271
272 va_start(ap, format);
273 icd_vlog(msg_type, validation_level, src_object,
274 location, msg_code, format, ap);
275 va_end(ap);
276}
277
Chia-I Wua207aba2014-08-05 15:13:37 +0800278XGL_RESULT XGLAPI intelCreateDevice(
279 XGL_PHYSICAL_GPU gpu_,
280 const XGL_DEVICE_CREATE_INFO* pCreateInfo,
281 XGL_DEVICE* pDevice)
282{
283 struct intel_gpu *gpu = intel_gpu(gpu_);
284
285 return intel_dev_create(gpu, pCreateInfo, (struct intel_dev **) pDevice);
286}
287
288XGL_RESULT XGLAPI intelDestroyDevice(
289 XGL_DEVICE device)
290{
291 struct intel_dev *dev = intel_dev(device);
292
293 intel_dev_destroy(dev);
294
295 return XGL_SUCCESS;
296}
297
298XGL_RESULT XGLAPI intelGetMemoryHeapCount(
299 XGL_DEVICE device,
300 XGL_UINT* pCount)
301{
302 *pCount = 1;
303 return XGL_SUCCESS;
304}
305
306XGL_RESULT XGLAPI intelGetMemoryHeapInfo(
307 XGL_DEVICE device,
308 XGL_UINT heapId,
309 XGL_MEMORY_HEAP_INFO_TYPE infoType,
310 XGL_SIZE* pDataSize,
311 XGL_VOID* pData)
312{
313 struct intel_dev *dev = intel_dev(device);
314
315 intel_dev_get_heap_props(dev, pData);
316 *pDataSize = sizeof(XGL_MEMORY_HEAP_PROPERTIES);
317
318 return XGL_SUCCESS;
319}
Chia-I Wu49dbee82014-08-06 12:48:47 +0800320
321XGL_RESULT XGLAPI intelGetDeviceQueue(
322 XGL_DEVICE device,
323 XGL_QUEUE_TYPE queueType,
324 XGL_UINT queueIndex,
325 XGL_QUEUE* pQueue)
326{
327 struct intel_dev *dev = intel_dev(device);
328
329 switch (queueType) {
330 case XGL_QUEUE_TYPE_GRAPHICS:
331 case XGL_QUEUE_TYPE_COMPUTE:
332 if (queueIndex > 0)
333 return XGL_ERROR_UNAVAILABLE;
334 *pQueue = dev->queues[INTEL_GPU_ENGINE_3D];
335 return XGL_SUCCESS;
336 case XGL_QUEUE_TYPE_DMA:
337 default:
338 return XGL_ERROR_UNAVAILABLE;
339 }
340}
341
Chia-I Wu49dbee82014-08-06 12:48:47 +0800342XGL_RESULT XGLAPI intelDeviceWaitIdle(
343 XGL_DEVICE device)
344{
345 struct intel_dev *dev = intel_dev(device);
346 XGL_RESULT ret = XGL_SUCCESS;
347 XGL_UINT i;
348
349 for (i = 0; i < ARRAY_SIZE(dev->queues); i++) {
350 if (dev->queues[i]) {
Chia-I Wue09b5362014-08-07 09:25:14 +0800351 const XGL_RESULT r = intel_queue_wait(dev->queues[i], -1);
Chia-I Wu49dbee82014-08-06 12:48:47 +0800352 if (r != XGL_SUCCESS)
353 ret = r;
354 }
355 }
356
357 return ret;
358}