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