Minor r200 vertex program cleanups. Remove disabled leftovers from r300 vertex progra...
[mesa.git] / src / mesa / drivers / dri / i965 / intel_regions.c
1 /**************************************************************************
2 *
3 * Copyright 2006 Tungsten Graphics, Inc., Cedar Park, Texas.
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 above copyright notice and this permission notice (including the
15 * next paragraph) shall be included in all copies or substantial portions
16 * of the Software.
17 *
18 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
19 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
20 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
21 * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
22 * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
23 * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
24 * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
25 *
26 **************************************************************************/
27
28 /* Provide additional functionality on top of bufmgr buffers:
29 * - 2d semantics and blit operations
30 * - refcounting of buffers for multiple images in a buffer.
31 * - refcounting of buffer mappings.
32 * - some logic for moving the buffers to the best memory pools for
33 * given operations.
34 *
35 * Most of this is to make it easier to implement the fixed-layout
36 * mipmap tree required by intel hardware in the face of GL's
37 * programming interface where each image can be specifed in random
38 * order and it isn't clear what layout the tree should have until the
39 * last moment.
40 */
41
42 #include "intel_context.h"
43 #include "intel_regions.h"
44 #include "intel_blit.h"
45 #include "bufmgr.h"
46 #include "imports.h"
47
48 /* XXX: Thread safety?
49 */
50 GLubyte *intel_region_map(struct intel_context *intel, struct intel_region *region)
51 {
52 DBG("%s\n", __FUNCTION__);
53 if (!region->map_refcount++) {
54 region->map = bmMapBuffer(intel, region->buffer, 0);
55 }
56
57 return region->map;
58 }
59
60 void intel_region_unmap(struct intel_context *intel,
61 struct intel_region *region)
62 {
63 DBG("%s\n", __FUNCTION__);
64 if (!--region->map_refcount) {
65 bmUnmapBufferAUB(intel, region->buffer, 0, 0);
66 region->map = NULL;
67 }
68 }
69
70 struct intel_region *intel_region_alloc( struct intel_context *intel,
71 GLuint cpp,
72 GLuint pitch,
73 GLuint height )
74 {
75 struct intel_region *region = calloc(sizeof(*region), 1);
76
77 DBG("%s %dx%dx%d == 0x%x bytes\n", __FUNCTION__,
78 cpp, pitch, height, cpp*pitch*height);
79
80 region->cpp = cpp;
81 region->pitch = pitch;
82 region->height = height; /* needed? */
83 region->refcount = 1;
84
85 bmGenBuffers(intel, "tex", 1, &region->buffer);
86 bmBufferData(intel, region->buffer, pitch * cpp * height, NULL, 0);
87
88 return region;
89 }
90
91 void intel_region_reference( struct intel_region **dst,
92 struct intel_region *src)
93 {
94 src->refcount++;
95 assert(*dst == NULL);
96 *dst = src;
97 }
98
99 void intel_region_release( struct intel_context *intel,
100 struct intel_region **region )
101 {
102 if (!*region)
103 return;
104
105 DBG("%s %d\n", __FUNCTION__, (*region)->refcount-1);
106
107 if (--(*region)->refcount == 0) {
108 assert((*region)->map_refcount == 0);
109 bmDeleteBuffers(intel, 1, &(*region)->buffer);
110 free(*region);
111 }
112 *region = NULL;
113 }
114
115
116 struct intel_region *intel_region_create_static( struct intel_context *intel,
117 GLuint mem_type,
118 GLuint offset,
119 void *virtual,
120 GLuint cpp,
121 GLuint pitch,
122 GLuint height,
123 GLboolean tiled )
124 {
125 struct intel_region *region = calloc(sizeof(*region), 1);
126 GLuint size = cpp * pitch * height;
127 GLint pool;
128
129 DBG("%s\n", __FUNCTION__);
130
131 region->cpp = cpp;
132 region->pitch = pitch;
133 region->height = height; /* needed? */
134 region->refcount = 1;
135 region->tiled = tiled;
136
137 /* Recipe for creating a static buffer - create a static pool with
138 * the right offset and size, generate a buffer and use a special
139 * call to bind it to all of the memory in that pool.
140 */
141 pool = bmInitPool(intel, offset, virtual, size,
142 (BM_MEM_AGP |
143 BM_NO_UPLOAD |
144 BM_NO_EVICT |
145 BM_NO_MOVE));
146 if (pool < 0) {
147 _mesa_printf("bmInitPool failed for static region\n");
148 exit(1);
149 }
150
151 region->buffer = bmGenBufferStatic(intel, pool);
152
153 return region;
154 }
155
156
157
158
159 void _mesa_copy_rect( GLubyte *dst,
160 GLuint cpp,
161 GLuint dst_pitch,
162 GLuint dst_x,
163 GLuint dst_y,
164 GLuint width,
165 GLuint height,
166 const GLubyte *src,
167 GLuint src_pitch,
168 GLuint src_x,
169 GLuint src_y )
170 {
171 GLuint i;
172
173 dst_pitch *= cpp;
174 src_pitch *= cpp;
175 dst += dst_x * cpp;
176 src += src_x * cpp;
177 dst += dst_y * dst_pitch;
178 src += src_y * dst_pitch;
179 width *= cpp;
180
181 if (width == dst_pitch &&
182 width == src_pitch)
183 do_memcpy(dst, src, height * width);
184 else {
185 for (i = 0; i < height; i++) {
186 do_memcpy(dst, src, width);
187 dst += dst_pitch;
188 src += src_pitch;
189 }
190 }
191 }
192
193
194 /* Upload data to a rectangular sub-region. Lots of choices how to do this:
195 *
196 * - memcpy by span to current destination
197 * - upload data as new buffer and blit
198 *
199 * Currently always memcpy.
200 */
201 void intel_region_data(struct intel_context *intel,
202 struct intel_region *dst,
203 GLuint dst_offset,
204 GLuint dstx, GLuint dsty,
205 const void *src, GLuint src_pitch,
206 GLuint srcx, GLuint srcy,
207 GLuint width, GLuint height)
208 {
209
210 DBG("%s\n", __FUNCTION__);
211
212 if (width == dst->pitch &&
213 width == src_pitch &&
214 dst_offset == 0 &&
215 height == dst->height &&
216 srcx == 0 &&
217 srcy == 0)
218 {
219 bmBufferDataAUB(intel,
220 dst->buffer,
221 dst->cpp * width * dst->height,
222 src,
223 0,
224 0, /* DW_NOTYPE */
225 0);
226 }
227 else {
228 assert (dst_offset + dstx + width +
229 (dsty + height - 1) * dst->pitch * dst->cpp <=
230 dst->pitch * dst->cpp * dst->height);
231
232 _mesa_copy_rect(intel_region_map(intel, dst) + dst_offset,
233 dst->cpp,
234 dst->pitch,
235 dstx, dsty,
236 width, height,
237 src,
238 src_pitch,
239 srcx, srcy);
240
241 intel_region_unmap(intel, dst);
242 }
243 }
244
245 /* Copy rectangular sub-regions. Need better logic about when to
246 * push buffers into AGP - will currently do so whenever possible.
247 */
248 void intel_region_copy( struct intel_context *intel,
249 struct intel_region *dst,
250 GLuint dst_offset,
251 GLuint dstx, GLuint dsty,
252 struct intel_region *src,
253 GLuint src_offset,
254 GLuint srcx, GLuint srcy,
255 GLuint width, GLuint height )
256 {
257 DBG("%s\n", __FUNCTION__);
258
259 assert(src->cpp == dst->cpp);
260
261 intelEmitCopyBlit(intel,
262 dst->cpp,
263 src->pitch, src->buffer, src_offset, src->tiled,
264 dst->pitch, dst->buffer, dst_offset, dst->tiled,
265 srcx, srcy,
266 dstx, dsty,
267 width, height);
268 }
269
270 /* Fill a rectangular sub-region. Need better logic about when to
271 * push buffers into AGP - will currently do so whenever possible.
272 */
273 void intel_region_fill( struct intel_context *intel,
274 struct intel_region *dst,
275 GLuint dst_offset,
276 GLuint dstx, GLuint dsty,
277 GLuint width, GLuint height,
278 GLuint color )
279 {
280 DBG("%s\n", __FUNCTION__);
281
282 intelEmitFillBlit(intel,
283 dst->cpp,
284 dst->pitch, dst->buffer, dst_offset, dst->tiled,
285 dstx, dsty,
286 width, height,
287 color );
288 }
289