From 4f6a1aed5f51d27d1a6d980669bbfb8628d4a407 Mon Sep 17 00:00:00 2001 From: Chia-I Wu Date: Sat, 11 Apr 2015 16:07:13 +0800 Subject: [PATCH] xgl-generate.py: rewrite LoaderEntrypointsSubcommand With the goal to generalize dispatch rules and avoid code duplication. As a result, xglOpenPeerImage() is fixed and xglAllocDescriptorSets() gains error checking. --- xgl-generate.py | 168 ++++++++++++++++++++++++++------------------------------ 1 file changed, 79 insertions(+), 89 deletions(-) diff --git a/xgl-generate.py b/xgl-generate.py index 8ad0316..cb79913 100755 --- a/xgl-generate.py +++ b/xgl-generate.py @@ -100,10 +100,6 @@ class LoaderEntrypointsSubcommand(Subcommand): def generate_header(self): return "#include \"loader.h\"" - def _does_function_create_object(self, proto): - out_objs = proto.object_out_params() - return out_objs and out_objs[-1] == proto.params[-1] - def _is_dispatchable(self, proto): if proto.name in ["GetProcAddr", "DestroyInstance", "EnumerateGpus", "EnumerateLayers"]: return False @@ -111,6 +107,35 @@ class LoaderEntrypointsSubcommand(Subcommand): in_objs = proto.object_in_params() return in_objs and in_objs[0] == proto.params[0] + def _generate_object_setup(self, proto): + method = "loader_init_data" + cond = "res == XGL_SUCCESS" + + if "Get" in proto.name: + method = "loader_set_data" + + setup = [] + + if proto.name == "AllocDescriptorSets": + psets = proto.params[-2].name + pcount = proto.params[-1].name + setup.append("uint32_t i;") + setup.append("for (i = 0; i < *%s; i++)" % pcount) + setup.append(" %s(%s[i], disp);" % (method, psets)) + else: + obj_params = proto.object_out_params() + for param in obj_params: + setup.append("%s(*%s, disp);" % (method, param.name)) + + if setup: + joined = "\n ".join(setup) + setup = [] + setup.append(" if (%s) {" % cond) + setup.append(" " + joined) + setup.append(" }") + + return "\n".join(setup) + def _generate_loader_dispatch_entrypoints(self, qual=""): if qual: qual += " " @@ -119,93 +144,58 @@ class LoaderEntrypointsSubcommand(Subcommand): for proto in self.protos: if not self._is_dispatchable(proto): continue - if 'WsiX11AssociateConnection' == proto.name: - funcs.append("#if defined(__linux__) || defined(XCB_NVIDIA)") - decl = proto.c_func(prefix="xgl", attr="XGLAPI") - stmt = "disp->%s" % proto.c_call() + + func = [] + + obj_setup = self._generate_object_setup(proto) + + func.append(qual + proto.c_func(prefix="xgl", attr="XGLAPI")) + func.append("{") + + # declare local variables + func.append(" const XGL_LAYER_DISPATCH_TABLE *disp;") + if proto.ret != 'void' and obj_setup: + func.append(" XGL_RESULT res;") + func.append("") + + # active layers before dispatching CreateDevice if proto.name == "CreateDevice": - funcs.append("%s%s\n" - "{\n" - " loader_activate_layers(%s, %s);\n" - " const XGL_LAYER_DISPATCH_TABLE *disp = loader_unwrap_gpu(&%s);\n" - " XGL_RESULT res = %s;\n" - " if (res == XGL_SUCCESS) {\n" - " loader_init_data(*%s, disp);\n" - " }\n" - " return res;\n" - "}" % (qual, decl, proto.params[0].name, proto.params[1].name, - proto.params[0].name, stmt, proto.params[-1].name)) - elif proto.name == "WsiX11CreatePresentableImage": - funcs.append("%s%s\n" - "{\n" - " const XGL_LAYER_DISPATCH_TABLE *disp = loader_get_data(%s);\n" - " XGL_RESULT res = %s;\n" - " if (res == XGL_SUCCESS) {\n" - " loader_init_data(*%s, disp);\n" - " loader_init_data(*%s, disp);\n" - " }\n" - " return res;\n" - "}" - % (qual, decl, proto.params[0].name, stmt, proto.params[-1].name, proto.params[-2].name)) - elif proto.name == "GetDeviceQueue": - # GetDeviceQueue returns an existing Queue object so cannot check for magic header as - # it may have already been replaced with a function table pointer - funcs.append("%s%s\n" - "{\n" - " const XGL_LAYER_DISPATCH_TABLE *disp = loader_get_data(%s);\n" - " XGL_RESULT res = %s;\n" - " if (res == XGL_SUCCESS) {\n" - " loader_set_data(*%s, disp);\n" - " }\n" - " return res;\n" - "}" - % (qual, decl, proto.params[0].name, stmt, proto.params[-1].name)) - elif self._does_function_create_object(proto): - funcs.append("%s%s\n" - "{\n" - " const XGL_LAYER_DISPATCH_TABLE *disp = loader_get_data(%s);\n" - " XGL_RESULT res = %s;\n" - " if (res == XGL_SUCCESS) {\n" - " loader_init_data(*%s, disp);\n" - " }\n" - " return res;\n" - "}" - % (qual, decl, proto.params[0].name, stmt, proto.params[-1].name)) - elif proto.name == "AllocDescriptorSets": - funcs.append("%s%s\n" - "{\n" - " const XGL_LAYER_DISPATCH_TABLE *disp = loader_get_data(%s);\n" - " uint32_t i;\n" - " XGL_RESULT res = %s;\n" - " for (i = 0; i < *%s; i++) {\n" - " loader_init_data(%s[i], disp);\n" - " }\n" - " return res;\n" - "}" % (qual, decl, proto.params[0].name, stmt, proto.params[-1].name, proto.params[-2].name)) - elif proto.name == "GetMultiGpuCompatibility": - funcs.append("%s%s\n" - "{\n" - " const XGL_LAYER_DISPATCH_TABLE *disp = loader_unwrap_gpu(&%s);\n" - " loader_unwrap_gpu(&%s);\n" - " return %s;\n" - "}" % (qual, decl, proto.params[0].name, proto.params[1].name, - stmt)) - elif proto.params[0].ty != "XGL_PHYSICAL_GPU": - if proto.ret != "void": - stmt = "return " + stmt - funcs.append("%s%s\n" - "{\n" - " const XGL_LAYER_DISPATCH_TABLE *disp = loader_get_data(%s);\n" - " %s;\n" - "}" % (qual, decl, proto.params[0].name, stmt)) + func.append(" loader_activate_layers(%s, %s);" % + (proto.params[0].name, proto.params[1].name)) + func.append("") + + # get dispatch table and unwrap GPUs + for param in proto.params: + stmt = "" + if param.ty == "XGL_PHYSICAL_GPU": + stmt = "loader_unwrap_gpu(&%s);" % param.name + if param == proto.params[0]: + stmt = "disp = " + stmt + elif param == proto.params[0]: + stmt = "disp = loader_get_data(%s);" % param.name + + if stmt: + func.append(" " + stmt) + func.append("") + + # dispatch! + dispatch = "disp->%s;" % proto.c_call() + if proto.ret == 'void': + func.append(" " + dispatch) + elif not obj_setup: + func.append(" return " + dispatch) else: - if proto.ret != "void": - stmt = "return " + stmt - funcs.append("%s%s\n" - "{\n" - " const XGL_LAYER_DISPATCH_TABLE *disp = loader_unwrap_gpu(&%s);\n" - " %s;\n" - "}" % (qual, decl, proto.params[0].name, stmt)) + func.append(" res = " + dispatch) + func.append(obj_setup) + func.append("") + func.append(" return res;") + + func.append("}") + + if 'WsiX11AssociateConnection' == proto.name: + funcs.append("#if defined(__linux__) || defined(XCB_NVIDIA)") + + funcs.append("\n".join(func)) funcs.append("#endif") return "\n\n".join(funcs) -- 2.7.4