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]), "../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,
54 'PIPE_FORMAT_Z16_UNORM_S8_UINT': None,
56 'PIPE_FORMAT_R9G9B9E5_FLOAT': hardcoded_format('5_9_9_9_FLOAT'),
57 'PIPE_FORMAT_R11G11B10_FLOAT': hardcoded_format('10_11_11_FLOAT'), # NOTE: full set of int/unorm/etc. exists
59 'PIPE_FORMAT_R8G8_B8G8_UNORM': hardcoded_format('GB_GR_UNORM'),
60 'PIPE_FORMAT_G8R8_B8R8_UNORM': hardcoded_format('GB_GR_UNORM'),
62 'PIPE_FORMAT_R8G8_R8B8_UNORM': hardcoded_format('BG_RG_UNORM'),
63 'PIPE_FORMAT_G8R8_G8B8_UNORM': hardcoded_format('BG_RG_UNORM'),
65 # These mixed channel types are not supported natively
66 'PIPE_FORMAT_R8SG8SB8UX8U_NORM': None,
67 'PIPE_FORMAT_R10SG10SB10SA2U_NORM': None,
68 'PIPE_FORMAT_R5SG5SB6U_NORM': None,
70 # Only R8G8_SRGB is supported, not L8A8_SRGB
71 'PIPE_FORMAT_L8A8_SRGB': None,
74 'PIPE_FORMAT_DXT1_RGB': hardcoded_format('BC1_UNORM'),
75 'PIPE_FORMAT_DXT1_RGBA': hardcoded_format('BC1_UNORM'),
76 'PIPE_FORMAT_DXT1_SRGB': hardcoded_format('BC1_SRGB'),
77 'PIPE_FORMAT_DXT1_SRGBA': hardcoded_format('BC1_SRGB'),
78 'PIPE_FORMAT_DXT3_RGBA': hardcoded_format('BC2_UNORM'),
79 'PIPE_FORMAT_DXT3_SRGBA': hardcoded_format('BC2_SRGB'),
80 'PIPE_FORMAT_DXT5_RGBA': hardcoded_format('BC3_UNORM'),
81 'PIPE_FORMAT_DXT5_SRGBA': hardcoded_format('BC3_SRGB'),
84 'PIPE_FORMAT_RGTC1_UNORM': hardcoded_format('BC4_UNORM'),
85 'PIPE_FORMAT_RGTC1_SNORM': hardcoded_format('BC4_SNORM'),
86 'PIPE_FORMAT_RGTC2_UNORM': hardcoded_format('BC5_UNORM'),
87 'PIPE_FORMAT_RGTC2_SNORM': hardcoded_format('BC5_SNORM'),
88 'PIPE_FORMAT_LATC1_UNORM': hardcoded_format('BC4_UNORM'),
89 'PIPE_FORMAT_LATC1_SNORM': hardcoded_format('BC4_SNORM'),
90 'PIPE_FORMAT_LATC2_UNORM': hardcoded_format('BC5_UNORM'),
91 'PIPE_FORMAT_LATC2_SNORM': hardcoded_format('BC5_SNORM'),
94 'PIPE_FORMAT_BPTC_RGB_UFLOAT': hardcoded_format('BC6_UFLOAT'),
95 'PIPE_FORMAT_BPTC_RGB_FLOAT': hardcoded_format('BC6_SFLOAT'),
97 'PIPE_FORMAT_BPTC_RGBA_UNORM': hardcoded_format('BC7_UNORM'),
98 'PIPE_FORMAT_BPTC_SRGBA': hardcoded_format('BC7_SRGB'),
102 # ----------------------------------------------------------------------------
105 header_template
= mako
.template
.Template("""\
106 // DO NOT EDIT -- AUTOMATICALLY GENERATED
108 #include "gfx10_format_table.h"
109 #include "amdgfxregs.h"
111 #define FMT(_img_format, ...) \
112 { .img_format = V_008F0C_IMG_FORMAT_##_img_format, \
115 const struct gfx10_format gfx10_format_table[PIPE_FORMAT_COUNT] = {
116 % for pipe_format, args in formats:
117 % if args is not None:
118 [${pipe_format}] = FMT(${args}),
120 /* ${pipe_format} is not supported */
126 class Gfx10Format(object):
127 RE_plain_channel
= re
.compile(r
'X?([0-9]+)')
129 def __init__(self
, enum_entry
):
130 self
.img_format
= enum_entry
.name
[11:]
131 self
.flags
= getattr(enum_entry
, 'flags', [])
133 code
= self
.img_format
.split('_')
135 self
.plain_chan_sizes
= []
136 for i
, chan_code
in enumerate(code
):
137 m
= self
.RE_plain_channel
.match(chan_code
)
140 self
.plain_chan_sizes
.append(int(m
.group(1)))
141 # Keep the bit sizes in little-endian order
142 self
.plain_chan_sizes
.reverse()
147 class Gfx10FormatMapping(object):
148 def __init__(self
, pipe_formats
, gfx10_formats
):
149 self
.pipe_formats
= pipe_formats
150 self
.gfx10_formats
= gfx10_formats
152 self
.plain_gfx10_formats
= dict(
153 (tuple(['_'.join(fmt
.code
)] + fmt
.plain_chan_sizes
), fmt
)
154 for fmt
in gfx10_formats
if fmt
.plain_chan_sizes
158 if fmt
.layout
== PLAIN
:
159 chan_type
= set([chan
.type for chan
in fmt
.le_channels
if chan
.type != VOID
])
160 chan_norm
= set([chan
.norm
for chan
in fmt
.le_channels
if chan
.type != VOID
])
161 chan_pure
= set([chan
.pure
for chan
in fmt
.le_channels
if chan
.type != VOID
])
162 if len(chan_type
) > 1 or len(chan_norm
) > 1 or len(chan_pure
) > 1:
163 print(('Format {fmt.name} has inconsistent channel types: ' +
164 '{chan_type} {chan_norm} {chan_pure}')
169 chan_type
= chan_type
.pop()
170 chan_norm
= chan_norm
.pop()
171 chan_pure
= chan_pure
.pop()
172 chan_sizes
= [chan
.size
for chan
in fmt
.le_channels
if chan
.size
!= 0]
176 if fmt
.colorspace
== SRGB
:
177 assert chan_type
== UNSIGNED
and chan_norm
180 if chan_type
== UNSIGNED
:
183 elif chan_sizes
[0] == 32:
184 # Shader-based work-around for 32-bit non-pure-integer
186 extra_flags
.append('buffers_only')
190 num_format
= 'USCALED'
191 elif chan_type
== SIGNED
:
194 elif chan_sizes
[0] == 32:
195 # Shader-based work-around for 32-bit non-pure-integer
197 extra_flags
.append('buffers_only')
201 num_format
= 'SSCALED'
202 elif chan_type
== FLOAT
:
205 if chan_sizes
[0] == 64:
206 # Shader-based work-around for doubles
207 if len(chan_sizes
) % 2 == 1:
208 # 1 or 3 loads for 1 or 3 double channels
209 chan_sizes
= [32, 32]
211 # 1 or 2 loads for 2 or 4 double channels
212 chan_sizes
= [32, 32, 32, 32]
213 extra_flags
.append('buffers_only')
215 # Shader-based work-around
216 assert chan_type
== FIXED
217 assert chan_sizes
[0] == 32
219 extra_flags
.append('buffers_only')
221 # These are not supported as render targets, so we don't support
222 # them as images either.
223 if (len(chan_sizes
) == 3 and chan_sizes
[0] in (8, 16, 32) and
224 chan_sizes
[0] == chan_sizes
[1]):
225 extra_flags
.append('buffers_only')
226 if chan_sizes
[0] in (8, 16):
227 # Shader-based work-around: one load per channel
228 chan_sizes
= [chan_sizes
[0]]
230 # Don't expose SRGB buffer formats
231 if 'buffers_only' in extra_flags
and fmt
.colorspace
== SRGB
:
234 # Don't support 4_4 because it's not supported as render targets
235 # and it's useless in other cases.
236 if len(chan_sizes
) == 2 and chan_sizes
[0] == 4:
239 key
= tuple([num_format
] + chan_sizes
)
240 if key
not in self
.plain_gfx10_formats
:
243 gfx10_fmt
= self
.plain_gfx10_formats
[key
]
245 img_format
=gfx10_fmt
.img_format
,
246 flags
=gfx10_fmt
.flags
+ extra_flags
,
252 if __name__
== '__main__':
253 pipe_formats
= parse(sys
.argv
[1])
255 with
open(sys
.argv
[2], 'r') as filp
:
256 db
= RegisterDatabase
.from_json(json
.load(filp
))
258 gfx10_formats
= [Gfx10Format(entry
) for entry
in db
.enum('IMG_FORMAT').entries
]
260 mapping
= Gfx10FormatMapping(pipe_formats
, gfx10_formats
)
263 for fmt
in pipe_formats
:
264 if fmt
.name
in HARDCODED
:
265 obj
= HARDCODED
[fmt
.name
]
267 obj
= mapping
.map(fmt
)
270 args
= obj
.img_format
271 if 'buffers_only' in obj
.flags
:
272 args
+= ', .buffers_only = 1'
275 formats
.append((fmt
.name
, args
))
277 print(header_template
.render(formats
=formats
))