mapi/glx: Remove xserver code generation

This hasn't been hooked up to the build since we deleted autotools back
in 2019. It's effectively dead code anyway, as GLX is not a moving
target, and at this point is it easier to modify the generated code
directly than to modify the generator. xserver is encouraged to copy
the generators from 2019 into its own build if it wants, or -
preferably, in this GLX greybeard's opinion - find a prettier codegen
solution in the process of finishing GL 3.0 support.

Reviewed-by: Alyssa Rosenzweig <alyssa@rosenzweig.io>
Reviewed-by: Eric Engestrom <eric@igalia.com>
Reviewed-by: Marek Olšák <marek.olsak@amd.com>
Acked-By: Mike Blumenkrantz <michael.blumenkrantz@gmail.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/33623>
This commit is contained in:
Adam Jackson
2025-02-18 11:46:47 -05:00
committed by Marge Bot
parent 09bbf71e68
commit 43fb26f8ea
3 changed files with 1 additions and 1253 deletions
-554
View File
@@ -1,554 +0,0 @@
# (C) Copyright IBM Corporation 2005
# All Rights Reserved.
#
# Permission is hereby granted, free of charge, to any person obtaining a
# copy of this software and associated documentation files (the "Software"),
# to deal in the Software without restriction, including without limitation
# on the rights to use, copy, modify, merge, publish, distribute, sub
# license, and/or sell copies of the Software, and to permit persons to whom
# the Software is furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice (including the next
# paragraph) shall be included in all copies or substantial portions of the
# Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
# IBM AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
# IN THE SOFTWARE.
#
# Authors:
# Ian Romanick <idr@us.ibm.com>
import argparse
import string
import gl_XML, glX_XML, glX_proto_common, license
class PrintGlxDispatch_h(gl_XML.gl_print_base):
def __init__(self):
gl_XML.gl_print_base.__init__(self)
self.name = "glX_proto_recv.py (from Mesa)"
self.license = license.bsd_license_template % ( "(C) Copyright IBM Corporation 2005", "IBM")
self.header_tag = "_INDIRECT_DISPATCH_H_"
return
def printRealHeader(self):
print '# include <X11/Xfuncproto.h>'
print ''
print 'struct __GLXclientStateRec;'
print ''
return
def printBody(self, api):
for func in api.functionIterateAll():
if not func.ignore and not func.vectorequiv:
if func.glx_rop:
print 'extern _X_HIDDEN void __glXDisp_%s(GLbyte * pc);' % (func.name)
print 'extern _X_HIDDEN _X_COLD void __glXDispSwap_%s(GLbyte * pc);' % (func.name)
elif func.glx_sop or func.glx_vendorpriv:
print 'extern _X_HIDDEN int __glXDisp_%s(struct __GLXclientStateRec *, GLbyte *);' % (func.name)
print 'extern _X_HIDDEN _X_COLD int __glXDispSwap_%s(struct __GLXclientStateRec *, GLbyte *);' % (func.name)
if func.glx_sop and func.glx_vendorpriv:
n = func.glx_vendorpriv_names[0]
print 'extern _X_HIDDEN int __glXDisp_%s(struct __GLXclientStateRec *, GLbyte *);' % (n)
print 'extern _X_HIDDEN _X_COLD int __glXDispSwap_%s(struct __GLXclientStateRec *, GLbyte *);' % (n)
return
class PrintGlxDispatchFunctions(glX_proto_common.glx_print_proto):
def __init__(self, do_swap):
gl_XML.gl_print_base.__init__(self)
self.name = "glX_proto_recv.py (from Mesa)"
self.license = license.bsd_license_template % ( "(C) Copyright IBM Corporation 2005", "IBM")
self.real_types = [ '', '', 'uint16_t', '', 'uint32_t', '', '', '', 'uint64_t' ]
self.do_swap = do_swap
return
def printRealHeader(self):
print '#include <inttypes.h>'
print '#include "glxserver.h"'
print '#include "indirect_size.h"'
print '#include "indirect_size_get.h"'
print '#include "indirect_dispatch.h"'
print '#include "glxbyteorder.h"'
print '#include "indirect_util.h"'
print '#include "singlesize.h"'
print ''
print 'typedef struct {'
print ' __GLX_PIXEL_3D_HDR;'
print '} __GLXpixel3DHeader;'
print ''
print 'extern GLboolean __glXErrorOccured( void );'
print 'extern void __glXClearErrorOccured( void );'
print ''
print 'static const unsigned dummy_answer[2] = {0, 0};'
print ''
return
def printBody(self, api):
if self.do_swap:
self.emit_swap_wrappers(api)
for func in api.functionIterateByOffset():
if not func.ignore and not func.server_handcode and not func.vectorequiv and (func.glx_rop or func.glx_sop or func.glx_vendorpriv):
self.printFunction(func, func.name)
if func.glx_sop and func.glx_vendorpriv:
self.printFunction(func, func.glx_vendorpriv_names[0])
return
def fptrType(self, name):
fptr = "pfngl" + name + "proc"
return fptr.upper()
def printFunction(self, f, name):
if (f.glx_sop or f.glx_vendorpriv) and (len(f.get_images()) != 0):
return
if not self.do_swap:
base = '__glXDisp'
else:
base = '__glXDispSwap'
if f.glx_rop:
print 'void %s_%s(GLbyte * pc)' % (base, name)
else:
print 'int %s_%s(__GLXclientState *cl, GLbyte *pc)' % (base, name)
print '{'
if f.glx_rop or f.vectorequiv:
self.printRenderFunction(f)
elif f.glx_sop or f.glx_vendorpriv:
if len(f.get_images()) == 0:
self.printSingleFunction(f, name)
else:
print "/* Missing GLX protocol for %s. */" % (name)
print '}'
print ''
return
def swap_name(self, bytes):
return 'bswap_%u_array' % (8 * bytes)
def emit_swap_wrappers(self, api):
self.type_map = {}
already_done = [ ]
for t in api.typeIterate():
te = t.get_type_expression()
t_size = te.get_element_size()
if t_size > 1 and t.glx_name:
t_name = "GL" + t.name
self.type_map[ t_name ] = t.glx_name
if t.glx_name not in already_done:
real_name = self.real_types[t_size]
print 'static _X_UNUSED %s' % (t_name)
print 'bswap_%s(const void * src)' % (t.glx_name)
print '{'
print ' union { %s dst; %s ret; } x;' % (real_name, t_name)
print ' x.dst = bswap_%u(*(%s *) src);' % (t_size * 8, real_name)
print ' return x.ret;'
print '}'
print ''
already_done.append( t.glx_name )
for bits in [16, 32, 64]:
print 'static void *'
print 'bswap_%u_array(uint%u_t * src, unsigned count)' % (bits, bits)
print '{'
print ' unsigned i;'
print ''
print ' for (i = 0 ; i < count ; i++) {'
print ' uint%u_t temp = bswap_%u(src[i]);' % (bits, bits)
print ' src[i] = temp;'
print ' }'
print ''
print ' return src;'
print '}'
print ''
def fetch_param(self, param):
t = param.type_string()
o = param.offset
element_size = param.size() / param.get_element_count()
if self.do_swap and (element_size != 1):
if param.is_array():
real_name = self.real_types[ element_size ]
swap_func = self.swap_name( element_size )
return ' (%-8s)%s( (%s *) (pc + %2s), %s )' % (t, swap_func, real_name, o, param.count)
else:
t_name = param.get_base_type_string()
return ' (%-8s)bswap_%-7s( pc + %2s )' % (t, self.type_map[ t_name ], o)
else:
if param.is_array():
return ' (%-8s)(pc + %2u)' % (t, o)
else:
return '*(%-8s *)(pc + %2u)' % (t, o)
return None
def emit_function_call(self, f, retval_assign, indent):
list = []
for param in f.parameterIterator():
if param.is_padding:
continue
if param.is_counter or param.is_image() or param.is_output or param.name in f.count_parameter_list or len(param.count_parameter_list):
location = param.name
else:
location = self.fetch_param(param)
list.append( '%s %s' % (indent, location) )
print '%s %sgl%s(%s);' % (indent, retval_assign, f.name, string.join(list, ',\n'))
def common_func_print_just_start(self, f, indent):
align64 = 0
need_blank = 0
f.calculate_offsets()
for param in f.parameterIterateGlxSend():
# If any parameter has a 64-bit base type, then we
# have to do alignment magic for the while thing.
if param.is_64_bit():
align64 = 1
# FIXME img_null_flag is over-loaded. In addition to
# FIXME being used for images, it is used to signify
# FIXME NULL data pointers for vertex buffer object
# FIXME related functions. Re-name it to null_data
# FIXME or something similar.
if param.img_null_flag:
print '%s const CARD32 ptr_is_null = *(CARD32 *)(pc + %s);' % (indent, param.offset - 4)
cond = '(ptr_is_null != 0) ? NULL : '
else:
cond = ""
type_string = param.type_string()
if param.is_image():
offset = f.offset_of( param.name )
print '%s %s const %s = (%s) (%s(pc + %s));' % (indent, type_string, param.name, type_string, cond, offset)
if param.depth:
print '%s __GLXpixel3DHeader * const hdr = (__GLXpixel3DHeader *)(pc);' % (indent)
else:
print '%s __GLXpixelHeader * const hdr = (__GLXpixelHeader *)(pc);' % (indent)
need_blank = 1
elif param.is_counter or param.name in f.count_parameter_list:
location = self.fetch_param(param)
print '%s const %s %s = %s;' % (indent, type_string, param.name, location)
need_blank = 1
elif len(param.count_parameter_list):
if param.size() == 1 and not self.do_swap:
location = self.fetch_param(param)
print '%s %s %s = %s%s;' % (indent, type_string, param.name, cond, location)
else:
print '%s %s %s;' % (indent, type_string, param.name)
need_blank = 1
if need_blank:
print ''
if align64:
print '#ifdef __GLX_ALIGN64'
if f.has_variable_size_request():
self.emit_packet_size_calculation(f, 4)
s = "cmdlen"
else:
s = str((f.command_fixed_length() + 3) & ~3)
print ' if ((unsigned long)(pc) & 7) {'
print ' (void) memmove(pc-4, pc, %s);' % (s)
print ' pc -= 4;'
print ' }'
print '#endif'
print ''
need_blank = 0
if self.do_swap:
for param in f.parameterIterateGlxSend():
if param.count_parameter_list:
o = param.offset
count = param.get_element_count()
type_size = param.size() / count
if param.counter:
count_name = param.counter
else:
count_name = str(count)
# This is basically an ugly special-
# case for glCallLists.
if type_size == 1:
x = []
x.append( [1, ['BYTE', 'UNSIGNED_BYTE', '2_BYTES', '3_BYTES', '4_BYTES']] )
x.append( [2, ['SHORT', 'UNSIGNED_SHORT']] )
x.append( [4, ['INT', 'UNSIGNED_INT', 'FLOAT']] )
print ' switch(%s) {' % (param.count_parameter_list[0])
for sub in x:
for t_name in sub[1]:
print ' case GL_%s:' % (t_name)
if sub[0] == 1:
print ' %s = (%s) (pc + %s); break;' % (param.name, param.type_string(), o)
else:
swap_func = self.swap_name(sub[0])
print ' %s = (%s) %s( (%s *) (pc + %s), %s ); break;' % (param.name, param.type_string(), swap_func, self.real_types[sub[0]], o, count_name)
print ' default:'
print ' return;'
print ' }'
else:
swap_func = self.swap_name(type_size)
compsize = self.size_call(f, 1)
print ' %s = (%s) %s( (%s *) (pc + %s), %s );' % (param.name, param.type_string(), swap_func, self.real_types[type_size], o, compsize)
need_blank = 1
else:
for param in f.parameterIterateGlxSend():
if param.count_parameter_list:
print '%s %s = (%s) (pc + %s);' % (indent, param.name, param.type_string(), param.offset)
need_blank = 1
if need_blank:
print ''
return
def printSingleFunction(self, f, name):
if name not in f.glx_vendorpriv_names:
print ' xGLXSingleReq * const req = (xGLXSingleReq *) pc;'
else:
print ' xGLXVendorPrivateReq * const req = (xGLXVendorPrivateReq *) pc;'
print ' int error;'
if self.do_swap:
print ' __GLXcontext * const cx = __glXForceCurrent(cl, bswap_CARD32( &req->contextTag ), &error);'
else:
print ' __GLXcontext * const cx = __glXForceCurrent(cl, req->contextTag, &error);'
print ''
if name not in f.glx_vendorpriv_names:
print ' pc += __GLX_SINGLE_HDR_SIZE;'
else:
print ' pc += __GLX_VENDPRIV_HDR_SIZE;'
print ' if ( cx != NULL ) {'
self.common_func_print_just_start(f, " ")
if f.return_type != 'void':
print ' %s retval;' % (f.return_type)
retval_string = "retval"
retval_assign = "retval = "
else:
retval_string = "0"
retval_assign = ""
type_size = 0
answer_string = "dummy_answer"
answer_count = "0"
is_array_string = "GL_FALSE"
for param in f.parameterIterateOutputs():
answer_type = param.get_base_type_string()
if answer_type == "GLvoid":
answer_type = "GLubyte"
c = param.get_element_count()
type_size = (param.size() / c)
if type_size == 1:
size_scale = ""
else:
size_scale = " * %u" % (type_size)
if param.count_parameter_list:
print ' const GLuint compsize = %s;' % (self.size_call(f, 1))
print ' %s answerBuffer[200];' % (answer_type)
print ' %s %s = __glXGetAnswerBuffer(cl, compsize%s, answerBuffer, sizeof(answerBuffer), %u);' % (param.type_string(), param.name, size_scale, type_size )
answer_string = param.name
answer_count = "compsize"
print ''
print ' if (%s == NULL) return BadAlloc;' % (param.name)
print ' __glXClearErrorOccured();'
print ''
elif param.counter:
print ' %s answerBuffer[200];' % (answer_type)
print ' %s %s = __glXGetAnswerBuffer(cl, %s%s, answerBuffer, sizeof(answerBuffer), %u);' % (param.type_string(), param.name, param.counter, size_scale, type_size)
answer_string = param.name
answer_count = param.counter
print ''
print ' if (%s == NULL) return BadAlloc;' % (param.name)
print ' __glXClearErrorOccured();'
print ''
elif c >= 1:
print ' %s %s[%u];' % (answer_type, param.name, c)
answer_string = param.name
answer_count = "%u" % (c)
if f.reply_always_array:
is_array_string = "GL_TRUE"
self.emit_function_call(f, retval_assign, " ")
if f.needs_reply():
if self.do_swap:
for param in f.parameterIterateOutputs():
c = param.get_element_count()
type_size = (param.size() / c)
if type_size > 1:
swap_name = self.swap_name( type_size )
print ' (void) %s( (uint%u_t *) %s, %s );' % (swap_name, 8 * type_size, param.name, answer_count)
reply_func = '__glXSendReplySwap'
else:
reply_func = '__glXSendReply'
print ' %s(cl->client, %s, %s, %u, %s, %s);' % (reply_func, answer_string, answer_count, type_size, is_array_string, retval_string)
#elif f.note_unflushed:
# print ' cx->hasUnflushedCommands = GL_TRUE;'
print ' error = Success;'
print ' }'
print ''
print ' return error;'
return
def printRenderFunction(self, f):
# There are 4 distinct phases in a rendering dispatch function.
# In the first phase we compute the sizes and offsets of each
# element in the command. In the second phase we (optionally)
# re-align 64-bit data elements. In the third phase we
# (optionally) byte-swap array data. Finally, in the fourth
# phase we actually dispatch the function.
self.common_func_print_just_start(f, "")
images = f.get_images()
if len(images):
if self.do_swap:
pre = "bswap_CARD32( & "
post = " )"
else:
pre = ""
post = ""
img = images[0]
# swapBytes and lsbFirst are single byte fields, so
# the must NEVER be byte-swapped.
if not (img.img_type == "GL_BITMAP" and img.img_format == "GL_COLOR_INDEX"):
print ' glPixelStorei(GL_UNPACK_SWAP_BYTES, hdr->swapBytes);'
print ' glPixelStorei(GL_UNPACK_LSB_FIRST, hdr->lsbFirst);'
print ' glPixelStorei(GL_UNPACK_ROW_LENGTH, (GLint) %shdr->rowLength%s);' % (pre, post)
if img.depth:
print ' glPixelStorei(GL_UNPACK_IMAGE_HEIGHT, (GLint) %shdr->imageHeight%s);' % (pre, post)
print ' glPixelStorei(GL_UNPACK_SKIP_ROWS, (GLint) %shdr->skipRows%s);' % (pre, post)
if img.depth:
print ' glPixelStorei(GL_UNPACK_SKIP_IMAGES, (GLint) %shdr->skipImages%s);' % (pre, post)
print ' glPixelStorei(GL_UNPACK_SKIP_PIXELS, (GLint) %shdr->skipPixels%s);' % (pre, post)
print ' glPixelStorei(GL_UNPACK_ALIGNMENT, (GLint) %shdr->alignment%s);' % (pre, post)
print ''
self.emit_function_call(f, "", "")
return
def _parser():
"""Parse any arguments passed and return a namespace."""
parser = argparse.ArgumentParser()
parser.add_argument('-f',
dest='filename',
default='gl_API.xml',
help='an xml file describing an OpenGL API')
parser.add_argument('-m',
dest='mode',
default='dispatch_c',
choices=['dispatch_c', 'dispatch_h'],
help='what file to generate')
parser.add_argument('-s',
dest='swap',
action='store_true',
help='emit swap in GlXDispatchFunctions')
return parser.parse_args()
def main():
"""Main function."""
args = _parser()
if args.mode == "dispatch_c":
printer = PrintGlxDispatchFunctions(args.swap)
elif args.mode == "dispatch_h":
printer = PrintGlxDispatch_h()
api = gl_XML.parse_GL_API(
args.filename, glX_proto_common.glx_proto_item_factory())
printer.Print(api)
if __name__ == '__main__':
main()
+1 -298
View File
@@ -236,64 +236,6 @@ class glx_enum_function(object):
print('')
class glx_server_enum_function(glx_enum_function):
def __init__(self, func, enum_dict):
glx_enum_function.__init__(self, func.name, enum_dict)
self.function = func
return
def signature( self ):
if self.sig == None:
sig = glx_enum_function.signature(self)
p = self.function.variable_length_parameter()
if p:
sig += "%u" % (p.size())
self.sig = sig
return self.sig;
def Print(self, name, printer):
f = self.function
printer.common_func_print_just_header( f )
fixup = []
foo = {}
for param_name in f.count_parameter_list:
o = f.offset_of( param_name )
foo[o] = param_name
for param_name in f.counter_list:
o = f.offset_of( param_name )
foo[o] = param_name
keys = sorted(foo.keys())
for o in keys:
p = f.parameters_by_name[ foo[o] ]
printer.common_emit_one_arg(p, "pc", 0)
fixup.append( p.name )
print(' GLsizei compsize;')
print('')
printer.common_emit_fixups(fixup)
print('')
print(' compsize = __gl%s_size(%s);' % (f.name, string.join(f.count_parameter_list, ",")))
p = f.variable_length_parameter()
print(' return safe_pad(%s);' % (p.size_string()))
print('}')
print('')
class PrintGlxSizeStubs_common(gl_XML.gl_print_base):
do_get = (1 << 0)
do_set = (1 << 1)
@@ -406,241 +348,6 @@ class PrintGlxReqSize_common(gl_XML.gl_print_base):
self.license = license.bsd_license_template % ( "(C) Copyright IBM Corporation 2005", "IBM")
class PrintGlxReqSize_h(PrintGlxReqSize_common):
def __init__(self):
PrintGlxReqSize_common.__init__(self)
self.header_tag = "_INDIRECT_REQSIZE_H_"
def printRealHeader(self):
print('#include <X11/Xfuncproto.h>')
print('')
self.printPure()
print('')
def printBody(self, api):
for func in api.functionIterateGlx():
if not func.ignore and func.has_variable_size_request():
print('extern PURE _X_HIDDEN int __glX%sReqSize(const GLbyte *pc, Bool swap, int reqlen);' % (func.name))
class PrintGlxReqSize_c(PrintGlxReqSize_common):
"""Create the server-side 'request size' functions.
Create the server-side functions that are used to determine what the
size of a varible length command should be. The server then uses
this value to determine if the incoming command packed it malformed.
"""
def __init__(self):
PrintGlxReqSize_common.__init__(self)
self.counter_sigs = {}
def printRealHeader(self):
print('')
print('#include "util/glheader.h"')
print('#include "glxserver.h"')
print('#include "glxbyteorder.h"')
print('#include "indirect_size.h"')
print('#include "indirect_reqsize.h"')
print('')
print('#ifdef HAVE_FUNC_ATTRIBUTE_ALIAS')
print('# define ALIAS2(from,to) \\')
print(' GLint __glX ## from ## ReqSize( const GLbyte * pc, Bool swap, int reqlen ) \\')
print(' __attribute__ ((alias( # to )));')
print('# define ALIAS(from,to) ALIAS2( from, __glX ## to ## ReqSize )')
print('#else')
print('# define ALIAS(from,to) \\')
print(' GLint __glX ## from ## ReqSize( const GLbyte * pc, Bool swap, int reqlen ) \\')
print(' { return __glX ## to ## ReqSize( pc, swap, reqlen ); }')
print('#endif')
print('')
print('')
def printBody(self, api):
aliases = []
enum_functions = {}
enum_sigs = {}
for func in api.functionIterateGlx():
if not func.has_variable_size_request(): continue
ef = glx_server_enum_function( func, api.enums_by_name )
if len(ef.enums) == 0: continue
sig = ef.signature()
if func.name not in enum_functions:
enum_functions[ func.name ] = sig
if sig not in enum_sigs:
enum_sigs[ sig ] = ef
for func in api.functionIterateGlx():
# Even though server-handcode fuctions are on "the
# list", and prototypes are generated for them, there
# isn't enough information to generate a size
# function. If there was enough information, they
# probably wouldn't need to be handcoded in the first
# place!
if func.server_handcode: continue
if not func.has_variable_size_request(): continue
if func.name in enum_functions:
sig = enum_functions[func.name]
ef = enum_sigs[ sig ]
if ef.name != func.name:
aliases.append( [func.name, ef.name] )
else:
ef.Print( func.name, self )
elif func.images:
self.printPixelFunction(func)
elif func.has_variable_size_request():
a = self.printCountedFunction(func)
if a: aliases.append(a)
for [alias_name, real_name] in aliases:
print('ALIAS( %s, %s )' % (alias_name, real_name))
return
def common_emit_fixups(self, fixup):
"""Utility function to emit conditional byte-swaps."""
if fixup:
print(' if (swap) {')
for name in fixup:
print(' %s = bswap_32(%s);' % (name, name))
print(' }')
return
def common_emit_one_arg(self, p, pc, adjust):
offset = p.offset
dst = p.string()
src = '(%s *)' % (p.type_string())
print('%-18s = *%11s(%s + %u);' % (dst, src, pc, offset + adjust));
return
def common_func_print_just_header(self, f):
print('int')
print('__glX%sReqSize( const GLbyte * pc, Bool swap, int reqlen )' % (f.name))
print('{')
def printPixelFunction(self, f):
self.common_func_print_just_header(f)
f.offset_of( f.parameters[0].name )
[dim, w, h, d, junk] = f.get_images()[0].get_dimensions()
print(' GLint row_length = * (GLint *)(pc + 4);')
if dim < 3:
fixup = ['row_length', 'skip_rows', 'alignment']
print(' GLint image_height = 0;')
print(' GLint skip_images = 0;')
print(' GLint skip_rows = * (GLint *)(pc + 8);')
print(' GLint alignment = * (GLint *)(pc + 16);')
else:
fixup = ['row_length', 'image_height', 'skip_rows', 'skip_images', 'alignment']
print(' GLint image_height = * (GLint *)(pc + 8);')
print(' GLint skip_rows = * (GLint *)(pc + 16);')
print(' GLint skip_images = * (GLint *)(pc + 20);')
print(' GLint alignment = * (GLint *)(pc + 32);')
img = f.images[0]
for p in f.parameterIterateGlxSend():
if p.name in [w, h, d, img.img_format, img.img_type, img.img_target]:
self.common_emit_one_arg(p, "pc", 0)
fixup.append( p.name )
print('')
self.common_emit_fixups(fixup)
if img.img_null_flag:
print('')
print(' if (*(CARD32 *) (pc + %s))' % (img.offset - 4))
print(' return 0;')
print('')
print(' return __glXImageSize(%s, %s, %s, %s, %s, %s,' % (img.img_format, img.img_type, img.img_target, w, h, d ))
print(' image_height, row_length, skip_images,')
print(' skip_rows, alignment);')
print('}')
print('')
return
def printCountedFunction(self, f):
sig = ""
offset = 0
fixup = []
params = []
size = ''
param_offsets = {}
# Calculate the offset of each counter parameter and the
# size string for the variable length parameter(s). While
# that is being done, calculate a unique signature for this
# function.
for p in f.parameterIterateGlxSend():
if p.is_counter:
fixup.append( p.name )
params.append( p )
elif p.counter:
s = p.size()
if s == 0: s = 1
sig += "(%u,%u)" % (f.offset_of(p.counter), s)
if size == '':
size = p.size_string()
else:
size = "safe_add(%s, %s)" % (size, p.size_string())
# If the calculated signature matches a function that has
# already be emitted, don't emit this function. Instead, add
# it to the list of function aliases.
if sig in self.counter_sigs:
n = self.counter_sigs[sig];
alias = [f.name, n]
else:
alias = None
self.counter_sigs[sig] = f.name
self.common_func_print_just_header(f)
for p in params:
self.common_emit_one_arg(p, "pc", 0)
print('')
self.common_emit_fixups(fixup)
print('')
print(' return safe_pad(%s);' % (size))
print('}')
print('')
return alias
def _parser():
"""Parse arguments and return a namespace."""
parser = argparse.ArgumentParser()
@@ -652,7 +359,7 @@ def _parser():
help='an XML file describing an OpenGL API.')
parser.add_argument('-m',
dest='mode',
choices=['size_c', 'size_h', 'reqsize_c', 'reqsize_h'],
choices=['size_c', 'size_h'],
help='Which file to generate')
getset = parser.add_mutually_exclusive_group()
getset.add_argument('--only-get',
@@ -683,10 +390,6 @@ def main():
printer = PrintGlxSizeStubs_h(args.which_functions)
if args.header_tag is not None:
printer.header_tag = args.header_tag
elif args.mode == "reqsize_c":
printer = PrintGlxReqSize_c()
elif args.mode == "reqsize_h":
printer = PrintGlxReqSize_h()
api = gl_XML.parse_GL_API(args.filename, glX_XML.glx_item_factory())
-401
View File
@@ -1,401 +0,0 @@
# (C) Copyright IBM Corporation 2005, 2006
# All Rights Reserved.
#
# Permission is hereby granted, free of charge, to any person obtaining a
# copy of this software and associated documentation files (the "Software"),
# to deal in the Software without restriction, including without limitation
# on the rights to use, copy, modify, merge, publish, distribute, sub
# license, and/or sell copies of the Software, and to permit persons to whom
# the Software is furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice (including the next
# paragraph) shall be included in all copies or substantial portions of the
# Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
# IBM AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
# IN THE SOFTWARE.
#
# Authors:
# Ian Romanick <idr@us.ibm.com>
import argparse
import gl_XML, glX_XML, glX_proto_common, license
def log2(value):
for i in range(0, 30):
p = 1 << i
if p >= value:
return i
return -1
def round_down_to_power_of_two(n):
"""Returns the nearest power-of-two less than or equal to n."""
for i in range(30, 0, -1):
p = 1 << i
if p <= n:
return p
return -1
class function_table:
def __init__(self, name, do_size_check):
self.name_base = name
self.do_size_check = do_size_check
self.max_bits = 1
self.next_opcode_threshold = (1 << self.max_bits)
self.max_opcode = 0
self.functions = {}
self.lookup_table = []
# Minimum number of opcodes in a leaf node.
self.min_op_bits = 3
self.min_op_count = (1 << self.min_op_bits)
return
def append(self, opcode, func):
self.functions[opcode] = func
if opcode > self.max_opcode:
self.max_opcode = opcode
if opcode > self.next_opcode_threshold:
bits = log2(opcode)
if (1 << bits) <= opcode:
bits += 1
self.max_bits = bits
self.next_opcode_threshold = 1 << bits
return
def divide_group(self, min_opcode, total):
"""Divide the group starting min_opcode into subgroups.
Returns a tuple containing the number of bits consumed by
the node, the list of the children's tuple, and the number
of entries in the final array used by this node and its
children, and the depth of the subtree rooted at the node."""
remaining_bits = self.max_bits - total
next_opcode = min_opcode + (1 << remaining_bits)
empty_children = 0
for M in range(0, remaining_bits):
op_count = 1 << (remaining_bits - M);
child_count = 1 << M;
empty_children = 0
full_children = 0
for i in range(min_opcode, next_opcode, op_count):
used = 0
empty = 0
for j in range(i, i + op_count):
if self.functions.has_key(j):
used += 1;
else:
empty += 1;
if empty == op_count:
empty_children += 1
if used == op_count:
full_children += 1
if (empty_children > 0) or (full_children == child_count) or (op_count <= self.min_op_count):
break
# If all the remaining bits are used by this node, as is the
# case when M is 0 or remaining_bits, the node is a leaf.
if (M == 0) or (M == remaining_bits):
return [remaining_bits, [], 0, 0]
else:
children = []
count = 1
depth = 1
all_children_are_nonempty_leaf_nodes = 1
for i in range(min_opcode, next_opcode, op_count):
n = self.divide_group(i, total + M)
if not (n[1] == [] and not self.is_empty_leaf(i, n[0])):
all_children_are_nonempty_leaf_nodes = 0
children.append(n)
count += n[2] + 1
if n[3] >= depth:
depth = n[3] + 1
# If all of the child nodes are non-empty leaf nodes, pull
# them up and make this node a leaf.
if all_children_are_nonempty_leaf_nodes:
return [remaining_bits, [], 0, 0]
else:
return [M, children, count, depth]
def is_empty_leaf(self, base_opcode, M):
for op in range(base_opcode, base_opcode + (1 << M)):
if self.functions.has_key(op):
return 0
break
return 1
def dump_tree(self, node, base_opcode, remaining_bits, base_entry, depth):
M = node[0]
children = node[1]
child_M = remaining_bits - M
# This actually an error condition.
if children == []:
return
print ' /* [%u] -> opcode range [%u, %u], node depth %u */' % (base_entry, base_opcode, base_opcode + (1 << remaining_bits), depth)
print ' %u,' % (M)
base_entry += (1 << M) + 1
child_index = base_entry
child_base_opcode = base_opcode
for child in children:
if child[1] == []:
if self.is_empty_leaf(child_base_opcode, child_M):
print ' EMPTY_LEAF,'
else:
# Emit the index of the next dispatch
# function. Then add all the
# dispatch functions for this leaf
# node to the dispatch function
# lookup table.
print ' LEAF(%u),' % (len(self.lookup_table))
for op in range(child_base_opcode, child_base_opcode + (1 << child_M)):
if self.functions.has_key(op):
func = self.functions[op]
size = func.command_fixed_length()
if func.glx_rop != 0:
size += 4
size = ((size + 3) & ~3)
if func.has_variable_size_request():
size_name = "__glX%sReqSize" % (func.name)
else:
size_name = ""
if func.glx_vendorpriv == op:
func_name = func.glx_vendorpriv_names[0]
else:
func_name = func.name
temp = [op, "__glXDisp_%s" % (func_name), "__glXDispSwap_%s" % (func_name), size, size_name]
else:
temp = [op, "NULL", "NULL", 0, ""]
self.lookup_table.append(temp)
else:
print ' %u,' % (child_index)
child_index += child[2]
child_base_opcode += 1 << child_M
print ''
child_index = base_entry
for child in children:
if child[1] != []:
self.dump_tree(child, base_opcode, remaining_bits - M, child_index, depth + 1)
child_index += child[2]
base_opcode += 1 << (remaining_bits - M)
def Print(self):
# Each dispatch table consists of two data structures.
#
# The first structure is an N-way tree where the opcode for
# the function is the key. Each node switches on a range of
# bits from the opcode. M bits are extracted from the opcde
# and are used as an index to select one of the N, where
# N = 2^M, children.
#
# The tree is stored as a flat array. The first value is the
# number of bits, M, used by the node. For inner nodes, the
# following 2^M values are indexes into the array for the
# child nodes. For leaf nodes, the followign 2^M values are
# indexes into the second data structure.
#
# If an inner node's child index is 0, the child is an empty
# leaf node. That is, none of the opcodes selectable from
# that child exist. Since most of the possible opcode space
# is unused, this allows compact data storage.
#
# The second data structure is an array of pairs of function
# pointers. Each function contains a pointer to a protocol
# decode function and a pointer to a byte-swapped protocol
# decode function. Elements in this array are selected by the
# leaf nodes of the first data structure.
#
# As the tree is traversed, an accumulator is kept. This
# accumulator counts the bits of the opcode consumed by the
# traversal. When accumulator + M = B, where B is the
# maximum number of bits in an opcode, the traversal has
# reached a leaf node. The traversal starts with the most
# significant bits and works down to the least significant
# bits.
#
# Creation of the tree is the most complicated part. At
# each node the elements are divided into groups of 2^M
# elements. The value of M selected is the smallest possible
# value where all of the groups are either empty or full, or
# the groups are a preset minimum size. If all the children
# of a node are non-empty leaf nodes, the children are merged
# to create a single leaf node that replaces the parent.
tree = self.divide_group(0, 0)
print '/*****************************************************************/'
print '/* tree depth = %u */' % (tree[3])
print 'static const int_fast16_t %s_dispatch_tree[%u] = {' % (self.name_base, tree[2])
self.dump_tree(tree, 0, self.max_bits, 0, 1)
print '};\n'
# After dumping the tree, dump the function lookup table.
print 'static const void *%s_function_table[%u][2] = {' % (self.name_base, len(self.lookup_table))
index = 0
for func in self.lookup_table:
opcode = func[0]
name = func[1]
name_swap = func[2]
print ' /* [% 3u] = %5u */ {%s, %s},' % (index, opcode, name, name_swap)
index += 1
print '};\n'
if self.do_size_check:
var_table = []
print 'static const int_fast16_t %s_size_table[%u][2] = {' % (self.name_base, len(self.lookup_table))
index = 0
var_table = []
for func in self.lookup_table:
opcode = func[0]
fixed = func[3]
var = func[4]
if var != "":
var_offset = "%2u" % (len(var_table))
var_table.append(var)
else:
var_offset = "~0"
print ' /* [%3u] = %5u */ {%3u, %s},' % (index, opcode, fixed, var_offset)
index += 1
print '};\n'
print 'static const gl_proto_size_func %s_size_func_table[%u] = {' % (self.name_base, len(var_table))
for func in var_table:
print ' %s,' % (func)
print '};\n'
print 'const struct __glXDispatchInfo %s_dispatch_info = {' % (self.name_base)
print ' %u,' % (self.max_bits)
print ' %s_dispatch_tree,' % (self.name_base)
print ' %s_function_table,' % (self.name_base)
if self.do_size_check:
print ' %s_size_table,' % (self.name_base)
print ' %s_size_func_table' % (self.name_base)
else:
print ' NULL,'
print ' NULL'
print '};\n'
return
class PrintGlxDispatchTables(glX_proto_common.glx_print_proto):
def __init__(self):
gl_XML.gl_print_base.__init__(self)
self.name = "glX_server_table.py (from Mesa)"
self.license = license.bsd_license_template % ( "(C) Copyright IBM Corporation 2005, 2006", "IBM")
self.rop_functions = function_table("Render", 1)
self.sop_functions = function_table("Single", 0)
self.vop_functions = function_table("VendorPriv", 0)
return
def printRealHeader(self):
print '#include <inttypes.h>'
print '#include "glxserver.h"'
print '#include "glxext.h"'
print '#include "indirect_dispatch.h"'
print '#include "indirect_reqsize.h"'
print '#include "indirect_table.h"'
print ''
return
def printBody(self, api):
for f in api.functionIterateAll():
if not f.ignore and f.vectorequiv == None:
if f.glx_rop != 0:
self.rop_functions.append(f.glx_rop, f)
if f.glx_sop != 0:
self.sop_functions.append(f.glx_sop, f)
if f.glx_vendorpriv != 0:
self.vop_functions.append(f.glx_vendorpriv, f)
self.sop_functions.Print()
self.rop_functions.Print()
self.vop_functions.Print()
return
def _parser():
"""Parse arguments and return namespace."""
parser = argparse.ArgumentParser()
parser.add_argument('-f',
dest='filename',
default='gl_API.xml',
help='An XML file describing an API.')
return parser.parse_args()
if __name__ == '__main__':
args = _parser()
printer = PrintGlxDispatchTables()
api = gl_XML.parse_GL_API(args.filename, glX_XML.glx_item_factory())
printer.Print(api)