1 | /*
|
---|
2 | * Mesa 3-D graphics library
|
---|
3 | * Version: 6.3
|
---|
4 | *
|
---|
5 | * Copyright (C) 1999-2005 Brian Paul All Rights Reserved.
|
---|
6 | *
|
---|
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:
|
---|
13 | *
|
---|
14 | * The above copyright notice and this permission notice shall be included
|
---|
15 | * in all copies or substantial portions of the Software.
|
---|
16 | *
|
---|
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.
|
---|
23 | */
|
---|
24 |
|
---|
25 | /* Minimal swrast-based dri loadable driver.
|
---|
26 | *
|
---|
27 | * Todo:
|
---|
28 | * -- Use malloced (rather than framebuffer) memory for backbuffer
|
---|
29 | * -- 32bpp is hardwired -- fix
|
---|
30 | *
|
---|
31 | * NOTES:
|
---|
32 | * -- No mechanism for cliprects or resize notification --
|
---|
33 | * assumes this is a fullscreen device.
|
---|
34 | * -- No locking -- assumes this is the only driver accessing this
|
---|
35 | * device.
|
---|
36 | * -- Doesn't (yet) make use of any acceleration or other interfaces
|
---|
37 | * provided by fb. Would be entirely happy working against any
|
---|
38 | * fullscreen interface.
|
---|
39 | * -- HOWEVER: only a small number of pixelformats are supported, and
|
---|
40 | * the mechanism for choosing between them makes some assumptions
|
---|
41 | * that may not be valid everywhere.
|
---|
42 | */
|
---|
43 |
|
---|
44 | #include "driver.h"
|
---|
45 | #include "drm.h"
|
---|
46 | #include "utils.h"
|
---|
47 | #include "drirenderbuffer.h"
|
---|
48 |
|
---|
49 | #include "buffers.h"
|
---|
50 | #include "extensions.h"
|
---|
51 | #include "framebuffer.h"
|
---|
52 | #include "renderbuffer.h"
|
---|
53 | #include "vbo/vbo.h"
|
---|
54 | #include "swrast/swrast.h"
|
---|
55 | #include "swrast_setup/swrast_setup.h"
|
---|
56 | #include "tnl/tnl.h"
|
---|
57 | #include "tnl/t_context.h"
|
---|
58 | #include "tnl/t_pipeline.h"
|
---|
59 | #include "drivers/common/driverfuncs.h"
|
---|
60 |
|
---|
61 | #define need_GL_VERSION_1_3
|
---|
62 | #define need_GL_VERSION_1_4
|
---|
63 | #define need_GL_VERSION_1_5
|
---|
64 | #define need_GL_VERSION_2_0
|
---|
65 | #define need_GL_VERSION_2_1
|
---|
66 |
|
---|
67 | /* sw extensions for imaging */
|
---|
68 | #define need_GL_EXT_blend_color
|
---|
69 | #define need_GL_EXT_blend_minmax
|
---|
70 | #define need_GL_EXT_convolution
|
---|
71 | #define need_GL_EXT_histogram
|
---|
72 | #define need_GL_SGI_color_table
|
---|
73 |
|
---|
74 | /* sw extensions not associated with some GL version */
|
---|
75 | #define need_GL_ARB_shader_objects
|
---|
76 | #define need_GL_ARB_vertex_program
|
---|
77 | #define need_GL_APPLE_vertex_array_object
|
---|
78 | #define need_GL_ATI_fragment_shader
|
---|
79 | #define need_GL_EXT_depth_bounds_test
|
---|
80 | #define need_GL_EXT_framebuffer_object
|
---|
81 | #define need_GL_EXT_framebuffer_blit
|
---|
82 | #define need_GL_EXT_gpu_program_parameters
|
---|
83 | #define need_GL_EXT_paletted_texture
|
---|
84 | #define need_GL_IBM_multimode_draw_arrays
|
---|
85 | #define need_GL_MESA_resize_buffers
|
---|
86 | #define need_GL_NV_vertex_program
|
---|
87 | #define need_GL_NV_fragment_program
|
---|
88 |
|
---|
89 | #include "extension_helper.h"
|
---|
90 |
|
---|
91 | const struct dri_extension card_extensions[] =
|
---|
92 | {
|
---|
93 | { "GL_VERSION_1_3", GL_VERSION_1_3_functions },
|
---|
94 | { "GL_VERSION_1_4", GL_VERSION_1_4_functions },
|
---|
95 | { "GL_VERSION_1_5", GL_VERSION_1_5_functions },
|
---|
96 | { "GL_VERSION_2_0", GL_VERSION_2_0_functions },
|
---|
97 | { "GL_VERSION_2_1", GL_VERSION_2_1_functions },
|
---|
98 |
|
---|
99 | { "GL_EXT_blend_color", GL_EXT_blend_color_functions },
|
---|
100 | { "GL_EXT_blend_minmax", GL_EXT_blend_minmax_functions },
|
---|
101 | { "GL_EXT_convolution", GL_EXT_convolution_functions },
|
---|
102 | { "GL_EXT_histogram", GL_EXT_histogram_functions },
|
---|
103 | { "GL_SGI_color_table", GL_SGI_color_table_functions },
|
---|
104 |
|
---|
105 | { "GL_ARB_shader_objects", GL_ARB_shader_objects_functions },
|
---|
106 | { "GL_ARB_vertex_program", GL_ARB_vertex_program_functions },
|
---|
107 | { "GL_APPLE_vertex_array_object", GL_APPLE_vertex_array_object_functions },
|
---|
108 | { "GL_ATI_fragment_shader", GL_ATI_fragment_shader_functions },
|
---|
109 | { "GL_EXT_depth_bounds_test", GL_EXT_depth_bounds_test_functions },
|
---|
110 | { "GL_EXT_framebuffer_object", GL_EXT_framebuffer_object_functions },
|
---|
111 | { "GL_EXT_framebuffer_blit", GL_EXT_framebuffer_blit_functions },
|
---|
112 | { "GL_EXT_gpu_program_parameters", GL_EXT_gpu_program_parameters_functions },
|
---|
113 | { "GL_EXT_paletted_texture", GL_EXT_paletted_texture_functions },
|
---|
114 | { "GL_IBM_multimode_draw_arrays", GL_IBM_multimode_draw_arrays_functions },
|
---|
115 | { "GL_MESA_resize_buffers", GL_MESA_resize_buffers_functions },
|
---|
116 | { "GL_NV_vertex_program", GL_NV_vertex_program_functions },
|
---|
117 | { "GL_NV_fragment_program", GL_NV_fragment_program_functions },
|
---|
118 | { NULL, NULL }
|
---|
119 | };
|
---|
120 |
|
---|
121 | void fbSetSpanFunctions(driRenderbuffer *drb, const GLvisual *vis);
|
---|
122 |
|
---|
123 | typedef struct {
|
---|
124 | GLcontext *glCtx; /* Mesa context */
|
---|
125 |
|
---|
126 | struct {
|
---|
127 | __DRIcontextPrivate *context;
|
---|
128 | __DRIscreenPrivate *screen;
|
---|
129 | __DRIdrawablePrivate *drawable; /* drawable bound to this ctx */
|
---|
130 | } dri;
|
---|
131 |
|
---|
132 | } fbContext, *fbContextPtr;
|
---|
133 |
|
---|
134 | #define FB_CONTEXT(ctx) ((fbContextPtr)(ctx->DriverCtx))
|
---|
135 |
|
---|
136 |
|
---|
137 | static const GLubyte *
|
---|
138 | get_string(GLcontext *ctx, GLenum pname)
|
---|
139 | {
|
---|
140 | (void) ctx;
|
---|
141 | switch (pname) {
|
---|
142 | case GL_RENDERER:
|
---|
143 | return (const GLubyte *) "Mesa dumb framebuffer";
|
---|
144 | default:
|
---|
145 | return NULL;
|
---|
146 | }
|
---|
147 | }
|
---|
148 |
|
---|
149 |
|
---|
150 | static void
|
---|
151 | update_state( GLcontext *ctx, GLuint new_state )
|
---|
152 | {
|
---|
153 | /* not much to do here - pass it on */
|
---|
154 | _swrast_InvalidateState( ctx, new_state );
|
---|
155 | _swsetup_InvalidateState( ctx, new_state );
|
---|
156 | _vbo_InvalidateState( ctx, new_state );
|
---|
157 | _tnl_InvalidateState( ctx, new_state );
|
---|
158 | }
|
---|
159 |
|
---|
160 |
|
---|
161 | /**
|
---|
162 | * Called by ctx->Driver.GetBufferSize from in core Mesa to query the
|
---|
163 | * current framebuffer size.
|
---|
164 | */
|
---|
165 | static void
|
---|
166 | get_buffer_size( GLframebuffer *buffer, GLuint *width, GLuint *height )
|
---|
167 | {
|
---|
168 | GET_CURRENT_CONTEXT(ctx);
|
---|
169 | fbContextPtr fbmesa = FB_CONTEXT(ctx);
|
---|
170 |
|
---|
171 | *width = fbmesa->dri.drawable->w;
|
---|
172 | *height = fbmesa->dri.drawable->h;
|
---|
173 | }
|
---|
174 |
|
---|
175 |
|
---|
176 | static void
|
---|
177 | updateFramebufferSize(GLcontext *ctx)
|
---|
178 | {
|
---|
179 | fbContextPtr fbmesa = FB_CONTEXT(ctx);
|
---|
180 | struct gl_framebuffer *fb = ctx->WinSysDrawBuffer;
|
---|
181 | if (fbmesa->dri.drawable->w != fb->Width ||
|
---|
182 | fbmesa->dri.drawable->h != fb->Height) {
|
---|
183 | driUpdateFramebufferSize(ctx, fbmesa->dri.drawable);
|
---|
184 | }
|
---|
185 | }
|
---|
186 |
|
---|
187 | static void
|
---|
188 | viewport(GLcontext *ctx, GLint x, GLint y, GLsizei w, GLsizei h)
|
---|
189 | {
|
---|
190 | /* XXX this should be called after we acquire the DRI lock, not here */
|
---|
191 | updateFramebufferSize(ctx);
|
---|
192 | }
|
---|
193 |
|
---|
194 |
|
---|
195 | static void
|
---|
196 | init_core_functions( struct dd_function_table *functions )
|
---|
197 | {
|
---|
198 | functions->GetString = get_string;
|
---|
199 | functions->UpdateState = update_state;
|
---|
200 | functions->GetBufferSize = get_buffer_size;
|
---|
201 | functions->Viewport = viewport;
|
---|
202 |
|
---|
203 | functions->Clear = _swrast_Clear; /* could accelerate with blits */
|
---|
204 | }
|
---|
205 |
|
---|
206 |
|
---|
207 | /*
|
---|
208 | * Generate code for span functions.
|
---|
209 | */
|
---|
210 |
|
---|
211 | /* 24-bit BGR */
|
---|
212 | #define NAME(PREFIX) PREFIX##_B8G8R8
|
---|
213 | #define RB_TYPE GLubyte
|
---|
214 | #define SPAN_VARS \
|
---|
215 | driRenderbuffer *drb = (driRenderbuffer *) rb;
|
---|
216 | #define INIT_PIXEL_PTR(P, X, Y) \
|
---|
217 | GLubyte *P = (GLubyte *)drb->Base.Data + (drb->Base.Height - (Y)) * drb->pitch + (X) * 3;
|
---|
218 | #define INC_PIXEL_PTR(P) P += 3
|
---|
219 | #define STORE_PIXEL(DST, X, Y, VALUE) \
|
---|
220 | DST[0] = VALUE[BCOMP]; \
|
---|
221 | DST[1] = VALUE[GCOMP]; \
|
---|
222 | DST[2] = VALUE[RCOMP]
|
---|
223 | #define FETCH_PIXEL(DST, SRC) \
|
---|
224 | DST[RCOMP] = SRC[2]; \
|
---|
225 | DST[GCOMP] = SRC[1]; \
|
---|
226 | DST[BCOMP] = SRC[0]; \
|
---|
227 | DST[ACOMP] = 0xff
|
---|
228 |
|
---|
229 | #include "swrast/s_spantemp.h"
|
---|
230 |
|
---|
231 |
|
---|
232 | /* 32-bit BGRA */
|
---|
233 | #define NAME(PREFIX) PREFIX##_B8G8R8A8
|
---|
234 | #define RB_TYPE GLubyte
|
---|
235 | #define SPAN_VARS \
|
---|
236 | driRenderbuffer *drb = (driRenderbuffer *) rb;
|
---|
237 | #define INIT_PIXEL_PTR(P, X, Y) \
|
---|
238 | GLubyte *P = (GLubyte *)drb->Base.Data + (drb->Base.Height - (Y)) * drb->pitch + (X) * 4;
|
---|
239 | #define INC_PIXEL_PTR(P) P += 4
|
---|
240 | #define STORE_PIXEL(DST, X, Y, VALUE) \
|
---|
241 | DST[0] = VALUE[BCOMP]; \
|
---|
242 | DST[1] = VALUE[GCOMP]; \
|
---|
243 | DST[2] = VALUE[RCOMP]; \
|
---|
244 | DST[3] = VALUE[ACOMP]
|
---|
245 | #define STORE_PIXEL_RGB(DST, X, Y, VALUE) \
|
---|
246 | DST[0] = VALUE[BCOMP]; \
|
---|
247 | DST[1] = VALUE[GCOMP]; \
|
---|
248 | DST[2] = VALUE[RCOMP]; \
|
---|
249 | DST[3] = 0xff
|
---|
250 | #define FETCH_PIXEL(DST, SRC) \
|
---|
251 | DST[RCOMP] = SRC[2]; \
|
---|
252 | DST[GCOMP] = SRC[1]; \
|
---|
253 | DST[BCOMP] = SRC[0]; \
|
---|
254 | DST[ACOMP] = SRC[3]
|
---|
255 |
|
---|
256 | #include "swrast/s_spantemp.h"
|
---|
257 |
|
---|
258 |
|
---|
259 | /* 16-bit BGR (XXX implement dithering someday) */
|
---|
260 | #define NAME(PREFIX) PREFIX##_B5G6R5
|
---|
261 | #define RB_TYPE GLubyte
|
---|
262 | #define SPAN_VARS \
|
---|
263 | driRenderbuffer *drb = (driRenderbuffer *) rb;
|
---|
264 | #define INIT_PIXEL_PTR(P, X, Y) \
|
---|
265 | GLushort *P = (GLushort *)drb->Base.Data + (drb->Base.Height - (Y)) * drb->pitch + (X) * 2;
|
---|
266 | #define INC_PIXEL_PTR(P) P += 1
|
---|
267 | #define STORE_PIXEL(DST, X, Y, VALUE) \
|
---|
268 | DST[0] = ( (((VALUE[RCOMP]) & 0xf8) << 8) | (((VALUE[GCOMP]) & 0xfc) << 3) | ((VALUE[BCOMP]) >> 3) )
|
---|
269 | #define FETCH_PIXEL(DST, SRC) \
|
---|
270 | DST[RCOMP] = ( (((SRC[0]) >> 8) & 0xf8) | (((SRC[0]) >> 11) & 0x7) ); \
|
---|
271 | DST[GCOMP] = ( (((SRC[0]) >> 3) & 0xfc) | (((SRC[0]) >> 5) & 0x3) ); \
|
---|
272 | DST[BCOMP] = ( (((SRC[0]) << 3) & 0xf8) | (((SRC[0]) ) & 0x7) ); \
|
---|
273 | DST[ACOMP] = 0xff
|
---|
274 |
|
---|
275 | #include "swrast/s_spantemp.h"
|
---|
276 |
|
---|
277 |
|
---|
278 | /* 15-bit BGR (XXX implement dithering someday) */
|
---|
279 | #define NAME(PREFIX) PREFIX##_B5G5R5
|
---|
280 | #define RB_TYPE GLubyte
|
---|
281 | #define SPAN_VARS \
|
---|
282 | driRenderbuffer *drb = (driRenderbuffer *) rb;
|
---|
283 | #define INIT_PIXEL_PTR(P, X, Y) \
|
---|
284 | GLushort *P = (GLushort *)drb->Base.Data + (drb->Base.Height - (Y)) * drb->pitch + (X) * 2;
|
---|
285 | #define INC_PIXEL_PTR(P) P += 1
|
---|
286 | #define STORE_PIXEL(DST, X, Y, VALUE) \
|
---|
287 | DST[0] = ( (((VALUE[RCOMP]) & 0xf8) << 7) | (((VALUE[GCOMP]) & 0xf8) << 2) | ((VALUE[BCOMP]) >> 3) )
|
---|
288 | #define FETCH_PIXEL(DST, SRC) \
|
---|
289 | DST[RCOMP] = ( (((SRC[0]) >> 7) & 0xf8) | (((SRC[0]) >> 10) & 0x7) ); \
|
---|
290 | DST[GCOMP] = ( (((SRC[0]) >> 2) & 0xf8) | (((SRC[0]) >> 5) & 0x7) ); \
|
---|
291 | DST[BCOMP] = ( (((SRC[0]) << 3) & 0xf8) | (((SRC[0]) ) & 0x7) ); \
|
---|
292 | DST[ACOMP] = 0xff
|
---|
293 |
|
---|
294 | #include "swrast/s_spantemp.h"
|
---|
295 |
|
---|
296 |
|
---|
297 | /* 8-bit color index */
|
---|
298 | #define NAME(PREFIX) PREFIX##_CI8
|
---|
299 | #define CI_MODE
|
---|
300 | #define RB_TYPE GLubyte
|
---|
301 | #define SPAN_VARS \
|
---|
302 | driRenderbuffer *drb = (driRenderbuffer *) rb;
|
---|
303 | #define INIT_PIXEL_PTR(P, X, Y) \
|
---|
304 | GLubyte *P = (GLubyte *)drb->Base.Data + (drb->Base.Height - (Y)) * drb->pitch + (X);
|
---|
305 | #define INC_PIXEL_PTR(P) P += 1
|
---|
306 | #define STORE_PIXEL(DST, X, Y, VALUE) \
|
---|
307 | *DST = VALUE[0]
|
---|
308 | #define FETCH_PIXEL(DST, SRC) \
|
---|
309 | DST = SRC[0]
|
---|
310 |
|
---|
311 | #include "swrast/s_spantemp.h"
|
---|
312 |
|
---|
313 |
|
---|
314 |
|
---|
315 | void
|
---|
316 | fbSetSpanFunctions(driRenderbuffer *drb, const GLvisual *vis)
|
---|
317 | {
|
---|
318 | ASSERT(drb->Base.InternalFormat == GL_RGBA);
|
---|
319 | if (drb->Base.InternalFormat == GL_RGBA) {
|
---|
320 | if (vis->redBits == 5 && vis->greenBits == 6 && vis->blueBits == 5) {
|
---|
321 | drb->Base.GetRow = get_row_B5G6R5;
|
---|
322 | drb->Base.GetValues = get_values_B5G6R5;
|
---|
323 | drb->Base.PutRow = put_row_B5G6R5;
|
---|
324 | drb->Base.PutMonoRow = put_mono_row_B5G6R5;
|
---|
325 | drb->Base.PutRowRGB = put_row_rgb_B5G6R5;
|
---|
326 | drb->Base.PutValues = put_values_B5G6R5;
|
---|
327 | drb->Base.PutMonoValues = put_mono_values_B5G6R5;
|
---|
328 | }
|
---|
329 | else if (vis->redBits == 5 && vis->greenBits == 5 && vis->blueBits == 5) {
|
---|
330 | drb->Base.GetRow = get_row_B5G5R5;
|
---|
331 | drb->Base.GetValues = get_values_B5G5R5;
|
---|
332 | drb->Base.PutRow = put_row_B5G5R5;
|
---|
333 | drb->Base.PutMonoRow = put_mono_row_B5G5R5;
|
---|
334 | drb->Base.PutRowRGB = put_row_rgb_B5G5R5;
|
---|
335 | drb->Base.PutValues = put_values_B5G5R5;
|
---|
336 | drb->Base.PutMonoValues = put_mono_values_B5G5R5;
|
---|
337 | }
|
---|
338 | else if (vis->redBits == 8 && vis->greenBits == 8 && vis->blueBits == 8
|
---|
339 | && vis->alphaBits == 8) {
|
---|
340 | drb->Base.GetRow = get_row_B8G8R8A8;
|
---|
341 | drb->Base.GetValues = get_values_B8G8R8A8;
|
---|
342 | drb->Base.PutRow = put_row_B8G8R8A8;
|
---|
343 | drb->Base.PutMonoRow = put_mono_row_B8G8R8A8;
|
---|
344 | drb->Base.PutRowRGB = put_row_rgb_B8G8R8A8;
|
---|
345 | drb->Base.PutValues = put_values_B8G8R8A8;
|
---|
346 | drb->Base.PutMonoValues = put_mono_values_B8G8R8A8;
|
---|
347 | }
|
---|
348 | else if (vis->redBits == 8 && vis->greenBits == 8 && vis->blueBits == 8
|
---|
349 | && vis->alphaBits == 0) {
|
---|
350 | drb->Base.GetRow = get_row_B8G8R8;
|
---|
351 | drb->Base.GetValues = get_values_B8G8R8;
|
---|
352 | drb->Base.PutRow = put_row_B8G8R8;
|
---|
353 | drb->Base.PutMonoRow = put_mono_row_B8G8R8;
|
---|
354 | drb->Base.PutRowRGB = put_row_rgb_B8G8R8;
|
---|
355 | drb->Base.PutValues = put_values_B8G8R8;
|
---|
356 | drb->Base.PutMonoValues = put_mono_values_B8G8R8;
|
---|
357 | }
|
---|
358 | else if (vis->indexBits == 8) {
|
---|
359 | drb->Base.GetRow = get_row_CI8;
|
---|
360 | drb->Base.GetValues = get_values_CI8;
|
---|
361 | drb->Base.PutRow = put_row_CI8;
|
---|
362 | drb->Base.PutMonoRow = put_mono_row_CI8;
|
---|
363 | drb->Base.PutValues = put_values_CI8;
|
---|
364 | drb->Base.PutMonoValues = put_mono_values_CI8;
|
---|
365 | }
|
---|
366 | }
|
---|
367 | else {
|
---|
368 | /* hardware z/stencil/etc someday */
|
---|
369 | }
|
---|
370 | }
|
---|
371 |
|
---|
372 |
|
---|
373 | static void
|
---|
374 | fbDestroyScreen( __DRIscreenPrivate *sPriv )
|
---|
375 | {
|
---|
376 | }
|
---|
377 |
|
---|
378 |
|
---|
379 | static const __DRIconfig **fbFillInModes(unsigned pixel_bits,
|
---|
380 | unsigned depth_bits,
|
---|
381 | unsigned stencil_bits,
|
---|
382 | GLboolean have_back_buffer)
|
---|
383 | {
|
---|
384 | unsigned deep = (depth_bits > 17);
|
---|
385 |
|
---|
386 | /* Right now GLX_SWAP_COPY_OML isn't supported, but it would be easy
|
---|
387 | * enough to add support. Basically, if a context is created with an
|
---|
388 | * fbconfig where the swap method is GLX_SWAP_COPY_OML, pageflipping
|
---|
389 | * will never be used.
|
---|
390 | */
|
---|
391 |
|
---|
392 | static const GLenum db_modes[2] = { GLX_NONE, GLX_SWAP_UNDEFINED_OML };
|
---|
393 | uint8_t depth_bits_array[4];
|
---|
394 | uint8_t stencil_bits_array[4];
|
---|
395 | if(deep) {
|
---|
396 | depth_bits_array[0] = 0;
|
---|
397 | depth_bits_array[1] = 24;
|
---|
398 | stencil_bits_array[0] = 0;
|
---|
399 | stencil_bits_array[1] = 8;
|
---|
400 | } else {
|
---|
401 | depth_bits_array[0] = depth_bits;
|
---|
402 | depth_bits_array[1] = 0;
|
---|
403 | depth_bits_array[2] = depth_bits;
|
---|
404 | depth_bits_array[3] = 0;
|
---|
405 | stencil_bits_array[0] = 0;
|
---|
406 | stencil_bits_array[1] = 0;
|
---|
407 | stencil_bits_array[2] = 8;
|
---|
408 | stencil_bits_array[3] = 8;
|
---|
409 | }
|
---|
410 |
|
---|
411 | return driCreateConfigs(
|
---|
412 | deep ? GL_RGBA : GL_RGB,
|
---|
413 | deep ? GL_UNSIGNED_INT_8_8_8_8 : GL_UNSIGNED_SHORT_5_6_5,
|
---|
414 | depth_bits_array,
|
---|
415 | stencil_bits_array,
|
---|
416 | deep ? 2 : 4,
|
---|
417 | db_modes, 2);
|
---|
418 | }
|
---|
419 |
|
---|
420 | /**
|
---|
421 | * This is the driver specific part of the createNewScreen entry point.
|
---|
422 | * Called when using legacy DRI.
|
---|
423 | *
|
---|
424 | * return the __GLcontextModes supported by this driver
|
---|
425 | */
|
---|
426 | static const __DRIconfig **fbInitScreen(__DRIscreenPrivate *psp)
|
---|
427 | {
|
---|
428 | static const __DRIversion ddx_expected = { 1, 0, 0 };
|
---|
429 | static const __DRIversion dri_expected = { 4, 0, 0 };
|
---|
430 | static const __DRIversion drm_expected = { 1, 0, 0 };
|
---|
431 |
|
---|
432 |
|
---|
433 | if ( ! driCheckDriDdxDrmVersions2( "vboxvideo",
|
---|
434 | & psp->dri_version, & dri_expected,
|
---|
435 | & psp->ddx_version, & ddx_expected,
|
---|
436 | & psp->drm_version, & drm_expected ) ) {
|
---|
437 | return NULL;
|
---|
438 | }
|
---|
439 |
|
---|
440 | driInitExtensions( NULL, card_extensions, GL_FALSE );
|
---|
441 |
|
---|
442 | return fbFillInModes( psp->fbBPP,
|
---|
443 | (psp->fbBPP == 16) ? 16 : 24,
|
---|
444 | (psp->fbBPP == 16) ? 0 : 8,
|
---|
445 | 1);
|
---|
446 | }
|
---|
447 |
|
---|
448 | /* Create the device specific context.
|
---|
449 | */
|
---|
450 | static GLboolean
|
---|
451 | fbCreateContext( const __GLcontextModes *glVisual,
|
---|
452 | __DRIcontextPrivate *driContextPriv,
|
---|
453 | void *sharedContextPrivate)
|
---|
454 | {
|
---|
455 | fbContextPtr fbmesa;
|
---|
456 | GLcontext *ctx, *shareCtx;
|
---|
457 | struct dd_function_table functions;
|
---|
458 |
|
---|
459 | assert(glVisual);
|
---|
460 | assert(driContextPriv);
|
---|
461 |
|
---|
462 | /* Allocate the Fb context */
|
---|
463 | fbmesa = (fbContextPtr) _mesa_calloc( sizeof(*fbmesa) );
|
---|
464 | if ( !fbmesa )
|
---|
465 | return GL_FALSE;
|
---|
466 |
|
---|
467 | /* Init default driver functions then plug in our FBdev-specific functions
|
---|
468 | */
|
---|
469 | _mesa_init_driver_functions(&functions);
|
---|
470 | init_core_functions(&functions);
|
---|
471 |
|
---|
472 | /* Allocate the Mesa context */
|
---|
473 | if (sharedContextPrivate)
|
---|
474 | shareCtx = ((fbContextPtr) sharedContextPrivate)->glCtx;
|
---|
475 | else
|
---|
476 | shareCtx = NULL;
|
---|
477 |
|
---|
478 | ctx = fbmesa->glCtx = _mesa_create_context(glVisual, shareCtx,
|
---|
479 | &functions, (void *) fbmesa);
|
---|
480 | if (!fbmesa->glCtx) {
|
---|
481 | _mesa_free(fbmesa);
|
---|
482 | return GL_FALSE;
|
---|
483 | }
|
---|
484 | driContextPriv->driverPrivate = fbmesa;
|
---|
485 |
|
---|
486 | /* Create module contexts */
|
---|
487 | _swrast_CreateContext( ctx );
|
---|
488 | _vbo_CreateContext( ctx );
|
---|
489 | _tnl_CreateContext( ctx );
|
---|
490 | _swsetup_CreateContext( ctx );
|
---|
491 | _swsetup_Wakeup( ctx );
|
---|
492 |
|
---|
493 |
|
---|
494 | /* use default TCL pipeline */
|
---|
495 | {
|
---|
496 | TNLcontext *tnl = TNL_CONTEXT(ctx);
|
---|
497 | tnl->Driver.RunPipeline = _tnl_run_pipeline;
|
---|
498 | }
|
---|
499 |
|
---|
500 | _mesa_enable_sw_extensions(ctx);
|
---|
501 |
|
---|
502 | return GL_TRUE;
|
---|
503 | }
|
---|
504 |
|
---|
505 |
|
---|
506 | static void
|
---|
507 | fbDestroyContext( __DRIcontextPrivate *driContextPriv )
|
---|
508 | {
|
---|
509 | GET_CURRENT_CONTEXT(ctx);
|
---|
510 | fbContextPtr fbmesa = (fbContextPtr) driContextPriv->driverPrivate;
|
---|
511 | fbContextPtr current = ctx ? FB_CONTEXT(ctx) : NULL;
|
---|
512 |
|
---|
513 | /* check if we're deleting the currently bound context */
|
---|
514 | if (fbmesa == current) {
|
---|
515 | _mesa_make_current(NULL, NULL, NULL);
|
---|
516 | }
|
---|
517 |
|
---|
518 | /* Free fb context resources */
|
---|
519 | if ( fbmesa ) {
|
---|
520 | _swsetup_DestroyContext( fbmesa->glCtx );
|
---|
521 | _tnl_DestroyContext( fbmesa->glCtx );
|
---|
522 | _vbo_DestroyContext( fbmesa->glCtx );
|
---|
523 | _swrast_DestroyContext( fbmesa->glCtx );
|
---|
524 |
|
---|
525 | /* free the Mesa context */
|
---|
526 | fbmesa->glCtx->DriverCtx = NULL;
|
---|
527 | _mesa_destroy_context( fbmesa->glCtx );
|
---|
528 |
|
---|
529 | _mesa_free( fbmesa );
|
---|
530 | }
|
---|
531 | }
|
---|
532 |
|
---|
533 |
|
---|
534 | /* Create and initialize the Mesa and driver specific pixmap buffer
|
---|
535 | * data.
|
---|
536 | */
|
---|
537 | static GLboolean
|
---|
538 | fbCreateBuffer( __DRIscreenPrivate *driScrnPriv,
|
---|
539 | __DRIdrawablePrivate *driDrawPriv,
|
---|
540 | const __GLcontextModes *mesaVis,
|
---|
541 | GLboolean isPixmap )
|
---|
542 | {
|
---|
543 | struct gl_framebuffer *mesa_framebuffer;
|
---|
544 |
|
---|
545 | if (isPixmap) {
|
---|
546 | return GL_FALSE; /* not implemented */
|
---|
547 | }
|
---|
548 | else {
|
---|
549 | const GLboolean swDepth = mesaVis->depthBits > 0;
|
---|
550 | const GLboolean swAlpha = mesaVis->alphaBits > 0;
|
---|
551 | const GLboolean swAccum = mesaVis->accumRedBits > 0;
|
---|
552 | const GLboolean swStencil = mesaVis->stencilBits > 0;
|
---|
553 |
|
---|
554 | mesa_framebuffer = _mesa_create_framebuffer(mesaVis);
|
---|
555 | if (!mesa_framebuffer)
|
---|
556 | return 0;
|
---|
557 |
|
---|
558 | /* XXX double-check these parameters (bpp vs cpp, etc) */
|
---|
559 | {
|
---|
560 | driRenderbuffer *drb = driNewRenderbuffer(GL_RGBA,
|
---|
561 | driScrnPriv->pFB,
|
---|
562 | driScrnPriv->fbBPP / 8,
|
---|
563 | driScrnPriv->fbOrigin,
|
---|
564 | driScrnPriv->fbStride,
|
---|
565 | driDrawPriv);
|
---|
566 | fbSetSpanFunctions(drb, mesaVis);
|
---|
567 | _mesa_add_renderbuffer(mesa_framebuffer,
|
---|
568 | BUFFER_FRONT_LEFT, &drb->Base);
|
---|
569 | }
|
---|
570 | if (mesaVis->doubleBufferMode) {
|
---|
571 | /* XXX what are the correct origin/stride values? */
|
---|
572 | GLvoid *backBuf = _mesa_malloc(driScrnPriv->fbStride
|
---|
573 | * driScrnPriv->fbHeight);
|
---|
574 | driRenderbuffer *drb = driNewRenderbuffer(GL_RGBA,
|
---|
575 | backBuf,
|
---|
576 | driScrnPriv->fbBPP /8,
|
---|
577 | driScrnPriv->fbOrigin,
|
---|
578 | driScrnPriv->fbStride,
|
---|
579 | driDrawPriv);
|
---|
580 | fbSetSpanFunctions(drb, mesaVis);
|
---|
581 | _mesa_add_renderbuffer(mesa_framebuffer,
|
---|
582 | BUFFER_BACK_LEFT, &drb->Base);
|
---|
583 | }
|
---|
584 |
|
---|
585 | _mesa_add_soft_renderbuffers(mesa_framebuffer,
|
---|
586 | GL_FALSE, /* color */
|
---|
587 | swDepth,
|
---|
588 | swStencil,
|
---|
589 | swAccum,
|
---|
590 | swAlpha, /* or always zero? */
|
---|
591 | GL_FALSE /* aux */);
|
---|
592 |
|
---|
593 | driDrawPriv->driverPrivate = mesa_framebuffer;
|
---|
594 |
|
---|
595 | return 1;
|
---|
596 | }
|
---|
597 | }
|
---|
598 |
|
---|
599 |
|
---|
600 | static void
|
---|
601 | fbDestroyBuffer(__DRIdrawablePrivate *driDrawPriv)
|
---|
602 | {
|
---|
603 | _mesa_unreference_framebuffer((GLframebuffer **)(&(driDrawPriv->driverPrivate)));
|
---|
604 | }
|
---|
605 |
|
---|
606 |
|
---|
607 |
|
---|
608 | /* If the backbuffer is on a videocard, this is extraordinarily slow!
|
---|
609 | */
|
---|
610 | static void
|
---|
611 | fbSwapBuffers( __DRIdrawablePrivate *dPriv )
|
---|
612 | {
|
---|
613 | struct gl_framebuffer *mesa_framebuffer = (struct gl_framebuffer *)dPriv->driverPrivate;
|
---|
614 | struct gl_renderbuffer * front_renderbuffer = mesa_framebuffer->Attachment[BUFFER_FRONT_LEFT].Renderbuffer;
|
---|
615 | void *frontBuffer = front_renderbuffer->Data;
|
---|
616 | int currentPitch = ((driRenderbuffer *)front_renderbuffer)->pitch;
|
---|
617 | void *backBuffer = mesa_framebuffer->Attachment[BUFFER_BACK_LEFT].Renderbuffer->Data;
|
---|
618 |
|
---|
619 | if (dPriv->driContextPriv && dPriv->driContextPriv->driverPrivate) {
|
---|
620 | fbContextPtr fbmesa = (fbContextPtr) dPriv->driContextPriv->driverPrivate;
|
---|
621 | GLcontext *ctx = fbmesa->glCtx;
|
---|
622 |
|
---|
623 | if (ctx->Visual.doubleBufferMode) {
|
---|
624 | int i;
|
---|
625 | int offset = 0;
|
---|
626 | char *tmp = _mesa_malloc(currentPitch);
|
---|
627 |
|
---|
628 | _mesa_notifySwapBuffers( ctx ); /* flush pending rendering commands */
|
---|
629 |
|
---|
630 | ASSERT(frontBuffer);
|
---|
631 | ASSERT(backBuffer);
|
---|
632 |
|
---|
633 | for (i = 0; i < dPriv->h; i++) {
|
---|
634 | _mesa_memcpy(tmp, (char *) backBuffer + offset,
|
---|
635 | currentPitch);
|
---|
636 | _mesa_memcpy((char *) frontBuffer + offset, tmp,
|
---|
637 | currentPitch);
|
---|
638 | offset += currentPitch;
|
---|
639 | }
|
---|
640 |
|
---|
641 | _mesa_free(tmp);
|
---|
642 | }
|
---|
643 | }
|
---|
644 | else {
|
---|
645 | /* XXX this shouldn't be an error but we can't handle it for now */
|
---|
646 | _mesa_problem(NULL, "fbSwapBuffers: drawable has no context!\n");
|
---|
647 | }
|
---|
648 | }
|
---|
649 |
|
---|
650 |
|
---|
651 | /* Force the context `c' to be the current context and associate with it
|
---|
652 | * buffer `b'.
|
---|
653 | */
|
---|
654 | static GLboolean
|
---|
655 | fbMakeCurrent( __DRIcontextPrivate *driContextPriv,
|
---|
656 | __DRIdrawablePrivate *driDrawPriv,
|
---|
657 | __DRIdrawablePrivate *driReadPriv )
|
---|
658 | {
|
---|
659 | if ( driContextPriv ) {
|
---|
660 | fbContextPtr newFbCtx =
|
---|
661 | (fbContextPtr) driContextPriv->driverPrivate;
|
---|
662 |
|
---|
663 | newFbCtx->dri.drawable = driDrawPriv;
|
---|
664 |
|
---|
665 | _mesa_make_current( newFbCtx->glCtx,
|
---|
666 | driDrawPriv->driverPrivate,
|
---|
667 | driReadPriv->driverPrivate);
|
---|
668 | } else {
|
---|
669 | _mesa_make_current( NULL, NULL, NULL );
|
---|
670 | }
|
---|
671 |
|
---|
672 | return GL_TRUE;
|
---|
673 | }
|
---|
674 |
|
---|
675 |
|
---|
676 | /* Force the context `c' to be unbound from its buffer.
|
---|
677 | */
|
---|
678 | static GLboolean
|
---|
679 | fbUnbindContext( __DRIcontextPrivate *driContextPriv )
|
---|
680 | {
|
---|
681 | return GL_TRUE;
|
---|
682 | }
|
---|
683 |
|
---|
684 | const struct __DriverAPIRec driDriverAPI = {
|
---|
685 | .InitScreen = fbInitScreen,
|
---|
686 | .DestroyScreen = fbDestroyScreen,
|
---|
687 | .CreateContext = fbCreateContext,
|
---|
688 | .DestroyContext = fbDestroyContext,
|
---|
689 | .CreateBuffer = fbCreateBuffer,
|
---|
690 | .DestroyBuffer = fbDestroyBuffer,
|
---|
691 | .SwapBuffers = fbSwapBuffers,
|
---|
692 | .MakeCurrent = fbMakeCurrent,
|
---|
693 | .UnbindContext = fbUnbindContext,
|
---|
694 | };
|
---|