diff options
author | Matt A. Tobin <mattatobin@localhost.localdomain> | 2018-02-02 04:16:08 -0500 |
---|---|---|
committer | Matt A. Tobin <mattatobin@localhost.localdomain> | 2018-02-02 04:16:08 -0500 |
commit | 5f8de423f190bbb79a62f804151bc24824fa32d8 (patch) | |
tree | 10027f336435511475e392454359edea8e25895d /gfx/angle/src/libANGLE/renderer/d3d/d3d11/gen_texture_format_table.py | |
parent | 49ee0794b5d912db1f95dce6eb52d781dc210db5 (diff) | |
download | UXP-5f8de423f190bbb79a62f804151bc24824fa32d8.tar UXP-5f8de423f190bbb79a62f804151bc24824fa32d8.tar.gz UXP-5f8de423f190bbb79a62f804151bc24824fa32d8.tar.lz UXP-5f8de423f190bbb79a62f804151bc24824fa32d8.tar.xz UXP-5f8de423f190bbb79a62f804151bc24824fa32d8.zip |
Add m-esr52 at 52.6.0
Diffstat (limited to 'gfx/angle/src/libANGLE/renderer/d3d/d3d11/gen_texture_format_table.py')
-rwxr-xr-x | gfx/angle/src/libANGLE/renderer/d3d/d3d11/gen_texture_format_table.py | 360 |
1 files changed, 360 insertions, 0 deletions
diff --git a/gfx/angle/src/libANGLE/renderer/d3d/d3d11/gen_texture_format_table.py b/gfx/angle/src/libANGLE/renderer/d3d/d3d11/gen_texture_format_table.py new file mode 100755 index 000000000..3c4b228e4 --- /dev/null +++ b/gfx/angle/src/libANGLE/renderer/d3d/d3d11/gen_texture_format_table.py @@ -0,0 +1,360 @@ +#!/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_texture_format_table.py: +# Code generation for texture format map +# + +from datetime import date +import json +import math +import pprint +import os +import re +import sys + +sys.path.append('../..') +import angle_format + +template_texture_format_table_autogen_cpp = """// GENERATED FILE - DO NOT EDIT. +// Generated by {script_name} using data from {data_source_name} +// +// 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. +// +// texture_format_table: +// Queries for full textureFormat information based in internalFormat +// + +#include "libANGLE/renderer/d3d/d3d11/texture_format_table.h" + +#include "image_util/copyimage.h" +#include "image_util/generatemip.h" +#include "image_util/loadimage.h" + +#include "libANGLE/renderer/d3d/d3d11/formatutils11.h" +#include "libANGLE/renderer/d3d/d3d11/renderer11_utils.h" +#include "libANGLE/renderer/d3d/d3d11/texture_format_table_utils.h" + +using namespace angle; + +namespace rx +{{ + +namespace d3d11 +{{ + +// static +const Format &Format::Get(GLenum internalFormat, const Renderer11DeviceCaps &deviceCaps) +{{ + // clang-format off + switch (internalFormat) + {{ +{angle_format_info_cases} + default: + break; + }} + // clang-format on + + UNREACHABLE(); + static constexpr Format defaultInfo; + return defaultInfo; +}} + +}} // namespace d3d11 + +}} // namespace rx +""" + +# TODO(oetuaho): Expand this code so that it could generate the gl format info tables as well. +def gl_format_channels(internal_format): + if internal_format == 'GL_BGR5_A1_ANGLEX': + return 'bgra' + if internal_format == 'GL_R11F_G11F_B10F': + return 'rgb' + if internal_format == 'GL_RGB5_A1': + return 'rgba' + if internal_format.find('GL_RGB10_A2') == 0: + return 'rgba' + + channels_pattern = re.compile('GL_(COMPRESSED_)?(SIGNED_)?(ETC\d_)?([A-Z]+)') + match = re.search(channels_pattern, internal_format) + channels_string = match.group(4) + + if channels_string == 'ALPHA': + return 'a' + if channels_string == 'LUMINANCE': + if (internal_format.find('ALPHA') >= 0): + return 'la' + return 'l' + if channels_string == 'SRGB': + if (internal_format.find('ALPHA') >= 0): + return 'rgba' + return 'rgb' + if channels_string == 'DEPTH': + if (internal_format.find('STENCIL') >= 0): + return 'ds' + return 'd' + if channels_string == 'STENCIL': + return 's' + return channels_string.lower() + +def get_internal_format_initializer(internal_format, angle_format): + internal_format_initializer = 'nullptr' + gl_channels = gl_format_channels(internal_format) + gl_format_no_alpha = gl_channels == 'rgb' or gl_channels == 'l' + if gl_format_no_alpha and angle_format['channels'] == 'rgba': + if angle_format['texFormat'] == 'DXGI_FORMAT_BC1_UNORM': + # BC1 is a special case since the texture data determines whether each block has an alpha channel or not. + # This if statement is hit by COMPRESSED_RGB_S3TC_DXT1, which is a bit of a mess. + # TODO(oetuaho): Look into whether COMPRESSED_RGB_S3TC_DXT1 works right in general. + # Reference: https://www.opengl.org/registry/specs/EXT/texture_compression_s3tc.txt + pass + elif 'componentType' not in angle_format: + raise ValueError('warning: internal format initializer could not be generated and may be needed for ' + internal_format) + elif angle_format['componentType'] == 'uint' and angle_format['bits']['red'] == 8: + internal_format_initializer = 'Initialize4ComponentData<GLubyte, 0x00, 0x00, 0x00, 0x01>' + elif angle_format['componentType'] == 'unorm' and angle_format['bits']['red'] == 8: + internal_format_initializer = 'Initialize4ComponentData<GLubyte, 0x00, 0x00, 0x00, 0xFF>' + elif angle_format['componentType'] == 'unorm' and angle_format['bits']['red'] == 16: + internal_format_initializer = 'Initialize4ComponentData<GLubyte, 0x0000, 0x0000, 0x0000, 0xFFFF>' + elif angle_format['componentType'] == 'int' and angle_format['bits']['red'] == 8: + internal_format_initializer = 'Initialize4ComponentData<GLbyte, 0x00, 0x00, 0x00, 0x01>' + elif angle_format['componentType'] == 'snorm' and angle_format['bits']['red'] == 8: + internal_format_initializer = 'Initialize4ComponentData<GLbyte, 0x00, 0x00, 0x00, 0x7F>' + elif angle_format['componentType'] == 'snorm' and angle_format['bits']['red'] == 16: + internal_format_initializer = 'Initialize4ComponentData<GLushort, 0x0000, 0x0000, 0x0000, 0x7FFF>' + elif angle_format['componentType'] == 'float' and angle_format['bits']['red'] == 16: + internal_format_initializer = 'Initialize4ComponentData<GLhalf, 0x0000, 0x0000, 0x0000, gl::Float16One>' + elif angle_format['componentType'] == 'uint' and angle_format['bits']['red'] == 16: + internal_format_initializer = 'Initialize4ComponentData<GLushort, 0x0000, 0x0000, 0x0000, 0x0001>' + elif angle_format['componentType'] == 'int' and angle_format['bits']['red'] == 16: + internal_format_initializer = 'Initialize4ComponentData<GLshort, 0x0000, 0x0000, 0x0000, 0x0001>' + elif angle_format['componentType'] == 'float' and angle_format['bits']['red'] == 32: + internal_format_initializer = 'Initialize4ComponentData<GLfloat, 0x00000000, 0x00000000, 0x00000000, gl::Float32One>' + elif angle_format['componentType'] == 'int' and angle_format['bits']['red'] == 32: + internal_format_initializer = 'Initialize4ComponentData<GLint, 0x00000000, 0x00000000, 0x00000000, 0x00000001>' + elif angle_format['componentType'] == 'uint' and angle_format['bits']['red'] == 32: + internal_format_initializer = 'Initialize4ComponentData<GLuint, 0x00000000, 0x00000000, 0x00000000, 0x00000001>' + else: + raise ValueError('warning: internal format initializer could not be generated and may be needed for ' + internal_format) + + return internal_format_initializer + +def get_swizzle_format_id(internal_format, angle_format): + angle_format_id = angle_format["formatName"] + if (internal_format == 'GL_NONE') or (angle_format_id == 'NONE'): + return 'GL_NONE' + + elif 'swizzleFormat' in angle_format: + # For some special formats like compressed formats that don't have a clearly defined number + # of bits per channel, swizzle format needs to be specified manually. + return angle_format['swizzleFormat'] + + if 'bits' not in angle_format: + raise ValueError('no bits information for determining swizzleformat for format: ' + internal_format) + + bits = angle_format['bits'] + max_component_bits = max(bits.itervalues()) + channels_different = not all([component_bits == bits.itervalues().next() for component_bits in bits.itervalues()]) + + # The format itself can be used for swizzles if it can be accessed as a render target and + # sampled and the bit count for all 4 channels is the same. + if "rtvFormat" in angle_format and "srvFormat" in angle_format and not channels_different and len(angle_format['channels']) == 4: + return angle_format["glInternalFormat"] if "glInternalFormat" in angle_format else internal_format + + b = int(math.ceil(float(max_component_bits) / 8) * 8) + + # Depth formats need special handling, since combined depth/stencil formats don't have a clearly + # defined component type. + if angle_format['channels'].find('d') >= 0: + if b == 24 or b == 32: + return 'GL_RGBA32F' + if b == 16: + return 'GL_RGBA16_EXT' + + if b == 24: + raise ValueError('unexpected 24-bit format when determining swizzleformat for format: ' + internal_format) + + if 'componentType' not in angle_format: + raise ValueError('no component type information for determining swizzleformat for format: ' + internal_format) + + component_type = angle_format['componentType'] + + swizzle = "GL_RGBA" + str(b) + + if component_type == 'uint': + swizzle += "I" + elif component_type == 'int': + swizzle += "I" + elif component_type == 'unorm': + if (b == 16): + swizzle += "_EXT" + elif component_type == 'snorm': + swizzle += "_SNORM" + if (b == 16): + swizzle += "_EXT" + elif component_type == 'float': + swizzle += "F" + if (b == 16): + swizzle += "_EXT" + else: + raise ValueError('could not determine swizzleformat based on componentType for format: ' + internal_format) + + return swizzle + +def get_blit_srv_format(angle_format): + if 'channels' not in angle_format: + return 'DXGI_FORMAT_UNKNOWN' + if 'r' in angle_format['channels'] and angle_format['componentType'] in ['int', 'uint']: + return angle_format['rtvFormat'] + + return angle_format["srvFormat"] if "srvFormat" in angle_format else "DXGI_FORMAT_UNKNOWN" + + +format_entry_template = """{space}{{ +{space} static constexpr Format info({internalFormat}, +{space} angle::Format::ID::{formatName}, +{space} {texFormat}, +{space} {srvFormat}, +{space} {rtvFormat}, +{space} {dsvFormat}, +{space} {blitSRVFormat}, +{space} {swizzleFormat}, +{space} {initializer}); +{space} return info; +{space}}} +""" + +split_format_entry_template = """{space} {condition} +{space} {{ +{space} static constexpr Format info({internalFormat}, +{space} angle::Format::ID::{formatName}, +{space} {texFormat}, +{space} {srvFormat}, +{space} {rtvFormat}, +{space} {dsvFormat}, +{space} {blitSRVFormat}, +{space} {swizzleFormat}, +{space} {initializer}); +{space} return info; +{space} }} +""" + +def json_to_table_data(internal_format, format_name, prefix, json): + + table_data = "" + + parsed = { + "space": " ", + "internalFormat": internal_format, + "formatName": format_name, + "texFormat": "DXGI_FORMAT_UNKNOWN", + "srvFormat": "DXGI_FORMAT_UNKNOWN", + "rtvFormat": "DXGI_FORMAT_UNKNOWN", + "dsvFormat": "DXGI_FORMAT_UNKNOWN", + "condition": prefix, + } + + for k, v in json.iteritems(): + parsed[k] = v + + # Derived values. + parsed["blitSRVFormat"] = get_blit_srv_format(parsed) + parsed["swizzleFormat"] = get_swizzle_format_id(internal_format, parsed) + parsed["initializer"] = get_internal_format_initializer(internal_format, json) + + if len(prefix) > 0: + return split_format_entry_template.format(**parsed) + else: + return format_entry_template.format(**parsed) + +def parse_json_angle_format_case(format_name, angle_format, json_data): + supported_case = {} + unsupported_case = {} + support_test = None + fallback = None + + for k, v in angle_format.iteritems(): + if k == "FL10Plus": + assert support_test is None + support_test = "OnlyFL10Plus(deviceCaps)" + for k2, v2 in v.iteritems(): + supported_case[k2] = v2 + elif k == "FL9_3": + split = True + for k2, v2 in v.iteritems(): + unsupported_case[k2] = v2 + elif k == "supportTest": + assert support_test is None + support_test = v + elif k == "fallbackFormat": + fallback = v + else: + supported_case[k] = v + unsupported_case[k] = v + + if fallback != None: + unsupported_case, _, _ = parse_json_angle_format_case( + fallback, json_data[fallback], json_data) + unsupported_case["formatName"] = fallback + + if support_test != None: + return supported_case, unsupported_case, support_test + else: + return supported_case, None, None + +def parse_json_into_switch_angle_format_string(json_map, json_data): + table_data = '' + + for internal_format, format_name in sorted(json_map.iteritems()): + + if format_name not in json_data: + continue + + angle_format = json_data[format_name] + + supported_case, unsupported_case, support_test = parse_json_angle_format_case( + format_name, angle_format, json_data) + + table_data += ' case ' + internal_format + ':\n' + + if support_test != None: + table_data += " {\n" + table_data += json_to_table_data(internal_format, format_name, "if (" + support_test + ")", supported_case) + table_data += json_to_table_data(internal_format, format_name, "else", unsupported_case) + table_data += " }\n" + else: + table_data += json_to_table_data(internal_format, format_name, "", supported_case) + + return table_data + +def reject_duplicate_keys(pairs): + found_keys = {} + for key, value in pairs: + if key in found_keys: + raise ValueError("duplicate key: %r" % (key,)) + else: + found_keys[key] = value + return found_keys + +json_map = angle_format.load_with_override(os.path.abspath('texture_format_map.json')) +data_source_name = 'texture_format_data.json' + +with open(data_source_name) as texture_format_json_file: + texture_format_data = texture_format_json_file.read() + texture_format_json_file.close() + json_data = json.loads(texture_format_data, object_pairs_hook=angle_format.reject_duplicate_keys) + + angle_format_cases = parse_json_into_switch_angle_format_string(json_map, json_data) + output_cpp = template_texture_format_table_autogen_cpp.format( + script_name = sys.argv[0], + copyright_year = date.today().year, + angle_format_info_cases = angle_format_cases, + data_source_name = data_source_name) + with open('texture_format_table_autogen.cpp', 'wt') as out_file: + out_file.write(output_cpp) + out_file.close() |