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_api.h"
30 static struct r300_winsys_buffer *
31 radeon_r300_winsys_buffer_create(struct r300_winsys_screen *rws,
36 struct radeon_libdrm_winsys *ws = radeon_winsys_screen(rws);
38 struct pb_manager *provider;
39 struct pb_buffer *buffer;
41 memset(&desc, 0, sizeof(desc));
42 desc.alignment = alignment;
45 if (usage & PIPE_BIND_CONSTANT_BUFFER)
47 else if ((usage & PIPE_BIND_VERTEX_BUFFER) ||
48 (usage & PIPE_BIND_INDEX_BUFFER))
52 buffer = provider->create_buffer(provider, size, &desc);
56 return radeon_libdrm_winsys_buffer(buffer);
59 static void radeon_r300_winsys_buffer_destroy(struct r300_winsys_buffer *buf)
61 struct pb_buffer *_buf = radeon_pb_buffer(buf);
65 static void radeon_r300_winsys_buffer_set_tiling(struct r300_winsys_screen *rws,
66 struct r300_winsys_buffer *buf,
68 enum r300_buffer_tiling microtiled,
69 enum r300_buffer_tiling macrotiled)
71 struct pb_buffer *_buf = radeon_pb_buffer(buf);
72 radeon_drm_bufmgr_set_tiling(_buf, microtiled, macrotiled, pitch);
75 static void radeon_r300_winsys_buffer_get_tiling(struct r300_winsys_screen *rws,
76 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_get_tiling(_buf, microtiled, macrotiled);
84 static void *radeon_r300_winsys_buffer_map(struct r300_winsys_screen *ws,
85 struct r300_winsys_buffer *buf,
88 struct pb_buffer *_buf = radeon_pb_buffer(buf);
90 return pb_map(_buf, usage);
93 static void radeon_r300_winsys_buffer_unmap(struct r300_winsys_screen *ws,
94 struct r300_winsys_buffer *buf)
96 struct pb_buffer *_buf = radeon_pb_buffer(buf);
101 static void radeon_r300_winsys_buffer_reference(struct r300_winsys_screen *rws,
102 struct r300_winsys_buffer **pdst,
103 struct r300_winsys_buffer *src)
105 struct pb_buffer *_src = radeon_pb_buffer(src);
106 struct pb_buffer *_dst = radeon_pb_buffer(*pdst);
108 pb_reference(&_dst, _src);
110 *pdst = radeon_libdrm_winsys_buffer(_dst);
113 static boolean radeon_r300_winsys_is_buffer_referenced(struct r300_winsys_screen *rws,
114 struct r300_winsys_buffer *buf)
116 struct pb_buffer *_buf = radeon_pb_buffer(buf);
118 return radeon_drm_bufmgr_is_buffer_referenced(_buf);
121 static struct r300_winsys_buffer *radeon_r300_winsys_buffer_from_handle(struct r300_winsys_screen *rws,
122 struct pipe_screen *screen,
123 struct winsys_handle *whandle,
126 struct radeon_libdrm_winsys *ws = radeon_winsys_screen(rws);
127 struct pb_buffer *_buf;
129 _buf = radeon_drm_bufmgr_create_buffer_from_handle(ws->kman, whandle->handle);
130 *stride = whandle->stride;
131 return radeon_libdrm_winsys_buffer(_buf);
134 static boolean radeon_r300_winsys_buffer_get_handle(struct r300_winsys_screen *rws,
135 struct r300_winsys_buffer *buffer,
137 struct winsys_handle *whandle)
139 struct pb_buffer *_buf = radeon_pb_buffer(buffer);
141 ret = radeon_drm_bufmgr_get_handle(_buf, whandle);
143 whandle->stride = stride;
147 static void radeon_set_flush_cb(struct r300_winsys_screen *rws,
148 void (*flush_cb)(void *),
151 struct radeon_libdrm_winsys *ws = radeon_winsys_screen(rws);
152 ws->flush_cb = flush_cb;
153 ws->flush_data = data;
154 radeon_cs_space_set_flush(ws->cs, flush_cb, data);
157 static boolean radeon_add_buffer(struct r300_winsys_screen *rws,
158 struct r300_winsys_buffer *buf,
162 struct pb_buffer *_buf = radeon_pb_buffer(buf);
164 return radeon_drm_bufmgr_add_buffer(_buf, rd, wd);
167 static boolean radeon_validate(struct r300_winsys_screen *rws)
169 struct radeon_libdrm_winsys *ws = radeon_winsys_screen(rws);
170 if (radeon_cs_space_check(ws->cs) < 0) {
174 /* Things are fine, we can proceed as normal. */
178 static boolean radeon_check_cs(struct r300_winsys_screen *rws, int size)
180 struct radeon_libdrm_winsys *ws = radeon_winsys_screen(rws);
181 struct radeon_cs *cs = ws->cs;
183 return radeon_validate(rws) && cs->cdw + size <= cs->ndw;
186 static void radeon_begin_cs(struct r300_winsys_screen *rws,
189 const char* function,
192 struct radeon_libdrm_winsys *ws = radeon_winsys_screen(rws);
193 radeon_cs_begin(ws->cs, size, file, function, line);
196 static void radeon_write_cs_dword(struct r300_winsys_screen *rws,
199 struct radeon_libdrm_winsys *ws = radeon_winsys_screen(rws);
200 radeon_cs_write_dword(ws->cs, dword);
203 static void radeon_write_cs_reloc(struct r300_winsys_screen *rws,
204 struct r300_winsys_buffer *buf,
209 struct pb_buffer *_buf = radeon_pb_buffer(buf);
210 radeon_drm_bufmgr_write_reloc(_buf, rd, wd, flags);
213 static void radeon_reset_bos(struct r300_winsys_screen *rws)
215 struct radeon_libdrm_winsys *ws = radeon_winsys_screen(rws);
216 radeon_cs_space_reset_bos(ws->cs);
219 static void radeon_end_cs(struct r300_winsys_screen *rws,
221 const char* function,
224 struct radeon_libdrm_winsys *ws = radeon_winsys_screen(rws);
225 radeon_cs_end(ws->cs, file, function, line);
228 static void radeon_flush_cs(struct r300_winsys_screen *rws)
230 struct radeon_libdrm_winsys *ws = radeon_winsys_screen(rws);
233 /* Don't flush a zero-sized CS. */
238 radeon_drm_bufmgr_flush_maps(ws->kman);
240 retval = radeon_cs_emit(ws->cs);
242 debug_printf("radeon: Bad CS, dumping...\n");
243 radeon_cs_print(ws->cs, stderr);
247 * Someday, when we care about performance, we should really find a way
248 * to rotate between two or three CS objects so that the GPU can be
249 * spinning through one CS while another one is being filled. */
250 radeon_cs_erase(ws->cs);
253 static uint32_t radeon_get_value(struct r300_winsys_screen *rws,
254 enum r300_value_id id)
256 struct radeon_libdrm_winsys *ws = (struct radeon_libdrm_winsys *)rws;
259 case R300_VID_PCI_ID:
261 case R300_VID_GB_PIPES:
263 case R300_VID_Z_PIPES:
265 case R300_VID_SQUARE_TILING_SUPPORT:
266 return ws->squaretiling;
272 radeon_winsys_destroy(struct r300_winsys_screen *rws)
274 struct radeon_libdrm_winsys *ws = (struct radeon_libdrm_winsys *)rws;
275 radeon_cs_destroy(ws->cs);
277 ws->cman->destroy(ws->cman);
278 ws->kman->destroy(ws->kman);
279 ws->mman->destroy(ws->mman);
281 radeon_bo_manager_gem_dtor(ws->bom);
282 radeon_cs_manager_gem_dtor(ws->csm);
286 radeon_setup_winsys(int fd, struct radeon_libdrm_winsys* ws)
289 ws->csm = radeon_cs_manager_gem_ctor(fd);
292 ws->bom = radeon_bo_manager_gem_ctor(fd);
295 ws->kman = radeon_drm_bufmgr_create(ws);
299 ws->cman = pb_cache_manager_create(ws->kman, 100000);
303 ws->mman = pb_malloc_bufmgr_create();
307 /* Size limit on IBs is 64 kibibytes. */
308 ws->cs = radeon_cs_create(ws->csm, 1024 * 64 / 4);
311 radeon_cs_set_limit(ws->cs,
312 RADEON_GEM_DOMAIN_GTT, ws->gart_size);
313 radeon_cs_set_limit(ws->cs,
314 RADEON_GEM_DOMAIN_VRAM, ws->vram_size);
316 ws->base.add_buffer = radeon_add_buffer;
317 ws->base.validate = radeon_validate;
318 ws->base.destroy = radeon_winsys_destroy;
319 ws->base.check_cs = radeon_check_cs;
320 ws->base.begin_cs = radeon_begin_cs;
321 ws->base.write_cs_dword = radeon_write_cs_dword;
322 ws->base.write_cs_reloc = radeon_write_cs_reloc;
323 ws->base.end_cs = radeon_end_cs;
324 ws->base.flush_cs = radeon_flush_cs;
325 ws->base.reset_bos = radeon_reset_bos;
326 ws->base.set_flush_cb = radeon_set_flush_cb;
327 ws->base.get_value = radeon_get_value;
329 ws->base.buffer_create = radeon_r300_winsys_buffer_create;
330 ws->base.buffer_destroy = radeon_r300_winsys_buffer_destroy;
331 ws->base.buffer_set_tiling = radeon_r300_winsys_buffer_set_tiling;
332 ws->base.buffer_get_tiling = radeon_r300_winsys_buffer_get_tiling;
333 ws->base.buffer_map = radeon_r300_winsys_buffer_map;
334 ws->base.buffer_unmap = radeon_r300_winsys_buffer_unmap;
335 ws->base.buffer_reference = radeon_r300_winsys_buffer_reference;
336 ws->base.buffer_from_handle = radeon_r300_winsys_buffer_from_handle;
337 ws->base.buffer_get_handle = radeon_r300_winsys_buffer_get_handle;
338 ws->base.is_buffer_referenced = radeon_r300_winsys_is_buffer_referenced;
343 radeon_cs_manager_gem_dtor(ws->csm);
346 radeon_bo_manager_gem_dtor(ws->bom);
349 ws->cman->destroy(ws->cman);
351 ws->kman->destroy(ws->kman);
353 ws->mman->destroy(ws->mman);
356 radeon_cs_destroy(ws->cs);