blob: 91f8e07213f77e83c446b1a3f336282c4f49970b [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.
Chia-I Wu44e42362014-09-02 08:32:09 +080023 *
24 * Authors:
25 * Chia-I Wu <olv@lunarg.com>
Chia-I Wue54854a2014-08-05 10:23:50 +080026 */
27
Chia-I Wu82d3d8b2014-08-09 13:07:44 +080028#include <stdarg.h>
Chia-I Wue54854a2014-08-05 10:23:50 +080029#include "kmd/winsys.h"
Chia-I Wude2bb862014-08-19 14:32:47 +080030#include "dispatch.h"
Chia-I Wue54854a2014-08-05 10:23:50 +080031#include "gpu.h"
Chia-I Wu9fe3ec42014-10-17 09:49:16 +080032#include "pipeline.h"
Chia-I Wue09b5362014-08-07 09:25:14 +080033#include "queue.h"
Chia-I Wue54854a2014-08-05 10:23:50 +080034#include "dev.h"
35
Chia-I Wu9fe3ec42014-10-17 09:49:16 +080036static void dev_destroy_meta_shaders(struct intel_dev *dev)
37{
38 XGL_UINT i;
39
40 for (i = 0; i < ARRAY_SIZE(dev->cmd_meta_shaders); i++) {
41 if (!dev->cmd_meta_shaders[i])
42 break;
43
44 intel_pipeline_shader_destroy(dev->cmd_meta_shaders[i]);
45 dev->cmd_meta_shaders[i] = NULL;
46 }
47}
48
49static bool dev_create_meta_shaders(struct intel_dev *dev)
50{
51 XGL_UINT i;
52
53 for (i = 0; i < ARRAY_SIZE(dev->cmd_meta_shaders); i++) {
54 struct intel_pipeline_shader *sh;
55
56 sh = intel_pipeline_shader_create_meta(dev, i);
57 if (!sh) {
58 dev_destroy_meta_shaders(dev);
59 return false;
60 }
61
62 dev->cmd_meta_shaders[i] = sh;
63 }
64
65 return true;
66}
67
Chia-I Wue54854a2014-08-05 10:23:50 +080068static XGL_RESULT dev_create_queues(struct intel_dev *dev,
69 const XGL_DEVICE_QUEUE_CREATE_INFO *queues,
70 XGL_UINT count)
71{
72 XGL_UINT i;
73
74 if (!count)
75 return XGL_ERROR_INVALID_POINTER;
76
77 for (i = 0; i < count; i++) {
78 const XGL_DEVICE_QUEUE_CREATE_INFO *q = &queues[i];
79 XGL_RESULT ret = XGL_SUCCESS;
80
Chia-I Wu9ae59c12014-08-07 10:08:49 +080081 if (q->queueNodeIndex < INTEL_GPU_ENGINE_COUNT &&
82 q->queueCount == 1 && !dev->queues[q->queueNodeIndex]) {
83 ret = intel_queue_create(dev, q->queueNodeIndex,
84 &dev->queues[q->queueNodeIndex]);
Chia-I Wue54854a2014-08-05 10:23:50 +080085 }
86 else {
Chia-I Wu9ae59c12014-08-07 10:08:49 +080087 ret = XGL_ERROR_INVALID_POINTER;
Chia-I Wue54854a2014-08-05 10:23:50 +080088 }
89
90 if (ret != XGL_SUCCESS) {
91 XGL_UINT j;
92 for (j = 0; j < i; j++)
Chia-I Wue09b5362014-08-07 09:25:14 +080093 intel_queue_destroy(dev->queues[j]);
Chia-I Wue54854a2014-08-05 10:23:50 +080094
95 return ret;
96 }
97 }
98
99 return XGL_SUCCESS;
100}
101
102XGL_RESULT intel_dev_create(struct intel_gpu *gpu,
103 const XGL_DEVICE_CREATE_INFO *info,
104 struct intel_dev **dev_ret)
105{
Chia-I Wue54854a2014-08-05 10:23:50 +0800106 struct intel_dev *dev;
Chia-I Wu1db76e02014-09-15 14:21:14 +0800107 XGL_UINT i;
Chia-I Wue54854a2014-08-05 10:23:50 +0800108 XGL_RESULT ret;
109
Chia-I Wud8965932014-10-13 13:32:37 +0800110 if (gpu->winsys)
Chia-I Wue54854a2014-08-05 10:23:50 +0800111 return XGL_ERROR_DEVICE_ALREADY_CREATED;
112
Courtney Goeltzenleuchterfb4fb532014-08-14 09:35:21 -0600113 dev = (struct intel_dev *) intel_base_create(NULL, sizeof(*dev),
Chia-I Wubbf2c932014-08-07 12:20:08 +0800114 info->flags & XGL_DEVICE_CREATE_VALIDATION_BIT,
115 XGL_DBG_OBJECT_DEVICE, info, sizeof(struct intel_dev_dbg));
Chia-I Wue54854a2014-08-05 10:23:50 +0800116 if (!dev)
117 return XGL_ERROR_OUT_OF_MEMORY;
118
Chia-I Wu1db76e02014-09-15 14:21:14 +0800119 for (i = 0; i < info->extensionCount; i++) {
120 const enum intel_ext_type ext = intel_gpu_lookup_extension(gpu,
121 (const char *) info->ppEnabledExtensionNames[i]);
122
123 if (ext == INTEL_EXT_INVALID)
124 return XGL_ERROR_INVALID_EXTENSION;
125
126 dev->exts[ext] = true;
127 }
128
Chia-I Wue54854a2014-08-05 10:23:50 +0800129 dev->gpu = gpu;
130
131 ret = intel_gpu_open(gpu);
132 if (ret != XGL_SUCCESS) {
133 intel_dev_destroy(dev);
134 return ret;
135 }
136
Chia-I Wud8965932014-10-13 13:32:37 +0800137 dev->winsys = gpu->winsys;
Chia-I Wue54854a2014-08-05 10:23:50 +0800138
Chia-I Wu0b784442014-08-25 22:54:16 +0800139 dev->cmd_scratch_bo = intel_winsys_alloc_buffer(dev->winsys,
Chia-I Wu32a22462014-08-26 14:13:46 +0800140 "command buffer scratch", 4096, false);
Chia-I Wu0b784442014-08-25 22:54:16 +0800141 if (!dev->cmd_scratch_bo) {
142 intel_dev_destroy(dev);
143 return XGL_ERROR_OUT_OF_GPU_MEMORY;
144 }
145
Chia-I Wu9fe3ec42014-10-17 09:49:16 +0800146 if (!dev_create_meta_shaders(dev)) {
147 intel_dev_destroy(dev);
148 return XGL_ERROR_OUT_OF_MEMORY;
149 }
150
Chia-I Wue54854a2014-08-05 10:23:50 +0800151 ret = dev_create_queues(dev, info->pRequestedQueues,
152 info->queueRecordCount);
153 if (ret != XGL_SUCCESS) {
154 intel_dev_destroy(dev);
155 return ret;
156 }
157
Chia-I Wue54854a2014-08-05 10:23:50 +0800158 *dev_ret = dev;
159
160 return XGL_SUCCESS;
161}
162
Chia-I Wubbf2c932014-08-07 12:20:08 +0800163static void dev_clear_msg_filters(struct intel_dev *dev)
164{
165 struct intel_dev_dbg *dbg = intel_dev_dbg(dev);
166 struct intel_dev_dbg_msg_filter *filter;
167
168 filter = dbg->filters;
169 while (filter) {
170 struct intel_dev_dbg_msg_filter *next = filter->next;
171 icd_free(filter);
172 filter = next;
173 }
174
175 dbg->filters = NULL;
176}
177
Chia-I Wue54854a2014-08-05 10:23:50 +0800178void intel_dev_destroy(struct intel_dev *dev)
179{
Chia-I Wud8965932014-10-13 13:32:37 +0800180 struct intel_gpu *gpu = dev->gpu;
Chia-I Wue54854a2014-08-05 10:23:50 +0800181 XGL_UINT i;
182
183 if (dev->base.dbg)
Chia-I Wubbf2c932014-08-07 12:20:08 +0800184 dev_clear_msg_filters(dev);
Chia-I Wue54854a2014-08-05 10:23:50 +0800185
186 for (i = 0; i < ARRAY_SIZE(dev->queues); i++) {
187 if (dev->queues[i])
Chia-I Wue09b5362014-08-07 09:25:14 +0800188 intel_queue_destroy(dev->queues[i]);
Chia-I Wue54854a2014-08-05 10:23:50 +0800189 }
190
Chia-I Wu9fe3ec42014-10-17 09:49:16 +0800191 dev_destroy_meta_shaders(dev);
192
Chia-I Wu0b784442014-08-25 22:54:16 +0800193 if (dev->cmd_scratch_bo)
194 intel_bo_unreference(dev->cmd_scratch_bo);
195
Chia-I Wubbf2c932014-08-07 12:20:08 +0800196 intel_base_destroy(&dev->base);
Chia-I Wud8965932014-10-13 13:32:37 +0800197
198 if (gpu->winsys)
199 intel_gpu_close(dev->gpu);
Chia-I Wue54854a2014-08-05 10:23:50 +0800200}
201
202void intel_dev_get_heap_props(const struct intel_dev *dev,
203 XGL_MEMORY_HEAP_PROPERTIES *props)
204{
205 props->structSize = sizeof(XGL_MEMORY_HEAP_PROPERTIES);
206
207 props->heapMemoryType = XGL_HEAP_MEMORY_LOCAL;
208
209 props->heapSize = 0xffffffff; /* TODO system memory size */
210
211 props->pageSize = 4096;
212 props->flags = XGL_MEMORY_HEAP_CPU_VISIBLE_BIT |
213 XGL_MEMORY_HEAP_CPU_GPU_COHERENT_BIT |
214 XGL_MEMORY_HEAP_CPU_WRITE_COMBINED_BIT |
215 XGL_MEMORY_HEAP_HOLDS_PINNED_BIT |
216 XGL_MEMORY_HEAP_SHAREABLE_BIT;
217
218 props->gpuReadPerfRating = 100.0f;
219 props->gpuWritePerfRating = 100.0f;
220 props->cpuReadPerfRating = 10.0f;
221 props->cpuWritePerfRating = 80.0f;
222}
223
224XGL_RESULT intel_dev_add_msg_filter(struct intel_dev *dev,
225 XGL_INT msg_code,
226 XGL_DBG_MSG_FILTER filter)
227{
228 struct intel_dev_dbg *dbg = intel_dev_dbg(dev);
229 struct intel_dev_dbg_msg_filter *f = dbg->filters;
230
231 assert(filter != XGL_DBG_MSG_FILTER_NONE);
232
233 while (f) {
234 if (f->msg_code == msg_code)
235 break;
236 f = f->next;
237 }
238
239 if (f) {
240 if (f->filter != filter) {
241 f->filter = filter;
242 f->triggered = false;
243 }
244 } else {
245 f = icd_alloc(sizeof(*f), 0, XGL_SYSTEM_ALLOC_DEBUG);
246 if (!f)
247 return XGL_ERROR_OUT_OF_MEMORY;
248
249 f->msg_code = msg_code;
250 f->filter = filter;
251 f->triggered = false;
252
253 f->next = dbg->filters;
254 dbg->filters = f;
255 }
256
257 return XGL_SUCCESS;
258}
259
260void intel_dev_remove_msg_filter(struct intel_dev *dev,
261 XGL_INT msg_code)
262{
263 struct intel_dev_dbg *dbg = intel_dev_dbg(dev);
264 struct intel_dev_dbg_msg_filter *f = dbg->filters, *prev = NULL;
265
266 while (f) {
267 if (f->msg_code == msg_code) {
268 if (prev)
269 prev->next = f->next;
270 else
271 dbg->filters = f->next;
272
273 icd_free(f);
274 break;
275 }
276
277 prev = f;
278 f = f->next;
279 }
280}
Chia-I Wua207aba2014-08-05 15:13:37 +0800281
Chia-I Wu82d3d8b2014-08-09 13:07:44 +0800282static bool dev_filter_msg(struct intel_dev *dev,
283 XGL_INT msg_code)
284{
285 struct intel_dev_dbg *dbg = intel_dev_dbg(dev);
286 struct intel_dev_dbg_msg_filter *filter;
287
288 if (!dbg)
289 return false;
290
291 filter = dbg->filters;
292 while (filter) {
293 if (filter->msg_code != msg_code) {
294 filter = filter->next;
295 continue;
296 }
297
298 if (filter->filter == XGL_DBG_MSG_FILTER_ALL)
299 return true;
300
301 if (filter->filter == XGL_DBG_MSG_FILTER_REPEATED &&
302 filter->triggered)
303 return true;
304
305 filter->triggered = true;
306 break;
307 }
308
309 return false;
310}
311
312void intel_dev_log(struct intel_dev *dev,
313 XGL_DBG_MSG_TYPE msg_type,
314 XGL_VALIDATION_LEVEL validation_level,
Chia-I Wuaabb3602014-08-19 14:18:23 +0800315 struct intel_base *src_object,
Chia-I Wu82d3d8b2014-08-09 13:07:44 +0800316 XGL_SIZE location,
317 XGL_INT msg_code,
318 const char *format, ...)
319{
320 va_list ap;
321
322 if (dev_filter_msg(dev, msg_code))
323 return;
324
325 va_start(ap, format);
Chia-I Wuaabb3602014-08-19 14:18:23 +0800326 icd_vlog(msg_type, validation_level, (XGL_BASE_OBJECT) src_object,
Chia-I Wu82d3d8b2014-08-09 13:07:44 +0800327 location, msg_code, format, ap);
328 va_end(ap);
329}
330
Chia-I Wua207aba2014-08-05 15:13:37 +0800331XGL_RESULT XGLAPI intelCreateDevice(
332 XGL_PHYSICAL_GPU gpu_,
333 const XGL_DEVICE_CREATE_INFO* pCreateInfo,
334 XGL_DEVICE* pDevice)
335{
336 struct intel_gpu *gpu = intel_gpu(gpu_);
337
338 return intel_dev_create(gpu, pCreateInfo, (struct intel_dev **) pDevice);
339}
340
341XGL_RESULT XGLAPI intelDestroyDevice(
342 XGL_DEVICE device)
343{
344 struct intel_dev *dev = intel_dev(device);
345
346 intel_dev_destroy(dev);
347
348 return XGL_SUCCESS;
349}
350
351XGL_RESULT XGLAPI intelGetMemoryHeapCount(
352 XGL_DEVICE device,
353 XGL_UINT* pCount)
354{
355 *pCount = 1;
356 return XGL_SUCCESS;
357}
358
359XGL_RESULT XGLAPI intelGetMemoryHeapInfo(
360 XGL_DEVICE device,
361 XGL_UINT heapId,
362 XGL_MEMORY_HEAP_INFO_TYPE infoType,
363 XGL_SIZE* pDataSize,
364 XGL_VOID* pData)
365{
366 struct intel_dev *dev = intel_dev(device);
367
368 intel_dev_get_heap_props(dev, pData);
369 *pDataSize = sizeof(XGL_MEMORY_HEAP_PROPERTIES);
370
371 return XGL_SUCCESS;
372}
Chia-I Wu49dbee82014-08-06 12:48:47 +0800373
374XGL_RESULT XGLAPI intelGetDeviceQueue(
375 XGL_DEVICE device,
376 XGL_QUEUE_TYPE queueType,
377 XGL_UINT queueIndex,
378 XGL_QUEUE* pQueue)
379{
380 struct intel_dev *dev = intel_dev(device);
381
382 switch (queueType) {
383 case XGL_QUEUE_TYPE_GRAPHICS:
384 case XGL_QUEUE_TYPE_COMPUTE:
385 if (queueIndex > 0)
386 return XGL_ERROR_UNAVAILABLE;
387 *pQueue = dev->queues[INTEL_GPU_ENGINE_3D];
388 return XGL_SUCCESS;
389 case XGL_QUEUE_TYPE_DMA:
390 default:
391 return XGL_ERROR_UNAVAILABLE;
392 }
393}
394
Chia-I Wu49dbee82014-08-06 12:48:47 +0800395XGL_RESULT XGLAPI intelDeviceWaitIdle(
396 XGL_DEVICE device)
397{
398 struct intel_dev *dev = intel_dev(device);
399 XGL_RESULT ret = XGL_SUCCESS;
400 XGL_UINT i;
401
402 for (i = 0; i < ARRAY_SIZE(dev->queues); i++) {
403 if (dev->queues[i]) {
Chia-I Wue09b5362014-08-07 09:25:14 +0800404 const XGL_RESULT r = intel_queue_wait(dev->queues[i], -1);
Chia-I Wu49dbee82014-08-06 12:48:47 +0800405 if (r != XGL_SUCCESS)
406 ret = r;
407 }
408 }
409
410 return ret;
411}
Chia-I Wu7ec9f342014-08-19 10:47:53 +0800412
413XGL_RESULT XGLAPI intelDbgSetValidationLevel(
414 XGL_DEVICE device,
415 XGL_VALIDATION_LEVEL validationLevel)
416{
417 struct intel_dev *dev = intel_dev(device);
Chia-I Wu069f30f2014-08-21 13:45:20 +0800418 struct intel_dev_dbg *dbg = intel_dev_dbg(dev);
Chia-I Wu7ec9f342014-08-19 10:47:53 +0800419
Chia-I Wu069f30f2014-08-21 13:45:20 +0800420 if (dbg)
421 dbg->validation_level = validationLevel;
Chia-I Wu7ec9f342014-08-19 10:47:53 +0800422
423 return XGL_SUCCESS;
424}
425
426XGL_RESULT XGLAPI intelDbgSetMessageFilter(
427 XGL_DEVICE device,
428 XGL_INT msgCode,
429 XGL_DBG_MSG_FILTER filter)
430{
431 struct intel_dev *dev = intel_dev(device);
432
433 if (!dev->base.dbg)
434 return XGL_SUCCESS;
435
436 if (filter == XGL_DBG_MSG_FILTER_NONE) {
437 intel_dev_remove_msg_filter(dev, msgCode);
438 return XGL_SUCCESS;
439 }
440
441 return intel_dev_add_msg_filter(dev, msgCode, filter);
442}
443
444XGL_RESULT XGLAPI intelDbgSetDeviceOption(
445 XGL_DEVICE device,
446 XGL_DBG_DEVICE_OPTION dbgOption,
447 XGL_SIZE dataSize,
448 const XGL_VOID* pData)
449{
450 struct intel_dev *dev = intel_dev(device);
Chia-I Wu069f30f2014-08-21 13:45:20 +0800451 struct intel_dev_dbg *dbg = intel_dev_dbg(dev);
Chia-I Wu7ec9f342014-08-19 10:47:53 +0800452 XGL_RESULT ret = XGL_SUCCESS;
453
454 if (dataSize == 0)
455 return XGL_ERROR_INVALID_VALUE;
456
457 switch (dbgOption) {
458 case XGL_DBG_OPTION_DISABLE_PIPELINE_LOADS:
Chia-I Wu069f30f2014-08-21 13:45:20 +0800459 if (dbg)
460 dbg->disable_pipeline_loads = *((const bool *) pData);
Chia-I Wu7ec9f342014-08-19 10:47:53 +0800461 break;
462 case XGL_DBG_OPTION_FORCE_OBJECT_MEMORY_REQS:
Chia-I Wu069f30f2014-08-21 13:45:20 +0800463 if (dbg)
464 dbg->force_object_memory_reqs = *((const bool *) pData);
Chia-I Wu7ec9f342014-08-19 10:47:53 +0800465 break;
466 case XGL_DBG_OPTION_FORCE_LARGE_IMAGE_ALIGNMENT:
Chia-I Wu069f30f2014-08-21 13:45:20 +0800467 if (dbg)
468 dbg->force_large_image_alignment = *((const bool *) pData);
Chia-I Wu7ec9f342014-08-19 10:47:53 +0800469 break;
470 default:
471 ret = XGL_ERROR_INVALID_VALUE;
472 break;
473 }
474
475 return ret;
476}