2 * Copyright 2008 Corbin Simpson <MostAwesomeDude@gmail.com>
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),
6 * to deal in the Software without restriction, including without limitation
7 * on the rights to use, copy, modify, merge, publish, distribute, sub
8 * license, and/or sell copies of the Software, and to permit persons to whom
9 * the Software is furnished to do so, subject to the following conditions:
11 * The above copyright notice and this permission notice (including the next
12 * paragraph) shall be included in all copies or substantial portions of the
15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
18 * THE AUTHOR(S) AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM,
19 * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
20 * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
21 * USE OR OTHER DEALINGS IN THE SOFTWARE. */
23 #include "radeon_r300.h"
24 #include "radeon_buffer.h"
26 #include "radeon_bo_gem.h"
27 #include "radeon_cs_gem.h"
28 #include "state_tracker/drm_driver.h"
30 static struct r300_winsys_buffer
*
31 radeon_r300_winsys_buffer_create(struct r300_winsys_screen
*rws
,
34 enum r300_buffer_domain domain
,
37 struct radeon_libdrm_winsys
*ws
= radeon_winsys_screen(rws
);
39 struct pb_manager
*provider
;
40 struct pb_buffer
*buffer
;
42 /* XXX this is hackish, but it's the only way to pass these flags
43 * to the real create function. */
44 usage
&= ~(RADEON_USAGE_DOMAIN_GTT
| RADEON_USAGE_DOMAIN_VRAM
);
45 if (domain
& R300_DOMAIN_GTT
)
46 usage
|= RADEON_USAGE_DOMAIN_GTT
;
47 if (domain
& R300_DOMAIN_VRAM
)
48 usage
|= RADEON_USAGE_DOMAIN_VRAM
;
50 memset(&desc
, 0, sizeof(desc
));
51 desc
.alignment
= alignment
;
54 if (usage
& PIPE_BIND_CONSTANT_BUFFER
)
56 else if ((usage
& PIPE_BIND_VERTEX_BUFFER
) ||
57 (usage
& PIPE_BIND_INDEX_BUFFER
))
61 buffer
= provider
->create_buffer(provider
, size
, &desc
);
65 return radeon_libdrm_winsys_buffer(buffer
);
68 static void radeon_r300_winsys_buffer_destroy(struct r300_winsys_buffer
*buf
)
70 struct pb_buffer
*_buf
= radeon_pb_buffer(buf
);
74 static void radeon_r300_winsys_buffer_set_tiling(struct r300_winsys_screen
*rws
,
75 struct r300_winsys_buffer
*buf
,
77 enum r300_buffer_tiling microtiled
,
78 enum r300_buffer_tiling macrotiled
)
80 struct pb_buffer
*_buf
= radeon_pb_buffer(buf
);
81 radeon_drm_bufmgr_set_tiling(_buf
, microtiled
, macrotiled
, pitch
);
84 static void radeon_r300_winsys_buffer_get_tiling(struct r300_winsys_screen
*rws
,
85 struct r300_winsys_buffer
*buf
,
86 enum r300_buffer_tiling
*microtiled
,
87 enum r300_buffer_tiling
*macrotiled
)
89 struct pb_buffer
*_buf
= radeon_pb_buffer(buf
);
90 radeon_drm_bufmgr_get_tiling(_buf
, microtiled
, macrotiled
);
93 static void *radeon_r300_winsys_buffer_map(struct r300_winsys_screen
*ws
,
94 struct r300_winsys_buffer
*buf
,
97 struct pb_buffer
*_buf
= radeon_pb_buffer(buf
);
99 return pb_map(_buf
, usage
);
102 static void radeon_r300_winsys_buffer_unmap(struct r300_winsys_screen
*ws
,
103 struct r300_winsys_buffer
*buf
)
105 struct pb_buffer
*_buf
= radeon_pb_buffer(buf
);
110 static void radeon_r300_winsys_buffer_wait(struct r300_winsys_screen
*ws
,
111 struct r300_winsys_buffer
*buf
)
113 struct pb_buffer
*_buf
= radeon_pb_buffer(buf
);
114 radeon_drm_bufmgr_wait(_buf
);
117 static void radeon_r300_winsys_buffer_reference(struct r300_winsys_screen
*rws
,
118 struct r300_winsys_buffer
**pdst
,
119 struct r300_winsys_buffer
*src
)
121 struct pb_buffer
*_src
= radeon_pb_buffer(src
);
122 struct pb_buffer
*_dst
= radeon_pb_buffer(*pdst
);
124 pb_reference(&_dst
, _src
);
126 *pdst
= radeon_libdrm_winsys_buffer(_dst
);
129 static boolean
radeon_r300_winsys_is_buffer_referenced(struct r300_winsys_screen
*rws
,
130 struct r300_winsys_buffer
*buf
,
131 enum r300_reference_domain domain
)
133 struct pb_buffer
*_buf
= radeon_pb_buffer(buf
);
135 return radeon_drm_bufmgr_is_buffer_referenced(_buf
, domain
);
138 static struct r300_winsys_buffer
*radeon_r300_winsys_buffer_from_handle(struct r300_winsys_screen
*rws
,
139 struct pipe_screen
*screen
,
140 struct winsys_handle
*whandle
,
143 struct radeon_libdrm_winsys
*ws
= radeon_winsys_screen(rws
);
144 struct pb_buffer
*_buf
;
146 _buf
= radeon_drm_bufmgr_create_buffer_from_handle(ws
->kman
, whandle
->handle
);
147 *stride
= whandle
->stride
;
148 return radeon_libdrm_winsys_buffer(_buf
);
151 static boolean
radeon_r300_winsys_buffer_get_handle(struct r300_winsys_screen
*rws
,
152 struct r300_winsys_buffer
*buffer
,
154 struct winsys_handle
*whandle
)
156 struct pb_buffer
*_buf
= radeon_pb_buffer(buffer
);
158 ret
= radeon_drm_bufmgr_get_handle(_buf
, whandle
);
160 whandle
->stride
= stride
;
164 static void radeon_set_flush_cb(struct r300_winsys_screen
*rws
,
165 void (*flush_cb
)(void *),
168 struct radeon_libdrm_winsys
*ws
= radeon_winsys_screen(rws
);
169 ws
->flush_cb
= flush_cb
;
170 ws
->flush_data
= data
;
171 radeon_cs_space_set_flush(ws
->cs
, flush_cb
, data
);
174 static boolean
radeon_add_buffer(struct r300_winsys_screen
*rws
,
175 struct r300_winsys_buffer
*buf
,
176 enum r300_buffer_domain rd
,
177 enum r300_buffer_domain wd
)
179 struct pb_buffer
*_buf
= radeon_pb_buffer(buf
);
181 return radeon_drm_bufmgr_add_buffer(_buf
, rd
, wd
);
184 static boolean
radeon_validate(struct r300_winsys_screen
*rws
)
186 struct radeon_libdrm_winsys
*ws
= radeon_winsys_screen(rws
);
187 if (radeon_cs_space_check(ws
->cs
) < 0) {
191 /* Things are fine, we can proceed as normal. */
195 static void radeon_get_cs_info(struct r300_winsys_screen
*rws
,
196 struct r300_cs_info
*info
)
198 struct radeon_libdrm_winsys
*ws
= radeon_winsys_screen(rws
);
199 struct radeon_cs
*cs
= ws
->cs
;
201 info
->capacity
= cs
->ndw
;
202 info
->used
= cs
->cdw
;
203 info
->free
= cs
->ndw
- cs
->cdw
;
206 static void radeon_begin_cs(struct r300_winsys_screen
*rws
,
209 const char* function
,
212 struct radeon_libdrm_winsys
*ws
= radeon_winsys_screen(rws
);
213 radeon_cs_begin(ws
->cs
, size
, file
, function
, line
);
216 static void radeon_write_cs_dword(struct r300_winsys_screen
*rws
,
219 struct radeon_libdrm_winsys
*ws
= radeon_winsys_screen(rws
);
220 radeon_cs_write_dword(ws
->cs
, dword
);
223 static void radeon_write_cs_table(struct r300_winsys_screen
*rws
,
224 const void *table
, unsigned count
)
226 struct radeon_libdrm_winsys
*ws
= radeon_winsys_screen(rws
);
227 radeon_cs_write_table(ws
->cs
, table
, count
);
230 static void radeon_write_cs_reloc(struct r300_winsys_screen
*rws
,
231 struct r300_winsys_buffer
*buf
,
232 enum r300_buffer_domain rd
,
233 enum r300_buffer_domain wd
,
236 struct pb_buffer
*_buf
= radeon_pb_buffer(buf
);
237 radeon_drm_bufmgr_write_reloc(_buf
, rd
, wd
, flags
);
240 static void radeon_reset_bos(struct r300_winsys_screen
*rws
)
242 struct radeon_libdrm_winsys
*ws
= radeon_winsys_screen(rws
);
243 radeon_cs_space_reset_bos(ws
->cs
);
246 static void radeon_end_cs(struct r300_winsys_screen
*rws
,
248 const char* function
,
251 struct radeon_libdrm_winsys
*ws
= radeon_winsys_screen(rws
);
252 radeon_cs_end(ws
->cs
, file
, function
, line
);
255 static void radeon_flush_cs(struct r300_winsys_screen
*rws
)
257 struct radeon_libdrm_winsys
*ws
= radeon_winsys_screen(rws
);
260 /* Don't flush a zero-sized CS. */
265 radeon_drm_bufmgr_flush_maps(ws
->kman
);
267 retval
= radeon_cs_emit(ws
->cs
);
269 debug_printf("radeon: Bad CS, dumping...\n");
270 radeon_cs_print(ws
->cs
, stderr
);
274 * Someday, when we care about performance, we should really find a way
275 * to rotate between two or three CS objects so that the GPU can be
276 * spinning through one CS while another one is being filled. */
277 radeon_cs_erase(ws
->cs
);
280 static uint32_t radeon_get_value(struct r300_winsys_screen
*rws
,
281 enum r300_value_id id
)
283 struct radeon_libdrm_winsys
*ws
= (struct radeon_libdrm_winsys
*)rws
;
286 case R300_VID_PCI_ID
:
288 case R300_VID_GB_PIPES
:
290 case R300_VID_Z_PIPES
:
292 case R300_VID_SQUARE_TILING_SUPPORT
:
293 return ws
->squaretiling
;
294 case R300_VID_DRM_2_3_0
:
295 return ws
->drm_2_3_0
;
301 radeon_winsys_destroy(struct r300_winsys_screen
*rws
)
303 struct radeon_libdrm_winsys
*ws
= (struct radeon_libdrm_winsys
*)rws
;
304 radeon_cs_destroy(ws
->cs
);
306 ws
->cman
->destroy(ws
->cman
);
307 ws
->kman
->destroy(ws
->kman
);
308 ws
->mman
->destroy(ws
->mman
);
310 radeon_bo_manager_gem_dtor(ws
->bom
);
311 radeon_cs_manager_gem_dtor(ws
->csm
);
315 radeon_setup_winsys(int fd
, struct radeon_libdrm_winsys
* ws
)
318 ws
->csm
= radeon_cs_manager_gem_ctor(fd
);
321 ws
->bom
= radeon_bo_manager_gem_ctor(fd
);
324 ws
->kman
= radeon_drm_bufmgr_create(ws
);
328 ws
->cman
= pb_cache_manager_create(ws
->kman
, 100000);
332 ws
->mman
= pb_malloc_bufmgr_create();
336 /* Size limit on IBs is 64 kibibytes. */
337 ws
->cs
= radeon_cs_create(ws
->csm
, 1024 * 64 / 4);
340 radeon_cs_set_limit(ws
->cs
,
341 RADEON_GEM_DOMAIN_GTT
, ws
->gart_size
);
342 radeon_cs_set_limit(ws
->cs
,
343 RADEON_GEM_DOMAIN_VRAM
, ws
->vram_size
);
345 ws
->base
.add_buffer
= radeon_add_buffer
;
346 ws
->base
.validate
= radeon_validate
;
347 ws
->base
.destroy
= radeon_winsys_destroy
;
348 ws
->base
.get_cs_info
= radeon_get_cs_info
;
349 ws
->base
.begin_cs
= radeon_begin_cs
;
350 ws
->base
.write_cs_dword
= radeon_write_cs_dword
;
351 ws
->base
.write_cs_table
= radeon_write_cs_table
;
352 ws
->base
.write_cs_reloc
= radeon_write_cs_reloc
;
353 ws
->base
.end_cs
= radeon_end_cs
;
354 ws
->base
.flush_cs
= radeon_flush_cs
;
355 ws
->base
.reset_bos
= radeon_reset_bos
;
356 ws
->base
.set_flush_cb
= radeon_set_flush_cb
;
357 ws
->base
.get_value
= radeon_get_value
;
359 ws
->base
.buffer_create
= radeon_r300_winsys_buffer_create
;
360 ws
->base
.buffer_destroy
= radeon_r300_winsys_buffer_destroy
;
361 ws
->base
.buffer_set_tiling
= radeon_r300_winsys_buffer_set_tiling
;
362 ws
->base
.buffer_get_tiling
= radeon_r300_winsys_buffer_get_tiling
;
363 ws
->base
.buffer_map
= radeon_r300_winsys_buffer_map
;
364 ws
->base
.buffer_unmap
= radeon_r300_winsys_buffer_unmap
;
365 ws
->base
.buffer_wait
= radeon_r300_winsys_buffer_wait
;
366 ws
->base
.buffer_reference
= radeon_r300_winsys_buffer_reference
;
367 ws
->base
.buffer_from_handle
= radeon_r300_winsys_buffer_from_handle
;
368 ws
->base
.buffer_get_handle
= radeon_r300_winsys_buffer_get_handle
;
369 ws
->base
.is_buffer_referenced
= radeon_r300_winsys_is_buffer_referenced
;
374 radeon_cs_manager_gem_dtor(ws
->csm
);
377 radeon_bo_manager_gem_dtor(ws
->bom
);
380 ws
->cman
->destroy(ws
->cman
);
382 ws
->kman
->destroy(ws
->kman
);
384 ws
->mman
->destroy(ws
->mman
);
387 radeon_cs_destroy(ws
->cs
);