1bf215546Sopenharmony_ci# 2bf215546Sopenharmony_ci# Copyright 2017 Advanced Micro Devices, Inc. 3bf215546Sopenharmony_ci# 4bf215546Sopenharmony_ci# Permission is hereby granted, free of charge, to any person obtaining a 5bf215546Sopenharmony_ci# copy of this software and associated documentation files (the "Software"), 6bf215546Sopenharmony_ci# to deal in the Software without restriction, including without limitation 7bf215546Sopenharmony_ci# on the rights to use, copy, modify, merge, publish, distribute, sub 8bf215546Sopenharmony_ci# license, and/or sell copies of the Software, and to permit persons to whom 9bf215546Sopenharmony_ci# the Software is furnished to do so, subject to the following conditions: 10bf215546Sopenharmony_ci# 11bf215546Sopenharmony_ci# The above copyright notice and this permission notice (including the next 12bf215546Sopenharmony_ci# paragraph) shall be included in all copies or substantial portions of the 13bf215546Sopenharmony_ci# Software. 14bf215546Sopenharmony_ci# 15bf215546Sopenharmony_ci# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16bf215546Sopenharmony_ci# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17bf215546Sopenharmony_ci# FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL 18bf215546Sopenharmony_ci# THE AUTHOR(S) AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM, 19bf215546Sopenharmony_ci# DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR 20bf215546Sopenharmony_ci# OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE 21bf215546Sopenharmony_ci# USE OR OTHER DEALINGS IN THE SOFTWARE. 22bf215546Sopenharmony_ci# 23bf215546Sopenharmony_ci""" 24bf215546Sopenharmony_ciScript that generates the mapping from Gallium PIPE_FORMAT_xxx to GFX10_FORMAT_xxx enums. 25bf215546Sopenharmony_ci""" 26bf215546Sopenharmony_ci 27bf215546Sopenharmony_ciimport json 28bf215546Sopenharmony_ciimport mako.template 29bf215546Sopenharmony_ciimport os 30bf215546Sopenharmony_ciimport re 31bf215546Sopenharmony_ciimport sys 32bf215546Sopenharmony_ci 33bf215546Sopenharmony_ciAMD_REGISTERS = os.path.abspath(os.path.join(os.path.dirname(sys.argv[0]), "../registers")) 34bf215546Sopenharmony_ciUTIL_FORMAT = os.path.abspath(os.path.join(os.path.dirname(sys.argv[0]), "../../util/format")) 35bf215546Sopenharmony_cisys.path.extend([AMD_REGISTERS, UTIL_FORMAT]) 36bf215546Sopenharmony_ci 37bf215546Sopenharmony_cifrom regdb import Object, RegisterDatabase 38bf215546Sopenharmony_cifrom u_format_parse import * 39bf215546Sopenharmony_ci 40bf215546Sopenharmony_ci# ---------------------------------------------------------------------------- 41bf215546Sopenharmony_ci# Hard-coded mappings 42bf215546Sopenharmony_ci 43bf215546Sopenharmony_cidef hardcoded_format(hw_enum): 44bf215546Sopenharmony_ci return Object(img_format=hw_enum, flags=[]) 45bf215546Sopenharmony_ci 46bf215546Sopenharmony_ciHARDCODED = { 47bf215546Sopenharmony_ci 'PIPE_FORMAT_Z32_FLOAT_S8X24_UINT': hardcoded_format('X24_8_32_FLOAT'), 48bf215546Sopenharmony_ci 'PIPE_FORMAT_Z24_UNORM_S8_UINT': hardcoded_format('8_24_UNORM'), 49bf215546Sopenharmony_ci 'PIPE_FORMAT_S8_UINT_Z24_UNORM': hardcoded_format('24_8_UNORM'), 50bf215546Sopenharmony_ci 'PIPE_FORMAT_Z32_UNORM': None, 51bf215546Sopenharmony_ci 'PIPE_FORMAT_Z16_UNORM_S8_UINT': None, 52bf215546Sopenharmony_ci 53bf215546Sopenharmony_ci 'PIPE_FORMAT_R9G9B9E5_FLOAT': hardcoded_format('5_9_9_9_FLOAT'), 54bf215546Sopenharmony_ci 'PIPE_FORMAT_R11G11B10_FLOAT': hardcoded_format('10_11_11_FLOAT'), # NOTE: full set of int/unorm/etc. exists 55bf215546Sopenharmony_ci 56bf215546Sopenharmony_ci 'PIPE_FORMAT_R8G8_B8G8_UNORM': hardcoded_format('GB_GR_UNORM'), 57bf215546Sopenharmony_ci 'PIPE_FORMAT_G8R8_B8R8_UNORM': hardcoded_format('GB_GR_UNORM'), 58bf215546Sopenharmony_ci 59bf215546Sopenharmony_ci 'PIPE_FORMAT_R8G8_R8B8_UNORM': hardcoded_format('BG_RG_UNORM'), 60bf215546Sopenharmony_ci 'PIPE_FORMAT_G8R8_G8B8_UNORM': hardcoded_format('BG_RG_UNORM'), 61bf215546Sopenharmony_ci 62bf215546Sopenharmony_ci # These mixed channel types are not supported natively 63bf215546Sopenharmony_ci 'PIPE_FORMAT_R8SG8SB8UX8U_NORM': None, 64bf215546Sopenharmony_ci 'PIPE_FORMAT_R10SG10SB10SA2U_NORM': None, 65bf215546Sopenharmony_ci 'PIPE_FORMAT_R5SG5SB6U_NORM': None, 66bf215546Sopenharmony_ci 67bf215546Sopenharmony_ci # Only R8G8_SRGB is supported, not L8A8_SRGB 68bf215546Sopenharmony_ci 'PIPE_FORMAT_L8A8_SRGB': None, 69bf215546Sopenharmony_ci 70bf215546Sopenharmony_ci # S3TC 71bf215546Sopenharmony_ci 'PIPE_FORMAT_DXT1_RGB': hardcoded_format('BC1_UNORM'), 72bf215546Sopenharmony_ci 'PIPE_FORMAT_DXT1_RGBA': hardcoded_format('BC1_UNORM'), 73bf215546Sopenharmony_ci 'PIPE_FORMAT_DXT1_SRGB': hardcoded_format('BC1_SRGB'), 74bf215546Sopenharmony_ci 'PIPE_FORMAT_DXT1_SRGBA': hardcoded_format('BC1_SRGB'), 75bf215546Sopenharmony_ci 'PIPE_FORMAT_DXT3_RGBA': hardcoded_format('BC2_UNORM'), 76bf215546Sopenharmony_ci 'PIPE_FORMAT_DXT3_SRGBA': hardcoded_format('BC2_SRGB'), 77bf215546Sopenharmony_ci 'PIPE_FORMAT_DXT5_RGBA': hardcoded_format('BC3_UNORM'), 78bf215546Sopenharmony_ci 'PIPE_FORMAT_DXT5_SRGBA': hardcoded_format('BC3_SRGB'), 79bf215546Sopenharmony_ci 80bf215546Sopenharmony_ci # RGTC 81bf215546Sopenharmony_ci 'PIPE_FORMAT_RGTC1_UNORM': hardcoded_format('BC4_UNORM'), 82bf215546Sopenharmony_ci 'PIPE_FORMAT_RGTC1_SNORM': hardcoded_format('BC4_SNORM'), 83bf215546Sopenharmony_ci 'PIPE_FORMAT_RGTC2_UNORM': hardcoded_format('BC5_UNORM'), 84bf215546Sopenharmony_ci 'PIPE_FORMAT_RGTC2_SNORM': hardcoded_format('BC5_SNORM'), 85bf215546Sopenharmony_ci 'PIPE_FORMAT_LATC1_UNORM': hardcoded_format('BC4_UNORM'), 86bf215546Sopenharmony_ci 'PIPE_FORMAT_LATC1_SNORM': hardcoded_format('BC4_SNORM'), 87bf215546Sopenharmony_ci 'PIPE_FORMAT_LATC2_UNORM': hardcoded_format('BC5_UNORM'), 88bf215546Sopenharmony_ci 'PIPE_FORMAT_LATC2_SNORM': hardcoded_format('BC5_SNORM'), 89bf215546Sopenharmony_ci 90bf215546Sopenharmony_ci # BPTC 91bf215546Sopenharmony_ci 'PIPE_FORMAT_BPTC_RGB_UFLOAT': hardcoded_format('BC6_UFLOAT'), 92bf215546Sopenharmony_ci 'PIPE_FORMAT_BPTC_RGB_FLOAT': hardcoded_format('BC6_SFLOAT'), 93bf215546Sopenharmony_ci 94bf215546Sopenharmony_ci 'PIPE_FORMAT_BPTC_RGBA_UNORM': hardcoded_format('BC7_UNORM'), 95bf215546Sopenharmony_ci 'PIPE_FORMAT_BPTC_SRGBA': hardcoded_format('BC7_SRGB'), 96bf215546Sopenharmony_ci 97bf215546Sopenharmony_ci 'PIPE_FORMAT_R64_UINT': hardcoded_format('32_32_UINT'), 98bf215546Sopenharmony_ci 'PIPE_FORMAT_R64_SINT': hardcoded_format('32_32_SINT'), 99bf215546Sopenharmony_ci} 100bf215546Sopenharmony_ci 101bf215546Sopenharmony_ci 102bf215546Sopenharmony_ci# ---------------------------------------------------------------------------- 103bf215546Sopenharmony_ci# Main script 104bf215546Sopenharmony_ci 105bf215546Sopenharmony_ciheader_template = mako.template.Template("""\ 106bf215546Sopenharmony_ci% if header: 107bf215546Sopenharmony_ci// DO NOT EDIT -- AUTOMATICALLY GENERATED 108bf215546Sopenharmony_ci 109bf215546Sopenharmony_ci#include "gfx10_format_table.h" 110bf215546Sopenharmony_ci#include "amdgfxregs.h" 111bf215546Sopenharmony_ci 112bf215546Sopenharmony_ci% endif 113bf215546Sopenharmony_ci 114bf215546Sopenharmony_ci#define FMT(_img_format, ...) \ 115bf215546Sopenharmony_ci { .img_format = V_008F0C_${gfx.upper()}_FORMAT_##_img_format, \ 116bf215546Sopenharmony_ci ##__VA_ARGS__ } 117bf215546Sopenharmony_ci 118bf215546Sopenharmony_ciconst struct gfx10_format ${gfx}_format_table[PIPE_FORMAT_COUNT] = { 119bf215546Sopenharmony_ci% for pipe_format, args in formats: 120bf215546Sopenharmony_ci % if args is not None: 121bf215546Sopenharmony_ci [${pipe_format}] = FMT(${args}), 122bf215546Sopenharmony_ci % else: 123bf215546Sopenharmony_ci/* ${pipe_format} is not supported */ 124bf215546Sopenharmony_ci % endif 125bf215546Sopenharmony_ci% endfor 126bf215546Sopenharmony_ci 127bf215546Sopenharmony_ci#undef FMT 128bf215546Sopenharmony_ci}; 129bf215546Sopenharmony_ci""") 130bf215546Sopenharmony_ci 131bf215546Sopenharmony_ciclass Gfx10Format(object): 132bf215546Sopenharmony_ci RE_plain_channel = re.compile(r'X?([0-9]+)') 133bf215546Sopenharmony_ci 134bf215546Sopenharmony_ci def __init__(self, enum_entry): 135bf215546Sopenharmony_ci self.img_format = enum_entry.name[13:] 136bf215546Sopenharmony_ci self.flags = getattr(enum_entry, 'flags', []) 137bf215546Sopenharmony_ci 138bf215546Sopenharmony_ci code = self.img_format.split('_') 139bf215546Sopenharmony_ci 140bf215546Sopenharmony_ci self.plain_chan_sizes = [] 141bf215546Sopenharmony_ci for i, chan_code in enumerate(code): 142bf215546Sopenharmony_ci m = self.RE_plain_channel.match(chan_code) 143bf215546Sopenharmony_ci if m is None: 144bf215546Sopenharmony_ci break 145bf215546Sopenharmony_ci self.plain_chan_sizes.append(int(m.group(1))) 146bf215546Sopenharmony_ci # Keep the bit sizes in little-endian order 147bf215546Sopenharmony_ci self.plain_chan_sizes.reverse() 148bf215546Sopenharmony_ci 149bf215546Sopenharmony_ci self.code = code[i:] 150bf215546Sopenharmony_ci 151bf215546Sopenharmony_ci 152bf215546Sopenharmony_ciclass Gfx10FormatMapping(object): 153bf215546Sopenharmony_ci def __init__(self, pipe_formats, gfx10_formats): 154bf215546Sopenharmony_ci self.pipe_formats = pipe_formats 155bf215546Sopenharmony_ci self.gfx10_formats = gfx10_formats 156bf215546Sopenharmony_ci 157bf215546Sopenharmony_ci self.plain_gfx10_formats = dict( 158bf215546Sopenharmony_ci (tuple(['_'.join(fmt.code)] + fmt.plain_chan_sizes), fmt) 159bf215546Sopenharmony_ci for fmt in gfx10_formats if fmt.plain_chan_sizes 160bf215546Sopenharmony_ci ) 161bf215546Sopenharmony_ci 162bf215546Sopenharmony_ci def map(self, fmt): 163bf215546Sopenharmony_ci if fmt.layout == PLAIN: 164bf215546Sopenharmony_ci chan_type = set([chan.type for chan in fmt.le_channels if chan.type != VOID]) 165bf215546Sopenharmony_ci chan_norm = set([chan.norm for chan in fmt.le_channels if chan.type != VOID]) 166bf215546Sopenharmony_ci chan_pure = set([chan.pure for chan in fmt.le_channels if chan.type != VOID]) 167bf215546Sopenharmony_ci if len(chan_type) > 1 or len(chan_norm) > 1 or len(chan_pure) > 1: 168bf215546Sopenharmony_ci print(('Format {fmt.name} has inconsistent channel types: ' + 169bf215546Sopenharmony_ci '{chan_type} {chan_norm} {chan_pure}') 170bf215546Sopenharmony_ci .format(**locals()), 171bf215546Sopenharmony_ci file=sys.stderr) 172bf215546Sopenharmony_ci return None 173bf215546Sopenharmony_ci 174bf215546Sopenharmony_ci chan_type = chan_type.pop() 175bf215546Sopenharmony_ci chan_norm = chan_norm.pop() 176bf215546Sopenharmony_ci chan_pure = chan_pure.pop() 177bf215546Sopenharmony_ci chan_sizes = [chan.size for chan in fmt.le_channels if chan.size != 0] 178bf215546Sopenharmony_ci 179bf215546Sopenharmony_ci extra_flags = [] 180bf215546Sopenharmony_ci 181bf215546Sopenharmony_ci if fmt.colorspace == SRGB: 182bf215546Sopenharmony_ci assert chan_type == UNSIGNED and chan_norm 183bf215546Sopenharmony_ci num_format = 'SRGB' 184bf215546Sopenharmony_ci else: 185bf215546Sopenharmony_ci if chan_type == UNSIGNED: 186bf215546Sopenharmony_ci if chan_pure: 187bf215546Sopenharmony_ci num_format = 'UINT' 188bf215546Sopenharmony_ci elif chan_sizes[0] == 32: 189bf215546Sopenharmony_ci # Shader-based work-around for 32-bit non-pure-integer 190bf215546Sopenharmony_ci num_format = 'UINT' 191bf215546Sopenharmony_ci extra_flags.append('buffers_only') 192bf215546Sopenharmony_ci elif chan_norm: 193bf215546Sopenharmony_ci num_format = 'UNORM' 194bf215546Sopenharmony_ci else: 195bf215546Sopenharmony_ci num_format = 'USCALED' 196bf215546Sopenharmony_ci extra_flags.append('buffers_only') 197bf215546Sopenharmony_ci elif chan_type == SIGNED: 198bf215546Sopenharmony_ci if chan_pure: 199bf215546Sopenharmony_ci num_format = 'SINT' 200bf215546Sopenharmony_ci elif chan_sizes[0] == 32: 201bf215546Sopenharmony_ci # Shader-based work-around for 32-bit non-pure-integer 202bf215546Sopenharmony_ci num_format = 'SINT' 203bf215546Sopenharmony_ci extra_flags.append('buffers_only') 204bf215546Sopenharmony_ci elif chan_norm: 205bf215546Sopenharmony_ci num_format = 'SNORM' 206bf215546Sopenharmony_ci else: 207bf215546Sopenharmony_ci num_format = 'SSCALED' 208bf215546Sopenharmony_ci extra_flags.append('buffers_only') 209bf215546Sopenharmony_ci elif chan_type == FLOAT: 210bf215546Sopenharmony_ci num_format = 'FLOAT' 211bf215546Sopenharmony_ci 212bf215546Sopenharmony_ci if chan_sizes[0] == 64: 213bf215546Sopenharmony_ci # Shader-based work-around for doubles 214bf215546Sopenharmony_ci if len(chan_sizes) % 2 == 1: 215bf215546Sopenharmony_ci # 1 or 3 loads for 1 or 3 double channels 216bf215546Sopenharmony_ci chan_sizes = [32, 32] 217bf215546Sopenharmony_ci else: 218bf215546Sopenharmony_ci # 1 or 2 loads for 2 or 4 double channels 219bf215546Sopenharmony_ci chan_sizes = [32, 32, 32, 32] 220bf215546Sopenharmony_ci extra_flags.append('buffers_only') 221bf215546Sopenharmony_ci else: 222bf215546Sopenharmony_ci # Shader-based work-around 223bf215546Sopenharmony_ci assert chan_type == FIXED 224bf215546Sopenharmony_ci assert chan_sizes[0] == 32 225bf215546Sopenharmony_ci num_format = 'SINT' 226bf215546Sopenharmony_ci extra_flags.append('buffers_only') 227bf215546Sopenharmony_ci 228bf215546Sopenharmony_ci # These are not supported as render targets, so we don't support 229bf215546Sopenharmony_ci # them as images either. 230bf215546Sopenharmony_ci if (len(chan_sizes) == 3 and chan_sizes[0] in (8, 16, 32) and 231bf215546Sopenharmony_ci chan_sizes[0] == chan_sizes[1]): 232bf215546Sopenharmony_ci extra_flags.append('buffers_only') 233bf215546Sopenharmony_ci if chan_sizes[0] in (8, 16): 234bf215546Sopenharmony_ci # Shader-based work-around: one load per channel 235bf215546Sopenharmony_ci chan_sizes = [chan_sizes[0]] 236bf215546Sopenharmony_ci 237bf215546Sopenharmony_ci # Don't expose SRGB buffer formats 238bf215546Sopenharmony_ci if 'buffers_only' in extra_flags and fmt.colorspace == SRGB: 239bf215546Sopenharmony_ci return None 240bf215546Sopenharmony_ci 241bf215546Sopenharmony_ci # Don't support 4_4 because it's not supported as render targets 242bf215546Sopenharmony_ci # and it's useless in other cases. 243bf215546Sopenharmony_ci if len(chan_sizes) == 2 and chan_sizes[0] == 4: 244bf215546Sopenharmony_ci return None 245bf215546Sopenharmony_ci 246bf215546Sopenharmony_ci key = tuple([num_format] + chan_sizes) 247bf215546Sopenharmony_ci if key not in self.plain_gfx10_formats: 248bf215546Sopenharmony_ci return None 249bf215546Sopenharmony_ci 250bf215546Sopenharmony_ci gfx10_fmt = self.plain_gfx10_formats[key] 251bf215546Sopenharmony_ci return Object( 252bf215546Sopenharmony_ci img_format=gfx10_fmt.img_format, 253bf215546Sopenharmony_ci flags=gfx10_fmt.flags + extra_flags, 254bf215546Sopenharmony_ci ) 255bf215546Sopenharmony_ci 256bf215546Sopenharmony_ci return None 257bf215546Sopenharmony_ci 258bf215546Sopenharmony_cidef pipe_formats_to_formats(pipe_formats, mapping): 259bf215546Sopenharmony_ci formats = [] 260bf215546Sopenharmony_ci for fmt in pipe_formats: 261bf215546Sopenharmony_ci if fmt.name in HARDCODED: 262bf215546Sopenharmony_ci obj = HARDCODED[fmt.name] 263bf215546Sopenharmony_ci else: 264bf215546Sopenharmony_ci obj = mapping.map(fmt) 265bf215546Sopenharmony_ci 266bf215546Sopenharmony_ci if obj is not None: 267bf215546Sopenharmony_ci args = obj.img_format 268bf215546Sopenharmony_ci if 'buffers_only' in obj.flags: 269bf215546Sopenharmony_ci args += ', .buffers_only = 1' 270bf215546Sopenharmony_ci else: 271bf215546Sopenharmony_ci args = None 272bf215546Sopenharmony_ci formats.append((fmt.name, args)) 273bf215546Sopenharmony_ci 274bf215546Sopenharmony_ci return formats 275bf215546Sopenharmony_ci 276bf215546Sopenharmony_ciif __name__ == '__main__': 277bf215546Sopenharmony_ci pipe_formats = parse(sys.argv[1]) 278bf215546Sopenharmony_ci 279bf215546Sopenharmony_ci # gfx10 280bf215546Sopenharmony_ci with open(sys.argv[2], 'r') as filp: 281bf215546Sopenharmony_ci db = RegisterDatabase.from_json(json.load(filp)) 282bf215546Sopenharmony_ci 283bf215546Sopenharmony_ci gfx10_formats = [Gfx10Format(entry) for entry in db.enum('GFX10_FORMAT').entries] 284bf215546Sopenharmony_ci mapping = Gfx10FormatMapping(pipe_formats, gfx10_formats) 285bf215546Sopenharmony_ci formats = pipe_formats_to_formats(pipe_formats, mapping) 286bf215546Sopenharmony_ci print(header_template.render(header=True, gfx='gfx10', formats=formats)) 287bf215546Sopenharmony_ci 288bf215546Sopenharmony_ci # gfx11 289bf215546Sopenharmony_ci with open(sys.argv[3], 'r') as filp: 290bf215546Sopenharmony_ci db = RegisterDatabase.from_json(json.load(filp)) 291bf215546Sopenharmony_ci 292bf215546Sopenharmony_ci gfx11_formats = [Gfx10Format(entry) for entry in db.enum('GFX11_FORMAT').entries] 293bf215546Sopenharmony_ci mapping = Gfx10FormatMapping(pipe_formats, gfx11_formats) 294bf215546Sopenharmony_ci formats = pipe_formats_to_formats(pipe_formats, mapping) 295bf215546Sopenharmony_ci print(header_template.render(header=False, gfx='gfx11', formats=formats)) 296