1#!/usr/bin/python 2# Copyright 2015 The ANGLE Project Authors. All rights reserved. 3# Use of this source code is governed by a BSD-style license that can be 4# found in the LICENSE file. 5# 6# gen_load_functions_table.py: 7# Code generation for the load function tables used for texture formats 8# 9 10import json, sys 11from datetime import date 12 13sys.path.append('../..') 14import angle_format 15 16template = """// GENERATED FILE - DO NOT EDIT. 17// Generated by gen_load_functions_table.py using data from load_functions_data.json 18// 19// Copyright {copyright_year} The ANGLE Project Authors. All rights reserved. 20// Use of this source code is governed by a BSD-style license that can be 21// found in the LICENSE file. 22// 23// load_functions_table: 24// Contains the GetLoadFunctionsMap for texture_format_util.h 25// 26 27#include "libANGLE/renderer/load_functions_table.h" 28 29#include "image_util/copyimage.h" 30#include "image_util/generatemip.h" 31#include "image_util/loadimage.h" 32 33using namespace rx; 34 35namespace angle 36{{ 37 38namespace 39{{ 40 41// ES3 image loading functions vary based on: 42// - the GL internal format (supplied to glTex*Image*D) 43// - the GL data type given (supplied to glTex*Image*D) 44// - the target DXGI_FORMAT that the image will be loaded into (which is chosen based on the D3D 45// device's capabilities) 46// This map type determines which loading function to use, based on these three parameters. 47// Source formats and types are taken from Tables 3.2 and 3.3 of the ES 3 spec. 48void UnimplementedLoadFunction(size_t width, 49 size_t height, 50 size_t depth, 51 const uint8_t *input, 52 size_t inputRowPitch, 53 size_t inputDepthPitch, 54 uint8_t *output, 55 size_t outputRowPitch, 56 size_t outputDepthPitch) 57{{ 58 UNIMPLEMENTED(); 59}} 60 61void UnreachableLoadFunction(size_t width, 62 size_t height, 63 size_t depth, 64 const uint8_t *input, 65 size_t inputRowPitch, 66 size_t inputDepthPitch, 67 uint8_t *output, 68 size_t outputRowPitch, 69 size_t outputDepthPitch) 70{{ 71 UNREACHABLE(); 72}} 73 74{load_functions_data}}} // namespace 75 76LoadFunctionMap GetLoadFunctionsMap(GLenum {internal_format}, Format::ID {angle_format}) 77{{ 78 // clang-format off 79 switch ({internal_format}) 80 {{ 81{switch_data} 82 default: 83 {{ 84 static LoadFunctionMap emptyLoadFunctionsMap; 85 return emptyLoadFunctionsMap; 86 }} 87 }} 88 // clang-format on 89 90}} // GetLoadFunctionsMap 91 92}} // namespace angle 93""" 94 95internal_format_param = 'internalFormat' 96angle_format_param = 'angleFormat' 97angle_format_unknown = 'NONE' 98 99def load_functions_name(internal_format, angle_format): 100 return internal_format[3:] + "_to_" + angle_format 101 102def unknown_func_name(internal_format): 103 return load_functions_name(internal_format, "default") 104 105def get_load_func(func_name, type_functions): 106 snippet = "LoadImageFunctionInfo " + func_name + "(GLenum type)\n" 107 snippet += "{\n" 108 snippet += " switch (type)\n" 109 snippet += " {\n" 110 for gl_type, load_function in sorted(type_functions.iteritems()): 111 snippet += " case " + gl_type + ":\n" 112 requiresConversion = str('LoadToNative<' not in load_function).lower() 113 snippet += " return LoadImageFunctionInfo(" + load_function + ", " + requiresConversion + ");\n" 114 snippet += " default:\n" 115 snippet += " UNREACHABLE();\n" 116 snippet += " return LoadImageFunctionInfo(UnreachableLoadFunction, true);\n" 117 snippet += " }\n" 118 snippet += "}\n" 119 snippet += "\n" 120 121 return snippet 122 123def get_unknown_load_func(angle_to_type_map, internal_format): 124 assert angle_format_unknown in angle_to_type_map 125 return get_load_func(unknown_func_name(internal_format), angle_to_type_map[angle_format_unknown]) 126 127def parse_json(json_data): 128 table_data = '' 129 load_functions_data = '' 130 for internal_format, angle_to_type_map in sorted(json_data.iteritems()): 131 132 s = ' ' 133 134 table_data += s + 'case ' + internal_format + ':\n' 135 136 do_switch = len(angle_to_type_map) > 1 or angle_to_type_map.keys()[0] != angle_format_unknown 137 138 if do_switch: 139 table_data += s + '{\n' 140 s += ' ' 141 table_data += s + 'switch (' + angle_format_param + ')\n' 142 table_data += s + '{\n' 143 s += ' ' 144 145 for angle_format, type_functions in sorted(angle_to_type_map.iteritems()): 146 147 if angle_format == angle_format_unknown: 148 continue 149 150 func_name = load_functions_name(internal_format, angle_format) 151 152 # Main case statements 153 table_data += s + 'case Format::ID::' + angle_format + ':\n' 154 table_data += s + ' return ' + func_name + ';\n' 155 156 if angle_format_unknown in angle_to_type_map: 157 for gl_type, load_function in angle_to_type_map[angle_format_unknown].iteritems(): 158 if gl_type not in type_functions: 159 type_functions[gl_type] = load_function 160 161 load_functions_data += get_load_func(func_name, type_functions) 162 163 if do_switch: 164 table_data += s + 'default:\n' 165 166 if angle_format_unknown in angle_to_type_map: 167 table_data += s + ' return ' + unknown_func_name(internal_format) + ';\n' 168 load_functions_data += get_unknown_load_func(angle_to_type_map, internal_format) 169 else: 170 table_data += s + ' break;\n' 171 172 if do_switch: 173 s = s[4:] 174 table_data += s + '}\n' 175 s = s[4:] 176 table_data += s + '}\n' 177 178 return table_data, load_functions_data 179 180json_data = angle_format.load_json('load_functions_data.json') 181 182switch_data, load_functions_data = parse_json(json_data) 183output = template.format(internal_format = internal_format_param, 184 angle_format = angle_format_param, 185 switch_data = switch_data, 186 load_functions_data = load_functions_data, 187 copyright_year = date.today().year) 188 189with open('load_functions_table_autogen.cpp', 'wt') as out_file: 190 out_file.write(output) 191 out_file.close() 192