2 * Mesa 3-D graphics library
5 * Copyright (C) 1999-2007 Brian Paul All Rights Reserved.
7 * Permission is hereby granted, free of charge, to any person obtaining a
8 * copy of this software and associated documentation files (the "Software"),
9 * to deal in the Software without restriction, including without limitation
10 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
11 * and/or sell copies of the Software, and to permit persons to whom the
12 * Software is furnished to do so, subject to the following conditions:
14 * The above copyright notice and this permission notice shall be included
15 * in all copies or substantial portions of the Software.
17 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
18 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
20 * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
21 * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
22 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
28 * Code to allow the softpipe code to write to X windows/buffers.
29 * This is a bit of a hack for now. We've basically got two different
30 * abstractions for color buffers: gl_renderbuffer and softpipe_surface.
31 * They'll need to get merged someday...
32 * For now, they're separate things that point to each other.
36 #include "glxheader.h"
42 #include "framebuffer.h"
43 #include "renderbuffer.h"
45 #include "pipe/p_state.h"
46 #include "pipe/softpipe/sp_context.h"
47 #include "pipe/softpipe/sp_surface.h"
51 * An xm_surface is derived from a softpipe_surface
55 struct softpipe_surface sps
;
56 struct xmesa_renderbuffer
*xrb
; /** ptr back to matching xmesa_renderbuffer */
57 struct gl_renderbuffer
*rb
; /* ptr to matching gl_renderbuffer */
64 static INLINE
struct xmesa_surface
*
65 xmesa_surface(struct softpipe_surface
*sps
)
67 return (struct xmesa_surface
*) sps
;
72 * quad reading/writing
73 * These functions are just wrappers around the existing renderbuffer
78 read_quad_f(struct softpipe_surface
*gs
, GLint x
, GLint y
,
79 GLfloat (*rgba
)[NUM_CHANNELS
])
81 struct xmesa_surface
*xmsurf
= xmesa_surface(gs
);
82 struct xmesa_renderbuffer
*xrb
= xmsurf
->xrb
;
84 GLfloat
*dst
= (GLfloat
*) rgba
;
86 GET_CURRENT_CONTEXT(ctx
);
87 xrb
->Base
.GetRow(ctx
, &xrb
->Base
, 2, x
, y
, temp
);
88 xrb
->Base
.GetRow(ctx
, &xrb
->Base
, 2, x
, y
+ 1, temp
+ 8);
89 for (i
= 0; i
< 16; i
++) {
90 dst
[i
] = UBYTE_TO_FLOAT(temp
[i
]);
95 read_quad_f_swz(struct softpipe_surface
*gs
, GLint x
, GLint y
,
96 GLfloat (*rrrr
)[QUAD_SIZE
])
98 struct xmesa_surface
*xmsurf
= xmesa_surface(gs
);
99 struct xmesa_renderbuffer
*xrb
= xmsurf
->xrb
;
101 GLfloat
*dst
= (GLfloat
*) rrrr
;
103 GET_CURRENT_CONTEXT(ctx
);
104 xrb
->Base
.GetRow(ctx
, &xrb
->Base
, 2, x
, y
, temp
);
105 xrb
->Base
.GetRow(ctx
, &xrb
->Base
, 2, x
, y
+ 1, temp
+ 8);
106 for (i
= 0; i
< 4; i
++) {
107 for (j
= 0; j
< 4; j
++) {
108 dst
[j
* 4 + i
] = UBYTE_TO_FLOAT(temp
[i
* 4 + j
]);
114 write_quad_f(struct softpipe_surface
*gs
, GLint x
, GLint y
,
115 GLfloat (*rgba
)[NUM_CHANNELS
])
117 struct xmesa_surface
*xmsurf
= xmesa_surface(gs
);
118 struct xmesa_renderbuffer
*xrb
= xmsurf
->xrb
;
120 const GLfloat
*src
= (const GLfloat
*) rgba
;
122 GET_CURRENT_CONTEXT(ctx
);
123 for (i
= 0; i
< 16; i
++) {
124 temp
[i
] = FLOAT_TO_UBYTE(src
[i
]);
126 xrb
->Base
.PutRow(ctx
, &xrb
->Base
, 2, x
, y
, temp
, NULL
);
127 xrb
->Base
.PutRow(ctx
, &xrb
->Base
, 2, x
, y
+ 1, temp
+ 8, NULL
);
131 write_quad_f_swz(struct softpipe_surface
*gs
, GLint x
, GLint y
,
132 GLfloat (*rrrr
)[QUAD_SIZE
])
134 struct xmesa_surface
*xmsurf
= xmesa_surface(gs
);
135 struct xmesa_renderbuffer
*xrb
= xmsurf
->xrb
;
137 const GLfloat
*src
= (const GLfloat
*) rrrr
;
139 GET_CURRENT_CONTEXT(ctx
);
140 for (i
= 0; i
< 4; i
++) {
141 for (j
= 0; j
< 4; j
++) {
142 temp
[j
* 4 + i
] = FLOAT_TO_UBYTE(src
[i
* 4 + j
]);
145 xrb
->Base
.PutRow(ctx
, &xrb
->Base
, 2, x
, y
, temp
, NULL
);
146 xrb
->Base
.PutRow(ctx
, &xrb
->Base
, 2, x
, y
+ 1, temp
+ 8, NULL
);
150 read_quad_ub(struct softpipe_surface
*gs
, GLint x
, GLint y
,
151 GLubyte (*rgba
)[NUM_CHANNELS
])
153 struct xmesa_surface
*xmsurf
= xmesa_surface(gs
);
154 struct xmesa_renderbuffer
*xrb
= xmsurf
->xrb
;
155 GET_CURRENT_CONTEXT(ctx
);
156 xrb
->Base
.GetRow(ctx
, &xrb
->Base
, 2, x
, y
, rgba
);
157 xrb
->Base
.GetRow(ctx
, &xrb
->Base
, 2, x
, y
+ 1, rgba
+ 2);
161 write_quad_ub(struct softpipe_surface
*gs
, GLint x
, GLint y
,
162 GLubyte (*rgba
)[NUM_CHANNELS
])
164 struct xmesa_surface
*xmsurf
= xmesa_surface(gs
);
165 struct xmesa_renderbuffer
*xrb
= xmsurf
->xrb
;
166 GET_CURRENT_CONTEXT(ctx
);
167 xrb
->Base
.GetRow(ctx
, &xrb
->Base
, 2, x
, y
, rgba
);
168 xrb
->Base
.GetRow(ctx
, &xrb
->Base
, 2, x
, y
+ 1, rgba
+ 2);
172 write_mono_row_ub(struct softpipe_surface
*gs
, GLuint count
, GLint x
, GLint y
,
173 GLubyte rgba
[NUM_CHANNELS
])
175 struct xmesa_surface
*xmsurf
= xmesa_surface(gs
);
176 struct xmesa_renderbuffer
*xrb
= xmsurf
->xrb
;
177 GET_CURRENT_CONTEXT(ctx
);
178 xrb
->Base
.PutMonoRow(ctx
, &xrb
->Base
, count
, x
, y
, rgba
, NULL
);
182 static struct xmesa_surface
*
183 create_surface(XMesaContext xmctx
, struct xmesa_renderbuffer
*xrb
)
185 struct xmesa_surface
*xmsurf
;
187 xmsurf
= CALLOC_STRUCT(xmesa_surface
);
190 xmsurf
->sps
.surface
.width
= xrb
->Base
.Width
;
191 xmsurf
->sps
.surface
.height
= xrb
->Base
.Height
;
193 xmsurf
->sps
.read_quad_f
= read_quad_f
;
194 xmsurf
->sps
.read_quad_f_swz
= read_quad_f_swz
;
195 xmsurf
->sps
.read_quad_ub
= read_quad_ub
;
196 xmsurf
->sps
.write_quad_f
= write_quad_f
;
197 xmsurf
->sps
.write_quad_f_swz
= write_quad_f_swz
;
198 xmsurf
->sps
.write_quad_ub
= write_quad_ub
;
199 xmsurf
->sps
.write_mono_row_ub
= write_mono_row_ub
;
203 xmsurf
->sps
.surface
.ptr
= (GLubyte
*) xrb
->ximage
->data
;
204 xmsurf
->sps
.surface
.stride
= xrb
->ximage
->bytes_per_line
;
205 xmsurf
->sps
.surface
.cpp
= xrb
->ximage
->depth
;
215 free_surface(struct softpipe_surface
*sps
)
217 /* XXX may need to do more in the future */
223 * Return generic surface pointer corresponding to the current color buffer.
225 struct pipe_surface
*
226 xmesa_get_color_surface(GLcontext
*ctx
, GLuint buf
)
228 XMesaContext xmctx
= XMESA_CONTEXT(ctx
);
229 struct gl_renderbuffer
*rb
= ctx
->DrawBuffer
->_ColorDrawBuffers
[0][buf
];
230 struct xmesa_renderbuffer
*xrb
= xmesa_renderbuffer(rb
);
231 struct softpipe_surface
*sps
= (struct softpipe_surface
*) xrb
->pSurface
;
234 xrb
->pSurface
= create_surface(xmctx
, xrb
);
236 else if (sps
->surface
.width
!= rb
->Width
||
237 sps
->surface
.height
!= rb
->Height
) {
239 xrb
->pSurface
= create_surface(xmctx
, xrb
);
242 return (struct pipe_surface
*) xrb
->pSurface
;
247 read_quad_z(struct softpipe_surface
*sps
,
248 GLint x
, GLint y
, GLfloat zzzz
[QUAD_SIZE
])
250 struct xmesa_surface
*xmsurf
= xmesa_surface(sps
);
251 struct gl_renderbuffer
*rb
= xmsurf
->rb
;
254 GET_CURRENT_CONTEXT(ctx
);
255 rb
->GetRow(ctx
, rb
, 2, x
, y
, temp
);
256 rb
->GetRow(ctx
, rb
, 2, x
, y
+ 1, temp
+ 2);
257 for (i
= 0; i
< 4; i
++) {
258 zzzz
[i
] = USHORT_TO_FLOAT(temp
[i
]);
263 write_quad_z(struct softpipe_surface
*sps
,
264 GLint x
, GLint y
, const GLfloat zzzz
[QUAD_SIZE
])
266 struct xmesa_surface
*xmsurf
= xmesa_surface(sps
);
267 struct gl_renderbuffer
*rb
= xmsurf
->rb
;
270 GET_CURRENT_CONTEXT(ctx
);
271 for (i
= 0; i
< 4; i
++) {
272 CLAMPED_FLOAT_TO_USHORT(temp
[i
], zzzz
[i
]);
274 rb
->PutRow(ctx
, rb
, 2, x
, y
, temp
, NULL
);
275 rb
->PutRow(ctx
, rb
, 2, x
, y
+ 1, temp
+ 2, NULL
);
279 static struct xmesa_surface
*
280 create_z_surface(XMesaContext xmctx
, struct gl_renderbuffer
*rb
)
282 struct xmesa_surface
*xmsurf
;
284 xmsurf
= CALLOC_STRUCT(xmesa_surface
);
286 xmsurf
->sps
.surface
.width
= rb
->Width
;
287 xmsurf
->sps
.surface
.height
= rb
->Height
;
288 xmsurf
->sps
.read_quad_z
= read_quad_z
;
289 xmsurf
->sps
.write_quad_z
= write_quad_z
;
296 * Return a pipe_surface that wraps the current Z/depth buffer.
297 * XXX this is pretty much a total hack until gl_renderbuffers and
298 * pipe_surfaces are merged...
300 struct pipe_surface
*
301 xmesa_get_z_surface(GLcontext
*ctx
)
303 XMesaContext xmctx
= XMESA_CONTEXT(ctx
);
304 struct gl_renderbuffer
*rb
= ctx
->DrawBuffer
->_DepthBuffer
;
305 static struct xmesa_surface
*xms
= NULL
;
311 xms
= create_z_surface(xmctx
, rb
);
313 else if (xms
->sps
.surface
.width
!= rb
->Width
||
314 xms
->sps
.surface
.height
!= rb
->Height
) {
315 free_surface(&xms
->sps
);
316 xms
= create_z_surface(xmctx
, rb
);
319 return (struct pipe_surface
*) &xms
->sps
.surface
;
323 struct pipe_surface
*
324 xmesa_get_stencil_surface(GLcontext
*ctx
)