intel_span.c revision 409469fb70682cd819ab405e0f92a4659381cfbe
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
42static void
43intel_set_span_functions(struct intel_context *intel,
44			 struct gl_renderbuffer *rb);
45
46#define SPAN_CACHE_SIZE		4096
47
48static void
49get_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
63static void
64clear_span_cache(struct intel_renderbuffer *irb)
65{
66   irb->span_cache_offset = -1;
67}
68
69static uint32_t
70pread_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
77static uint32_t
78pread_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
86static uint16_t
87pread_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
94static uint8_t
95pread_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
102static void
103pwrite_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
110static void
111pwrite_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
118static void
119pwrite_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
126static void
127pwrite_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
134static 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
144static 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        x += irb->region->draw_x;
154        y += irb->region->draw_y;
155
156	tile_stride = (irb->region->pitch * irb->region->cpp) << 3;
157
158	xbyte = x * irb->region->cpp;
159
160	x_tile_off = xbyte & 0x1ff;
161	y_tile_off = y & 7;
162
163	x_tile_number = xbyte >> 9;
164	y_tile_number = y >> 3;
165
166	tile_off = (y_tile_off << 9) + x_tile_off;
167
168	switch (irb->region->bit_6_swizzle) {
169	case I915_BIT_6_SWIZZLE_NONE:
170	   break;
171	case I915_BIT_6_SWIZZLE_9:
172	   tile_off ^= ((tile_off >> 3) & 64);
173	   break;
174	case I915_BIT_6_SWIZZLE_9_10:
175	   tile_off ^= ((tile_off >> 3) & 64) ^ ((tile_off >> 4) & 64);
176	   break;
177	case I915_BIT_6_SWIZZLE_9_11:
178	   tile_off ^= ((tile_off >> 3) & 64) ^ ((tile_off >> 5) & 64);
179	   break;
180	case I915_BIT_6_SWIZZLE_9_10_11:
181	   tile_off ^= ((tile_off >> 3) & 64) ^ ((tile_off >> 4) & 64) ^
182	      ((tile_off >> 5) & 64);
183	   break;
184	default:
185	   fprintf(stderr, "Unknown tile swizzling mode %d\n",
186		   irb->region->bit_6_swizzle);
187	   exit(1);
188	}
189
190	tile_base = (x_tile_number << 12) + y_tile_number * tile_stride;
191
192#if 0
193	printf("(%d,%d) -> %d + %d = %d (pitch = %d, tstride = %d)\n",
194	       x, y, tile_off, tile_base,
195	       tile_off + tile_base,
196	       irb->region->pitch, tile_stride);
197#endif
198
199	return tile_base + tile_off;
200}
201
202static uint32_t y_tile_swizzle(struct intel_renderbuffer *irb,
203			       int x, int y)
204{
205	int	tile_stride;
206	int	xbyte;
207	int	x_tile_off, y_tile_off;
208	int	x_tile_number, y_tile_number;
209	int	tile_off, tile_base;
210
211        x += irb->region->draw_x;
212        y += irb->region->draw_y;
213
214	tile_stride = (irb->region->pitch * irb->region->cpp) << 5;
215
216	xbyte = x * irb->region->cpp;
217
218	x_tile_off = xbyte & 0x7f;
219	y_tile_off = y & 0x1f;
220
221	x_tile_number = xbyte >> 7;
222	y_tile_number = y >> 5;
223
224	tile_off = ((x_tile_off & ~0xf) << 5) + (y_tile_off << 4) +
225	   (x_tile_off & 0xf);
226
227	switch (irb->region->bit_6_swizzle) {
228	case I915_BIT_6_SWIZZLE_NONE:
229	   break;
230	case I915_BIT_6_SWIZZLE_9:
231	   tile_off ^= ((tile_off >> 3) & 64);
232	   break;
233	case I915_BIT_6_SWIZZLE_9_10:
234	   tile_off ^= ((tile_off >> 3) & 64) ^ ((tile_off >> 4) & 64);
235	   break;
236	case I915_BIT_6_SWIZZLE_9_11:
237	   tile_off ^= ((tile_off >> 3) & 64) ^ ((tile_off >> 5) & 64);
238	   break;
239	case I915_BIT_6_SWIZZLE_9_10_11:
240	   tile_off ^= ((tile_off >> 3) & 64) ^ ((tile_off >> 4) & 64) ^
241	      ((tile_off >> 5) & 64);
242	   break;
243	default:
244	   fprintf(stderr, "Unknown tile swizzling mode %d\n",
245		   irb->region->bit_6_swizzle);
246	   exit(1);
247	}
248
249	tile_base = (x_tile_number << 12) + y_tile_number * tile_stride;
250
251	return tile_base + tile_off;
252}
253
254/*
255  break intelWriteRGBASpan_ARGB8888
256*/
257
258#undef DBG
259#define DBG 0
260
261#define LOCAL_VARS							\
262   struct intel_context *intel = intel_context(ctx);			\
263   struct intel_renderbuffer *irb = intel_renderbuffer(rb);		\
264   const GLint yScale = ctx->DrawBuffer->Name ? 1 : -1;			\
265   const GLint yBias = ctx->DrawBuffer->Name ? 0 : irb->Base.Height - 1;\
266   unsigned int num_cliprects;						\
267   struct drm_clip_rect *cliprects;					\
268   int x_off, y_off;							\
269   GLuint p;								\
270   (void) p;								\
271   intel_get_cliprects(intel, &cliprects, &num_cliprects, &x_off, &y_off);
272
273/* XXX FBO: this is identical to the macro in spantmp2.h except we get
274 * the cliprect info from the context, not the driDrawable.
275 * Move this into spantmp2.h someday.
276 */
277#define HW_CLIPLOOP()							\
278   do {									\
279      int _nc = num_cliprects;						\
280      while ( _nc-- ) {							\
281	 int minx = cliprects[_nc].x1 - x_off;				\
282	 int miny = cliprects[_nc].y1 - y_off;				\
283	 int maxx = cliprects[_nc].x2 - x_off;				\
284	 int maxy = cliprects[_nc].y2 - y_off;
285
286#if 0
287      }}
288#endif
289
290#define Y_FLIP(_y) ((_y) * yScale + yBias)
291
292/* XXX with GEM, these need to tell the kernel */
293#define HW_LOCK()
294
295#define HW_UNLOCK()
296
297/* Convenience macros to avoid typing the swizzle argument over and over */
298#define NO_TILE(_X, _Y) no_tile_swizzle(irb, (_X) + x_off, (_Y) + y_off)
299#define X_TILE(_X, _Y) x_tile_swizzle(irb, (_X) + x_off, (_Y) + y_off)
300#define Y_TILE(_X, _Y) y_tile_swizzle(irb, (_X) + x_off, (_Y) + y_off)
301
302/* r5g6b5 color span and pixel functions */
303#define INTEL_PIXEL_FMT GL_RGB
304#define INTEL_PIXEL_TYPE GL_UNSIGNED_SHORT_5_6_5
305#define INTEL_READ_VALUE(offset) pread_16(irb, offset)
306#define INTEL_WRITE_VALUE(offset, v) pwrite_16(irb, offset, v)
307#define INTEL_TAG(x) x##_RGB565
308#include "intel_spantmp.h"
309
310/* a4r4g4b4 color span and pixel functions */
311#define INTEL_PIXEL_FMT GL_BGRA
312#define INTEL_PIXEL_TYPE GL_UNSIGNED_SHORT_4_4_4_4_REV
313#define INTEL_READ_VALUE(offset) pread_16(irb, offset)
314#define INTEL_WRITE_VALUE(offset, v) pwrite_16(irb, offset, v)
315#define INTEL_TAG(x) x##_ARGB4444
316#include "intel_spantmp.h"
317
318/* a1r5g5b5 color span and pixel functions */
319#define INTEL_PIXEL_FMT GL_BGRA
320#define INTEL_PIXEL_TYPE GL_UNSIGNED_SHORT_1_5_5_5_REV
321#define INTEL_READ_VALUE(offset) pread_16(irb, offset)
322#define INTEL_WRITE_VALUE(offset, v) pwrite_16(irb, offset, v)
323#define INTEL_TAG(x) x##_ARGB1555
324#include "intel_spantmp.h"
325
326/* a8r8g8b8 color span and pixel functions */
327#define INTEL_PIXEL_FMT GL_BGRA
328#define INTEL_PIXEL_TYPE GL_UNSIGNED_INT_8_8_8_8_REV
329#define INTEL_READ_VALUE(offset) pread_32(irb, offset)
330#define INTEL_WRITE_VALUE(offset, v) pwrite_32(irb, offset, v)
331#define INTEL_TAG(x) x##_ARGB8888
332#include "intel_spantmp.h"
333
334/* x8r8g8b8 color span and pixel functions */
335#define INTEL_PIXEL_FMT GL_BGRA
336#define INTEL_PIXEL_TYPE GL_UNSIGNED_INT_8_8_8_8_REV
337#define INTEL_READ_VALUE(offset) pread_xrgb8888(irb, offset)
338#define INTEL_WRITE_VALUE(offset, v) pwrite_xrgb8888(irb, offset, v)
339#define INTEL_TAG(x) x##_xRGB8888
340#include "intel_spantmp.h"
341
342#define LOCAL_DEPTH_VARS						\
343   struct intel_context *intel = intel_context(ctx);			\
344   struct intel_renderbuffer *irb = intel_renderbuffer(rb);		\
345   const GLint yScale = ctx->DrawBuffer->Name ? 1 : -1;			\
346   const GLint yBias = ctx->DrawBuffer->Name ? 0 : irb->Base.Height - 1;\
347   unsigned int num_cliprects;						\
348   struct drm_clip_rect *cliprects;					\
349   int x_off, y_off;							\
350   intel_get_cliprects(intel, &cliprects, &num_cliprects, &x_off, &y_off);
351
352
353#define LOCAL_STENCIL_VARS LOCAL_DEPTH_VARS
354
355/* z16 depthbuffer functions. */
356#define INTEL_VALUE_TYPE GLushort
357#define INTEL_WRITE_DEPTH(offset, d) pwrite_16(irb, offset, d)
358#define INTEL_READ_DEPTH(offset) pread_16(irb, offset)
359#define INTEL_TAG(name) name##_z16
360#include "intel_depthtmp.h"
361
362/* z24 depthbuffer functions. */
363#define INTEL_VALUE_TYPE GLuint
364#define INTEL_WRITE_DEPTH(offset, d) pwrite_32(irb, offset, d)
365#define INTEL_READ_DEPTH(offset) pread_32(irb, offset)
366#define INTEL_TAG(name) name##_z24
367#include "intel_depthtmp.h"
368
369/* z24s8 depthbuffer functions. */
370#define INTEL_VALUE_TYPE GLuint
371#define INTEL_WRITE_DEPTH(offset, d) pwrite_32(irb, offset, d)
372#define INTEL_READ_DEPTH(offset) pread_32(irb, offset)
373#define INTEL_TAG(name) name##_z24_s8
374#include "intel_depthtmp.h"
375
376
377/**
378 ** 8-bit stencil function (XXX FBO: This is obsolete)
379 **/
380#define WRITE_STENCIL(_x, _y, d) pwrite_8(irb, NO_TILE(_x, _y) + 3, d)
381#define READ_STENCIL(d, _x, _y) d = pread_8(irb, NO_TILE(_x, _y) + 3);
382#define TAG(x) intel##x##_z24_s8
383#include "stenciltmp.h"
384
385/**
386 ** 8-bit x-tile stencil function (XXX FBO: This is obsolete)
387 **/
388#define WRITE_STENCIL(_x, _y, d) pwrite_8(irb, X_TILE(_x, _y) + 3, d)
389#define READ_STENCIL(d, _x, _y) d = pread_8(irb, X_TILE(_x, _y) + 3);
390#define TAG(x) intel_XTile_##x##_z24_s8
391#include "stenciltmp.h"
392
393/**
394 ** 8-bit y-tile stencil function (XXX FBO: This is obsolete)
395 **/
396#define WRITE_STENCIL(_x, _y, d) pwrite_8(irb, Y_TILE(_x, _y) + 3, d)
397#define READ_STENCIL(d, _x, _y) d = pread_8(irb, Y_TILE(_x, _y) + 3)
398#define TAG(x) intel_YTile_##x##_z24_s8
399#include "stenciltmp.h"
400
401void
402intel_renderbuffer_map(struct intel_context *intel, struct gl_renderbuffer *rb)
403{
404   struct intel_renderbuffer *irb = intel_renderbuffer(rb);
405
406   if (irb == NULL || irb->region == NULL)
407      return;
408
409   intel_set_span_functions(intel, rb);
410}
411
412void
413intel_renderbuffer_unmap(struct intel_context *intel,
414			 struct gl_renderbuffer *rb)
415{
416   struct intel_renderbuffer *irb = intel_renderbuffer(rb);
417
418   if (irb == NULL || irb->region == NULL)
419      return;
420
421   clear_span_cache(irb);
422
423   rb->GetRow = NULL;
424   rb->PutRow = NULL;
425}
426
427/**
428 * Map or unmap all the renderbuffers which we may need during
429 * software rendering.
430 * XXX in the future, we could probably convey extra information to
431 * reduce the number of mappings needed.  I.e. if doing a glReadPixels
432 * from the depth buffer, we really only need one mapping.
433 *
434 * XXX Rewrite this function someday.
435 * We can probably just loop over all the renderbuffer attachments,
436 * map/unmap all of them, and not worry about the _ColorDrawBuffers
437 * _ColorReadBuffer, _DepthBuffer or _StencilBuffer fields.
438 */
439static void
440intel_map_unmap_framebuffer(struct intel_context *intel,
441			    struct gl_framebuffer *fb,
442			    GLboolean map)
443{
444   GLuint i;
445
446   /* color draw buffers */
447   for (i = 0; i < fb->_NumColorDrawBuffers; i++) {
448      if (map)
449         intel_renderbuffer_map(intel, fb->_ColorDrawBuffers[i]);
450      else
451         intel_renderbuffer_unmap(intel, fb->_ColorDrawBuffers[i]);
452   }
453
454   /* color read buffer */
455   if (map)
456      intel_renderbuffer_map(intel, fb->_ColorReadBuffer);
457   else
458      intel_renderbuffer_unmap(intel, fb->_ColorReadBuffer);
459
460   /* check for render to textures */
461   for (i = 0; i < BUFFER_COUNT; i++) {
462      struct gl_renderbuffer_attachment *att =
463         fb->Attachment + i;
464      struct gl_texture_object *tex = att->Texture;
465      if (tex) {
466         /* render to texture */
467         ASSERT(att->Renderbuffer);
468         if (map)
469            intel_tex_map_images(intel, intel_texture_object(tex));
470         else
471            intel_tex_unmap_images(intel, intel_texture_object(tex));
472      }
473   }
474
475   /* depth buffer (Note wrapper!) */
476   if (fb->_DepthBuffer) {
477      if (map)
478         intel_renderbuffer_map(intel, fb->_DepthBuffer->Wrapped);
479      else
480         intel_renderbuffer_unmap(intel, fb->_DepthBuffer->Wrapped);
481   }
482
483   /* stencil buffer (Note wrapper!) */
484   if (fb->_StencilBuffer) {
485      if (map)
486         intel_renderbuffer_map(intel, fb->_StencilBuffer->Wrapped);
487      else
488         intel_renderbuffer_unmap(intel, fb->_StencilBuffer->Wrapped);
489   }
490}
491
492/**
493 * Prepare for software rendering.  Map current read/draw framebuffers'
494 * renderbuffes and all currently bound texture objects.
495 *
496 * Old note: Moved locking out to get reasonable span performance.
497 */
498void
499intelSpanRenderStart(GLcontext * ctx)
500{
501   struct intel_context *intel = intel_context(ctx);
502   GLuint i;
503
504   intelFlush(&intel->ctx);
505   LOCK_HARDWARE(intel);
506
507   for (i = 0; i < ctx->Const.MaxTextureImageUnits; i++) {
508      if (ctx->Texture.Unit[i]._ReallyEnabled) {
509         struct gl_texture_object *texObj = ctx->Texture.Unit[i]._Current;
510         intel_tex_map_images(intel, intel_texture_object(texObj));
511      }
512   }
513
514   intel_map_unmap_framebuffer(intel, ctx->DrawBuffer, GL_TRUE);
515   if (ctx->ReadBuffer != ctx->DrawBuffer)
516      intel_map_unmap_framebuffer(intel, ctx->ReadBuffer, GL_TRUE);
517}
518
519/**
520 * Called when done software rendering.  Unmap the buffers we mapped in
521 * the above function.
522 */
523void
524intelSpanRenderFinish(GLcontext * ctx)
525{
526   struct intel_context *intel = intel_context(ctx);
527   GLuint i;
528
529   _swrast_flush(ctx);
530
531   for (i = 0; i < ctx->Const.MaxTextureImageUnits; i++) {
532      if (ctx->Texture.Unit[i]._ReallyEnabled) {
533         struct gl_texture_object *texObj = ctx->Texture.Unit[i]._Current;
534         intel_tex_unmap_images(intel, intel_texture_object(texObj));
535      }
536   }
537
538   intel_map_unmap_framebuffer(intel, ctx->DrawBuffer, GL_FALSE);
539   if (ctx->ReadBuffer != ctx->DrawBuffer)
540      intel_map_unmap_framebuffer(intel, ctx->ReadBuffer, GL_FALSE);
541
542   UNLOCK_HARDWARE(intel);
543}
544
545
546void
547intelInitSpanFuncs(GLcontext * ctx)
548{
549   struct swrast_device_driver *swdd = _swrast_GetDeviceDriverReference(ctx);
550   swdd->SpanRenderStart = intelSpanRenderStart;
551   swdd->SpanRenderFinish = intelSpanRenderFinish;
552}
553
554void
555intel_map_vertex_shader_textures(GLcontext *ctx)
556{
557   struct intel_context *intel = intel_context(ctx);
558   int i;
559
560   if (ctx->VertexProgram._Current == NULL)
561      return;
562
563   for (i = 0; i < ctx->Const.MaxTextureImageUnits; i++) {
564      if (ctx->Texture.Unit[i]._ReallyEnabled &&
565	  ctx->VertexProgram._Current->Base.TexturesUsed[i] != 0) {
566         struct gl_texture_object *texObj = ctx->Texture.Unit[i]._Current;
567
568         intel_tex_map_images(intel, intel_texture_object(texObj));
569      }
570   }
571}
572
573void
574intel_unmap_vertex_shader_textures(GLcontext *ctx)
575{
576   struct intel_context *intel = intel_context(ctx);
577   int i;
578
579   if (ctx->VertexProgram._Current == NULL)
580      return;
581
582   for (i = 0; i < ctx->Const.MaxTextureImageUnits; i++) {
583      if (ctx->Texture.Unit[i]._ReallyEnabled &&
584	  ctx->VertexProgram._Current->Base.TexturesUsed[i] != 0) {
585         struct gl_texture_object *texObj = ctx->Texture.Unit[i]._Current;
586
587         intel_tex_unmap_images(intel, intel_texture_object(texObj));
588      }
589   }
590}
591
592/**
593 * Plug in appropriate span read/write functions for the given renderbuffer.
594 * These are used for the software fallbacks.
595 */
596static void
597intel_set_span_functions(struct intel_context *intel,
598			 struct gl_renderbuffer *rb)
599{
600   struct intel_renderbuffer *irb = (struct intel_renderbuffer *) rb;
601   uint32_t tiling;
602
603   /* If in GEM mode, we need to do the tile address swizzling ourselves,
604    * instead of the fence registers handling it.
605    */
606   if (intel->ttm)
607      tiling = irb->region->tiling;
608   else
609      tiling = I915_TILING_NONE;
610
611   switch (irb->texformat) {
612   case MESA_FORMAT_RGB565:
613      switch (tiling) {
614      case I915_TILING_NONE:
615      default:
616	 intelInitPointers_RGB565(rb);
617	 break;
618      case I915_TILING_X:
619	 intel_XTile_InitPointers_RGB565(rb);
620	 break;
621      case I915_TILING_Y:
622	 intel_YTile_InitPointers_RGB565(rb);
623	 break;
624      }
625      break;
626   case MESA_FORMAT_ARGB4444:
627      switch (tiling) {
628      case I915_TILING_NONE:
629      default:
630	 intelInitPointers_ARGB4444(rb);
631	 break;
632      case I915_TILING_X:
633	 intel_XTile_InitPointers_ARGB4444(rb);
634	 break;
635      case I915_TILING_Y:
636	 intel_YTile_InitPointers_ARGB4444(rb);
637	 break;
638      }
639      break;
640   case MESA_FORMAT_ARGB1555:
641      switch (tiling) {
642      case I915_TILING_NONE:
643      default:
644	 intelInitPointers_ARGB1555(rb);
645	 break;
646      case I915_TILING_X:
647	 intel_XTile_InitPointers_ARGB1555(rb);
648	 break;
649      case I915_TILING_Y:
650	 intel_YTile_InitPointers_ARGB1555(rb);
651	 break;
652      }
653      break;
654   case MESA_FORMAT_XRGB8888:
655      switch (tiling) {
656      case I915_TILING_NONE:
657      default:
658         intelInitPointers_xRGB8888(rb);
659         break;
660      case I915_TILING_X:
661         intel_XTile_InitPointers_xRGB8888(rb);
662         break;
663      case I915_TILING_Y:
664         intel_YTile_InitPointers_xRGB8888(rb);
665         break;
666      }
667      break;
668   case MESA_FORMAT_ARGB8888:
669      if (rb->_BaseFormat == GL_RGB) {
670         /* XXX remove this code someday when we enable XRGB surfaces */
671	 /* 8888 RGBx */
672	 switch (tiling) {
673	 case I915_TILING_NONE:
674	 default:
675	    intelInitPointers_xRGB8888(rb);
676	    break;
677	 case I915_TILING_X:
678	    intel_XTile_InitPointers_xRGB8888(rb);
679	    break;
680	 case I915_TILING_Y:
681	    intel_YTile_InitPointers_xRGB8888(rb);
682	    break;
683	 }
684      } else {
685	 /* 8888 RGBA */
686	 switch (tiling) {
687	 case I915_TILING_NONE:
688	 default:
689	    intelInitPointers_ARGB8888(rb);
690	    break;
691	 case I915_TILING_X:
692	    intel_XTile_InitPointers_ARGB8888(rb);
693	    break;
694	 case I915_TILING_Y:
695	    intel_YTile_InitPointers_ARGB8888(rb);
696	    break;
697	 }
698      }
699      break;
700   case MESA_FORMAT_Z16:
701      switch (tiling) {
702      case I915_TILING_NONE:
703      default:
704	 intelInitDepthPointers_z16(rb);
705	 break;
706      case I915_TILING_X:
707	 intel_XTile_InitDepthPointers_z16(rb);
708	 break;
709      case I915_TILING_Y:
710	 intel_YTile_InitDepthPointers_z16(rb);
711	 break;
712      }
713      break;
714   case MESA_FORMAT_S8_Z24:
715      /* There are a few different ways SW asks us to access the S8Z24 data:
716       * Z24 depth-only depth reads
717       * S8Z24 depth reads
718       * S8Z24 stencil reads.
719       */
720      if (rb->Format == MESA_FORMAT_S8_Z24) {
721	 switch (tiling) {
722	 case I915_TILING_NONE:
723	 default:
724	    intelInitDepthPointers_z24_s8(rb);
725	    break;
726	 case I915_TILING_X:
727	    intel_XTile_InitDepthPointers_z24_s8(rb);
728	    break;
729	 case I915_TILING_Y:
730	    intel_YTile_InitDepthPointers_z24_s8(rb);
731	    break;
732	 }
733      } else if (rb->Format == MESA_FORMAT_S8) {
734	 switch (tiling) {
735	 case I915_TILING_NONE:
736	 default:
737	    intelInitStencilPointers_z24_s8(rb);
738	    break;
739	 case I915_TILING_X:
740	    intel_XTile_InitStencilPointers_z24_s8(rb);
741	    break;
742	 case I915_TILING_Y:
743	    intel_YTile_InitStencilPointers_z24_s8(rb);
744	    break;
745	 }
746      } else {
747	 _mesa_problem(NULL,
748		       "Unexpected ActualFormat in intelSetSpanFunctions");
749      }
750      break;
751   default:
752      _mesa_problem(NULL,
753                    "Unexpected MesaFormat in intelSetSpanFunctions");
754      break;
755   }
756}
757