Subversion Repositories Kolibri OS

Rev

Go to most recent revision | Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
1901 serge 1
#!/usr/bin/env python
2
 
3
# (C) Copyright IBM Corporation 2004, 2005
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 "Software"),
8
# to deal in the Software without restriction, including without limitation
9
# on the rights to use, copy, modify, merge, publish, distribute, sub
10
# license, and/or sell copies of the Software, and to permit persons to whom
11
# the Software is furnished to do so, subject to the following conditions:
12
#
13
# The above copyright notice and this permission notice (including the next
14
# paragraph) shall be included in all copies or substantial portions of the
15
# Software.
16
#
17
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19
# FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.  IN NO EVENT SHALL
20
# IBM AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
22
# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
23
# IN THE SOFTWARE.
24
#
25
# Authors:
26
#    Ian Romanick 
27
#    Jeremy Kolb 
28
 
29
import gl_XML, glX_XML, glX_proto_common, license
30
import sys, getopt, copy, string
31
 
32
def convertStringForXCB(str):
33
    tmp = ""
34
    special = [ "ARB" ]
35
    i = 0
36
    while i < len(str):
37
        if str[i:i+3] in special:
38
            tmp = '%s_%s' % (tmp, string.lower(str[i:i+3]))
39
            i = i + 2;
40
        elif str[i].isupper():
41
            tmp = '%s_%s' % (tmp, string.lower(str[i]))
42
        else:
43
            tmp = '%s%s' % (tmp, str[i])
44
        i += 1
45
    return tmp
46
 
47
def hash_pixel_function(func):
48
	"""Generate a 'unique' key for a pixel function.  The key is based on
49
	the parameters written in the command packet.  This includes any
50
	padding that might be added for the original function and the 'NULL
51
	image' flag."""
52
 
53
 
54
	h = ""
55
	hash_pre = ""
56
	hash_suf = ""
57
	for param in func.parameterIterateGlxSend():
58
		if param.is_image():
59
			[dim, junk, junk, junk, junk] = param.get_dimensions()
60
 
61
			d = (dim + 1) & ~1
62
			hash_pre = "%uD%uD_" % (d - 1, d)
63
 
64
			if param.img_null_flag:
65
				hash_suf = "_NF"
66
 
67
		h += "%u" % (param.size())
68
 
69
		if func.pad_after(param):
70
			h += "4"
71
 
72
 
73
	n = func.name.replace("%uD" % (dim), "")
74
	n = "__glx_%s_%uD%uD" % (n, d - 1, d)
75
 
76
	h = hash_pre + h + hash_suf
77
	return [h, n]
78
 
79
 
80
class glx_pixel_function_stub(glX_XML.glx_function):
81
	"""Dummy class used to generate pixel "utility" functions that are
82
	shared by multiple dimension image functions.  For example, these
83
	objects are used to generate shared functions used to send GLX
84
	protocol for TexImage1D and TexImage2D, TexSubImage1D and
85
	TexSubImage2D, etc."""
86
 
87
	def __init__(self, func, name):
88
		# The parameters to the utility function are the same as the
89
		# parameters to the real function except for the added "pad"
90
		# parameters.
91
 
92
		self.name = name
93
		self.images = []
94
		self.parameters = []
95
		self.parameters_by_name = {}
96
		for _p in func.parameterIterator():
97
			p = copy.copy(_p)
98
			self.parameters.append(p)
99
			self.parameters_by_name[ p.name ] = p
100
 
101
 
102
			if p.is_image():
103
				self.images.append(p)
104
				p.height = "height"
105
 
106
				if p.img_yoff == None:
107
					p.img_yoff = "yoffset"
108
 
109
				if p.depth:
110
					if p.extent == None:
111
						p.extent = "extent"
112
 
113
					if p.img_woff == None:
114
						p.img_woff = "woffset"
115
 
116
 
117
			pad_name = func.pad_after(p)
118
			if pad_name:
119
				pad = copy.copy(p)
120
				pad.name = pad_name
121
				self.parameters.append(pad)
122
				self.parameters_by_name[ pad.name ] = pad
123
 
124
 
125
		self.return_type = func.return_type
126
 
127
		self.glx_rop = ~0
128
		self.glx_sop = 0
129
		self.glx_vendorpriv = 0
130
 
131
		self.glx_doubles_in_order = func.glx_doubles_in_order
132
 
133
		self.vectorequiv = None
134
		self.output = None
135
		self.can_be_large = func.can_be_large
136
		self.reply_always_array = func.reply_always_array
137
		self.dimensions_in_reply = func.dimensions_in_reply
138
		self.img_reset = None
139
 
140
		self.server_handcode = 0
141
		self.client_handcode = 0
142
		self.ignore = 0
143
 
144
		self.count_parameter_list = func.count_parameter_list
145
		self.counter_list = func.counter_list
146
		self.offsets_calculated = 0
147
		return
148
 
149
 
150
class PrintGlxProtoStubs(glX_proto_common.glx_print_proto):
151
	def __init__(self):
152
		glX_proto_common.glx_print_proto.__init__(self)
153
		self.name = "glX_proto_send.py (from Mesa)"
154
		self.license = license.bsd_license_template % ( "(C) Copyright IBM Corporation 2004, 2005", "IBM")
155
 
156
 
157
		self.last_category = ""
158
		self.generic_sizes = [3, 4, 6, 8, 12, 16, 24, 32]
159
		self.pixel_stubs = {}
160
		self.debug = 0
161
		return
162
 
163
	def printRealHeader(self):
164
		print ''
165
		print '#include '
166
		print '#include "indirect.h"'
167
		print '#include "glxclient.h"'
168
		print '#include "indirect_size.h"'
169
		print '#include "glapi.h"'
170
		print '#include "glthread.h"'
171
		print '#include '
172
		print '#ifdef USE_XCB'
173
		print '#include '
174
		print '#include '
175
		print '#include '
176
		print '#endif /* USE_XCB */'
177
 
178
		print ''
179
		print '#define __GLX_PAD(n) (((n) + 3) & ~3)'
180
		print ''
181
		self.printFastcall()
182
		self.printNoinline()
183
		print ''
184
		print '#ifndef __GNUC__'
185
		print '#  define __builtin_expect(x, y) x'
186
		print '#endif'
187
		print ''
188
		print '/* If the size and opcode values are known at compile-time, this will, on'
189
		print ' * x86 at least, emit them with a single instruction.'
190
		print ' */'
191
		print '#define emit_header(dest, op, size)            \\'
192
		print '    do { union { short s[2]; int i; } temp;    \\'
193
		print '         temp.s[0] = (size); temp.s[1] = (op); \\'
194
		print '         *((int *)(dest)) = temp.i; } while(0)'
195
		print ''
196
		print """NOINLINE CARD32
197
__glXReadReply( Display *dpy, size_t size, void * dest, GLboolean reply_is_always_array )
198
{
199
    xGLXSingleReply reply;
200
 
201
    (void) _XReply(dpy, (xReply *) & reply, 0, False);
202
    if (size != 0) {
203
        if ((reply.length > 0) || reply_is_always_array) {
204
            const GLint bytes = (reply_is_always_array)
205
              ? (4 * reply.length) : (reply.size * size);
206
            const GLint extra = 4 - (bytes & 3);
207
 
208
            _XRead(dpy, dest, bytes);
209
            if ( extra < 4 ) {
210
                _XEatData(dpy, extra);
211
            }
212
        }
213
        else {
214
            (void) memcpy( dest, &(reply.pad3), size);
215
        }
216
    }
217
 
218
    return reply.retval;
219
}
220
 
221
NOINLINE void
222
__glXReadPixelReply( Display *dpy, struct glx_context * gc, unsigned max_dim,
223
    GLint width, GLint height, GLint depth, GLenum format, GLenum type,
224
    void * dest, GLboolean dimensions_in_reply )
225
{
226
    xGLXSingleReply reply;
227
    GLint size;
228
 
229
    (void) _XReply(dpy, (xReply *) & reply, 0, False);
230
 
231
    if ( dimensions_in_reply ) {
232
        width  = reply.pad3;
233
        height = reply.pad4;
234
        depth  = reply.pad5;
235
 
236
	if ((height == 0) || (max_dim < 2)) { height = 1; }
237
	if ((depth  == 0) || (max_dim < 3)) { depth  = 1; }
238
    }
239
 
240
    size = reply.length * 4;
241
    if (size != 0) {
242
        void * buf = Xmalloc( size );
243
 
244
        if ( buf == NULL ) {
245
            _XEatData(dpy, size);
246
            __glXSetError(gc, GL_OUT_OF_MEMORY);
247
        }
248
        else {
249
            const GLint extra = 4 - (size & 3);
250
 
251
            _XRead(dpy, buf, size);
252
            if ( extra < 4 ) {
253
                _XEatData(dpy, extra);
254
            }
255
 
256
            __glEmptyImage(gc, 3, width, height, depth, format, type,
257
                           buf, dest);
258
            Xfree(buf);
259
        }
260
    }
261
}
262
 
263
#define X_GLXSingle 0
264
 
265
NOINLINE FASTCALL GLubyte *
266
__glXSetupSingleRequest( struct glx_context * gc, GLint sop, GLint cmdlen )
267
{
268
    xGLXSingleReq * req;
269
    Display * const dpy = gc->currentDpy;
270
 
271
    (void) __glXFlushRenderBuffer(gc, gc->pc);
272
    LockDisplay(dpy);
273
    GetReqExtra(GLXSingle, cmdlen, req);
274
    req->reqType = gc->majorOpcode;
275
    req->contextTag = gc->currentContextTag;
276
    req->glxCode = sop;
277
    return (GLubyte *)(req) + sz_xGLXSingleReq;
278
}
279
 
280
NOINLINE FASTCALL GLubyte *
281
__glXSetupVendorRequest( struct glx_context * gc, GLint code, GLint vop, GLint cmdlen )
282
{
283
    xGLXVendorPrivateReq * req;
284
    Display * const dpy = gc->currentDpy;
285
 
286
    (void) __glXFlushRenderBuffer(gc, gc->pc);
287
    LockDisplay(dpy);
288
    GetReqExtra(GLXVendorPrivate, cmdlen, req);
289
    req->reqType = gc->majorOpcode;
290
    req->glxCode = code;
291
    req->vendorCode = vop;
292
    req->contextTag = gc->currentContextTag;
293
    return (GLubyte *)(req) + sz_xGLXVendorPrivateReq;
294
}
295
 
296
const GLuint __glXDefaultPixelStore[9] = { 0, 0, 0, 0, 0, 0, 0, 0, 1 };
297
 
298
#define zero                        (__glXDefaultPixelStore+0)
299
#define one                         (__glXDefaultPixelStore+8)
300
#define default_pixel_store_1D      (__glXDefaultPixelStore+4)
301
#define default_pixel_store_1D_size 20
302
#define default_pixel_store_2D      (__glXDefaultPixelStore+4)
303
#define default_pixel_store_2D_size 20
304
#define default_pixel_store_3D      (__glXDefaultPixelStore+0)
305
#define default_pixel_store_3D_size 36
306
#define default_pixel_store_4D      (__glXDefaultPixelStore+0)
307
#define default_pixel_store_4D_size 36
308
"""
309
 
310
		for size in self.generic_sizes:
311
			self.print_generic_function(size)
312
		return
313
 
314
 
315
	def printBody(self, api):
316
 
317
		self.pixel_stubs = {}
318
		generated_stubs = []
319
 
320
		for func in api.functionIterateGlx():
321
			if func.client_handcode: continue
322
 
323
			# If the function is a pixel function with a certain
324
			# GLX protocol signature, create a fake stub function
325
			# for it.  For example, create a single stub function
326
			# that is used to implement both glTexImage1D and
327
			# glTexImage2D.
328
 
329
			if func.glx_rop != 0:
330
				do_it = 0
331
				for image in func.get_images():
332
					if image.img_pad_dimensions:
333
						do_it = 1
334
						break
335
 
336
 
337
				if do_it:
338
					[h, n] = hash_pixel_function(func)
339
 
340
 
341
					self.pixel_stubs[ func.name ] = n
342
					if h not in generated_stubs:
343
						generated_stubs.append(h)
344
 
345
						fake_func = glx_pixel_function_stub( func, n )
346
						self.printFunction(fake_func, fake_func.name)
347
 
348
 
349
			self.printFunction(func, func.name)
350
			if func.glx_sop and func.glx_vendorpriv:
351
				self.printFunction(func, func.glx_vendorpriv_names[0])
352
 
353
		return
354
 
355
 
356
	def printFunction(self, func, name):
357
		footer = '}\n'
358
		if func.glx_rop == ~0:
359
			print 'static %s' % (func.return_type)
360
			print '%s( unsigned opcode, unsigned dim, %s )' % (func.name, func.get_parameter_string())
361
			print '{'
362
		else:
363
			if func.has_different_protocol(name):
364
				if func.return_type == "void":
365
					ret_string = ''
366
				else:
367
					ret_string = "return "
368
 
369
				func_name = func.static_glx_name(name)
370
				print '#define %s %d' % (func.opcode_vendor_name(name), func.glx_vendorpriv)
371
				print '%s gl%s(%s)' % (func.return_type, func_name, func.get_parameter_string())
372
				print '{'
373
				print '    struct glx_context * const gc = __glXGetCurrentContext();'
374
				print ''
375
				print '#if defined(GLX_DIRECT_RENDERING) && !defined(GLX_USE_APPLEGL)'
376
				print '    if (gc->isDirect) {'
377
				print '    %sGET_DISPATCH()->%s(%s);' % (ret_string, func.name, func.get_called_parameter_string())
378
				print '    } else'
379
				print '#endif'
380
				print '    {'
381
 
382
				footer = '}\n}\n'
383
			else:
384
				print '#define %s %d' % (func.opcode_name(), func.opcode_value())
385
 
386
				print '%s __indirect_gl%s(%s)' % (func.return_type, name, func.get_parameter_string())
387
				print '{'
388
 
389
 
390
		if func.glx_rop != 0 or func.vectorequiv != None:
391
			if len(func.images):
392
				self.printPixelFunction(func)
393
			else:
394
				self.printRenderFunction(func)
395
		elif func.glx_sop != 0 or func.glx_vendorpriv != 0:
396
			self.printSingleFunction(func, name)
397
			pass
398
		else:
399
			print "/* Missing GLX protocol for %s. */" % (name)
400
 
401
		print footer
402
		return
403
 
404
 
405
	def print_generic_function(self, n):
406
		size = (n + 3) & ~3
407
		print """static FASTCALL NOINLINE void
408
generic_%u_byte( GLint rop, const void * ptr )
409
{
410
    struct glx_context * const gc = __glXGetCurrentContext();
411
    const GLuint cmdlen = %u;
412
 
413
    emit_header(gc->pc, rop, cmdlen);
414
    (void) memcpy((void *)(gc->pc + 4), ptr, %u);
415
    gc->pc += cmdlen;
416
    if (__builtin_expect(gc->pc > gc->limit, 0)) { (void) __glXFlushRenderBuffer(gc, gc->pc); }
417
}
418
""" % (n, size + 4, size)
419
		return
420
 
421
 
422
	def common_emit_one_arg(self, p, pc, adjust, extra_offset):
423
		if p.is_array():
424
			src_ptr = p.name
425
		else:
426
			src_ptr = "&" + p.name
427
 
428
		if p.is_padding:
429
			print '(void) memset((void *)(%s + %u), 0, %s);' \
430
			    % (pc, p.offset + adjust, p.size_string() )
431
		elif not extra_offset:
432
			print '(void) memcpy((void *)(%s + %u), (void *)(%s), %s);' \
433
			    % (pc, p.offset + adjust, src_ptr, p.size_string() )
434
		else:
435
			print '(void) memcpy((void *)(%s + %u + %s), (void *)(%s), %s);' \
436
			    % (pc, p.offset + adjust, extra_offset, src_ptr, p.size_string() )
437
 
438
	def common_emit_args(self, f, pc, adjust, skip_vla):
439
		extra_offset = None
440
 
441
		for p in f.parameterIterateGlxSend( not skip_vla ):
442
			if p.name != f.img_reset:
443
				self.common_emit_one_arg(p, pc, adjust, extra_offset)
444
 
445
				if p.is_variable_length():
446
					temp = p.size_string()
447
					if extra_offset:
448
						extra_offset += " + %s" % (temp)
449
					else:
450
						extra_offset = temp
451
 
452
		return
453
 
454
 
455
	def pixel_emit_args(self, f, pc, large):
456
		"""Emit the arguments for a pixel function.  This differs from
457
		common_emit_args in that pixel functions may require padding
458
		be inserted (i.e., for the missing width field for
459
		TexImage1D), and they may also require a 'NULL image' flag
460
		be inserted before the image data."""
461
 
462
		if large:
463
			adjust = 8
464
		else:
465
			adjust = 4
466
 
467
		for param in f.parameterIterateGlxSend():
468
			if not param.is_image():
469
				self.common_emit_one_arg(param, pc, adjust, None)
470
 
471
				if f.pad_after(param):
472
					print '(void) memcpy((void *)(%s + %u), zero, 4);' % (pc, (param.offset + param.size()) + adjust)
473
 
474
			else:
475
				[dim, width, height, depth, extent] = param.get_dimensions()
476
				if f.glx_rop == ~0:
477
					dim_str = "dim"
478
				else:
479
					dim_str = str(dim)
480
 
481
				if param.is_padding:
482
					print '(void) memset((void *)(%s + %u), 0, %s);' \
483
					% (pc, (param.offset - 4) + adjust, param.size_string() )
484
 
485
				if param.img_null_flag:
486
					if large:
487
						print '(void) memcpy((void *)(%s + %u), zero, 4);' % (pc, (param.offset - 4) + adjust)
488
					else:
489
						print '(void) memcpy((void *)(%s + %u), (void *)((%s == NULL) ? one : zero), 4);' % (pc, (param.offset - 4) + adjust, param.name)
490
 
491
 
492
				pixHeaderPtr = "%s + %u" % (pc, adjust)
493
				pcPtr = "%s + %u" % (pc, param.offset + adjust)
494
 
495
				if not large:
496
					if param.img_send_null:
497
						condition = '(compsize > 0) && (%s != NULL)' % (param.name)
498
					else:
499
						condition = 'compsize > 0'
500
 
501
					print 'if (%s) {' % (condition)
502
					print '    (*gc->fillImage)(gc, %s, %s, %s, %s, %s, %s, %s, %s, %s);' % (dim_str, width, height, depth, param.img_format, param.img_type, param.name, pcPtr, pixHeaderPtr)
503
					print '} else {'
504
					print '    (void) memcpy( %s, default_pixel_store_%uD, default_pixel_store_%uD_size );' % (pixHeaderPtr, dim, dim)
505
					print '}'
506
				else:
507
					print '__glXSendLargeImage(gc, compsize, %s, %s, %s, %s, %s, %s, %s, %s, %s);' % (dim_str, width, height, depth, param.img_format, param.img_type, param.name, pcPtr, pixHeaderPtr)
508
 
509
		return
510
 
511
 
512
	def large_emit_begin(self, f, op_name = None):
513
		if not op_name:
514
			op_name = f.opcode_real_name()
515
 
516
		print 'const GLint op = %s;' % (op_name)
517
		print 'const GLuint cmdlenLarge = cmdlen + 4;'
518
		print 'GLubyte * const pc = __glXFlushRenderBuffer(gc, gc->pc);'
519
		print '(void) memcpy((void *)(pc + 0), (void *)(&cmdlenLarge), 4);'
520
		print '(void) memcpy((void *)(pc + 4), (void *)(&op), 4);'
521
		return
522
 
523
 
524
	def common_func_print_just_start(self, f, name):
525
		print '    struct glx_context * const gc = __glXGetCurrentContext();'
526
 
527
		# The only reason that single and vendor private commands need
528
		# a variable called 'dpy' is becuase they use the SyncHandle
529
		# macro.  For whatever brain-dead reason, that macro is hard-
530
		# coded to use a variable called 'dpy' instead of taking a
531
		# parameter.
532
 
533
		# FIXME Simplify the logic related to skip_condition and
534
		# FIXME condition_list in this function.  Basically, remove
535
		# FIXME skip_condition, and just append the "dpy != NULL" type
536
		# FIXME condition to condition_list from the start.  The only
537
		# FIXME reason it's done in this confusing way now is to
538
		# FIXME minimize the diffs in the generated code.
539
 
540
		if not f.glx_rop:
541
			for p in f.parameterIterateOutputs():
542
				if p.is_image() and (p.img_format != "GL_COLOR_INDEX" or p.img_type != "GL_BITMAP"):
543
					print '    const __GLXattribute * const state = gc->client_state_private;'
544
					break
545
 
546
			print '    Display * const dpy = gc->currentDpy;'
547
			skip_condition = "dpy != NULL"
548
		elif f.can_be_large:
549
			skip_condition = "gc->currentDpy != NULL"
550
		else:
551
			skip_condition = None
552
 
553
 
554
		if f.return_type != 'void':
555
			print '    %s retval = (%s) 0;' % (f.return_type, f.return_type)
556
 
557
 
558
		if name != None and name not in f.glx_vendorpriv_names:
559
			print '#ifndef USE_XCB'
560
		self.emit_packet_size_calculation(f, 0)
561
		if name != None and name not in f.glx_vendorpriv_names:
562
			print '#endif'
563
 
564
		condition_list = []
565
		for p in f.parameterIterateCounters():
566
			condition_list.append( "%s >= 0" % (p.name) )
567
			# 'counter' parameters cannot be negative
568
			print "    if (%s < 0) {" % p.name
569
			print "        __glXSetError(gc, GL_INVALID_VALUE);"
570
			if f.return_type != 'void':
571
				print "        return 0;"
572
			else:
573
				print "        return;"
574
			print "    }"
575
 
576
		if skip_condition:
577
			condition_list.append( skip_condition )
578
 
579
		if len( condition_list ) > 0:
580
			if len( condition_list ) > 1:
581
				skip_condition = "(%s)" % (string.join( condition_list, ") && (" ))
582
			else:
583
				skip_condition = "%s" % (condition_list.pop(0))
584
 
585
			print '    if (__builtin_expect(%s, 1)) {' % (skip_condition)
586
			return 1
587
		else:
588
			return 0
589
 
590
 
591
	def printSingleFunction(self, f, name):
592
		self.common_func_print_just_start(f, name)
593
 
594
		if self.debug:
595
			print '        printf( "Enter %%s...\\n", "gl%s" );' % (f.name)
596
 
597
		if name not in f.glx_vendorpriv_names:
598
 
599
			# XCB specific:
600
			print '#ifdef USE_XCB'
601
			if self.debug:
602
				print '        printf("\\tUsing XCB.\\n");'
603
			print '        xcb_connection_t *c = XGetXCBConnection(dpy);'
604
			print '        (void) __glXFlushRenderBuffer(gc, gc->pc);'
605
			xcb_name = 'xcb_glx%s' % convertStringForXCB(name)
606
 
607
			iparams=[]
608
			extra_iparams = []
609
			output = None
610
			for p in f.parameterIterator():
611
				if p.is_output:
612
					output = p
613
 
614
					if p.is_image():
615
						if p.img_format != "GL_COLOR_INDEX" or p.img_type != "GL_BITMAP":
616
							extra_iparams.append("state->storePack.swapEndian")
617
						else:
618
							extra_iparams.append("0")
619
 
620
						# Hardcode this in.  lsb_first param (apparently always GL_FALSE)
621
						# also present in GetPolygonStipple, but taken care of above.
622
						if xcb_name == "xcb_glx_read_pixels":
623
							extra_iparams.append("0")
624
				else:
625
					iparams.append(p.name)
626
 
627
 
628
			xcb_request = '%s(%s)' % (xcb_name, ", ".join(["c", "gc->currentContextTag"] + iparams + extra_iparams))
629
 
630
			if f.needs_reply():
631
				print '        %s_reply_t *reply = %s_reply(c, %s, NULL);' % (xcb_name, xcb_name, xcb_request)
632
				if output and f.reply_always_array:
633
					print '        (void)memcpy(%s, %s_data(reply), %s_data_length(reply) * sizeof(%s));' % (output.name, xcb_name, xcb_name, output.get_base_type_string())
634
 
635
				elif output and not f.reply_always_array:
636
					if not output.is_image():
637
						print '        if (%s_data_length(reply) == 0)' % (xcb_name)
638
						print '            (void)memcpy(%s, &reply->datum, sizeof(reply->datum));' % (output.name)
639
						print '        else'
640
					print '        (void)memcpy(%s, %s_data(reply), %s_data_length(reply) * sizeof(%s));' % (output.name, xcb_name, xcb_name, output.get_base_type_string())
641
 
642
 
643
				if f.return_type != 'void':
644
					print '        retval = reply->ret_val;'
645
				print '        free(reply);'
646
			else:
647
				print '        ' + xcb_request + ';'
648
			print '#else'
649
			# End of XCB specific.
650
 
651
 
652
		if f.parameters != []:
653
			pc_decl = "GLubyte const * pc ="
654
		else:
655
			pc_decl = "(void)"
656
 
657
		if name in f.glx_vendorpriv_names:
658
			print '        %s __glXSetupVendorRequest(gc, %s, %s, cmdlen);' % (pc_decl, f.opcode_real_name(), f.opcode_vendor_name(name))
659
		else:
660
			print '        %s __glXSetupSingleRequest(gc, %s, cmdlen);' % (pc_decl, f.opcode_name())
661
 
662
		self.common_emit_args(f, "pc", 0, 0)
663
 
664
		images = f.get_images()
665
 
666
		for img in images:
667
			if img.is_output:
668
				o = f.command_fixed_length() - 4
669
				print '        *(int32_t *)(pc + %u) = 0;' % (o)
670
				if img.img_format != "GL_COLOR_INDEX" or img.img_type != "GL_BITMAP":
671
					print '        * (int8_t *)(pc + %u) = state->storePack.swapEndian;' % (o)
672
 
673
				if f.img_reset:
674
					print '        * (int8_t *)(pc + %u) = %s;' % (o + 1, f.img_reset)
675
 
676
 
677
		return_name = ''
678
		if f.needs_reply():
679
			if f.return_type != 'void':
680
				return_name = " retval"
681
				return_str = " retval = (%s)" % (f.return_type)
682
			else:
683
				return_str = " (void)"
684
 
685
			got_reply = 0
686
 
687
			for p in f.parameterIterateOutputs():
688
				if p.is_image():
689
					[dim, w, h, d, junk] = p.get_dimensions()
690
					if f.dimensions_in_reply:
691
						print "        __glXReadPixelReply(dpy, gc, %u, 0, 0, 0, %s, %s, %s, GL_TRUE);" % (dim, p.img_format, p.img_type, p.name)
692
					else:
693
						print "        __glXReadPixelReply(dpy, gc, %u, %s, %s, %s, %s, %s, %s, GL_FALSE);" % (dim, w, h, d, p.img_format, p.img_type, p.name)
694
 
695
					got_reply = 1
696
				else:
697
					if f.reply_always_array:
698
						aa = "GL_TRUE"
699
					else:
700
						aa = "GL_FALSE"
701
 
702
					# gl_parameter.size() returns the size
703
					# of the entire data item.  If the
704
					# item is a fixed-size array, this is
705
					# the size of the whole array.  This
706
					# is not what __glXReadReply wants. It
707
					# wants the size of a single data
708
					# element in the reply packet.
709
					# Dividing by the array size (1 for
710
					# non-arrays) gives us this.
711
 
712
					s = p.size() / p.get_element_count()
713
					print "       %s __glXReadReply(dpy, %s, %s, %s);" % (return_str, s, p.name, aa)
714
					got_reply = 1
715
 
716
 
717
			# If a reply wasn't read to fill an output parameter,
718
			# read a NULL reply to get the return value.
719
 
720
			if not got_reply:
721
				print "       %s __glXReadReply(dpy, 0, NULL, GL_FALSE);" % (return_str)
722
 
723
 
724
		elif self.debug:
725
			# Only emit the extra glFinish call for functions
726
			# that don't already require a reply from the server.
727
			print '        __indirect_glFinish();'
728
 
729
		if self.debug:
730
			print '        printf( "Exit %%s.\\n", "gl%s" );' % (name)
731
 
732
 
733
		print '        UnlockDisplay(dpy); SyncHandle();'
734
 
735
		if name not in f.glx_vendorpriv_names:
736
			print '#endif /* USE_XCB */'
737
 
738
		print '    }'
739
		print '    return%s;' % (return_name)
740
		return
741
 
742
 
743
	def printPixelFunction(self, f):
744
		if self.pixel_stubs.has_key( f.name ):
745
			# Normally gl_function::get_parameter_string could be
746
			# used.  However, this call needs to have the missing
747
			# dimensions (e.g., a fake height value for
748
			# glTexImage1D) added in.
749
 
750
			p_string = ""
751
			for param in f.parameterIterateGlxSend():
752
				if param.is_padding:
753
					continue
754
 
755
				p_string += ", " + param.name
756
 
757
				if param.is_image():
758
					[dim, junk, junk, junk, junk] = param.get_dimensions()
759
 
760
				if f.pad_after(param):
761
					p_string += ", 1"
762
 
763
			print '    %s(%s, %u%s );' % (self.pixel_stubs[f.name] , f.opcode_name(), dim, p_string)
764
			return
765
 
766
 
767
		if self.common_func_print_just_start(f, None):
768
			trailer = "    }"
769
		else:
770
			trailer = None
771
 
772
 
773
		if f.can_be_large:
774
			print 'if (cmdlen <= gc->maxSmallRenderCommandSize) {'
775
			print '    if ( (gc->pc + cmdlen) > gc->bufEnd ) {'
776
			print '        (void) __glXFlushRenderBuffer(gc, gc->pc);'
777
			print '    }'
778
 
779
		if f.glx_rop == ~0:
780
			opcode = "opcode"
781
		else:
782
			opcode = f.opcode_real_name()
783
 
784
		print 'emit_header(gc->pc, %s, cmdlen);' % (opcode)
785
 
786
		self.pixel_emit_args( f, "gc->pc", 0 )
787
		print 'gc->pc += cmdlen;'
788
		print 'if (gc->pc > gc->limit) { (void) __glXFlushRenderBuffer(gc, gc->pc); }'
789
 
790
		if f.can_be_large:
791
			print '}'
792
			print 'else {'
793
 
794
			self.large_emit_begin(f, opcode)
795
			self.pixel_emit_args(f, "pc", 1)
796
 
797
			print '}'
798
 
799
		if trailer: print trailer
800
		return
801
 
802
 
803
	def printRenderFunction(self, f):
804
		# There is a class of GL functions that take a single pointer
805
		# as a parameter.  This pointer points to a fixed-size chunk
806
		# of data, and the protocol for this functions is very
807
		# regular.  Since they are so regular and there are so many
808
		# of them, special case them with generic functions.  On
809
		# x86, this saves about 26KB in the libGL.so binary.
810
 
811
		if f.variable_length_parameter() == None and len(f.parameters) == 1:
812
			p = f.parameters[0]
813
			if p.is_pointer():
814
				cmdlen = f.command_fixed_length()
815
				if cmdlen in self.generic_sizes:
816
					print '    generic_%u_byte( %s, %s );' % (cmdlen, f.opcode_real_name(), p.name)
817
					return
818
 
819
		if self.common_func_print_just_start(f, None):
820
			trailer = "    }"
821
		else:
822
			trailer = None
823
 
824
		if self.debug:
825
			print 'printf( "Enter %%s...\\n", "gl%s" );' % (f.name)
826
 
827
		if f.can_be_large:
828
			print 'if (cmdlen <= gc->maxSmallRenderCommandSize) {'
829
			print '    if ( (gc->pc + cmdlen) > gc->bufEnd ) {'
830
			print '        (void) __glXFlushRenderBuffer(gc, gc->pc);'
831
			print '    }'
832
 
833
		print 'emit_header(gc->pc, %s, cmdlen);' % (f.opcode_real_name())
834
 
835
		self.common_emit_args(f, "gc->pc", 4, 0)
836
		print 'gc->pc += cmdlen;'
837
		print 'if (__builtin_expect(gc->pc > gc->limit, 0)) { (void) __glXFlushRenderBuffer(gc, gc->pc); }'
838
 
839
		if f.can_be_large:
840
			print '}'
841
			print 'else {'
842
 
843
			self.large_emit_begin(f)
844
			self.common_emit_args(f, "pc", 8, 1)
845
 
846
			p = f.variable_length_parameter()
847
			print '    __glXSendLargeCommand(gc, pc, %u, %s, %s);' % (p.offset + 8, p.name, p.size_string())
848
			print '}'
849
 
850
		if self.debug:
851
			print '__indirect_glFinish();'
852
			print 'printf( "Exit %%s.\\n", "gl%s" );' % (f.name)
853
 
854
		if trailer: print trailer
855
		return
856
 
857
 
858
class PrintGlxProtoInit_c(gl_XML.gl_print_base):
859
	def __init__(self):
860
		gl_XML.gl_print_base.__init__(self)
861
 
862
		self.name = "glX_proto_send.py (from Mesa)"
863
		self.license = license.bsd_license_template % ( \
864
"""Copyright 1998-1999 Precision Insight, Inc., Cedar Park, Texas.
865
(C) Copyright IBM Corporation 2004""", "PRECISION INSIGHT, IBM")
866
		return
867
 
868
 
869
	def printRealHeader(self):
870
		print """/**
871
 * \\file indirect_init.c
872
 * Initialize indirect rendering dispatch table.
873
 *
874
 * \\author Kevin E. Martin 
875
 * \\author Brian Paul 
876
 * \\author Ian Romanick 
877
 */
878
 
879
#include "indirect_init.h"
880
#include "indirect.h"
881
#include "glapi.h"
882
 
883
 
884
/**
885
 * No-op function used to initialize functions that have no GLX protocol
886
 * support.
887
 */
888
static int NoOp(void)
889
{
890
    return 0;
891
}
892
 
893
/**
894
 * Create and initialize a new GL dispatch table.  The table is initialized
895
 * with GLX indirect rendering protocol functions.
896
 */
897
struct _glapi_table * __glXNewIndirectAPI( void )
898
{
899
    struct _glapi_table *glAPI;
900
    GLuint entries;
901
 
902
    entries = _glapi_get_dispatch_table_size();
903
    glAPI = (struct _glapi_table *) Xmalloc(entries * sizeof(void *));
904
 
905
    /* first, set all entries to point to no-op functions */
906
    {
907
       int i;
908
       void **dispatch = (void **) glAPI;
909
       for (i = 0; i < entries; i++) {
910
          dispatch[i] = (void *) NoOp;
911
       }
912
    }
913
 
914
    /* now, initialize the entries we understand */"""
915
 
916
	def printRealFooter(self):
917
		print """
918
    return glAPI;
919
}
920
"""
921
		return
922
 
923
 
924
	def printBody(self, api):
925
		for [name, number] in api.categoryIterate():
926
			if number != None:
927
				preamble = '\n    /* %3u. %s */\n\n' % (int(number), name)
928
			else:
929
				preamble = '\n    /* %s */\n\n' % (name)
930
 
931
			for func in api.functionIterateByCategory(name):
932
				if func.client_supported_for_indirect():
933
					print '%s    glAPI->%s = __indirect_gl%s;' % (preamble, func.name, func.name)
934
					preamble = ''
935
 
936
		return
937
 
938
 
939
class PrintGlxProtoInit_h(gl_XML.gl_print_base):
940
	def __init__(self):
941
		gl_XML.gl_print_base.__init__(self)
942
 
943
		self.name = "glX_proto_send.py (from Mesa)"
944
		self.license = license.bsd_license_template % ( \
945
"""Copyright 1998-1999 Precision Insight, Inc., Cedar Park, Texas.
946
(C) Copyright IBM Corporation 2004""", "PRECISION INSIGHT, IBM")
947
		self.header_tag = "_INDIRECT_H_"
948
 
949
		self.last_category = ""
950
		return
951
 
952
 
953
	def printRealHeader(self):
954
		print """/**
955
 * \\file
956
 * Prototypes for indirect rendering functions.
957
 *
958
 * \\author Kevin E. Martin 
959
 * \\author Ian Romanick 
960
 */
961
"""
962
		self.printVisibility( "HIDDEN", "hidden" )
963
		self.printFastcall()
964
		self.printNoinline()
965
 
966
		print """
967
#include "glxclient.h"
968
 
969
extern HIDDEN NOINLINE CARD32 __glXReadReply( Display *dpy, size_t size,
970
    void * dest, GLboolean reply_is_always_array );
971
 
972
extern HIDDEN NOINLINE void __glXReadPixelReply( Display *dpy,
973
    struct glx_context * gc, unsigned max_dim, GLint width, GLint height,
974
    GLint depth, GLenum format, GLenum type, void * dest,
975
    GLboolean dimensions_in_reply );
976
 
977
extern HIDDEN NOINLINE FASTCALL GLubyte * __glXSetupSingleRequest(
978
    struct glx_context * gc, GLint sop, GLint cmdlen );
979
 
980
extern HIDDEN NOINLINE FASTCALL GLubyte * __glXSetupVendorRequest(
981
    struct glx_context * gc, GLint code, GLint vop, GLint cmdlen );
982
"""
983
 
984
 
985
	def printBody(self, api):
986
		for func in api.functionIterateGlx():
987
			params = func.get_parameter_string()
988
 
989
			print 'extern HIDDEN %s __indirect_gl%s(%s);' % (func.return_type, func.name, params)
990
 
991
			for n in func.entry_points:
992
				if func.has_different_protocol(n):
993
					asdf = func.static_glx_name(n)
994
					if asdf not in func.static_entry_points:
995
						print 'extern HIDDEN %s gl%s(%s);' % (func.return_type, asdf, params)
996
						# give it a easy-to-remember name
997
						if func.client_handcode:
998
							print '#define gl_dispatch_stub_%s gl%s' % (n, asdf)
999
					else:
1000
						print 'GLAPI %s GLAPIENTRY gl%s(%s);' % (func.return_type, asdf, params)
1001
 
1002
					break
1003
 
1004
 
1005
 
1006
def show_usage():
1007
	print "Usage: %s [-f input_file_name] [-m output_mode] [-d]" % sys.argv[0]
1008
	print "    -m output_mode   Output mode can be one of 'proto', 'init_c' or 'init_h'."
1009
	print "    -d               Enable extra debug information in the generated code."
1010
	sys.exit(1)
1011
 
1012
 
1013
if __name__ == '__main__':
1014
	file_name = "gl_API.xml"
1015
 
1016
	try:
1017
		(args, trail) = getopt.getopt(sys.argv[1:], "f:m:d")
1018
	except Exception,e:
1019
		show_usage()
1020
 
1021
	debug = 0
1022
	mode = "proto"
1023
	for (arg,val) in args:
1024
		if arg == "-f":
1025
			file_name = val
1026
		elif arg == "-m":
1027
			mode = val
1028
		elif arg == "-d":
1029
			debug = 1
1030
 
1031
	if mode == "proto":
1032
		printer = PrintGlxProtoStubs()
1033
	elif mode == "init_c":
1034
		printer = PrintGlxProtoInit_c()
1035
	elif mode == "init_h":
1036
		printer = PrintGlxProtoInit_h()
1037
	else:
1038
		show_usage()
1039
 
1040
 
1041
	printer.debug = debug
1042
	api = gl_XML.parse_GL_API( file_name, glX_XML.glx_item_factory() )
1043
 
1044
	printer.Print( api )