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 */
63 static INLINE
struct xmesa_surface
*
64 xmesa_surface(struct softpipe_surface
*sps
)
66 return (struct xmesa_surface
*) sps
;
71 * quad reading/writing
72 * These functions are just wrappers around the existing renderbuffer
77 read_quad_f(struct softpipe_surface
*gs
, GLint x
, GLint y
,
78 GLfloat (*rgba
)[NUM_CHANNELS
])
80 struct xmesa_surface
*xmsurf
= xmesa_surface(gs
);
81 struct xmesa_renderbuffer
*xrb
= xmsurf
->xrb
;
83 GLfloat
*dst
= (GLfloat
*) rgba
;
85 GET_CURRENT_CONTEXT(ctx
);
86 xrb
->Base
.GetRow(ctx
, &xrb
->Base
, 2, x
, y
, temp
);
87 xrb
->Base
.GetRow(ctx
, &xrb
->Base
, 2, x
, y
+ 1, temp
+ 8);
88 for (i
= 0; i
< 16; i
++) {
89 dst
[i
] = UBYTE_TO_FLOAT(temp
[i
]);
94 read_quad_f_swz(struct softpipe_surface
*gs
, GLint x
, GLint y
,
95 GLfloat (*rrrr
)[QUAD_SIZE
])
97 struct xmesa_surface
*xmsurf
= xmesa_surface(gs
);
98 struct xmesa_renderbuffer
*xrb
= xmsurf
->xrb
;
100 GLfloat
*dst
= (GLfloat
*) rrrr
;
102 GET_CURRENT_CONTEXT(ctx
);
103 xrb
->Base
.GetRow(ctx
, &xrb
->Base
, 2, x
, y
, temp
);
104 xrb
->Base
.GetRow(ctx
, &xrb
->Base
, 2, x
, y
+ 1, temp
+ 8);
105 for (i
= 0; i
< 4; i
++) {
106 for (j
= 0; j
< 4; j
++) {
107 dst
[j
* 4 + i
] = UBYTE_TO_FLOAT(temp
[i
* 4 + j
]);
113 write_quad_f(struct softpipe_surface
*gs
, GLint x
, GLint y
,
114 GLfloat (*rgba
)[NUM_CHANNELS
])
116 struct xmesa_surface
*xmsurf
= xmesa_surface(gs
);
117 struct xmesa_renderbuffer
*xrb
= xmsurf
->xrb
;
119 const GLfloat
*src
= (const GLfloat
*) rgba
;
121 GET_CURRENT_CONTEXT(ctx
);
122 for (i
= 0; i
< 16; i
++) {
123 temp
[i
] = FLOAT_TO_UBYTE(src
[i
]);
125 xrb
->Base
.PutRow(ctx
, &xrb
->Base
, 2, x
, y
, temp
, NULL
);
126 xrb
->Base
.PutRow(ctx
, &xrb
->Base
, 2, x
, y
+ 1, temp
+ 8, NULL
);
130 write_quad_f_swz(struct softpipe_surface
*gs
, GLint x
, GLint y
,
131 GLfloat (*rrrr
)[QUAD_SIZE
])
133 struct xmesa_surface
*xmsurf
= xmesa_surface(gs
);
134 struct xmesa_renderbuffer
*xrb
= xmsurf
->xrb
;
136 const GLfloat
*src
= (const GLfloat
*) rrrr
;
138 GET_CURRENT_CONTEXT(ctx
);
139 for (i
= 0; i
< 4; i
++) {
140 for (j
= 0; j
< 4; j
++) {
141 temp
[j
* 4 + i
] = FLOAT_TO_UBYTE(src
[i
* 4 + j
]);
144 xrb
->Base
.PutRow(ctx
, &xrb
->Base
, 2, x
, y
, temp
, NULL
);
145 xrb
->Base
.PutRow(ctx
, &xrb
->Base
, 2, x
, y
+ 1, temp
+ 8, NULL
);
149 read_quad_ub(struct softpipe_surface
*gs
, GLint x
, GLint y
,
150 GLubyte (*rgba
)[NUM_CHANNELS
])
152 struct xmesa_surface
*xmsurf
= xmesa_surface(gs
);
153 struct xmesa_renderbuffer
*xrb
= xmsurf
->xrb
;
154 GET_CURRENT_CONTEXT(ctx
);
155 xrb
->Base
.GetRow(ctx
, &xrb
->Base
, 2, x
, y
, rgba
);
156 xrb
->Base
.GetRow(ctx
, &xrb
->Base
, 2, x
, y
+ 1, rgba
+ 2);
160 write_quad_ub(struct softpipe_surface
*gs
, GLint x
, GLint y
,
161 GLubyte (*rgba
)[NUM_CHANNELS
])
163 struct xmesa_surface
*xmsurf
= xmesa_surface(gs
);
164 struct xmesa_renderbuffer
*xrb
= xmsurf
->xrb
;
165 GET_CURRENT_CONTEXT(ctx
);
166 xrb
->Base
.GetRow(ctx
, &xrb
->Base
, 2, x
, y
, rgba
);
167 xrb
->Base
.GetRow(ctx
, &xrb
->Base
, 2, x
, y
+ 1, rgba
+ 2);
171 write_mono_row_ub(struct softpipe_surface
*gs
, GLuint count
, GLint x
, GLint y
,
172 GLubyte rgba
[NUM_CHANNELS
])
174 struct xmesa_surface
*xmsurf
= xmesa_surface(gs
);
175 struct xmesa_renderbuffer
*xrb
= xmsurf
->xrb
;
176 GET_CURRENT_CONTEXT(ctx
);
177 xrb
->Base
.PutMonoRow(ctx
, &xrb
->Base
, count
, x
, y
, rgba
, NULL
);
181 static struct xmesa_surface
*
182 create_surface(XMesaContext xmctx
, struct xmesa_renderbuffer
*xrb
)
184 struct xmesa_surface
*xmsurf
;
186 xmsurf
= CALLOC_STRUCT(xmesa_surface
);
189 xmsurf
->sps
.surface
.width
= xrb
->Base
.Width
;
190 xmsurf
->sps
.surface
.height
= xrb
->Base
.Height
;
192 xmsurf
->sps
.read_quad_f
= read_quad_f
;
193 xmsurf
->sps
.read_quad_f_swz
= read_quad_f_swz
;
194 xmsurf
->sps
.read_quad_ub
= read_quad_ub
;
195 xmsurf
->sps
.write_quad_f
= write_quad_f
;
196 xmsurf
->sps
.write_quad_f_swz
= write_quad_f_swz
;
197 xmsurf
->sps
.write_quad_ub
= write_quad_ub
;
198 xmsurf
->sps
.write_mono_row_ub
= write_mono_row_ub
;
202 xmsurf
->sps
.surface
.ptr
= (GLubyte
*) xrb
->ximage
->data
;
203 xmsurf
->sps
.surface
.stride
= xrb
->ximage
->bytes_per_line
;
204 xmsurf
->sps
.surface
.cpp
= xrb
->ximage
->depth
;
214 free_surface(struct softpipe_surface
*sps
)
216 /* XXX may need to do more in the future */
222 * Return generic surface pointer corresponding to the current color buffer.
224 struct pipe_surface
*
225 xmesa_get_color_surface(GLcontext
*ctx
, GLuint buf
)
227 XMesaContext xmctx
= XMESA_CONTEXT(ctx
);
228 struct gl_renderbuffer
*rb
= ctx
->DrawBuffer
->_ColorDrawBuffers
[0][buf
];
229 struct xmesa_renderbuffer
*xrb
= xmesa_renderbuffer(rb
);
230 struct softpipe_surface
*sps
= (struct softpipe_surface
*) xrb
->pSurface
;
233 xrb
->pSurface
= create_surface(xmctx
, xrb
);
235 else if (sps
->surface
.width
!= rb
->Width
||
236 sps
->surface
.height
!= rb
->Height
) {
238 xrb
->pSurface
= create_surface(xmctx
, xrb
);
241 return (struct pipe_surface
*) xrb
->pSurface
;
245 struct pipe_surface
*
246 xmesa_get_z_surface(GLcontext
*ctx
, GLuint i
)
252 struct pipe_surface
*
253 xmesa_get_stencil_surface(GLcontext
*ctx
, GLuint i
)