2 # Copyright 2017 Advanced Micro Devices, Inc.
4 # Permission is hereby granted, free of charge, to any person obtaining a
5 # copy of this software and associated documentation files (the "Software"),
6 # to deal in the Software without restriction, including without limitation
7 # on the rights to use, copy, modify, merge, publish, distribute, sub
8 # license, and/or sell copies of the Software, and to permit persons to whom
9 # the Software is furnished to do so, subject to the following conditions:
11 # The above copyright notice and this permission notice (including the next
12 # paragraph) shall be included in all copies or substantial portions of the
15 # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 # FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
18 # THE AUTHOR(S) AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM,
19 # DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
20 # OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
21 # USE OR OTHER DEALINGS IN THE SOFTWARE.
24 Script that generates the mapping from Gallium PIPE_FORMAT_xxx to gfx10
28 from __future__
import absolute_import
, division
, print_function
, unicode_literals
36 AMD_REGISTERS
= os
.path
.abspath(os
.path
.join(os
.path
.dirname(sys
.argv
[0]), "../../../amd/registers"))
37 UTIL_FORMAT
= os
.path
.abspath(os
.path
.join(os
.path
.dirname(sys
.argv
[0]), "../../../util/format"))
38 sys
.path
.extend([AMD_REGISTERS
, UTIL_FORMAT
])
40 from regdb
import Object
, RegisterDatabase
41 from u_format_parse
import *
43 # ----------------------------------------------------------------------------
46 def hardcoded_format(hw_enum
):
47 return Object(img_format
=hw_enum
, flags
=[])
50 'PIPE_FORMAT_Z32_FLOAT_S8X24_UINT': hardcoded_format('X24_8_32_FLOAT'),
51 'PIPE_FORMAT_Z24_UNORM_S8_UINT': hardcoded_format('8_24_UNORM'),
52 'PIPE_FORMAT_S8_UINT_Z24_UNORM': hardcoded_format('24_8_UNORM'),
53 'PIPE_FORMAT_Z32_UNORM': None,
55 'PIPE_FORMAT_R9G9B9E5_FLOAT': hardcoded_format('5_9_9_9_FLOAT'),
56 'PIPE_FORMAT_R11G11B10_FLOAT': hardcoded_format('10_11_11_FLOAT'), # NOTE: full set of int/unorm/etc. exists
58 'PIPE_FORMAT_R8G8_B8G8_UNORM': hardcoded_format('GB_GR_UNORM'),
59 'PIPE_FORMAT_G8R8_B8R8_UNORM': hardcoded_format('GB_GR_UNORM'),
61 'PIPE_FORMAT_R8G8_R8B8_UNORM': hardcoded_format('BG_RG_UNORM'),
62 'PIPE_FORMAT_G8R8_G8B8_UNORM': hardcoded_format('BG_RG_UNORM'),
64 # These mixed channel types are not supported natively
65 'PIPE_FORMAT_R8SG8SB8UX8U_NORM': None,
66 'PIPE_FORMAT_R10SG10SB10SA2U_NORM': None,
67 'PIPE_FORMAT_R5SG5SB6U_NORM': None,
69 # Only R8G8_SRGB is supported, not L8A8_SRGB
70 'PIPE_FORMAT_L8A8_SRGB': None,
73 'PIPE_FORMAT_DXT1_RGB': hardcoded_format('BC1_UNORM'),
74 'PIPE_FORMAT_DXT1_RGBA': hardcoded_format('BC1_UNORM'),
75 'PIPE_FORMAT_DXT1_SRGB': hardcoded_format('BC1_SRGB'),
76 'PIPE_FORMAT_DXT1_SRGBA': hardcoded_format('BC1_SRGB'),
77 'PIPE_FORMAT_DXT3_RGBA': hardcoded_format('BC2_UNORM'),
78 'PIPE_FORMAT_DXT3_SRGBA': hardcoded_format('BC2_SRGB'),
79 'PIPE_FORMAT_DXT5_RGBA': hardcoded_format('BC3_UNORM'),
80 'PIPE_FORMAT_DXT5_SRGBA': hardcoded_format('BC3_SRGB'),
83 'PIPE_FORMAT_RGTC1_UNORM': hardcoded_format('BC4_UNORM'),
84 'PIPE_FORMAT_RGTC1_SNORM': hardcoded_format('BC4_SNORM'),
85 'PIPE_FORMAT_RGTC2_UNORM': hardcoded_format('BC5_UNORM'),
86 'PIPE_FORMAT_RGTC2_SNORM': hardcoded_format('BC5_SNORM'),
87 'PIPE_FORMAT_LATC1_UNORM': hardcoded_format('BC4_UNORM'),
88 'PIPE_FORMAT_LATC1_SNORM': hardcoded_format('BC4_SNORM'),
89 'PIPE_FORMAT_LATC2_UNORM': hardcoded_format('BC5_UNORM'),
90 'PIPE_FORMAT_LATC2_SNORM': hardcoded_format('BC5_SNORM'),
93 'PIPE_FORMAT_BPTC_RGB_UFLOAT': hardcoded_format('BC6_UFLOAT'),
94 'PIPE_FORMAT_BPTC_RGB_FLOAT': hardcoded_format('BC6_SFLOAT'),
96 'PIPE_FORMAT_BPTC_RGBA_UNORM': hardcoded_format('BC7_UNORM'),
97 'PIPE_FORMAT_BPTC_SRGBA': hardcoded_format('BC7_SRGB'),
101 # ----------------------------------------------------------------------------
104 header_template
= mako
.template
.Template("""\
105 // DO NOT EDIT -- AUTOMATICALLY GENERATED
107 #define FMT(_img_format, ...) \
108 { .img_format = V_008F0C_IMG_FORMAT_##_img_format, \
111 static const struct gfx10_format gfx10_format_table[PIPE_FORMAT_COUNT] = {
112 % for pipe_format, args in formats:
113 % if args is not None:
114 [${pipe_format}] = FMT(${args}),
116 /* ${pipe_format} is not supported */
122 class Gfx10Format(object):
123 RE_plain_channel
= re
.compile(r
'X?([0-9]+)')
125 def __init__(self
, enum_entry
):
126 self
.img_format
= enum_entry
.name
[11:]
127 self
.flags
= getattr(enum_entry
, 'flags', [])
129 code
= self
.img_format
.split('_')
131 self
.plain_chan_sizes
= []
132 for i
, chan_code
in enumerate(code
):
133 m
= self
.RE_plain_channel
.match(chan_code
)
136 self
.plain_chan_sizes
.append(int(m
.group(1)))
137 # Keep the bit sizes in little-endian order
138 self
.plain_chan_sizes
.reverse()
143 class Gfx10FormatMapping(object):
144 def __init__(self
, pipe_formats
, gfx10_formats
):
145 self
.pipe_formats
= pipe_formats
146 self
.gfx10_formats
= gfx10_formats
148 self
.plain_gfx10_formats
= dict(
149 (tuple(['_'.join(fmt
.code
)] + fmt
.plain_chan_sizes
), fmt
)
150 for fmt
in gfx10_formats
if fmt
.plain_chan_sizes
154 if fmt
.layout
== PLAIN
:
155 chan_type
= set([chan
.type for chan
in fmt
.le_channels
if chan
.type != VOID
])
156 chan_norm
= set([chan
.norm
for chan
in fmt
.le_channels
if chan
.type != VOID
])
157 chan_pure
= set([chan
.pure
for chan
in fmt
.le_channels
if chan
.type != VOID
])
158 if len(chan_type
) > 1 or len(chan_norm
) > 1 or len(chan_pure
) > 1:
159 print(('Format {fmt.name} has inconsistent channel types: ' +
160 '{chan_type} {chan_norm} {chan_pure}')
165 chan_type
= chan_type
.pop()
166 chan_norm
= chan_norm
.pop()
167 chan_pure
= chan_pure
.pop()
168 chan_sizes
= [chan
.size
for chan
in fmt
.le_channels
if chan
.size
!= 0]
172 if fmt
.colorspace
== SRGB
:
173 assert chan_type
== UNSIGNED
and chan_norm
176 if chan_type
== UNSIGNED
:
179 elif chan_sizes
[0] == 32:
180 # Shader-based work-around for 32-bit non-pure-integer
182 extra_flags
.append('buffers_only')
186 num_format
= 'USCALED'
187 elif chan_type
== SIGNED
:
190 elif chan_sizes
[0] == 32:
191 # Shader-based work-around for 32-bit non-pure-integer
193 extra_flags
.append('buffers_only')
197 num_format
= 'SSCALED'
198 elif chan_type
== FLOAT
:
201 if chan_sizes
[0] == 64:
202 # Shader-based work-around for doubles
203 if len(chan_sizes
) % 2 == 1:
204 # 1 or 3 loads for 1 or 3 double channels
205 chan_sizes
= [32, 32]
207 # 1 or 2 loads for 2 or 4 double channels
208 chan_sizes
= [32, 32, 32, 32]
209 extra_flags
.append('buffers_only')
211 # Shader-based work-around
212 assert chan_type
== FIXED
213 assert chan_sizes
[0] == 32
215 extra_flags
.append('buffers_only')
217 # These are not supported as render targets, so we don't support
218 # them as images either.
219 if (len(chan_sizes
) == 3 and chan_sizes
[0] in (8, 16, 32) and
220 chan_sizes
[0] == chan_sizes
[1]):
221 extra_flags
.append('buffers_only')
222 if chan_sizes
[0] in (8, 16):
223 # Shader-based work-around: one load per channel
224 chan_sizes
= [chan_sizes
[0]]
226 # Don't expose SRGB buffer formats
227 if 'buffers_only' in extra_flags
and fmt
.colorspace
== SRGB
:
230 # Don't support 4_4 because it's not supported as render targets
231 # and it's useless in other cases.
232 if len(chan_sizes
) == 2 and chan_sizes
[0] == 4:
235 key
= tuple([num_format
] + chan_sizes
)
236 if key
not in self
.plain_gfx10_formats
:
239 gfx10_fmt
= self
.plain_gfx10_formats
[key
]
241 img_format
=gfx10_fmt
.img_format
,
242 flags
=gfx10_fmt
.flags
+ extra_flags
,
248 if __name__
== '__main__':
249 pipe_formats
= parse(sys
.argv
[1])
251 with
open(sys
.argv
[2], 'r') as filp
:
252 db
= RegisterDatabase
.from_json(json
.load(filp
))
254 gfx10_formats
= [Gfx10Format(entry
) for entry
in db
.enum('IMG_FORMAT').entries
]
256 mapping
= Gfx10FormatMapping(pipe_formats
, gfx10_formats
)
259 for fmt
in pipe_formats
:
260 if fmt
.name
in HARDCODED
:
261 obj
= HARDCODED
[fmt
.name
]
263 obj
= mapping
.map(fmt
)
266 args
= obj
.img_format
267 if 'buffers_only' in obj
.flags
:
268 args
+= ', .buffers_only = 1'
271 formats
.append((fmt
.name
, args
))
273 print(header_template
.render(formats
=formats
))