2 * Copyright © 2008 Nicolai Haehnle
3 * Copyright © 2008 Jérôme Glisse
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:
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.
22 * The above copyright notice and this permission notice (including the
23 * next paragraph) shall be included in all copies or substantial portions
28 * Aapo Tahkola <aet@rasterburn.org>
29 * Nicolai Haehnle <prefect_@gmx.net>
30 * Jérôme Glisse <glisse@freedesktop.org>
38 #include "radeon_drm.h"
40 struct radeon_cs_reloc
{
43 uint32_t write_domain
;
48 #define RADEON_CS_SPACE_OK 0
49 #define RADEON_CS_SPACE_OP_TO_BIG 1
50 #define RADEON_CS_SPACE_FLUSH 2
52 struct radeon_cs_space_check
{
54 uint32_t read_domains
;
55 uint32_t write_domain
;
56 uint32_t new_accounted
;
59 #define MAX_SPACE_BOS (32)
61 struct radeon_cs_manager
;
64 struct radeon_cs_manager
*csm
;
68 unsigned relocs_total_size
;
74 const char *section_file
;
75 const char *section_func
;
77 struct radeon_cs_space_check bos
[MAX_SPACE_BOS
];
79 void (*space_flush_fn
)(void *);
80 void *space_flush_data
;
84 struct radeon_cs_funcs
{
85 struct radeon_cs
*(*cs_create
)(struct radeon_cs_manager
*csm
,
87 int (*cs_write_reloc
)(struct radeon_cs
*cs
,
90 uint32_t write_domain
,
92 int (*cs_begin
)(struct radeon_cs
*cs
,
97 int (*cs_end
)(struct radeon_cs
*cs
,
101 int (*cs_emit
)(struct radeon_cs
*cs
);
102 int (*cs_destroy
)(struct radeon_cs
*cs
);
103 int (*cs_erase
)(struct radeon_cs
*cs
);
104 int (*cs_need_flush
)(struct radeon_cs
*cs
);
105 void (*cs_print
)(struct radeon_cs
*cs
, FILE *file
);
108 struct radeon_cs_manager
{
109 struct radeon_cs_funcs
*funcs
;
111 int32_t vram_limit
, gart_limit
;
112 int32_t vram_write_used
, gart_write_used
;
116 static inline struct radeon_cs
*radeon_cs_create(struct radeon_cs_manager
*csm
,
119 return csm
->funcs
->cs_create(csm
, ndw
);
122 static inline int radeon_cs_write_reloc(struct radeon_cs
*cs
,
123 struct radeon_bo
*bo
,
124 uint32_t read_domain
,
125 uint32_t write_domain
,
128 return cs
->csm
->funcs
->cs_write_reloc(cs
,
135 static inline int radeon_cs_begin(struct radeon_cs
*cs
,
141 return cs
->csm
->funcs
->cs_begin(cs
, ndw
, file
, func
, line
);
144 static inline int radeon_cs_end(struct radeon_cs
*cs
,
149 return cs
->csm
->funcs
->cs_end(cs
, file
, func
, line
);
152 static inline int radeon_cs_emit(struct radeon_cs
*cs
)
154 return cs
->csm
->funcs
->cs_emit(cs
);
157 static inline int radeon_cs_destroy(struct radeon_cs
*cs
)
159 return cs
->csm
->funcs
->cs_destroy(cs
);
162 static inline int radeon_cs_erase(struct radeon_cs
*cs
)
164 return cs
->csm
->funcs
->cs_erase(cs
);
167 static inline int radeon_cs_need_flush(struct radeon_cs
*cs
)
169 return cs
->csm
->funcs
->cs_need_flush(cs
);
172 static inline void radeon_cs_print(struct radeon_cs
*cs
, FILE *file
)
174 cs
->csm
->funcs
->cs_print(cs
, file
);
177 static inline void radeon_cs_set_limit(struct radeon_cs
*cs
, uint32_t domain
, uint32_t limit
)
180 if (domain
== RADEON_GEM_DOMAIN_VRAM
)
181 cs
->csm
->vram_limit
= limit
;
183 cs
->csm
->gart_limit
= limit
;
186 static inline void radeon_cs_write_dword(struct radeon_cs
*cs
, uint32_t dword
)
188 cs
->packets
[cs
->cdw
++] = dword
;
194 static inline void radeon_cs_write_qword(struct radeon_cs
*cs
, uint64_t qword
)
197 memcpy(cs
->packets
+ cs
->cdw
, &qword
, sizeof(qword
));
204 static inline void radeon_cs_write_table(struct radeon_cs
*cs
, void *data
, uint32_t size
)
206 memcpy(cs
->packets
+ cs
->cdw
, data
, size
* 4);
209 cs
->section_cdw
+= size
;
213 static inline void radeon_cs_space_set_flush(struct radeon_cs
*cs
, void (*fn
)(void *), void *data
)
215 cs
->space_flush_fn
= fn
;
216 cs
->space_flush_data
= data
;
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.
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
);
232 /* reset the persistent BO list */
233 void radeon_cs_space_reset_bos(struct radeon_cs
*cs
);
235 /* do a space check with the current persistent BO list */
236 int radeon_cs_space_check(struct radeon_cs
*cs
);
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
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
);