winsys/xlib: sketch of cell support
[mesa.git] / src / gallium / winsys / xlib / xlib_cell.c
1 /**************************************************************************
2 *
3 * Copyright 2007 Tungsten Graphics, Inc., Bismarck, ND., USA
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 SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
17 * THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM,
18 * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
19 * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
20 * USE OR OTHER DEALINGS IN THE SOFTWARE.
21 *
22 * The above copyright notice and this permission notice (including the
23 * next paragraph) shall be included in all copies or substantial portions
24 * of the Software.
25 *
26 *
27 **************************************************************************/
28
29 /*
30 * Authors:
31 * Keith Whitwell
32 * Brian Paul
33 */
34
35
36
37
38 #include "xlib.h"
39
40
41 #if defined(GALLIUM_CELL)
42
43 #include "cell/ppu/cell_texture.h"
44 #include "cell/ppu/cell_screen.h"
45 #include "state_tracker/sw_winsys.h"
46 #include "util/u_debug.h"
47
48
49
50 /**
51 * For Cell. Basically, rearrange the pixels/quads from this layout:
52 * +--+--+--+--+
53 * |p0|p1|p2|p3|....
54 * +--+--+--+--+
55 *
56 * to this layout:
57 * +--+--+
58 * |p0|p1|....
59 * +--+--+
60 * |p2|p3|
61 * +--+--+
62 */
63 static void
64 twiddle_tile(const uint *tileIn, uint *tileOut)
65 {
66 int y, x;
67
68 for (y = 0; y < TILE_SIZE; y+=2) {
69 for (x = 0; x < TILE_SIZE; x+=2) {
70 int k = 4 * (y/2 * TILE_SIZE/2 + x/2);
71 tileOut[y * TILE_SIZE + (x + 0)] = tileIn[k];
72 tileOut[y * TILE_SIZE + (x + 1)] = tileIn[k+1];
73 tileOut[(y + 1) * TILE_SIZE + (x + 0)] = tileIn[k+2];
74 tileOut[(y + 1) * TILE_SIZE + (x + 1)] = tileIn[k+3];
75 }
76 }
77 }
78
79 /**
80 * Display a surface that's in a tiled configuration. That is, all the
81 * pixels for a TILE_SIZExTILE_SIZE block are contiguous in memory.
82 */
83 static void
84 xm_displaytarget_display(struct sw_winsys *ws,
85 struct sw_displaytarget *dt,
86 void *winsys_drawable)
87 {
88 struct xmesa_buffer *xm_buffer = (struct xm_drawable *)winsys_drawable;
89 XImage *ximage;
90 struct xm_buffer *xm_buf = xm_buffer(
91 cell_texture(surf->texture)->buffer);
92 const uint tilesPerRow = (surf->width + TILE_SIZE - 1) / TILE_SIZE;
93 uint x, y;
94
95 ximage = b->tempImage;
96
97 /* check that the XImage has been previously initialized */
98 assert(ximage->format);
99 assert(ximage->bitmap_unit);
100
101 /* update XImage's fields */
102 ximage->width = TILE_SIZE;
103 ximage->height = TILE_SIZE;
104 ximage->bytes_per_line = TILE_SIZE * 4;
105
106 for (y = 0; y < surf->height; y += TILE_SIZE) {
107 for (x = 0; x < surf->width; x += TILE_SIZE) {
108 uint tmpTile[TILE_SIZE * TILE_SIZE];
109 int tx = x / TILE_SIZE;
110 int ty = y / TILE_SIZE;
111 int offset = ty * tilesPerRow + tx;
112 int w = TILE_SIZE;
113 int h = TILE_SIZE;
114
115 if (y + h > surf->height)
116 h = surf->height - y;
117 if (x + w > surf->width)
118 w = surf->width - x;
119
120 /* offset in pixels */
121 offset *= TILE_SIZE * TILE_SIZE;
122
123 /* twiddle from ximage buffer to temp tile */
124 twiddle_tile((uint *) xm_buf->data + offset, tmpTile);
125 /* display temp tile data */
126 ximage->data = (char *) tmpTile;
127 XPutImage(b->xm_visual->display, b->drawable, b->gc,
128 ximage, 0, 0, x, y, w, h);
129 }
130 }
131 }
132
133
134
135 static struct pipe_screen *
136 xlib_create_cell_screen( Display *dpy )
137 {
138 struct sw_winsys *winsys;
139 struct pipe_screen *screen;
140
141 winsys = xlib_create_sw_winsys( dpy );
142 if (winsys == NULL)
143 return NULL;
144
145 /* Plug in a little cell-specific code:
146 */
147
148 ws->base.displaytarget_display = xm_cell_displaytarget_display;
149
150 screen = cell_create_screen(winsys);
151 if (screen == NULL)
152 goto fail;
153
154 return screen;
155
156 fail:
157 if (winsys)
158 winsys->destroy( winsys );
159
160 return NULL;
161 }
162
163
164
165
166 struct xm_driver xlib_cell_driver =
167 {
168 .create_pipe_screen = xlib_create_cell_screen,
169 };
170
171
172
173 #endif /* GALLIUM_CELL */