blob: eb3e4c5bf08212d427d6ab5031d7574ec4664930 [file] [log] [blame]
#!/usr/bin/python
# Copyright 2015 The ANGLE Project Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
#
# gen_load_functions_table.py:
# Code generation for the load function tables used for texture formats
#
import json, sys
from datetime import date
sys.path.append('../..')
import angle_format
template = """// GENERATED FILE - DO NOT EDIT.
// Generated by gen_load_functions_table.py using data from load_functions_data.json
//
// Copyright {copyright_year} The ANGLE Project Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
//
// load_functions_table:
// Contains the GetLoadFunctionsMap for texture_format_util.h
//
#include "libANGLE/renderer/load_functions_table.h"
#include "image_util/copyimage.h"
#include "image_util/generatemip.h"
#include "image_util/loadimage.h"
using namespace rx;
namespace angle
{{
namespace
{{
// ES3 image loading functions vary based on:
// - the GL internal format (supplied to glTex*Image*D)
// - the GL data type given (supplied to glTex*Image*D)
// - the target DXGI_FORMAT that the image will be loaded into (which is chosen based on the D3D
// device's capabilities)
// This map type determines which loading function to use, based on these three parameters.
// Source formats and types are taken from Tables 3.2 and 3.3 of the ES 3 spec.
void UnimplementedLoadFunction(size_t width,
size_t height,
size_t depth,
const uint8_t *input,
size_t inputRowPitch,
size_t inputDepthPitch,
uint8_t *output,
size_t outputRowPitch,
size_t outputDepthPitch)
{{
UNIMPLEMENTED();
}}
void UnreachableLoadFunction(size_t width,
size_t height,
size_t depth,
const uint8_t *input,
size_t inputRowPitch,
size_t inputDepthPitch,
uint8_t *output,
size_t outputRowPitch,
size_t outputDepthPitch)
{{
UNREACHABLE();
}}
{load_functions_data}}} // namespace
LoadFunctionMap GetLoadFunctionsMap(GLenum {internal_format}, Format::ID {angle_format})
{{
// clang-format off
switch ({internal_format})
{{
{switch_data}
default:
{{
static LoadFunctionMap emptyLoadFunctionsMap;
return emptyLoadFunctionsMap;
}}
}}
// clang-format on
}} // GetLoadFunctionsMap
}} // namespace angle
"""
internal_format_param = 'internalFormat'
angle_format_param = 'angleFormat'
angle_format_unknown = 'NONE'
def load_functions_name(internal_format, angle_format):
return internal_format[3:] + "_to_" + angle_format
def unknown_func_name(internal_format):
return load_functions_name(internal_format, "default")
def get_load_func(func_name, type_functions):
snippet = "LoadImageFunctionInfo " + func_name + "(GLenum type)\n"
snippet += "{\n"
snippet += " switch (type)\n"
snippet += " {\n"
for gl_type, load_function in sorted(type_functions.iteritems()):
snippet += " case " + gl_type + ":\n"
requiresConversion = str('LoadToNative<' not in load_function).lower()
snippet += " return LoadImageFunctionInfo(" + load_function + ", " + requiresConversion + ");\n"
snippet += " default:\n"
snippet += " UNREACHABLE();\n"
snippet += " return LoadImageFunctionInfo(UnreachableLoadFunction, true);\n"
snippet += " }\n"
snippet += "}\n"
snippet += "\n"
return snippet
def get_unknown_load_func(angle_to_type_map, internal_format):
assert angle_format_unknown in angle_to_type_map
return get_load_func(unknown_func_name(internal_format), angle_to_type_map[angle_format_unknown])
def parse_json(json_data):
table_data = ''
load_functions_data = ''
for internal_format, angle_to_type_map in sorted(json_data.iteritems()):
s = ' '
table_data += s + 'case ' + internal_format + ':\n'
do_switch = len(angle_to_type_map) > 1 or angle_to_type_map.keys()[0] != angle_format_unknown
if do_switch:
table_data += s + '{\n'
s += ' '
table_data += s + 'switch (' + angle_format_param + ')\n'
table_data += s + '{\n'
s += ' '
for angle_format, type_functions in sorted(angle_to_type_map.iteritems()):
if angle_format == angle_format_unknown:
continue
func_name = load_functions_name(internal_format, angle_format)
# Main case statements
table_data += s + 'case Format::ID::' + angle_format + ':\n'
table_data += s + ' return ' + func_name + ';\n'
if angle_format_unknown in angle_to_type_map:
for gl_type, load_function in angle_to_type_map[angle_format_unknown].iteritems():
if gl_type not in type_functions:
type_functions[gl_type] = load_function
load_functions_data += get_load_func(func_name, type_functions)
if do_switch:
table_data += s + 'default:\n'
if angle_format_unknown in angle_to_type_map:
table_data += s + ' return ' + unknown_func_name(internal_format) + ';\n'
load_functions_data += get_unknown_load_func(angle_to_type_map, internal_format)
else:
table_data += s + ' break;\n'
if do_switch:
s = s[4:]
table_data += s + '}\n'
s = s[4:]
table_data += s + '}\n'
return table_data, load_functions_data
json_data = angle_format.load_json('load_functions_data.json')
switch_data, load_functions_data = parse_json(json_data)
output = template.format(internal_format = internal_format_param,
angle_format = angle_format_param,
switch_data = switch_data,
load_functions_data = load_functions_data,
copyright_year = date.today().year)
with open('load_functions_table_autogen.cpp', 'wt') as out_file:
out_file.write(output)
out_file.close()