blob: 50e04ea730fc850de76ae6dff951f724cc3bfaed [file] [log] [blame]
Chia-I Wu9737a102014-08-07 07:59:51 +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 "dev.h"
27#include "mem.h"
28#include "event.h"
29
30static XGL_RESULT event_map(struct intel_event *event, uint32_t **ptr_ret)
31{
32 void *ptr;
33
34 if (!event->obj.mem)
35 return XGL_ERROR_MEMORY_NOT_BOUND;
36
37 /*
38 * This is an unsynchronous mapping. It doesn't look like we want a
39 * synchronous mapping. But it is also unclear what would happen when GPU
40 * writes to it at the same time. We need atomicy here.
41 */
42 ptr = intel_mem_map(event->obj.mem, 0);
43 if (!ptr)
44 return XGL_ERROR_MEMORY_MAP_FAILED;
45
46 *ptr_ret = (uint32_t *) ((uint8_t *) ptr + event->obj.offset);
47
48 return XGL_SUCCESS;
49}
50
51static void event_unmap(struct intel_event *event)
52{
53 intel_mem_unmap(event->obj.mem);
54}
55
56static XGL_RESULT event_write(struct intel_event *event, uint32_t val)
57{
58 XGL_RESULT ret;
59 uint32_t *ptr;
60
61 ret = event_map(event, &ptr);
62 if (ret == XGL_SUCCESS) {
63 *ptr = val;
64 event_unmap(event);
65 }
66
67 return ret;
68}
69
70static XGL_RESULT event_read(struct intel_event *event, uint32_t *val)
71{
72 XGL_RESULT ret;
73 uint32_t *ptr;
74
75 ret = event_map(event, &ptr);
76 if (ret == XGL_SUCCESS) {
77 *val = *ptr;
78 event_unmap(event);
79 }
80
81 return ret;
82}
83
84static void event_destroy_callback(struct intel_obj *obj)
85{
86 struct intel_event *event = intel_event_from_obj(obj);
87
88 intel_event_destroy(event);
89}
90
91XGL_RESULT intel_event_create(struct intel_dev *dev,
92 const XGL_EVENT_CREATE_INFO *info,
93 struct intel_event **event_ret)
94{
95 struct intel_event *event;
96 XGL_MEMORY_REQUIREMENTS *mem_req;
97
98 event = icd_alloc(sizeof(*event), 0, XGL_SYSTEM_ALLOC_API_OBJECT);
99 if (!event)
100 return XGL_ERROR_OUT_OF_MEMORY;
101
102 memset(event, 0, sizeof(*event));
103
104 event->obj.destroy = event_destroy_callback;
105
106 /* use dword aligned to 64-byte boundaries */
107 mem_req = &event->obj.base.mem_requirements;
108 mem_req->size = 4;
109 mem_req->alignment = 64;
110 mem_req->heapCount = 1;
111 mem_req->heaps[0] = 0;
112
113 event->obj.base.dispatch = dev->base.dispatch;
114 if (dev->base.dbg) {
115 event->obj.base.dbg =
116 intel_base_dbg_create(XGL_DBG_OBJECT_EVENT, info, sizeof(*info));
117 if (!event->obj.base.dbg) {
118 icd_free(event);
119 return XGL_ERROR_OUT_OF_MEMORY;
120 }
121 }
122
123 *event_ret = event;
124
125 return XGL_SUCCESS;
126}
127
128void intel_event_destroy(struct intel_event *event)
129{
130 if (event->obj.base.dbg)
131 intel_base_dbg_destroy(event->obj.base.dbg);
132
133 icd_free(event);
134}
135
136XGL_RESULT intel_event_set(struct intel_event *event)
137{
138 return event_write(event, 1);
139}
140
141XGL_RESULT intel_event_reset(struct intel_event *event)
142{
143 return event_write(event, 0);
144}
145
146XGL_RESULT intel_event_get_status(struct intel_event *event)
147{
148 XGL_RESULT ret;
149 uint32_t val;
150
151 ret = event_read(event, &val);
152 if (ret != XGL_SUCCESS)
153 return ret;
154
155 return (val) ? XGL_EVENT_SET : XGL_EVENT_RESET;
156}
157
158XGL_RESULT XGLAPI intelCreateEvent(
159 XGL_DEVICE device,
160 const XGL_EVENT_CREATE_INFO* pCreateInfo,
161 XGL_EVENT* pEvent)
162{
163 struct intel_dev *dev = intel_dev(device);
164
165 return intel_event_create(dev, pCreateInfo,
166 (struct intel_event **) pEvent);
167}
168
169XGL_RESULT XGLAPI intelGetEventStatus(
170 XGL_EVENT event_)
171{
172 struct intel_event *event = intel_event(event_);
173
174 return intel_event_get_status(event);
175}
176
177XGL_RESULT XGLAPI intelSetEvent(
178 XGL_EVENT event_)
179{
180 struct intel_event *event = intel_event(event_);
181
182 return intel_event_set(event);
183}
184
185XGL_RESULT XGLAPI intelResetEvent(
186 XGL_EVENT event_)
187{
188 struct intel_event *event = intel_event(event_);
189
190 return intel_event_reset(event);
191}