1
/**************************************************************************
3
* Copyright 2007 Tungsten Graphics, Inc., Bismarck, ND., USA
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:
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.
22
* The above copyright notice and this permission notice (including the
23
* next paragraph) shall be included in all copies or substantial portions
27
**************************************************************************/
44
#include "util/u_simple_screen.h"
45
#include "pipe/p_format.h"
46
#include "pipe/p_context.h"
47
#include "util/u_inlines.h"
48
#include "util/u_format.h"
49
#include "util/u_math.h"
50
#include "util/u_memory.h"
52
#include "cell/ppu/cell_context.h"
53
#include "cell/ppu/cell_screen.h"
54
#include "cell/ppu/cell_winsys.h"
55
#include "cell/ppu/cell_texture.h"
59
* Subclass of pipe_buffer for Xlib winsys.
60
* Low-level OS/window system memory buffer
64
struct pipe_buffer base;
65
boolean userBuffer; /** Is this a user-space buffer? */
75
* Subclass of pipe_winsys for Xlib winsys
77
struct xmesa_pipe_winsys
79
struct pipe_winsys base;
85
static INLINE struct xm_buffer *
86
xm_buffer( struct pipe_buffer *buf )
88
return (struct xm_buffer *)buf;
92
/* Most callbacks map direcly onto dri_bufmgr operations:
95
xm_buffer_map(struct pipe_winsys *pws, struct pipe_buffer *buf,
98
struct xm_buffer *xm_buf = xm_buffer(buf);
99
xm_buf->mapped = xm_buf->data;
100
return xm_buf->mapped;
104
xm_buffer_unmap(struct pipe_winsys *pws, struct pipe_buffer *buf)
106
struct xm_buffer *xm_buf = xm_buffer(buf);
107
xm_buf->mapped = NULL;
111
xm_buffer_destroy(/*struct pipe_winsys *pws,*/
112
struct pipe_buffer *buf)
114
struct xm_buffer *oldBuf = xm_buffer(buf);
118
if (!oldBuf->userBuffer) {
119
align_free(oldBuf->data);
130
* For Cell. Basically, rearrange the pixels/quads from this layout:
143
twiddle_tile(const uint *tileIn, uint *tileOut)
147
for (y = 0; y < TILE_SIZE; y+=2) {
148
for (x = 0; x < TILE_SIZE; x+=2) {
149
int k = 4 * (y/2 * TILE_SIZE/2 + x/2);
150
tileOut[y * TILE_SIZE + (x + 0)] = tileIn[k];
151
tileOut[y * TILE_SIZE + (x + 1)] = tileIn[k+1];
152
tileOut[(y + 1) * TILE_SIZE + (x + 0)] = tileIn[k+2];
153
tileOut[(y + 1) * TILE_SIZE + (x + 1)] = tileIn[k+3];
161
* Display a surface that's in a tiled configuration. That is, all the
162
* pixels for a TILE_SIZExTILE_SIZE block are contiguous in memory.
165
xlib_cell_display_surface(struct xmesa_buffer *b, struct pipe_surface *surf)
168
struct xm_buffer *xm_buf = xm_buffer(
169
cell_texture(surf->texture)->buffer);
170
const uint tilesPerRow = (surf->width + TILE_SIZE - 1) / TILE_SIZE;
173
ximage = b->tempImage;
175
/* check that the XImage has been previously initialized */
176
assert(ximage->format);
177
assert(ximage->bitmap_unit);
179
/* update XImage's fields */
180
ximage->width = TILE_SIZE;
181
ximage->height = TILE_SIZE;
182
ximage->bytes_per_line = TILE_SIZE * 4;
184
for (y = 0; y < surf->height; y += TILE_SIZE) {
185
for (x = 0; x < surf->width; x += TILE_SIZE) {
186
uint tmpTile[TILE_SIZE * TILE_SIZE];
187
int tx = x / TILE_SIZE;
188
int ty = y / TILE_SIZE;
189
int offset = ty * tilesPerRow + tx;
193
if (y + h > surf->height)
194
h = surf->height - y;
195
if (x + w > surf->width)
198
/* offset in pixels */
199
offset *= TILE_SIZE * TILE_SIZE;
201
/* twiddle from ximage buffer to temp tile */
202
twiddle_tile((uint *) xm_buf->data + offset, tmpTile);
203
/* display temp tile data */
204
ximage->data = (char *) tmpTile;
205
XPutImage(b->xm_visual->display, b->drawable, b->gc,
206
ximage, 0, 0, x, y, w, h);
216
xm_flush_frontbuffer(struct pipe_winsys *pws,
217
struct pipe_surface *surf,
218
void *context_private)
221
* The front color buffer is actually just another XImage buffer.
222
* This function copies that XImage to the actual X Window.
224
XMesaContext xmctx = (XMesaContext) context_private;
226
xlib_cell_display_surface(xmctx->xm_buffer, surf);
232
xm_get_name(struct pipe_winsys *pws)
238
static struct pipe_buffer *
239
xm_buffer_create(struct pipe_winsys *pws,
244
struct xm_buffer *buffer = CALLOC_STRUCT(xm_buffer);
246
pipe_reference_init(&buffer->base.reference, 1);
247
buffer->base.alignment = alignment;
248
buffer->base.usage = usage;
249
buffer->base.size = size;
252
if (buffer->data == NULL) {
255
/* align to 16-byte multiple for Cell */
256
buffer->data = align_malloc(size, max(alignment, 16));
259
return &buffer->base;
264
* Create buffer which wraps user-space data.
266
static struct pipe_buffer *
267
xm_user_buffer_create(struct pipe_winsys *pws, void *ptr, unsigned bytes)
269
struct xm_buffer *buffer = CALLOC_STRUCT(xm_buffer);
270
pipe_reference_init(&buffer->base.reference, 1);
271
buffer->base.size = bytes;
272
buffer->userBuffer = TRUE;
276
return &buffer->base;
281
static struct pipe_buffer *
282
xm_surface_buffer_create(struct pipe_winsys *winsys,
283
unsigned width, unsigned height,
284
enum pipe_format format,
289
const unsigned alignment = 64;
292
nblocksy = util_format_get_nblocksy(format, height);
293
*stride = align(util_format_get_stride(format, width), alignment);
295
return winsys->buffer_create(winsys, alignment,
297
/* XXX a bit of a hack */
298
*stride * align(nblocksy, TILE_SIZE));
303
* Fence functions - basically nothing to do, as we don't create any actual
308
xm_fence_reference(struct pipe_winsys *sws, struct pipe_fence_handle **ptr,
309
struct pipe_fence_handle *fence)
315
xm_fence_signalled(struct pipe_winsys *sws, struct pipe_fence_handle *fence,
323
xm_fence_finish(struct pipe_winsys *sws, struct pipe_fence_handle *fence,
331
static struct pipe_winsys *
332
xlib_create_cell_winsys( void )
334
static struct xmesa_pipe_winsys *ws = NULL;
337
ws = CALLOC_STRUCT(xmesa_pipe_winsys);
339
/* Fill in this struct with callbacks that pipe will need to
340
* communicate with the window system, buffer manager, etc.
342
ws->base.buffer_create = xm_buffer_create;
343
ws->base.user_buffer_create = xm_user_buffer_create;
344
ws->base.buffer_map = xm_buffer_map;
345
ws->base.buffer_unmap = xm_buffer_unmap;
346
ws->base.buffer_destroy = xm_buffer_destroy;
348
ws->base.surface_buffer_create = xm_surface_buffer_create;
350
ws->base.fence_reference = xm_fence_reference;
351
ws->base.fence_signalled = xm_fence_signalled;
352
ws->base.fence_finish = xm_fence_finish;
354
ws->base.flush_frontbuffer = xm_flush_frontbuffer;
355
ws->base.get_name = xm_get_name;
362
static struct pipe_screen *
363
xlib_create_cell_screen( void )
365
struct pipe_winsys *winsys;
366
struct pipe_screen *screen;
368
winsys = xlib_create_cell_winsys();
372
screen = cell_create_screen(winsys);
380
winsys->destroy( winsys );
387
struct xm_driver xlib_cell_driver =
389
.create_pipe_screen = xlib_create_cell_screen,
390
.display_surface = xlib_cell_display_surface,
395
struct xm_driver xlib_cell_driver =
397
.create_pipe_screen = NULL,
398
.display_surface = NULL,