1 | /*
|
---|
2 | * Copyright © 2008 Nicolai Haehnle
|
---|
3 | * Copyright © 2008 Jérôme Glisse
|
---|
4 | * All Rights Reserved.
|
---|
5 | *
|
---|
6 | * Permission is hereby granted, free of charge, to any person obtaining a
|
---|
7 | * copy of this software and associated documentation files (the
|
---|
8 | * "Software"), to deal in the Software without restriction, including
|
---|
9 | * without limitation the rights to use, copy, modify, merge, publish,
|
---|
10 | * distribute, sub license, and/or sell copies of the Software, and to
|
---|
11 | * permit persons to whom the Software is furnished to do so, subject to
|
---|
12 | * the following conditions:
|
---|
13 | *
|
---|
14 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
---|
15 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
---|
16 | * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
|
---|
17 | * THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM,
|
---|
18 | * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
|
---|
19 | * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
|
---|
20 | * USE OR OTHER DEALINGS IN THE SOFTWARE.
|
---|
21 | *
|
---|
22 | * The above copyright notice and this permission notice (including the
|
---|
23 | * next paragraph) shall be included in all copies or substantial portions
|
---|
24 | * of the Software.
|
---|
25 | */
|
---|
26 | /*
|
---|
27 | * Authors:
|
---|
28 | * Aapo Tahkola <[email protected]>
|
---|
29 | * Nicolai Haehnle <[email protected]>
|
---|
30 | * Jérôme Glisse <[email protected]>
|
---|
31 | */
|
---|
32 | #ifndef RADEON_CS_H
|
---|
33 | #define RADEON_CS_H
|
---|
34 |
|
---|
35 | #include <stdint.h>
|
---|
36 | #include <string.h>
|
---|
37 | #include "drm.h"
|
---|
38 | #include "radeon_drm.h"
|
---|
39 | #include "radeon_bo.h"
|
---|
40 |
|
---|
41 | struct radeon_cs_reloc {
|
---|
42 | struct radeon_bo *bo;
|
---|
43 | uint32_t read_domain;
|
---|
44 | uint32_t write_domain;
|
---|
45 | uint32_t flags;
|
---|
46 | };
|
---|
47 |
|
---|
48 |
|
---|
49 | #define RADEON_CS_SPACE_OK 0
|
---|
50 | #define RADEON_CS_SPACE_OP_TO_BIG 1
|
---|
51 | #define RADEON_CS_SPACE_FLUSH 2
|
---|
52 |
|
---|
53 | struct radeon_cs_space_check {
|
---|
54 | struct radeon_bo *bo;
|
---|
55 | uint32_t read_domains;
|
---|
56 | uint32_t write_domain;
|
---|
57 | uint32_t new_accounted;
|
---|
58 | };
|
---|
59 |
|
---|
60 | #define MAX_SPACE_BOS (32)
|
---|
61 |
|
---|
62 | struct radeon_cs_manager;
|
---|
63 |
|
---|
64 | struct radeon_cs {
|
---|
65 | struct radeon_cs_manager *csm;
|
---|
66 | void *relocs;
|
---|
67 | uint32_t *packets;
|
---|
68 | unsigned crelocs;
|
---|
69 | unsigned relocs_total_size;
|
---|
70 | unsigned cdw;
|
---|
71 | unsigned ndw;
|
---|
72 | int section;
|
---|
73 | unsigned section_ndw;
|
---|
74 | unsigned section_cdw;
|
---|
75 | const char *section_file;
|
---|
76 | const char *section_func;
|
---|
77 | int section_line;
|
---|
78 | struct radeon_cs_space_check bos[MAX_SPACE_BOS];
|
---|
79 | int bo_count;
|
---|
80 | void (*space_flush_fn)(void *);
|
---|
81 | void *space_flush_data;
|
---|
82 | };
|
---|
83 |
|
---|
84 | /* cs functions */
|
---|
85 | struct radeon_cs_funcs {
|
---|
86 | struct radeon_cs *(*cs_create)(struct radeon_cs_manager *csm,
|
---|
87 | uint32_t ndw);
|
---|
88 | int (*cs_write_reloc)(struct radeon_cs *cs,
|
---|
89 | struct radeon_bo *bo,
|
---|
90 | uint32_t read_domain,
|
---|
91 | uint32_t write_domain,
|
---|
92 | uint32_t flags);
|
---|
93 | int (*cs_begin)(struct radeon_cs *cs,
|
---|
94 | uint32_t ndw,
|
---|
95 | const char *file,
|
---|
96 | const char *func,
|
---|
97 | int line);
|
---|
98 | int (*cs_end)(struct radeon_cs *cs,
|
---|
99 | const char *file,
|
---|
100 | const char *func,
|
---|
101 | int line);
|
---|
102 | int (*cs_emit)(struct radeon_cs *cs);
|
---|
103 | int (*cs_destroy)(struct radeon_cs *cs);
|
---|
104 | int (*cs_erase)(struct radeon_cs *cs);
|
---|
105 | int (*cs_need_flush)(struct radeon_cs *cs);
|
---|
106 | void (*cs_print)(struct radeon_cs *cs, FILE *file);
|
---|
107 | };
|
---|
108 |
|
---|
109 | struct radeon_cs_manager {
|
---|
110 | struct radeon_cs_funcs *funcs;
|
---|
111 | int fd;
|
---|
112 | int32_t vram_limit, gart_limit;
|
---|
113 | int32_t vram_write_used, gart_write_used;
|
---|
114 | int32_t read_used;
|
---|
115 | };
|
---|
116 |
|
---|
117 | static inline struct radeon_cs *radeon_cs_create(struct radeon_cs_manager *csm,
|
---|
118 | uint32_t ndw)
|
---|
119 | {
|
---|
120 | return csm->funcs->cs_create(csm, ndw);
|
---|
121 | }
|
---|
122 |
|
---|
123 | static inline int radeon_cs_write_reloc(struct radeon_cs *cs,
|
---|
124 | struct radeon_bo *bo,
|
---|
125 | uint32_t read_domain,
|
---|
126 | uint32_t write_domain,
|
---|
127 | uint32_t flags)
|
---|
128 | {
|
---|
129 | return cs->csm->funcs->cs_write_reloc(cs,
|
---|
130 | bo,
|
---|
131 | read_domain,
|
---|
132 | write_domain,
|
---|
133 | flags);
|
---|
134 | }
|
---|
135 |
|
---|
136 | static inline int radeon_cs_begin(struct radeon_cs *cs,
|
---|
137 | uint32_t ndw,
|
---|
138 | const char *file,
|
---|
139 | const char *func,
|
---|
140 | int line)
|
---|
141 | {
|
---|
142 | return cs->csm->funcs->cs_begin(cs, ndw, file, func, line);
|
---|
143 | }
|
---|
144 |
|
---|
145 | static inline int radeon_cs_end(struct radeon_cs *cs,
|
---|
146 | const char *file,
|
---|
147 | const char *func,
|
---|
148 | int line)
|
---|
149 | {
|
---|
150 | return cs->csm->funcs->cs_end(cs, file, func, line);
|
---|
151 | }
|
---|
152 |
|
---|
153 | static inline int radeon_cs_emit(struct radeon_cs *cs)
|
---|
154 | {
|
---|
155 | return cs->csm->funcs->cs_emit(cs);
|
---|
156 | }
|
---|
157 |
|
---|
158 | static inline int radeon_cs_destroy(struct radeon_cs *cs)
|
---|
159 | {
|
---|
160 | return cs->csm->funcs->cs_destroy(cs);
|
---|
161 | }
|
---|
162 |
|
---|
163 | static inline int radeon_cs_erase(struct radeon_cs *cs)
|
---|
164 | {
|
---|
165 | return cs->csm->funcs->cs_erase(cs);
|
---|
166 | }
|
---|
167 |
|
---|
168 | static inline int radeon_cs_need_flush(struct radeon_cs *cs)
|
---|
169 | {
|
---|
170 | return cs->csm->funcs->cs_need_flush(cs);
|
---|
171 | }
|
---|
172 |
|
---|
173 | static inline void radeon_cs_print(struct radeon_cs *cs, FILE *file)
|
---|
174 | {
|
---|
175 | cs->csm->funcs->cs_print(cs, file);
|
---|
176 | }
|
---|
177 |
|
---|
178 | static inline void radeon_cs_set_limit(struct radeon_cs *cs, uint32_t domain, uint32_t limit)
|
---|
179 | {
|
---|
180 |
|
---|
181 | if (domain == RADEON_GEM_DOMAIN_VRAM)
|
---|
182 | cs->csm->vram_limit = limit;
|
---|
183 | else
|
---|
184 | cs->csm->gart_limit = limit;
|
---|
185 | }
|
---|
186 |
|
---|
187 | static inline void radeon_cs_write_dword(struct radeon_cs *cs, uint32_t dword)
|
---|
188 | {
|
---|
189 | cs->packets[cs->cdw++] = dword;
|
---|
190 | if (cs->section) {
|
---|
191 | cs->section_cdw++;
|
---|
192 | }
|
---|
193 | }
|
---|
194 |
|
---|
195 | static inline void radeon_cs_write_qword(struct radeon_cs *cs, uint64_t qword)
|
---|
196 | {
|
---|
197 | memcpy(cs->packets + cs->cdw, &qword, sizeof(uint64_t));
|
---|
198 | cs->cdw += 2;
|
---|
199 | if (cs->section) {
|
---|
200 | cs->section_cdw += 2;
|
---|
201 | }
|
---|
202 | }
|
---|
203 |
|
---|
204 | static inline void radeon_cs_write_table(struct radeon_cs *cs, void *data, uint32_t size)
|
---|
205 | {
|
---|
206 | memcpy(cs->packets + cs->cdw, data, size * 4);
|
---|
207 | cs->cdw += size;
|
---|
208 | if (cs->section) {
|
---|
209 | cs->section_cdw += size;
|
---|
210 | }
|
---|
211 | }
|
---|
212 |
|
---|
213 | static inline void radeon_cs_space_set_flush(struct radeon_cs *cs, void (*fn)(void *), void *data)
|
---|
214 | {
|
---|
215 | cs->space_flush_fn = fn;
|
---|
216 | cs->space_flush_data = data;
|
---|
217 | }
|
---|
218 |
|
---|
219 |
|
---|
220 | /*
|
---|
221 | * add a persistent BO to the list
|
---|
222 | * a persistent BO is one that will be referenced across flushes,
|
---|
223 | * i.e. colorbuffer, textures etc.
|
---|
224 | * They get reset when a new "operation" happens, where an operation
|
---|
225 | * is a state emission with a color/textures etc followed by a bunch of vertices.
|
---|
226 | */
|
---|
227 | void radeon_cs_space_add_persistent_bo(struct radeon_cs *cs,
|
---|
228 | struct radeon_bo *bo,
|
---|
229 | uint32_t read_domains,
|
---|
230 | uint32_t write_domain);
|
---|
231 |
|
---|
232 | /* reset the persistent BO list */
|
---|
233 | void radeon_cs_space_reset_bos(struct radeon_cs *cs);
|
---|
234 |
|
---|
235 | /* do a space check with the current persistent BO list */
|
---|
236 | int radeon_cs_space_check(struct radeon_cs *cs);
|
---|
237 |
|
---|
238 | /* do a space check with the current persistent BO list and a temporary BO
|
---|
239 | * a temporary BO is like a DMA buffer, which gets flushed with the
|
---|
240 | * command buffer */
|
---|
241 | int radeon_cs_space_check_with_bo(struct radeon_cs *cs,
|
---|
242 | struct radeon_bo *bo,
|
---|
243 | uint32_t read_domains,
|
---|
244 | uint32_t write_domain);
|
---|
245 |
|
---|
246 | #endif
|
---|