summaryrefslogtreecommitdiffstats
path: root/gfx/angle/src/libANGLE/renderer/d3d/d3d11/gen_texture_format_table.py
diff options
context:
space:
mode:
authorMatt A. Tobin <mattatobin@localhost.localdomain>2018-02-02 04:16:08 -0500
committerMatt A. Tobin <mattatobin@localhost.localdomain>2018-02-02 04:16:08 -0500
commit5f8de423f190bbb79a62f804151bc24824fa32d8 (patch)
tree10027f336435511475e392454359edea8e25895d /gfx/angle/src/libANGLE/renderer/d3d/d3d11/gen_texture_format_table.py
parent49ee0794b5d912db1f95dce6eb52d781dc210db5 (diff)
downloadUXP-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-xgfx/angle/src/libANGLE/renderer/d3d/d3d11/gen_texture_format_table.py360
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()