intel-gem: Move bit 6 x tiling swizzle to a driconf option, and add new mode.
[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 "glheader.h"
29 #include "macros.h"
30 #include "mtypes.h"
31 #include "colormac.h"
32
33 #include "intel_fbo.h"
34 #include "intel_screen.h"
35 #include "intel_span.h"
36 #include "intel_regions.h"
37 #include "intel_ioctl.h"
38 #include "intel_tex.h"
39
40 #include "swrast/swrast.h"
41
42 /*
43 * Deal with tiled surfaces
44 */
45
46 #if 0
47 /* These are pre-965 tile swizzling functions -- power of two widths */
48 static uintptr_t x_tile_swizzle_pow2 (uintptr_t addr, int n)
49 {
50 uintptr_t a = addr;
51 uintptr_t base_mask = (((~0) << (n + 4)) | 0xff);
52 uintptr_t x_mask = ((~0) << 12) & ~base_mask;
53
54 a = ((a & base_mask) |
55 ((a >> (n-8)) & 0x7) |
56 ((a << 3) & x_mask));
57 _mesa_printf ("x_swizzle %08x (base %x yrow %x tile#x %x xsword %x byte %x) %08x\n",
58 addr,
59 addr >> (n + 4),
60 (addr >> (n + 1)) & 0x7,
61 (addr >> 9) & ((1 << (n-8)) - 1),
62 (addr >> 5) & 0xf,
63 (addr & 0x1f),
64 a);
65 return a;
66 }
67
68 static uintptr_t y_tile_swizzle_pow2 (uintptr_t addr, int n)
69 {
70 uintptr_t a = (uintptr_t) addr;
71 uintptr_t base_mask = (((~0) << (n + 6)) | 0xf);
72 uintptr_t x_mask = ((~0) << 9) & ~base_mask;
73
74 a = ((a & base_mask) |
75 ((a >> (n-3)) & 0x1f) |
76 ((a << 5) & x_mask));
77 _mesa_printf ("y_swizzle %08x (base %x yrow %x tile#x %x xoword %x byte %x) %08x\n",
78 addr,
79 addr >> (n + 6),
80 (addr >> (n + 1)) & 0x01f,
81 (addr >> 7) & ((1 << (n-6)) - 1),
82 (addr >> 4) & 0x7,
83 (addr & 0xf),
84 a);
85 return a;
86 }
87 #endif
88
89 static GLubyte *x_tile_swizzle(struct intel_renderbuffer *irb, struct intel_context *intel,
90 int x, int y)
91 {
92 GLubyte *buf = (GLubyte *) irb->pfMap;
93 int tile_stride;
94 int xbyte;
95 int x_tile_off, y_tile_off;
96 int x_tile_number, y_tile_number;
97 int tile_off, tile_base;
98
99 tile_stride = (irb->pfPitch * irb->region->cpp) << 3;
100
101 x += intel->drawX;
102 y += intel->drawY;
103
104 xbyte = x * irb->region->cpp;
105
106 x_tile_off = xbyte & 0x1ff;
107 y_tile_off = y & 7;
108
109 x_tile_number = xbyte >> 9;
110 y_tile_number = y >> 3;
111
112 tile_off = (y_tile_off << 9) + x_tile_off;
113
114 /* bit swizzling tricks your parents never told you about:
115 *
116 * The specs say that the X tiling layout is just 8 512-byte rows
117 * packed into a page. It turns out that there's some additional
118 * swizzling of bit 6 to reduce cache aliasing issues. Experimental
119 * results below:
120 *
121 * line bit GM965 945G/Q965
122 * 9 10 11
123 * 0 0 0 0 0 0
124 * 1 0 1 0 1 1
125 * 2 1 0 0 1 1
126 * 3 1 1 0 0 0
127 * 4 0 0 1 1 0
128 * 5 0 1 1 0 1
129 * 6 1 0 1 0 1
130 * 7 1 1 1 1 0
131 *
132 * So we see that the GM965 is bit 6 ^ 9 ^ 10 ^ 11, while other
133 * parts were just 6 ^ 9 ^ 10. However, some systems, including a
134 * GM965 we've seen, don't perform the swizzling at all. Information
135 * on how to detect it through register reads is expected soon.
136 */
137 switch (intel->tiling_swizzle_mode) {
138 case 0:
139 break;
140 case 1:
141 tile_off ^= ((tile_off >> 3) & 64) ^ ((tile_off >> 4) & 64);
142 break;
143 case 2:
144 tile_off ^= ((tile_off >> 3) & 64) ^ ((tile_off >> 4) & 64) ^
145 ((tile_off >> 5) & 64);
146 break;
147 }
148
149 tile_base = (x_tile_number << 12) + y_tile_number * tile_stride;
150
151 #if 0
152 printf("(%d,%d) -> %d + %d = %d (pitch = %d, tstride = %d)\n",
153 x, y, tile_off, tile_base,
154 tile_off + tile_base,
155 irb->pfPitch, tile_stride);
156 #endif
157
158 return buf + tile_base + tile_off;
159 }
160
161 static GLubyte *y_tile_swizzle(struct intel_renderbuffer *irb, struct intel_context *intel,
162 int x, int y)
163 {
164 GLubyte *buf = (GLubyte *) irb->pfMap;
165 int tile_stride;
166 int xbyte;
167 int x_tile_off, y_tile_off;
168 int x_tile_number, y_tile_number;
169 int tile_off, tile_base;
170
171 tile_stride = (irb->pfPitch * irb->region->cpp) << 3;
172
173 x += intel->drawX;
174 y += intel->drawY;
175
176 xbyte = x * irb->region->cpp;
177
178 x_tile_off = xbyte & 0x7f;
179 y_tile_off = y & 0x1f;
180
181 x_tile_number = xbyte >> 7;
182 y_tile_number = y >> 5;
183
184 tile_off = ((x_tile_off & ~0xf) << 5) + (y_tile_off << 4) + (x_tile_off & 0xf);
185 tile_base = (x_tile_number << 12) + y_tile_number * tile_stride;
186
187 return buf + tile_base + tile_off;
188 }
189
190 /*
191 break intelWriteRGBASpan_ARGB8888
192 */
193
194 #undef DBG
195 #define DBG 0
196
197 #define LOCAL_VARS \
198 struct intel_context *intel = intel_context(ctx); \
199 struct intel_renderbuffer *irb = intel_renderbuffer(rb); \
200 const GLint yScale = irb->RenderToTexture ? 1 : -1; \
201 const GLint yBias = irb->RenderToTexture ? 0 : irb->Base.Height - 1; \
202 GLubyte *buf = (GLubyte *) irb->pfMap \
203 + (intel->drawY * irb->pfPitch + intel->drawX) * irb->region->cpp;\
204 GLuint p; \
205 assert(irb->pfMap);\
206 (void) p; (void) buf;
207
208 /* XXX FBO: this is identical to the macro in spantmp2.h except we get
209 * the cliprect info from the context, not the driDrawable.
210 * Move this into spantmp2.h someday.
211 */
212 #define HW_CLIPLOOP() \
213 do { \
214 int _nc = intel->numClipRects; \
215 while ( _nc-- ) { \
216 int minx = intel->pClipRects[_nc].x1 - intel->drawX; \
217 int miny = intel->pClipRects[_nc].y1 - intel->drawY; \
218 int maxx = intel->pClipRects[_nc].x2 - intel->drawX; \
219 int maxy = intel->pClipRects[_nc].y2 - intel->drawY;
220
221 #if 0
222 }}
223 #endif
224
225 #define Y_FLIP(_y) ((_y) * yScale + yBias)
226
227 /* XXX with GEM, these need to tell the kernel */
228 #define HW_LOCK()
229
230 #define HW_UNLOCK()
231
232 /* 16 bit, RGB565 color spanline and pixel functions
233 */
234 #define SPANTMP_PIXEL_FMT GL_RGB
235 #define SPANTMP_PIXEL_TYPE GL_UNSIGNED_SHORT_5_6_5
236
237 #define TAG(x) intel##x##_RGB565
238 #define TAG2(x,y) intel##x##_RGB565##y
239 #define GET_PTR(X,Y) (buf + ((Y) * irb->pfPitch + (X)) * 2)
240 #include "spantmp2.h"
241
242 /* 32 bit, ARGB8888 color spanline and pixel functions
243 */
244 #define SPANTMP_PIXEL_FMT GL_BGRA
245 #define SPANTMP_PIXEL_TYPE GL_UNSIGNED_INT_8_8_8_8_REV
246
247 #define TAG(x) intel##x##_ARGB8888
248 #define TAG2(x,y) intel##x##_ARGB8888##y
249 #define GET_PTR(X,Y) (buf + ((Y) * irb->pfPitch + (X)) * 4)
250 #include "spantmp2.h"
251
252 /* 16 bit RGB565 color tile spanline and pixel functions
253 */
254
255 #define SPANTMP_PIXEL_FMT GL_RGB
256 #define SPANTMP_PIXEL_TYPE GL_UNSIGNED_SHORT_5_6_5
257
258 #define TAG(x) intel_XTile_##x##_RGB565
259 #define TAG2(x,y) intel_XTile_##x##_RGB565##y
260 #define GET_PTR(X,Y) x_tile_swizzle(irb, intel, X, Y)
261 #include "spantmp2.h"
262
263 #define SPANTMP_PIXEL_FMT GL_RGB
264 #define SPANTMP_PIXEL_TYPE GL_UNSIGNED_SHORT_5_6_5
265
266 #define TAG(x) intel_YTile_##x##_RGB565
267 #define TAG2(x,y) intel_YTile_##x##_RGB565##y
268 #define GET_PTR(X,Y) y_tile_swizzle(irb, intel, X, Y)
269 #include "spantmp2.h"
270
271 /* 32 bit ARGB888 color tile spanline and pixel functions
272 */
273
274 #define SPANTMP_PIXEL_FMT GL_BGRA
275 #define SPANTMP_PIXEL_TYPE GL_UNSIGNED_INT_8_8_8_8_REV
276
277 #define TAG(x) intel_XTile_##x##_ARGB8888
278 #define TAG2(x,y) intel_XTile_##x##_ARGB8888##y
279 #define GET_PTR(X,Y) x_tile_swizzle(irb, intel, X, Y)
280 #include "spantmp2.h"
281
282 #define SPANTMP_PIXEL_FMT GL_BGRA
283 #define SPANTMP_PIXEL_TYPE GL_UNSIGNED_INT_8_8_8_8_REV
284
285 #define TAG(x) intel_YTile_##x##_ARGB8888
286 #define TAG2(x,y) intel_YTile_##x##_ARGB8888##y
287 #define GET_PTR(X,Y) y_tile_swizzle(irb, intel, X, Y)
288 #include "spantmp2.h"
289
290 #define LOCAL_DEPTH_VARS \
291 struct intel_context *intel = intel_context(ctx); \
292 struct intel_renderbuffer *irb = intel_renderbuffer(rb); \
293 const GLuint pitch = irb->pfPitch/***XXX region->pitch*/; /* in pixels */ \
294 const GLint yScale = irb->RenderToTexture ? 1 : -1; \
295 const GLint yBias = irb->RenderToTexture ? 0 : irb->Base.Height - 1; \
296 char *buf = (char *) irb->pfMap/*XXX use region->map*/ + \
297 (intel->drawY * pitch + intel->drawX) * irb->region->cpp; (void) buf;
298
299
300 #define LOCAL_STENCIL_VARS LOCAL_DEPTH_VARS
301
302 /**
303 ** 16-bit depthbuffer functions.
304 **/
305 #define WRITE_DEPTH( _x, _y, d ) \
306 ((GLushort *)buf)[(_x) + (_y) * pitch] = d;
307
308 #define READ_DEPTH( d, _x, _y ) \
309 d = ((GLushort *)buf)[(_x) + (_y) * pitch];
310
311
312 #define TAG(x) intel##x##_z16
313 #include "depthtmp.h"
314
315
316 /**
317 ** 16-bit x tile depthbuffer functions.
318 **/
319 #define WRITE_DEPTH( _x, _y, d ) \
320 (*((GLushort *)x_tile_swizzle (irb, intel, _x, _y)) = d)
321
322 #define READ_DEPTH( d, _x, _y ) \
323 d = *((GLushort *)x_tile_swizzle (irb, intel, _x, _y))
324
325
326 #define TAG(x) intel_XTile_##x##_z16
327 #include "depthtmp.h"
328
329 /**
330 ** 16-bit y tile depthbuffer functions.
331 **/
332 #define WRITE_DEPTH( _x, _y, d ) \
333 (*((GLushort *)y_tile_swizzle (irb, intel, _x, _y)) = d)
334
335 #define READ_DEPTH( d, _x, _y ) \
336 (d = *((GLushort *)y_tile_swizzle (irb, intel, _x, _y)))
337
338
339 #define TAG(x) intel_YTile_##x##_z16
340 #include "depthtmp.h"
341
342
343 /**
344 ** 24/8-bit interleaved depth/stencil functions
345 ** Note: we're actually reading back combined depth+stencil values.
346 ** The wrappers in main/depthstencil.c are used to extract the depth
347 ** and stencil values.
348 **/
349 /* Change ZZZS -> SZZZ */
350 #define WRITE_DEPTH( _x, _y, d ) { \
351 GLuint tmp = ((d) >> 8) | ((d) << 24); \
352 ((GLuint *)buf)[(_x) + (_y) * pitch] = tmp; \
353 }
354
355 /* Change SZZZ -> ZZZS */
356 #define READ_DEPTH( d, _x, _y ) { \
357 GLuint tmp = ((GLuint *)buf)[(_x) + (_y) * pitch]; \
358 d = (tmp << 8) | (tmp >> 24); \
359 }
360
361 #define TAG(x) intel##x##_z24_s8
362 #include "depthtmp.h"
363
364
365 /**
366 ** 24/8-bit x-tile interleaved depth/stencil functions
367 ** Note: we're actually reading back combined depth+stencil values.
368 ** The wrappers in main/depthstencil.c are used to extract the depth
369 ** and stencil values.
370 **/
371 /* Change ZZZS -> SZZZ */
372 #define WRITE_DEPTH( _x, _y, d ) { \
373 GLuint tmp = ((d) >> 8) | ((d) << 24); \
374 *((GLuint *)x_tile_swizzle (irb, intel, _x, _y)) = tmp; \
375 }
376
377 /* Change SZZZ -> ZZZS */
378 #define READ_DEPTH( d, _x, _y ) { \
379 GLuint tmp = *((GLuint *)x_tile_swizzle (irb, intel, _x, _y)); \
380 d = (tmp << 8) | (tmp >> 24); \
381 }
382
383 #define TAG(x) intel_XTile_##x##_z24_s8
384 #include "depthtmp.h"
385
386 /**
387 ** 24/8-bit y-tile interleaved depth/stencil functions
388 ** Note: we're actually reading back combined depth+stencil values.
389 ** The wrappers in main/depthstencil.c are used to extract the depth
390 ** and stencil values.
391 **/
392 /* Change ZZZS -> SZZZ */
393 #define WRITE_DEPTH( _x, _y, d ) { \
394 GLuint tmp = ((d) >> 8) | ((d) << 24); \
395 *((GLuint *)y_tile_swizzle (irb, intel, _x, _y)) = tmp; \
396 }
397
398 /* Change SZZZ -> ZZZS */
399 #define READ_DEPTH( d, _x, _y ) { \
400 GLuint tmp = *((GLuint *)y_tile_swizzle (irb, intel, _x, _y)); \
401 d = (tmp << 8) | (tmp >> 24); \
402 }
403
404 #define TAG(x) intel_YTile_##x##_z24_s8
405 #include "depthtmp.h"
406
407
408 /**
409 ** 8-bit stencil function (XXX FBO: This is obsolete)
410 **/
411 #define WRITE_STENCIL( _x, _y, d ) { \
412 GLuint tmp = ((GLuint *)buf)[(_x) + (_y) * pitch]; \
413 tmp &= 0xffffff; \
414 tmp |= ((d) << 24); \
415 ((GLuint *) buf)[(_x) + (_y) * pitch] = tmp; \
416 }
417
418 #define READ_STENCIL( d, _x, _y ) \
419 d = ((GLuint *)buf)[(_x) + (_y) * pitch] >> 24;
420
421 #define TAG(x) intel##x##_z24_s8
422 #include "stenciltmp.h"
423
424 /**
425 ** 8-bit x-tile stencil function (XXX FBO: This is obsolete)
426 **/
427 #define WRITE_STENCIL( _x, _y, d ) { \
428 GLuint *a = (GLuint *) x_tile_swizzle (irb, intel, _x, _y); \
429 GLuint tmp = *a; \
430 tmp &= 0xffffff; \
431 tmp |= ((d) << 24); \
432 *a = tmp; \
433 }
434
435 #define READ_STENCIL( d, _x, _y ) \
436 (d = *((GLuint*) x_tile_swizzle (irb, intel, _x, _y)) >> 24)
437
438 #define TAG(x) intel_XTile_##x##_z24_s8
439 #include "stenciltmp.h"
440
441 /**
442 ** 8-bit y-tile stencil function (XXX FBO: This is obsolete)
443 **/
444 #define WRITE_STENCIL( _x, _y, d ) { \
445 GLuint *a = (GLuint *) y_tile_swizzle (irb, intel, _x, _y); \
446 GLuint tmp = *a; \
447 tmp &= 0xffffff; \
448 tmp |= ((d) << 24); \
449 *a = tmp; \
450 }
451
452 #define READ_STENCIL( d, _x, _y ) \
453 (d = *((GLuint*) y_tile_swizzle (irb, intel, _x, _y)) >> 24)
454
455 #define TAG(x) intel_YTile_##x##_z24_s8
456 #include "stenciltmp.h"
457
458
459
460 /**
461 * Map or unmap all the renderbuffers which we may need during
462 * software rendering.
463 * XXX in the future, we could probably convey extra information to
464 * reduce the number of mappings needed. I.e. if doing a glReadPixels
465 * from the depth buffer, we really only need one mapping.
466 *
467 * XXX Rewrite this function someday.
468 * We can probably just loop over all the renderbuffer attachments,
469 * map/unmap all of them, and not worry about the _ColorDrawBuffers
470 * _ColorReadBuffer, _DepthBuffer or _StencilBuffer fields.
471 */
472 static void
473 intel_map_unmap_buffers(struct intel_context *intel, GLboolean map)
474 {
475 GLcontext *ctx = &intel->ctx;
476 GLuint i, j;
477 struct intel_renderbuffer *irb;
478
479 /* color draw buffers */
480 for (j = 0; j < ctx->DrawBuffer->_NumColorDrawBuffers; j++) {
481 struct gl_renderbuffer *rb = ctx->DrawBuffer->_ColorDrawBuffers[j];
482 irb = intel_renderbuffer(rb);
483 if (irb) {
484 /* this is a user-created intel_renderbuffer */
485 if (irb->region) {
486 if (map)
487 intel_region_map(intel, irb->region);
488 else
489 intel_region_unmap(intel, irb->region);
490 irb->pfMap = irb->region->map;
491 irb->pfPitch = irb->region->pitch;
492 }
493 }
494 }
495
496 /* check for render to textures */
497 for (i = 0; i < BUFFER_COUNT; i++) {
498 struct gl_renderbuffer_attachment *att =
499 ctx->DrawBuffer->Attachment + i;
500 struct gl_texture_object *tex = att->Texture;
501 if (tex) {
502 /* render to texture */
503 ASSERT(att->Renderbuffer);
504 if (map) {
505 struct gl_texture_image *texImg;
506 texImg = tex->Image[att->CubeMapFace][att->TextureLevel];
507 intel_tex_map_images(intel, intel_texture_object(tex));
508 }
509 else {
510 intel_tex_unmap_images(intel, intel_texture_object(tex));
511 }
512 }
513 }
514
515 /* color read buffers */
516 irb = intel_renderbuffer(ctx->ReadBuffer->_ColorReadBuffer);
517 if (irb && irb->region) {
518 if (map)
519 intel_region_map(intel, irb->region);
520 else
521 intel_region_unmap(intel, irb->region);
522 irb->pfMap = irb->region->map;
523 irb->pfPitch = irb->region->pitch;
524 }
525
526 /* Account for front/back color page flipping.
527 * The span routines use the pfMap and pfPitch fields which will
528 * swap the front/back region map/pitch if we're page flipped.
529 * Do this after mapping, above, so the map field is valid.
530 */
531 #if 0
532 if (map && ctx->DrawBuffer->Name == 0) {
533 struct intel_renderbuffer *irbFront
534 = intel_get_renderbuffer(ctx->DrawBuffer, BUFFER_FRONT_LEFT);
535 struct intel_renderbuffer *irbBack
536 = intel_get_renderbuffer(ctx->DrawBuffer, BUFFER_BACK_LEFT);
537 if (irbBack) {
538 /* double buffered */
539 if (intel->sarea->pf_current_page == 0) {
540 irbFront->pfMap = irbFront->region->map;
541 irbFront->pfPitch = irbFront->region->pitch;
542 irbBack->pfMap = irbBack->region->map;
543 irbBack->pfPitch = irbBack->region->pitch;
544 }
545 else {
546 irbFront->pfMap = irbBack->region->map;
547 irbFront->pfPitch = irbBack->region->pitch;
548 irbBack->pfMap = irbFront->region->map;
549 irbBack->pfPitch = irbFront->region->pitch;
550 }
551 }
552 }
553 #endif
554
555 /* depth buffer (Note wrapper!) */
556 if (ctx->DrawBuffer->_DepthBuffer) {
557 irb = intel_renderbuffer(ctx->DrawBuffer->_DepthBuffer->Wrapped);
558 if (irb && irb->region) {
559 if (map) {
560 intel_region_map(intel, irb->region);
561 irb->pfMap = irb->region->map;
562 irb->pfPitch = irb->region->pitch;
563 }
564 else {
565 intel_region_unmap(intel, irb->region);
566 irb->pfMap = irb->region->map;
567 irb->pfPitch = irb->region->pitch;
568 }
569 }
570 }
571
572 /* stencil buffer (Note wrapper!) */
573 if (ctx->DrawBuffer->_StencilBuffer) {
574 irb = intel_renderbuffer(ctx->DrawBuffer->_StencilBuffer->Wrapped);
575 if (irb && irb->region) {
576 if (map) {
577 intel_region_map(intel, irb->region);
578 irb->pfMap = irb->region->map;
579 irb->pfPitch = irb->region->pitch;
580 }
581 else {
582 intel_region_unmap(intel, irb->region);
583 irb->pfMap = irb->region->map;
584 irb->pfPitch = irb->region->pitch;
585 }
586 }
587 }
588 }
589
590
591
592 /**
593 * Prepare for softare rendering. Map current read/draw framebuffers'
594 * renderbuffes and all currently bound texture objects.
595 *
596 * Old note: Moved locking out to get reasonable span performance.
597 */
598 void
599 intelSpanRenderStart(GLcontext * ctx)
600 {
601 struct intel_context *intel = intel_context(ctx);
602 GLuint i;
603
604 intelFinish(&intel->ctx);
605 LOCK_HARDWARE(intel);
606
607 #if 0
608 /* Just map the framebuffer and all textures. Bufmgr code will
609 * take care of waiting on the necessary fences:
610 */
611 intel_region_map(intel, intel->front_region);
612 intel_region_map(intel, intel->back_region);
613 intel_region_map(intel, intel->depth_region);
614 #endif
615
616 for (i = 0; i < ctx->Const.MaxTextureCoordUnits; i++) {
617 if (ctx->Texture.Unit[i]._ReallyEnabled) {
618 struct gl_texture_object *texObj = ctx->Texture.Unit[i]._Current;
619 intel_tex_map_images(intel, intel_texture_object(texObj));
620 }
621 }
622
623 intel_map_unmap_buffers(intel, GL_TRUE);
624 }
625
626 /**
627 * Called when done softare rendering. Unmap the buffers we mapped in
628 * the above function.
629 */
630 void
631 intelSpanRenderFinish(GLcontext * ctx)
632 {
633 struct intel_context *intel = intel_context(ctx);
634 GLuint i;
635
636 _swrast_flush(ctx);
637
638 /* Now unmap the framebuffer:
639 */
640 #if 0
641 intel_region_unmap(intel, intel->front_region);
642 intel_region_unmap(intel, intel->back_region);
643 intel_region_unmap(intel, intel->depth_region);
644 #endif
645
646 for (i = 0; i < ctx->Const.MaxTextureCoordUnits; i++) {
647 if (ctx->Texture.Unit[i]._ReallyEnabled) {
648 struct gl_texture_object *texObj = ctx->Texture.Unit[i]._Current;
649 intel_tex_unmap_images(intel, intel_texture_object(texObj));
650 }
651 }
652
653 intel_map_unmap_buffers(intel, GL_FALSE);
654
655 UNLOCK_HARDWARE(intel);
656 }
657
658
659 void
660 intelInitSpanFuncs(GLcontext * ctx)
661 {
662 struct swrast_device_driver *swdd = _swrast_GetDeviceDriverReference(ctx);
663 swdd->SpanRenderStart = intelSpanRenderStart;
664 swdd->SpanRenderFinish = intelSpanRenderFinish;
665 }
666
667
668 /**
669 * Plug in appropriate span read/write functions for the given renderbuffer.
670 * These are used for the software fallbacks.
671 */
672 void
673 intel_set_span_functions(struct gl_renderbuffer *rb, int tiling)
674 {
675 if (rb->_ActualFormat == GL_RGB5) {
676 /* 565 RGB */
677 switch (tiling) {
678 case INTEL_TILE_NONE:
679 default:
680 intelInitPointers_RGB565(rb);
681 break;
682 case INTEL_TILE_X:
683 intel_XTile_InitPointers_RGB565(rb);
684 break;
685 case INTEL_TILE_Y:
686 intel_YTile_InitPointers_RGB565(rb);
687 break;
688 }
689 }
690 else if (rb->_ActualFormat == GL_RGBA8) {
691 /* 8888 RGBA */
692 switch (tiling) {
693 case INTEL_TILE_NONE:
694 default:
695 intelInitPointers_ARGB8888(rb);
696 break;
697 case INTEL_TILE_X:
698 intel_XTile_InitPointers_ARGB8888(rb);
699 break;
700 case INTEL_TILE_Y:
701 intel_YTile_InitPointers_ARGB8888(rb);
702 break;
703 }
704 }
705 else if (rb->_ActualFormat == GL_DEPTH_COMPONENT16) {
706 switch (tiling) {
707 case INTEL_TILE_NONE:
708 default:
709 intelInitDepthPointers_z16(rb);
710 break;
711 case INTEL_TILE_X:
712 intel_XTile_InitDepthPointers_z16(rb);
713 break;
714 case INTEL_TILE_Y:
715 intel_YTile_InitDepthPointers_z16(rb);
716 break;
717 }
718 }
719 else if (rb->_ActualFormat == GL_DEPTH_COMPONENT24 || /* XXX FBO remove */
720 rb->_ActualFormat == GL_DEPTH24_STENCIL8_EXT) {
721 switch (tiling) {
722 case INTEL_TILE_NONE:
723 default:
724 intelInitDepthPointers_z24_s8(rb);
725 break;
726 case INTEL_TILE_X:
727 intel_XTile_InitDepthPointers_z24_s8(rb);
728 break;
729 case INTEL_TILE_Y:
730 intel_YTile_InitDepthPointers_z24_s8(rb);
731 break;
732 }
733 }
734 else if (rb->_ActualFormat == GL_STENCIL_INDEX8_EXT) {
735 switch (tiling) {
736 case INTEL_TILE_NONE:
737 default:
738 intelInitStencilPointers_z24_s8(rb);
739 break;
740 case INTEL_TILE_X:
741 intel_XTile_InitStencilPointers_z24_s8(rb);
742 break;
743 case INTEL_TILE_Y:
744 intel_YTile_InitStencilPointers_z24_s8(rb);
745 break;
746 }
747 }
748 else {
749 _mesa_problem(NULL,
750 "Unexpected _ActualFormat in intelSetSpanFunctions");
751 }
752 }