blob: ff80f24686751d37b75306419ee6b2c7da78e4c1 [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 XGL_RESULT dev_create_queues(struct intel_dev *dev,
32 const XGL_DEVICE_QUEUE_CREATE_INFO *queues,
33 XGL_UINT count)
34{
35 XGL_UINT i;
36
37 if (!count)
38 return XGL_ERROR_INVALID_POINTER;
39
40 for (i = 0; i < count; i++) {
41 const XGL_DEVICE_QUEUE_CREATE_INFO *q = &queues[i];
42 XGL_RESULT ret = XGL_SUCCESS;
43
Chia-I Wu9ae59c12014-08-07 10:08:49 +080044 if (q->queueNodeIndex < INTEL_GPU_ENGINE_COUNT &&
45 q->queueCount == 1 && !dev->queues[q->queueNodeIndex]) {
46 ret = intel_queue_create(dev, q->queueNodeIndex,
47 &dev->queues[q->queueNodeIndex]);
Chia-I Wue54854a2014-08-05 10:23:50 +080048 }
49 else {
Chia-I Wu9ae59c12014-08-07 10:08:49 +080050 ret = XGL_ERROR_INVALID_POINTER;
Chia-I Wue54854a2014-08-05 10:23:50 +080051 }
52
53 if (ret != XGL_SUCCESS) {
54 XGL_UINT j;
55 for (j = 0; j < i; j++)
Chia-I Wue09b5362014-08-07 09:25:14 +080056 intel_queue_destroy(dev->queues[j]);
Chia-I Wue54854a2014-08-05 10:23:50 +080057
58 return ret;
59 }
60 }
61
62 return XGL_SUCCESS;
63}
64
65XGL_RESULT intel_dev_create(struct intel_gpu *gpu,
66 const XGL_DEVICE_CREATE_INFO *info,
67 struct intel_dev **dev_ret)
68{
Chia-I Wue54854a2014-08-05 10:23:50 +080069 struct intel_dev *dev;
70 XGL_RESULT ret;
71
72 if (info->extensionCount)
73 return XGL_ERROR_INVALID_EXTENSION;
74
75 if (gpu->fd >= 0)
76 return XGL_ERROR_DEVICE_ALREADY_CREATED;
77
Chia-I Wubbf2c932014-08-07 12:20:08 +080078 dev = (struct intel_dev *) intel_base_create(sizeof(*dev),
79 info->flags & XGL_DEVICE_CREATE_VALIDATION_BIT,
80 XGL_DBG_OBJECT_DEVICE, info, sizeof(struct intel_dev_dbg));
Chia-I Wue54854a2014-08-05 10:23:50 +080081 if (!dev)
82 return XGL_ERROR_OUT_OF_MEMORY;
83
Chia-I Wue54854a2014-08-05 10:23:50 +080084 dev->gpu = gpu;
85
86 ret = intel_gpu_open(gpu);
87 if (ret != XGL_SUCCESS) {
88 intel_dev_destroy(dev);
89 return ret;
90 }
91
92 dev->winsys = intel_winsys_create_for_fd(gpu->fd);
93 if (!dev->winsys) {
94 icd_log(XGL_DBG_MSG_ERROR, XGL_VALIDATION_LEVEL_0, XGL_NULL_HANDLE,
95 0, 0, "failed to create device winsys for %s", gpu->path);
96 intel_dev_destroy(dev);
97 return XGL_ERROR_UNKNOWN;
98 }
99
100 ret = dev_create_queues(dev, info->pRequestedQueues,
101 info->queueRecordCount);
102 if (ret != XGL_SUCCESS) {
103 intel_dev_destroy(dev);
104 return ret;
105 }
106
Chia-I Wue54854a2014-08-05 10:23:50 +0800107 *dev_ret = dev;
108
109 return XGL_SUCCESS;
110}
111
Chia-I Wubbf2c932014-08-07 12:20:08 +0800112static void dev_clear_msg_filters(struct intel_dev *dev)
113{
114 struct intel_dev_dbg *dbg = intel_dev_dbg(dev);
115 struct intel_dev_dbg_msg_filter *filter;
116
117 filter = dbg->filters;
118 while (filter) {
119 struct intel_dev_dbg_msg_filter *next = filter->next;
120 icd_free(filter);
121 filter = next;
122 }
123
124 dbg->filters = NULL;
125}
126
Chia-I Wue54854a2014-08-05 10:23:50 +0800127void intel_dev_destroy(struct intel_dev *dev)
128{
129 XGL_UINT i;
130
131 if (dev->base.dbg)
Chia-I Wubbf2c932014-08-07 12:20:08 +0800132 dev_clear_msg_filters(dev);
Chia-I Wue54854a2014-08-05 10:23:50 +0800133
134 for (i = 0; i < ARRAY_SIZE(dev->queues); i++) {
135 if (dev->queues[i])
Chia-I Wue09b5362014-08-07 09:25:14 +0800136 intel_queue_destroy(dev->queues[i]);
Chia-I Wue54854a2014-08-05 10:23:50 +0800137 }
138
139 if (dev->winsys)
140 intel_winsys_destroy(dev->winsys);
141
142 if (dev->gpu->fd >= 0)
143 intel_gpu_close(dev->gpu);
144
Chia-I Wubbf2c932014-08-07 12:20:08 +0800145 intel_base_destroy(&dev->base);
Chia-I Wue54854a2014-08-05 10:23:50 +0800146}
147
148void intel_dev_get_heap_props(const struct intel_dev *dev,
149 XGL_MEMORY_HEAP_PROPERTIES *props)
150{
151 props->structSize = sizeof(XGL_MEMORY_HEAP_PROPERTIES);
152
153 props->heapMemoryType = XGL_HEAP_MEMORY_LOCAL;
154
155 props->heapSize = 0xffffffff; /* TODO system memory size */
156
157 props->pageSize = 4096;
158 props->flags = XGL_MEMORY_HEAP_CPU_VISIBLE_BIT |
159 XGL_MEMORY_HEAP_CPU_GPU_COHERENT_BIT |
160 XGL_MEMORY_HEAP_CPU_WRITE_COMBINED_BIT |
161 XGL_MEMORY_HEAP_HOLDS_PINNED_BIT |
162 XGL_MEMORY_HEAP_SHAREABLE_BIT;
163
164 props->gpuReadPerfRating = 100.0f;
165 props->gpuWritePerfRating = 100.0f;
166 props->cpuReadPerfRating = 10.0f;
167 props->cpuWritePerfRating = 80.0f;
168}
169
170XGL_RESULT intel_dev_add_msg_filter(struct intel_dev *dev,
171 XGL_INT msg_code,
172 XGL_DBG_MSG_FILTER filter)
173{
174 struct intel_dev_dbg *dbg = intel_dev_dbg(dev);
175 struct intel_dev_dbg_msg_filter *f = dbg->filters;
176
177 assert(filter != XGL_DBG_MSG_FILTER_NONE);
178
179 while (f) {
180 if (f->msg_code == msg_code)
181 break;
182 f = f->next;
183 }
184
185 if (f) {
186 if (f->filter != filter) {
187 f->filter = filter;
188 f->triggered = false;
189 }
190 } else {
191 f = icd_alloc(sizeof(*f), 0, XGL_SYSTEM_ALLOC_DEBUG);
192 if (!f)
193 return XGL_ERROR_OUT_OF_MEMORY;
194
195 f->msg_code = msg_code;
196 f->filter = filter;
197 f->triggered = false;
198
199 f->next = dbg->filters;
200 dbg->filters = f;
201 }
202
203 return XGL_SUCCESS;
204}
205
206void intel_dev_remove_msg_filter(struct intel_dev *dev,
207 XGL_INT msg_code)
208{
209 struct intel_dev_dbg *dbg = intel_dev_dbg(dev);
210 struct intel_dev_dbg_msg_filter *f = dbg->filters, *prev = NULL;
211
212 while (f) {
213 if (f->msg_code == msg_code) {
214 if (prev)
215 prev->next = f->next;
216 else
217 dbg->filters = f->next;
218
219 icd_free(f);
220 break;
221 }
222
223 prev = f;
224 f = f->next;
225 }
226}
Chia-I Wua207aba2014-08-05 15:13:37 +0800227
228XGL_RESULT XGLAPI intelCreateDevice(
229 XGL_PHYSICAL_GPU gpu_,
230 const XGL_DEVICE_CREATE_INFO* pCreateInfo,
231 XGL_DEVICE* pDevice)
232{
233 struct intel_gpu *gpu = intel_gpu(gpu_);
234
235 return intel_dev_create(gpu, pCreateInfo, (struct intel_dev **) pDevice);
236}
237
238XGL_RESULT XGLAPI intelDestroyDevice(
239 XGL_DEVICE device)
240{
241 struct intel_dev *dev = intel_dev(device);
242
243 intel_dev_destroy(dev);
244
245 return XGL_SUCCESS;
246}
247
248XGL_RESULT XGLAPI intelGetMemoryHeapCount(
249 XGL_DEVICE device,
250 XGL_UINT* pCount)
251{
252 *pCount = 1;
253 return XGL_SUCCESS;
254}
255
256XGL_RESULT XGLAPI intelGetMemoryHeapInfo(
257 XGL_DEVICE device,
258 XGL_UINT heapId,
259 XGL_MEMORY_HEAP_INFO_TYPE infoType,
260 XGL_SIZE* pDataSize,
261 XGL_VOID* pData)
262{
263 struct intel_dev *dev = intel_dev(device);
264
265 intel_dev_get_heap_props(dev, pData);
266 *pDataSize = sizeof(XGL_MEMORY_HEAP_PROPERTIES);
267
268 return XGL_SUCCESS;
269}
Chia-I Wu49dbee82014-08-06 12:48:47 +0800270
271XGL_RESULT XGLAPI intelGetDeviceQueue(
272 XGL_DEVICE device,
273 XGL_QUEUE_TYPE queueType,
274 XGL_UINT queueIndex,
275 XGL_QUEUE* pQueue)
276{
277 struct intel_dev *dev = intel_dev(device);
278
279 switch (queueType) {
280 case XGL_QUEUE_TYPE_GRAPHICS:
281 case XGL_QUEUE_TYPE_COMPUTE:
282 if (queueIndex > 0)
283 return XGL_ERROR_UNAVAILABLE;
284 *pQueue = dev->queues[INTEL_GPU_ENGINE_3D];
285 return XGL_SUCCESS;
286 case XGL_QUEUE_TYPE_DMA:
287 default:
288 return XGL_ERROR_UNAVAILABLE;
289 }
290}
291
Chia-I Wu49dbee82014-08-06 12:48:47 +0800292XGL_RESULT XGLAPI intelDeviceWaitIdle(
293 XGL_DEVICE device)
294{
295 struct intel_dev *dev = intel_dev(device);
296 XGL_RESULT ret = XGL_SUCCESS;
297 XGL_UINT i;
298
299 for (i = 0; i < ARRAY_SIZE(dev->queues); i++) {
300 if (dev->queues[i]) {
Chia-I Wue09b5362014-08-07 09:25:14 +0800301 const XGL_RESULT r = intel_queue_wait(dev->queues[i], -1);
Chia-I Wu49dbee82014-08-06 12:48:47 +0800302 if (r != XGL_SUCCESS)
303 ret = r;
304 }
305 }
306
307 return ret;
308}