r300g: rework command submission and resource space checking
[mesa.git] / src / gallium / winsys / radeon / drm / radeon_r300.c
1 /*
2 * Copyright 2008 Corbin Simpson <MostAwesomeDude@gmail.com>
3 *
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:
10 *
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
13 * Software.
14 *
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. */
22
23 #include "radeon_drm_buffer.h"
24
25 #include "util/u_memory.h"
26 #include "pipebuffer/pb_bufmgr.h"
27
28 #include "state_tracker/drm_driver.h"
29
30 static unsigned get_pb_usage_from_create_flags(unsigned bind, unsigned usage,
31 enum r300_buffer_domain domain)
32 {
33 unsigned res = 0;
34
35 if (bind & (PIPE_BIND_DEPTH_STENCIL | PIPE_BIND_RENDER_TARGET |
36 PIPE_BIND_DISPLAY_TARGET | PIPE_BIND_SCANOUT))
37 res |= PB_USAGE_GPU_WRITE;
38
39 if (bind & PIPE_BIND_SAMPLER_VIEW)
40 res |= PB_USAGE_GPU_READ | PB_USAGE_GPU_WRITE;
41
42 if (bind & (PIPE_BIND_VERTEX_BUFFER | PIPE_BIND_INDEX_BUFFER))
43 res |= PB_USAGE_GPU_READ;
44
45 if (bind & PIPE_BIND_TRANSFER_WRITE)
46 res |= PB_USAGE_CPU_WRITE;
47
48 if (bind & PIPE_BIND_TRANSFER_READ)
49 res |= PB_USAGE_CPU_READ;
50
51 /* Is usage of any use for us? Probably not. */
52
53 /* Now add driver-specific usage flags. */
54 if (bind & (PIPE_BIND_VERTEX_BUFFER | PIPE_BIND_INDEX_BUFFER))
55 res |= RADEON_PB_USAGE_VERTEX;
56
57 if (domain & R300_DOMAIN_GTT)
58 res |= RADEON_PB_USAGE_DOMAIN_GTT;
59
60 if (domain & R300_DOMAIN_VRAM)
61 res |= RADEON_PB_USAGE_DOMAIN_VRAM;
62
63 return res;
64 }
65
66 static struct r300_winsys_buffer *
67 radeon_r300_winsys_buffer_create(struct r300_winsys_screen *rws,
68 unsigned size,
69 unsigned alignment,
70 unsigned bind,
71 unsigned usage,
72 enum r300_buffer_domain domain)
73 {
74 struct radeon_drm_winsys *ws = radeon_drm_winsys(rws);
75 struct pb_desc desc;
76 struct pb_manager *provider;
77 struct pb_buffer *buffer;
78
79 memset(&desc, 0, sizeof(desc));
80 desc.alignment = alignment;
81 desc.usage = get_pb_usage_from_create_flags(bind, usage, domain);
82
83 /* Assign a buffer manager. */
84 if (bind & (PIPE_BIND_VERTEX_BUFFER | PIPE_BIND_INDEX_BUFFER))
85 provider = ws->cman;
86 else
87 provider = ws->kman;
88
89 buffer = provider->create_buffer(provider, size, &desc);
90 if (!buffer)
91 return NULL;
92
93 return (struct r300_winsys_buffer*)buffer;
94 }
95
96 static void radeon_r300_winsys_buffer_reference(struct r300_winsys_screen *rws,
97 struct r300_winsys_buffer **pdst,
98 struct r300_winsys_buffer *src)
99 {
100 struct pb_buffer *_src = radeon_pb_buffer(src);
101 struct pb_buffer *_dst = radeon_pb_buffer(*pdst);
102
103 pb_reference(&_dst, _src);
104
105 *pdst = (struct r300_winsys_buffer*)_dst;
106 }
107
108 static struct r300_winsys_buffer *radeon_r300_winsys_buffer_from_handle(struct r300_winsys_screen *rws,
109 struct winsys_handle *whandle,
110 unsigned *stride,
111 unsigned *size)
112 {
113 struct radeon_drm_winsys *ws = radeon_drm_winsys(rws);
114 struct pb_buffer *_buf;
115
116 _buf = radeon_drm_bufmgr_create_buffer_from_handle(ws->kman, whandle->handle);
117
118 if (stride)
119 *stride = whandle->stride;
120 if (size)
121 *size = _buf->base.size;
122
123 return (struct r300_winsys_buffer*)_buf;
124 }
125
126 static boolean radeon_r300_winsys_buffer_get_handle(struct r300_winsys_screen *rws,
127 struct r300_winsys_buffer *buffer,
128 unsigned stride,
129 struct winsys_handle *whandle)
130 {
131 struct pb_buffer *_buf = radeon_pb_buffer(buffer);
132 whandle->stride = stride;
133 return radeon_drm_bufmgr_get_handle(_buf, whandle);
134 }
135
136 static uint32_t radeon_get_value(struct r300_winsys_screen *rws,
137 enum r300_value_id id)
138 {
139 struct radeon_drm_winsys *ws = (struct radeon_drm_winsys *)rws;
140
141 switch(id) {
142 case R300_VID_PCI_ID:
143 return ws->pci_id;
144 case R300_VID_GB_PIPES:
145 return ws->gb_pipes;
146 case R300_VID_Z_PIPES:
147 return ws->z_pipes;
148 case R300_VID_SQUARE_TILING_SUPPORT:
149 return ws->squaretiling;
150 case R300_VID_DRM_2_3_0:
151 return ws->drm_2_3_0;
152 case R300_VID_DRM_2_6_0:
153 return ws->drm_2_6_0;
154 case R300_VID_DRM_2_8_0:
155 return ws->drm_2_8_0;
156 case R300_CAN_HYPERZ:
157 return ws->hyperz;
158 }
159 return 0;
160 }
161
162 void radeon_winsys_init_functions(struct radeon_drm_winsys *ws)
163 {
164 ws->base.get_value = radeon_get_value;
165 ws->base.buffer_create = radeon_r300_winsys_buffer_create;
166 ws->base.buffer_reference = radeon_r300_winsys_buffer_reference;
167 ws->base.buffer_from_handle = radeon_r300_winsys_buffer_from_handle;
168 ws->base.buffer_get_handle = radeon_r300_winsys_buffer_get_handle;
169 }