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