blob: 3613f54a321efcaa5b8be8e71a284165e7da3afd [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"
Chia-I Wude2bb862014-08-19 14:32:47 +080027#include "dispatch.h"
Chia-I Wue54854a2014-08-05 10:23:50 +080028#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
Courtney Goeltzenleuchterfb4fb532014-08-14 09:35:21 -060079 dev = (struct intel_dev *) intel_base_create(NULL, sizeof(*dev),
Chia-I Wubbf2c932014-08-07 12:20:08 +080080 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
Chia-I Wu0b784442014-08-25 22:54:16 +0800101 dev->cmd_scratch_bo = intel_winsys_alloc_buffer(dev->winsys,
102 "command buffer scratch", 4096, INTEL_DOMAIN_INSTRUCTION);
103 if (!dev->cmd_scratch_bo) {
104 intel_dev_destroy(dev);
105 return XGL_ERROR_OUT_OF_GPU_MEMORY;
106 }
107
Chia-I Wue54854a2014-08-05 10:23:50 +0800108 ret = dev_create_queues(dev, info->pRequestedQueues,
109 info->queueRecordCount);
110 if (ret != XGL_SUCCESS) {
111 intel_dev_destroy(dev);
112 return ret;
113 }
114
Chia-I Wue54854a2014-08-05 10:23:50 +0800115 *dev_ret = dev;
116
117 return XGL_SUCCESS;
118}
119
Chia-I Wubbf2c932014-08-07 12:20:08 +0800120static void dev_clear_msg_filters(struct intel_dev *dev)
121{
122 struct intel_dev_dbg *dbg = intel_dev_dbg(dev);
123 struct intel_dev_dbg_msg_filter *filter;
124
125 filter = dbg->filters;
126 while (filter) {
127 struct intel_dev_dbg_msg_filter *next = filter->next;
128 icd_free(filter);
129 filter = next;
130 }
131
132 dbg->filters = NULL;
133}
134
Chia-I Wue54854a2014-08-05 10:23:50 +0800135void intel_dev_destroy(struct intel_dev *dev)
136{
137 XGL_UINT i;
138
139 if (dev->base.dbg)
Chia-I Wubbf2c932014-08-07 12:20:08 +0800140 dev_clear_msg_filters(dev);
Chia-I Wue54854a2014-08-05 10:23:50 +0800141
142 for (i = 0; i < ARRAY_SIZE(dev->queues); i++) {
143 if (dev->queues[i])
Chia-I Wue09b5362014-08-07 09:25:14 +0800144 intel_queue_destroy(dev->queues[i]);
Chia-I Wue54854a2014-08-05 10:23:50 +0800145 }
146
Chia-I Wu0b784442014-08-25 22:54:16 +0800147 if (dev->cmd_scratch_bo)
148 intel_bo_unreference(dev->cmd_scratch_bo);
149
Chia-I Wue54854a2014-08-05 10:23:50 +0800150 if (dev->winsys)
151 intel_winsys_destroy(dev->winsys);
152
153 if (dev->gpu->fd >= 0)
154 intel_gpu_close(dev->gpu);
155
Chia-I Wubbf2c932014-08-07 12:20:08 +0800156 intel_base_destroy(&dev->base);
Chia-I Wue54854a2014-08-05 10:23:50 +0800157}
158
159void intel_dev_get_heap_props(const struct intel_dev *dev,
160 XGL_MEMORY_HEAP_PROPERTIES *props)
161{
162 props->structSize = sizeof(XGL_MEMORY_HEAP_PROPERTIES);
163
164 props->heapMemoryType = XGL_HEAP_MEMORY_LOCAL;
165
166 props->heapSize = 0xffffffff; /* TODO system memory size */
167
168 props->pageSize = 4096;
169 props->flags = XGL_MEMORY_HEAP_CPU_VISIBLE_BIT |
170 XGL_MEMORY_HEAP_CPU_GPU_COHERENT_BIT |
171 XGL_MEMORY_HEAP_CPU_WRITE_COMBINED_BIT |
172 XGL_MEMORY_HEAP_HOLDS_PINNED_BIT |
173 XGL_MEMORY_HEAP_SHAREABLE_BIT;
174
175 props->gpuReadPerfRating = 100.0f;
176 props->gpuWritePerfRating = 100.0f;
177 props->cpuReadPerfRating = 10.0f;
178 props->cpuWritePerfRating = 80.0f;
179}
180
181XGL_RESULT intel_dev_add_msg_filter(struct intel_dev *dev,
182 XGL_INT msg_code,
183 XGL_DBG_MSG_FILTER filter)
184{
185 struct intel_dev_dbg *dbg = intel_dev_dbg(dev);
186 struct intel_dev_dbg_msg_filter *f = dbg->filters;
187
188 assert(filter != XGL_DBG_MSG_FILTER_NONE);
189
190 while (f) {
191 if (f->msg_code == msg_code)
192 break;
193 f = f->next;
194 }
195
196 if (f) {
197 if (f->filter != filter) {
198 f->filter = filter;
199 f->triggered = false;
200 }
201 } else {
202 f = icd_alloc(sizeof(*f), 0, XGL_SYSTEM_ALLOC_DEBUG);
203 if (!f)
204 return XGL_ERROR_OUT_OF_MEMORY;
205
206 f->msg_code = msg_code;
207 f->filter = filter;
208 f->triggered = false;
209
210 f->next = dbg->filters;
211 dbg->filters = f;
212 }
213
214 return XGL_SUCCESS;
215}
216
217void intel_dev_remove_msg_filter(struct intel_dev *dev,
218 XGL_INT msg_code)
219{
220 struct intel_dev_dbg *dbg = intel_dev_dbg(dev);
221 struct intel_dev_dbg_msg_filter *f = dbg->filters, *prev = NULL;
222
223 while (f) {
224 if (f->msg_code == msg_code) {
225 if (prev)
226 prev->next = f->next;
227 else
228 dbg->filters = f->next;
229
230 icd_free(f);
231 break;
232 }
233
234 prev = f;
235 f = f->next;
236 }
237}
Chia-I Wua207aba2014-08-05 15:13:37 +0800238
Chia-I Wu82d3d8b2014-08-09 13:07:44 +0800239static bool dev_filter_msg(struct intel_dev *dev,
240 XGL_INT msg_code)
241{
242 struct intel_dev_dbg *dbg = intel_dev_dbg(dev);
243 struct intel_dev_dbg_msg_filter *filter;
244
245 if (!dbg)
246 return false;
247
248 filter = dbg->filters;
249 while (filter) {
250 if (filter->msg_code != msg_code) {
251 filter = filter->next;
252 continue;
253 }
254
255 if (filter->filter == XGL_DBG_MSG_FILTER_ALL)
256 return true;
257
258 if (filter->filter == XGL_DBG_MSG_FILTER_REPEATED &&
259 filter->triggered)
260 return true;
261
262 filter->triggered = true;
263 break;
264 }
265
266 return false;
267}
268
269void intel_dev_log(struct intel_dev *dev,
270 XGL_DBG_MSG_TYPE msg_type,
271 XGL_VALIDATION_LEVEL validation_level,
Chia-I Wuaabb3602014-08-19 14:18:23 +0800272 struct intel_base *src_object,
Chia-I Wu82d3d8b2014-08-09 13:07:44 +0800273 XGL_SIZE location,
274 XGL_INT msg_code,
275 const char *format, ...)
276{
277 va_list ap;
278
279 if (dev_filter_msg(dev, msg_code))
280 return;
281
282 va_start(ap, format);
Chia-I Wuaabb3602014-08-19 14:18:23 +0800283 icd_vlog(msg_type, validation_level, (XGL_BASE_OBJECT) src_object,
Chia-I Wu82d3d8b2014-08-09 13:07:44 +0800284 location, msg_code, format, ap);
285 va_end(ap);
286}
287
Chia-I Wua207aba2014-08-05 15:13:37 +0800288XGL_RESULT XGLAPI intelCreateDevice(
289 XGL_PHYSICAL_GPU gpu_,
290 const XGL_DEVICE_CREATE_INFO* pCreateInfo,
291 XGL_DEVICE* pDevice)
292{
293 struct intel_gpu *gpu = intel_gpu(gpu_);
294
295 return intel_dev_create(gpu, pCreateInfo, (struct intel_dev **) pDevice);
296}
297
298XGL_RESULT XGLAPI intelDestroyDevice(
299 XGL_DEVICE device)
300{
301 struct intel_dev *dev = intel_dev(device);
302
303 intel_dev_destroy(dev);
304
305 return XGL_SUCCESS;
306}
307
308XGL_RESULT XGLAPI intelGetMemoryHeapCount(
309 XGL_DEVICE device,
310 XGL_UINT* pCount)
311{
312 *pCount = 1;
313 return XGL_SUCCESS;
314}
315
316XGL_RESULT XGLAPI intelGetMemoryHeapInfo(
317 XGL_DEVICE device,
318 XGL_UINT heapId,
319 XGL_MEMORY_HEAP_INFO_TYPE infoType,
320 XGL_SIZE* pDataSize,
321 XGL_VOID* pData)
322{
323 struct intel_dev *dev = intel_dev(device);
324
325 intel_dev_get_heap_props(dev, pData);
326 *pDataSize = sizeof(XGL_MEMORY_HEAP_PROPERTIES);
327
328 return XGL_SUCCESS;
329}
Chia-I Wu49dbee82014-08-06 12:48:47 +0800330
331XGL_RESULT XGLAPI intelGetDeviceQueue(
332 XGL_DEVICE device,
333 XGL_QUEUE_TYPE queueType,
334 XGL_UINT queueIndex,
335 XGL_QUEUE* pQueue)
336{
337 struct intel_dev *dev = intel_dev(device);
338
339 switch (queueType) {
340 case XGL_QUEUE_TYPE_GRAPHICS:
341 case XGL_QUEUE_TYPE_COMPUTE:
342 if (queueIndex > 0)
343 return XGL_ERROR_UNAVAILABLE;
344 *pQueue = dev->queues[INTEL_GPU_ENGINE_3D];
345 return XGL_SUCCESS;
346 case XGL_QUEUE_TYPE_DMA:
347 default:
348 return XGL_ERROR_UNAVAILABLE;
349 }
350}
351
Chia-I Wu49dbee82014-08-06 12:48:47 +0800352XGL_RESULT XGLAPI intelDeviceWaitIdle(
353 XGL_DEVICE device)
354{
355 struct intel_dev *dev = intel_dev(device);
356 XGL_RESULT ret = XGL_SUCCESS;
357 XGL_UINT i;
358
359 for (i = 0; i < ARRAY_SIZE(dev->queues); i++) {
360 if (dev->queues[i]) {
Chia-I Wue09b5362014-08-07 09:25:14 +0800361 const XGL_RESULT r = intel_queue_wait(dev->queues[i], -1);
Chia-I Wu49dbee82014-08-06 12:48:47 +0800362 if (r != XGL_SUCCESS)
363 ret = r;
364 }
365 }
366
367 return ret;
368}
Chia-I Wu7ec9f342014-08-19 10:47:53 +0800369
370XGL_RESULT XGLAPI intelDbgSetValidationLevel(
371 XGL_DEVICE device,
372 XGL_VALIDATION_LEVEL validationLevel)
373{
374 struct intel_dev *dev = intel_dev(device);
Chia-I Wu069f30f2014-08-21 13:45:20 +0800375 struct intel_dev_dbg *dbg = intel_dev_dbg(dev);
Chia-I Wu7ec9f342014-08-19 10:47:53 +0800376
Chia-I Wu069f30f2014-08-21 13:45:20 +0800377 if (dbg)
378 dbg->validation_level = validationLevel;
Chia-I Wu7ec9f342014-08-19 10:47:53 +0800379
380 return XGL_SUCCESS;
381}
382
383XGL_RESULT XGLAPI intelDbgSetMessageFilter(
384 XGL_DEVICE device,
385 XGL_INT msgCode,
386 XGL_DBG_MSG_FILTER filter)
387{
388 struct intel_dev *dev = intel_dev(device);
389
390 if (!dev->base.dbg)
391 return XGL_SUCCESS;
392
393 if (filter == XGL_DBG_MSG_FILTER_NONE) {
394 intel_dev_remove_msg_filter(dev, msgCode);
395 return XGL_SUCCESS;
396 }
397
398 return intel_dev_add_msg_filter(dev, msgCode, filter);
399}
400
401XGL_RESULT XGLAPI intelDbgSetDeviceOption(
402 XGL_DEVICE device,
403 XGL_DBG_DEVICE_OPTION dbgOption,
404 XGL_SIZE dataSize,
405 const XGL_VOID* pData)
406{
407 struct intel_dev *dev = intel_dev(device);
Chia-I Wu069f30f2014-08-21 13:45:20 +0800408 struct intel_dev_dbg *dbg = intel_dev_dbg(dev);
Chia-I Wu7ec9f342014-08-19 10:47:53 +0800409 XGL_RESULT ret = XGL_SUCCESS;
410
411 if (dataSize == 0)
412 return XGL_ERROR_INVALID_VALUE;
413
414 switch (dbgOption) {
415 case XGL_DBG_OPTION_DISABLE_PIPELINE_LOADS:
Chia-I Wu069f30f2014-08-21 13:45:20 +0800416 if (dbg)
417 dbg->disable_pipeline_loads = *((const bool *) pData);
Chia-I Wu7ec9f342014-08-19 10:47:53 +0800418 break;
419 case XGL_DBG_OPTION_FORCE_OBJECT_MEMORY_REQS:
Chia-I Wu069f30f2014-08-21 13:45:20 +0800420 if (dbg)
421 dbg->force_object_memory_reqs = *((const bool *) pData);
Chia-I Wu7ec9f342014-08-19 10:47:53 +0800422 break;
423 case XGL_DBG_OPTION_FORCE_LARGE_IMAGE_ALIGNMENT:
Chia-I Wu069f30f2014-08-21 13:45:20 +0800424 if (dbg)
425 dbg->force_large_image_alignment = *((const bool *) pData);
Chia-I Wu7ec9f342014-08-19 10:47:53 +0800426 break;
427 default:
428 ret = XGL_ERROR_INVALID_VALUE;
429 break;
430 }
431
432 return ret;
433}