Merge commit 'origin/master' into gallium-0.2
[mesa.git] / src / mesa / drivers / dri / intel / intel_span.c
1 /**************************************************************************
2 *
3 * Copyright 2003 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 #include "main/glheader.h"
29 #include "main/macros.h"
30 #include "main/mtypes.h"
31 #include "main/colormac.h"
32
33 #include "intel_buffers.h"
34 #include "intel_fbo.h"
35 #include "intel_screen.h"
36 #include "intel_span.h"
37 #include "intel_regions.h"
38 #include "intel_tex.h"
39
40 #include "swrast/swrast.h"
41
42 static void
43 intel_set_span_functions(struct intel_context *intel,
44 struct gl_renderbuffer *rb);
45
46 #define SPAN_CACHE_SIZE 4096
47
48 static void
49 get_span_cache(struct intel_renderbuffer *irb, uint32_t offset)
50 {
51 if (irb->span_cache == NULL) {
52 irb->span_cache = _mesa_malloc(SPAN_CACHE_SIZE);
53 irb->span_cache_offset = -1;
54 }
55
56 if ((offset & ~(SPAN_CACHE_SIZE - 1)) != irb->span_cache_offset) {
57 irb->span_cache_offset = offset & ~(SPAN_CACHE_SIZE - 1);
58 dri_bo_get_subdata(irb->region->buffer, irb->span_cache_offset,
59 SPAN_CACHE_SIZE, irb->span_cache);
60 }
61 }
62
63 static void
64 clear_span_cache(struct intel_renderbuffer *irb)
65 {
66 irb->span_cache_offset = -1;
67 }
68
69 static uint32_t
70 pread_32(struct intel_renderbuffer *irb, uint32_t offset)
71 {
72 get_span_cache(irb, offset);
73
74 return *(uint32_t *)(irb->span_cache + (offset & (SPAN_CACHE_SIZE - 1)));
75 }
76
77 static uint32_t
78 pread_xrgb8888(struct intel_renderbuffer *irb, uint32_t offset)
79 {
80 get_span_cache(irb, offset);
81
82 return *(uint32_t *)(irb->span_cache + (offset & (SPAN_CACHE_SIZE - 1))) |
83 0xff000000;
84 }
85
86 static uint16_t
87 pread_16(struct intel_renderbuffer *irb, uint32_t offset)
88 {
89 get_span_cache(irb, offset);
90
91 return *(uint16_t *)(irb->span_cache + (offset & (SPAN_CACHE_SIZE - 1)));
92 }
93
94 static uint8_t
95 pread_8(struct intel_renderbuffer *irb, uint32_t offset)
96 {
97 get_span_cache(irb, offset);
98
99 return *(uint8_t *)(irb->span_cache + (offset & (SPAN_CACHE_SIZE - 1)));
100 }
101
102 static void
103 pwrite_32(struct intel_renderbuffer *irb, uint32_t offset, uint32_t val)
104 {
105 clear_span_cache(irb);
106
107 dri_bo_subdata(irb->region->buffer, offset, 4, &val);
108 }
109
110 static void
111 pwrite_xrgb8888(struct intel_renderbuffer *irb, uint32_t offset, uint32_t val)
112 {
113 clear_span_cache(irb);
114
115 dri_bo_subdata(irb->region->buffer, offset, 3, &val);
116 }
117
118 static void
119 pwrite_16(struct intel_renderbuffer *irb, uint32_t offset, uint16_t val)
120 {
121 clear_span_cache(irb);
122
123 dri_bo_subdata(irb->region->buffer, offset, 2, &val);
124 }
125
126 static void
127 pwrite_8(struct intel_renderbuffer *irb, uint32_t offset, uint8_t val)
128 {
129 clear_span_cache(irb);
130
131 dri_bo_subdata(irb->region->buffer, offset, 1, &val);
132 }
133
134 static uint32_t no_tile_swizzle(struct intel_renderbuffer *irb,
135 int x, int y)
136 {
137 return (y * irb->region->pitch + x) * irb->region->cpp;
138 }
139
140 /*
141 * Deal with tiled surfaces
142 */
143
144 static uint32_t x_tile_swizzle(struct intel_renderbuffer *irb,
145 int x, int y)
146 {
147 int tile_stride;
148 int xbyte;
149 int x_tile_off, y_tile_off;
150 int x_tile_number, y_tile_number;
151 int tile_off, tile_base;
152
153 tile_stride = (irb->pfPitch * irb->region->cpp) << 3;
154
155 xbyte = x * irb->region->cpp;
156
157 x_tile_off = xbyte & 0x1ff;
158 y_tile_off = y & 7;
159
160 x_tile_number = xbyte >> 9;
161 y_tile_number = y >> 3;
162
163 tile_off = (y_tile_off << 9) + x_tile_off;
164
165 switch (irb->region->bit_6_swizzle) {
166 case I915_BIT_6_SWIZZLE_NONE:
167 break;
168 case I915_BIT_6_SWIZZLE_9:
169 tile_off ^= ((tile_off >> 3) & 64);
170 break;
171 case I915_BIT_6_SWIZZLE_9_10:
172 tile_off ^= ((tile_off >> 3) & 64) ^ ((tile_off >> 4) & 64);
173 break;
174 case I915_BIT_6_SWIZZLE_9_11:
175 tile_off ^= ((tile_off >> 3) & 64) ^ ((tile_off >> 5) & 64);
176 break;
177 case I915_BIT_6_SWIZZLE_9_10_11:
178 tile_off ^= ((tile_off >> 3) & 64) ^ ((tile_off >> 4) & 64) ^
179 ((tile_off >> 5) & 64);
180 break;
181 default:
182 fprintf(stderr, "Unknown tile swizzling mode %d\n",
183 irb->region->bit_6_swizzle);
184 exit(1);
185 }
186
187 tile_base = (x_tile_number << 12) + y_tile_number * tile_stride;
188
189 #if 0
190 printf("(%d,%d) -> %d + %d = %d (pitch = %d, tstride = %d)\n",
191 x, y, tile_off, tile_base,
192 tile_off + tile_base,
193 irb->pfPitch, tile_stride);
194 #endif
195
196 return tile_base + tile_off;
197 }
198
199 static uint32_t y_tile_swizzle(struct intel_renderbuffer *irb,
200 int x, int y)
201 {
202 int tile_stride;
203 int xbyte;
204 int x_tile_off, y_tile_off;
205 int x_tile_number, y_tile_number;
206 int tile_off, tile_base;
207
208 tile_stride = (irb->pfPitch * irb->region->cpp) << 5;
209
210 xbyte = x * irb->region->cpp;
211
212 x_tile_off = xbyte & 0x7f;
213 y_tile_off = y & 0x1f;
214
215 x_tile_number = xbyte >> 7;
216 y_tile_number = y >> 5;
217
218 tile_off = ((x_tile_off & ~0xf) << 5) + (y_tile_off << 4) +
219 (x_tile_off & 0xf);
220
221 switch (irb->region->bit_6_swizzle) {
222 case I915_BIT_6_SWIZZLE_NONE:
223 break;
224 case I915_BIT_6_SWIZZLE_9:
225 tile_off ^= ((tile_off >> 3) & 64);
226 break;
227 case I915_BIT_6_SWIZZLE_9_10:
228 tile_off ^= ((tile_off >> 3) & 64) ^ ((tile_off >> 4) & 64);
229 break;
230 case I915_BIT_6_SWIZZLE_9_11:
231 tile_off ^= ((tile_off >> 3) & 64) ^ ((tile_off >> 5) & 64);
232 break;
233 case I915_BIT_6_SWIZZLE_9_10_11:
234 tile_off ^= ((tile_off >> 3) & 64) ^ ((tile_off >> 4) & 64) ^
235 ((tile_off >> 5) & 64);
236 break;
237 default:
238 fprintf(stderr, "Unknown tile swizzling mode %d\n",
239 irb->region->bit_6_swizzle);
240 exit(1);
241 }
242
243 tile_base = (x_tile_number << 12) + y_tile_number * tile_stride;
244
245 return tile_base + tile_off;
246 }
247
248 /*
249 break intelWriteRGBASpan_ARGB8888
250 */
251
252 #undef DBG
253 #define DBG 0
254
255 #define LOCAL_VARS \
256 struct intel_context *intel = intel_context(ctx); \
257 struct intel_renderbuffer *irb = intel_renderbuffer(rb); \
258 const GLint yScale = irb->RenderToTexture ? 1 : -1; \
259 const GLint yBias = irb->RenderToTexture ? 0 : irb->Base.Height - 1; \
260 unsigned int num_cliprects; \
261 struct drm_clip_rect *cliprects; \
262 int x_off, y_off; \
263 GLuint p; \
264 (void) p; \
265 intel_get_cliprects(intel, &cliprects, &num_cliprects, &x_off, &y_off);
266
267 /* XXX FBO: this is identical to the macro in spantmp2.h except we get
268 * the cliprect info from the context, not the driDrawable.
269 * Move this into spantmp2.h someday.
270 */
271 #define HW_CLIPLOOP() \
272 do { \
273 int _nc = num_cliprects; \
274 while ( _nc-- ) { \
275 int minx = cliprects[_nc].x1 - x_off; \
276 int miny = cliprects[_nc].y1 - y_off; \
277 int maxx = cliprects[_nc].x2 - x_off; \
278 int maxy = cliprects[_nc].y2 - y_off;
279
280 #if 0
281 }}
282 #endif
283
284 #define Y_FLIP(_y) ((_y) * yScale + yBias)
285
286 /* XXX with GEM, these need to tell the kernel */
287 #define HW_LOCK()
288
289 #define HW_UNLOCK()
290
291 /* Convenience macros to avoid typing the swizzle argument over and over */
292 #define NO_TILE(_X, _Y) no_tile_swizzle(irb, (_X) + x_off, (_Y) + y_off)
293 #define X_TILE(_X, _Y) x_tile_swizzle(irb, (_X) + x_off, (_Y) + y_off)
294 #define Y_TILE(_X, _Y) y_tile_swizzle(irb, (_X) + x_off, (_Y) + y_off)
295
296 /* 16 bit, RGB565 color spanline and pixel functions
297 */
298 #define SPANTMP_PIXEL_FMT GL_RGB
299 #define SPANTMP_PIXEL_TYPE GL_UNSIGNED_SHORT_5_6_5
300
301 #define TAG(x) intel##x##_RGB565
302 #define TAG2(x,y) intel##x##_RGB565##y
303 #define GET_VALUE(X, Y) pread_16(irb, NO_TILE(X, Y))
304 #define PUT_VALUE(X, Y, V) pwrite_16(irb, NO_TILE(X, Y), V)
305 #include "spantmp2.h"
306
307 /* 32 bit, ARGB8888 color spanline and pixel functions
308 */
309 #define SPANTMP_PIXEL_FMT GL_BGRA
310 #define SPANTMP_PIXEL_TYPE GL_UNSIGNED_INT_8_8_8_8_REV
311
312 #define TAG(x) intel##x##_ARGB8888
313 #define TAG2(x,y) intel##x##_ARGB8888##y
314 #define GET_VALUE(X, Y) pread_32(irb, NO_TILE(X, Y))
315 #define PUT_VALUE(X, Y, V) pwrite_32(irb, NO_TILE(X, Y), V)
316 #include "spantmp2.h"
317
318 /* 32 bit, xRGB8888 color spanline and pixel functions
319 */
320 #define SPANTMP_PIXEL_FMT GL_BGRA
321 #define SPANTMP_PIXEL_TYPE GL_UNSIGNED_INT_8_8_8_8_REV
322
323 #define TAG(x) intel##x##_xRGB8888
324 #define TAG2(x,y) intel##x##_xRGB8888##y
325 #define GET_VALUE(X, Y) pread_xrgb8888(irb, NO_TILE(X, Y))
326 #define PUT_VALUE(X, Y, V) pwrite_xrgb8888(irb, NO_TILE(X, Y), V)
327 #include "spantmp2.h"
328
329 /* 16 bit RGB565 color tile spanline and pixel functions
330 */
331
332 #define SPANTMP_PIXEL_FMT GL_RGB
333 #define SPANTMP_PIXEL_TYPE GL_UNSIGNED_SHORT_5_6_5
334
335 #define TAG(x) intel_XTile_##x##_RGB565
336 #define TAG2(x,y) intel_XTile_##x##_RGB565##y
337 #define GET_VALUE(X, Y) pread_16(irb, X_TILE(X, Y))
338 #define PUT_VALUE(X, Y, V) pwrite_16(irb, X_TILE(X, Y), V)
339 #include "spantmp2.h"
340
341 #define SPANTMP_PIXEL_FMT GL_RGB
342 #define SPANTMP_PIXEL_TYPE GL_UNSIGNED_SHORT_5_6_5
343
344 #define TAG(x) intel_YTile_##x##_RGB565
345 #define TAG2(x,y) intel_YTile_##x##_RGB565##y
346 #define GET_VALUE(X, Y) pread_16(irb, Y_TILE(X, Y))
347 #define PUT_VALUE(X, Y, V) pwrite_16(irb, Y_TILE(X, Y), V)
348 #include "spantmp2.h"
349
350 /* 32 bit ARGB888 color tile spanline and pixel functions
351 */
352
353 #define SPANTMP_PIXEL_FMT GL_BGRA
354 #define SPANTMP_PIXEL_TYPE GL_UNSIGNED_INT_8_8_8_8_REV
355
356 #define TAG(x) intel_XTile_##x##_ARGB8888
357 #define TAG2(x,y) intel_XTile_##x##_ARGB8888##y
358 #define GET_VALUE(X, Y) pread_32(irb, X_TILE(X, Y))
359 #define PUT_VALUE(X, Y, V) pwrite_32(irb, X_TILE(X, Y), V)
360 #include "spantmp2.h"
361
362 #define SPANTMP_PIXEL_FMT GL_BGRA
363 #define SPANTMP_PIXEL_TYPE GL_UNSIGNED_INT_8_8_8_8_REV
364
365 #define TAG(x) intel_YTile_##x##_ARGB8888
366 #define TAG2(x,y) intel_YTile_##x##_ARGB8888##y
367 #define GET_VALUE(X, Y) pread_32(irb, Y_TILE(X, Y))
368 #define PUT_VALUE(X, Y, V) pwrite_32(irb, Y_TILE(X, Y), V)
369 #include "spantmp2.h"
370
371 /* 32 bit xRGB888 color tile spanline and pixel functions
372 */
373
374 #define SPANTMP_PIXEL_FMT GL_BGRA
375 #define SPANTMP_PIXEL_TYPE GL_UNSIGNED_INT_8_8_8_8_REV
376
377 #define TAG(x) intel_XTile_##x##_xRGB8888
378 #define TAG2(x,y) intel_XTile_##x##_xRGB8888##y
379 #define GET_VALUE(X, Y) pread_xrgb8888(irb, X_TILE(X, Y))
380 #define PUT_VALUE(X, Y, V) pwrite_xrgb8888(irb, X_TILE(X, Y), V)
381 #include "spantmp2.h"
382
383 #define SPANTMP_PIXEL_FMT GL_BGRA
384 #define SPANTMP_PIXEL_TYPE GL_UNSIGNED_INT_8_8_8_8_REV
385
386 #define TAG(x) intel_YTile_##x##_xRGB8888
387 #define TAG2(x,y) intel_YTile_##x##_xRGB8888##y
388 #define GET_VALUE(X, Y) pread_xrgb8888(irb, Y_TILE(X, Y))
389 #define PUT_VALUE(X, Y, V) pwrite_xrgb8888(irb, Y_TILE(X, Y), V)
390 #include "spantmp2.h"
391
392 #define LOCAL_DEPTH_VARS \
393 struct intel_context *intel = intel_context(ctx); \
394 struct intel_renderbuffer *irb = intel_renderbuffer(rb); \
395 const GLint yScale = irb->RenderToTexture ? 1 : -1; \
396 const GLint yBias = irb->RenderToTexture ? 0 : irb->Base.Height - 1; \
397 unsigned int num_cliprects; \
398 struct drm_clip_rect *cliprects; \
399 int x_off, y_off; \
400 intel_get_cliprects(intel, &cliprects, &num_cliprects, &x_off, &y_off);
401
402
403 #define LOCAL_STENCIL_VARS LOCAL_DEPTH_VARS
404
405 /**
406 ** 16-bit depthbuffer functions.
407 **/
408 #define VALUE_TYPE GLushort
409 #define WRITE_DEPTH(_x, _y, d) pwrite_16(irb, NO_TILE(_x, _y), d)
410 #define READ_DEPTH(d, _x, _y) d = pread_16(irb, NO_TILE(_x, _y))
411 #define TAG(x) intel##x##_z16
412 #include "depthtmp.h"
413
414
415 /**
416 ** 16-bit x tile depthbuffer functions.
417 **/
418 #define VALUE_TYPE GLushort
419 #define WRITE_DEPTH(_x, _y, d) pwrite_16(irb, X_TILE(_x, _y), d)
420 #define READ_DEPTH(d, _x, _y) d = pread_16(irb, X_TILE(_x, _y))
421 #define TAG(x) intel_XTile_##x##_z16
422 #include "depthtmp.h"
423
424 /**
425 ** 16-bit y tile depthbuffer functions.
426 **/
427 #define VALUE_TYPE GLushort
428 #define WRITE_DEPTH(_x, _y, d) pwrite_16(irb, Y_TILE(_x, _y), d)
429 #define READ_DEPTH(d, _x, _y) d = pread_16(irb, Y_TILE(_x, _y))
430 #define TAG(x) intel_YTile_##x##_z16
431 #include "depthtmp.h"
432
433
434 /**
435 ** 24/8-bit interleaved depth/stencil functions
436 ** Note: we're actually reading back combined depth+stencil values.
437 ** The wrappers in main/depthstencil.c are used to extract the depth
438 ** and stencil values.
439 **/
440 #define VALUE_TYPE GLuint
441
442 /* Change ZZZS -> SZZZ */
443 #define WRITE_DEPTH(_x, _y, d) \
444 pwrite_32(irb, NO_TILE(_x, _y), ((d) >> 8) | ((d) << 24))
445
446 /* Change SZZZ -> ZZZS */
447 #define READ_DEPTH( d, _x, _y ) { \
448 GLuint tmp = pread_32(irb, NO_TILE(_x, _y)); \
449 d = (tmp << 8) | (tmp >> 24); \
450 }
451
452 #define TAG(x) intel##x##_z24_s8
453 #include "depthtmp.h"
454
455
456 /**
457 ** 24/8-bit x-tile interleaved depth/stencil functions
458 ** Note: we're actually reading back combined depth+stencil values.
459 ** The wrappers in main/depthstencil.c are used to extract the depth
460 ** and stencil values.
461 **/
462 #define VALUE_TYPE GLuint
463
464 /* Change ZZZS -> SZZZ */
465 #define WRITE_DEPTH(_x, _y, d) \
466 pwrite_32(irb, X_TILE(_x, _y), ((d) >> 8) | ((d) << 24))
467
468 /* Change SZZZ -> ZZZS */
469 #define READ_DEPTH( d, _x, _y ) { \
470 GLuint tmp = pread_32(irb, X_TILE(_x, _y)); \
471 d = (tmp << 8) | (tmp >> 24); \
472 }
473
474 #define TAG(x) intel_XTile_##x##_z24_s8
475 #include "depthtmp.h"
476
477 /**
478 ** 24/8-bit y-tile interleaved depth/stencil functions
479 ** Note: we're actually reading back combined depth+stencil values.
480 ** The wrappers in main/depthstencil.c are used to extract the depth
481 ** and stencil values.
482 **/
483 #define VALUE_TYPE GLuint
484
485 /* Change ZZZS -> SZZZ */
486 #define WRITE_DEPTH(_x, _y, d) \
487 pwrite_32(irb, Y_TILE(_x, _y), ((d) >> 8) | ((d) << 24))
488
489 /* Change SZZZ -> ZZZS */
490 #define READ_DEPTH( d, _x, _y ) { \
491 GLuint tmp = pread_32(irb, Y_TILE(_x, _y)); \
492 d = (tmp << 8) | (tmp >> 24); \
493 }
494
495 #define TAG(x) intel_YTile_##x##_z24_s8
496 #include "depthtmp.h"
497
498
499 /**
500 ** 8-bit stencil function (XXX FBO: This is obsolete)
501 **/
502 #define WRITE_STENCIL(_x, _y, d) pwrite_8(irb, NO_TILE(_x, _y) + 3, d)
503 #define READ_STENCIL(d, _x, _y) d = pread_8(irb, NO_TILE(_x, _y) + 3);
504 #define TAG(x) intel##x##_z24_s8
505 #include "stenciltmp.h"
506
507 /**
508 ** 8-bit x-tile stencil function (XXX FBO: This is obsolete)
509 **/
510 #define WRITE_STENCIL(_x, _y, d) pwrite_8(irb, X_TILE(_x, _y) + 3, d)
511 #define READ_STENCIL(d, _x, _y) d = pread_8(irb, X_TILE(_x, _y) + 3);
512 #define TAG(x) intel_XTile_##x##_z24_s8
513 #include "stenciltmp.h"
514
515 /**
516 ** 8-bit y-tile stencil function (XXX FBO: This is obsolete)
517 **/
518 #define WRITE_STENCIL(_x, _y, d) pwrite_8(irb, Y_TILE(_x, _y) + 3, d)
519 #define READ_STENCIL(d, _x, _y) d = pread_8(irb, Y_TILE(_x, _y) + 3)
520 #define TAG(x) intel_YTile_##x##_z24_s8
521 #include "stenciltmp.h"
522
523 void
524 intel_renderbuffer_map(struct intel_context *intel, struct gl_renderbuffer *rb)
525 {
526 struct intel_renderbuffer *irb = intel_renderbuffer(rb);
527
528 if (irb == NULL || irb->region == NULL)
529 return;
530
531 irb->pfPitch = irb->region->pitch;
532
533 intel_set_span_functions(intel, rb);
534 }
535
536 void
537 intel_renderbuffer_unmap(struct intel_context *intel,
538 struct gl_renderbuffer *rb)
539 {
540 struct intel_renderbuffer *irb = intel_renderbuffer(rb);
541
542 if (irb == NULL || irb->region == NULL)
543 return;
544
545 clear_span_cache(irb);
546 irb->pfPitch = 0;
547
548 rb->GetRow = NULL;
549 rb->PutRow = NULL;
550 }
551
552 /**
553 * Map or unmap all the renderbuffers which we may need during
554 * software rendering.
555 * XXX in the future, we could probably convey extra information to
556 * reduce the number of mappings needed. I.e. if doing a glReadPixels
557 * from the depth buffer, we really only need one mapping.
558 *
559 * XXX Rewrite this function someday.
560 * We can probably just loop over all the renderbuffer attachments,
561 * map/unmap all of them, and not worry about the _ColorDrawBuffers
562 * _ColorReadBuffer, _DepthBuffer or _StencilBuffer fields.
563 */
564 static void
565 intel_map_unmap_buffers(struct intel_context *intel, GLboolean map)
566 {
567 GLcontext *ctx = &intel->ctx;
568 GLuint i, j;
569
570 /* color draw buffers */
571 for (j = 0; j < ctx->DrawBuffer->_NumColorDrawBuffers; j++) {
572 if (map)
573 intel_renderbuffer_map(intel, ctx->DrawBuffer->_ColorDrawBuffers[j]);
574 else
575 intel_renderbuffer_unmap(intel, ctx->DrawBuffer->_ColorDrawBuffers[j]);
576 }
577
578 /* check for render to textures */
579 for (i = 0; i < BUFFER_COUNT; i++) {
580 struct gl_renderbuffer_attachment *att =
581 ctx->DrawBuffer->Attachment + i;
582 struct gl_texture_object *tex = att->Texture;
583 if (tex) {
584 /* render to texture */
585 ASSERT(att->Renderbuffer);
586 if (map)
587 intel_tex_map_images(intel, intel_texture_object(tex));
588 else
589 intel_tex_unmap_images(intel, intel_texture_object(tex));
590 }
591 }
592
593 /* color read buffers */
594 if (map)
595 intel_renderbuffer_map(intel, ctx->ReadBuffer->_ColorReadBuffer);
596 else
597 intel_renderbuffer_unmap(intel, ctx->ReadBuffer->_ColorReadBuffer);
598
599 /* depth buffer (Note wrapper!) */
600 if (ctx->DrawBuffer->_DepthBuffer) {
601 if (map)
602 intel_renderbuffer_map(intel, ctx->DrawBuffer->_DepthBuffer->Wrapped);
603 else
604 intel_renderbuffer_unmap(intel,
605 ctx->DrawBuffer->_DepthBuffer->Wrapped);
606 }
607
608 /* stencil buffer (Note wrapper!) */
609 if (ctx->DrawBuffer->_StencilBuffer) {
610 if (map)
611 intel_renderbuffer_map(intel,
612 ctx->DrawBuffer->_StencilBuffer->Wrapped);
613 else
614 intel_renderbuffer_unmap(intel,
615 ctx->DrawBuffer->_StencilBuffer->Wrapped);
616 }
617 }
618
619
620
621 /**
622 * Prepare for softare rendering. Map current read/draw framebuffers'
623 * renderbuffes and all currently bound texture objects.
624 *
625 * Old note: Moved locking out to get reasonable span performance.
626 */
627 void
628 intelSpanRenderStart(GLcontext * ctx)
629 {
630 struct intel_context *intel = intel_context(ctx);
631 GLuint i;
632
633 intelFlush(&intel->ctx);
634 LOCK_HARDWARE(intel);
635
636 for (i = 0; i < ctx->Const.MaxTextureImageUnits; i++) {
637 if (ctx->Texture.Unit[i]._ReallyEnabled) {
638 struct gl_texture_object *texObj = ctx->Texture.Unit[i]._Current;
639 intel_tex_map_images(intel, intel_texture_object(texObj));
640 }
641 }
642
643 intel_map_unmap_buffers(intel, GL_TRUE);
644 }
645
646 /**
647 * Called when done softare rendering. Unmap the buffers we mapped in
648 * the above function.
649 */
650 void
651 intelSpanRenderFinish(GLcontext * ctx)
652 {
653 struct intel_context *intel = intel_context(ctx);
654 GLuint i;
655
656 _swrast_flush(ctx);
657
658 for (i = 0; i < ctx->Const.MaxTextureImageUnits; i++) {
659 if (ctx->Texture.Unit[i]._ReallyEnabled) {
660 struct gl_texture_object *texObj = ctx->Texture.Unit[i]._Current;
661 intel_tex_unmap_images(intel, intel_texture_object(texObj));
662 }
663 }
664
665 intel_map_unmap_buffers(intel, GL_FALSE);
666
667 UNLOCK_HARDWARE(intel);
668 }
669
670
671 void
672 intelInitSpanFuncs(GLcontext * ctx)
673 {
674 struct swrast_device_driver *swdd = _swrast_GetDeviceDriverReference(ctx);
675 swdd->SpanRenderStart = intelSpanRenderStart;
676 swdd->SpanRenderFinish = intelSpanRenderFinish;
677 }
678
679
680 /**
681 * Plug in appropriate span read/write functions for the given renderbuffer.
682 * These are used for the software fallbacks.
683 */
684 static void
685 intel_set_span_functions(struct intel_context *intel,
686 struct gl_renderbuffer *rb)
687 {
688 struct intel_renderbuffer *irb = (struct intel_renderbuffer *) rb;
689 uint32_t tiling;
690
691 /* If in GEM mode, we need to do the tile address swizzling ourselves,
692 * instead of the fence registers handling it.
693 */
694 if (intel->ttm)
695 tiling = irb->region->tiling;
696 else
697 tiling = I915_TILING_NONE;
698
699 if (rb->_ActualFormat == GL_RGB5) {
700 /* 565 RGB */
701 switch (tiling) {
702 case I915_TILING_NONE:
703 default:
704 intelInitPointers_RGB565(rb);
705 break;
706 case I915_TILING_X:
707 intel_XTile_InitPointers_RGB565(rb);
708 break;
709 case I915_TILING_Y:
710 intel_YTile_InitPointers_RGB565(rb);
711 break;
712 }
713 }
714 else if (rb->_ActualFormat == GL_RGB8) {
715 /* 8888 RGBx */
716 switch (tiling) {
717 case I915_TILING_NONE:
718 default:
719 intelInitPointers_xRGB8888(rb);
720 break;
721 case I915_TILING_X:
722 intel_XTile_InitPointers_xRGB8888(rb);
723 break;
724 case I915_TILING_Y:
725 intel_YTile_InitPointers_xRGB8888(rb);
726 break;
727 }
728 }
729 else if (rb->_ActualFormat == GL_RGBA8) {
730 /* 8888 RGBA */
731 switch (tiling) {
732 case I915_TILING_NONE:
733 default:
734 intelInitPointers_ARGB8888(rb);
735 break;
736 case I915_TILING_X:
737 intel_XTile_InitPointers_ARGB8888(rb);
738 break;
739 case I915_TILING_Y:
740 intel_YTile_InitPointers_ARGB8888(rb);
741 break;
742 }
743 }
744 else if (rb->_ActualFormat == GL_DEPTH_COMPONENT16) {
745 switch (tiling) {
746 case I915_TILING_NONE:
747 default:
748 intelInitDepthPointers_z16(rb);
749 break;
750 case I915_TILING_X:
751 intel_XTile_InitDepthPointers_z16(rb);
752 break;
753 case I915_TILING_Y:
754 intel_YTile_InitDepthPointers_z16(rb);
755 break;
756 }
757 }
758 else if (rb->_ActualFormat == GL_DEPTH_COMPONENT24 || /* XXX FBO remove */
759 rb->_ActualFormat == GL_DEPTH24_STENCIL8_EXT) {
760 switch (tiling) {
761 case I915_TILING_NONE:
762 default:
763 intelInitDepthPointers_z24_s8(rb);
764 break;
765 case I915_TILING_X:
766 intel_XTile_InitDepthPointers_z24_s8(rb);
767 break;
768 case I915_TILING_Y:
769 intel_YTile_InitDepthPointers_z24_s8(rb);
770 break;
771 }
772 }
773 else if (rb->_ActualFormat == GL_STENCIL_INDEX8_EXT) {
774 switch (tiling) {
775 case I915_TILING_NONE:
776 default:
777 intelInitStencilPointers_z24_s8(rb);
778 break;
779 case I915_TILING_X:
780 intel_XTile_InitStencilPointers_z24_s8(rb);
781 break;
782 case I915_TILING_Y:
783 intel_YTile_InitStencilPointers_z24_s8(rb);
784 break;
785 }
786 }
787 else {
788 _mesa_problem(NULL,
789 "Unexpected _ActualFormat in intelSetSpanFunctions");
790 }
791 }