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 #GALLIUM_UTIL = os.path.abspath(os.path.join(os.path.dirname(sys.argv[0]), "../../auxiliary/util"))
38 sys
.path
.extend([AMD_REGISTERS
])
40 from regdb
import Object
, RegisterDatabase
41 from vk_format_parse
import *
42 #from u_format_parse import *
44 # ----------------------------------------------------------------------------
47 def hardcoded_format(hw_enum
):
48 return Object(img_format
=hw_enum
, flags
=[])
51 'VK_FORMAT_E5B9G9R9_UFLOAT_PACK32': hardcoded_format('5_9_9_9_FLOAT'),
52 'VK_FORMAT_B10G11R11_UFLOAT_PACK32': hardcoded_format('10_11_11_FLOAT'), # NOTE: full set of int/unorm/etc. exists
55 'VK_FORMAT_BC1_RGB_UNORM_BLOCK': hardcoded_format('BC1_UNORM'),
56 'VK_FORMAT_BC1_RGBA_UNORM_BLOCK': hardcoded_format('BC1_UNORM'),
57 'VK_FORMAT_BC1_RGB_SRGB_BLOCK': hardcoded_format('BC1_SRGB'),
58 'VK_FORMAT_BC1_RGBA_SRGB_BLOCK': hardcoded_format('BC1_SRGB'),
59 'VK_FORMAT_BC2_UNORM_BLOCK': hardcoded_format('BC2_UNORM'),
60 'VK_FORMAT_BC2_SRGB_BLOCK': hardcoded_format('BC2_SRGB'),
61 'VK_FORMAT_BC3_UNORM_BLOCK': hardcoded_format('BC3_UNORM'),
62 'VK_FORMAT_BC3_SRGB_BLOCK': hardcoded_format('BC3_SRGB'),
63 'VK_FORMAT_BC4_UNORM_BLOCK': hardcoded_format('BC4_UNORM'),
64 'VK_FORMAT_BC4_SNORM_BLOCK': hardcoded_format('BC4_SNORM'),
65 'VK_FORMAT_BC5_UNORM_BLOCK': hardcoded_format('BC5_UNORM'),
66 'VK_FORMAT_BC5_SNORM_BLOCK': hardcoded_format('BC5_SNORM'),
67 'VK_FORMAT_BC6H_UFLOAT_BLOCK': hardcoded_format('BC6_UFLOAT'),
68 'VK_FORMAT_BC6H_SFLOAT_BLOCK': hardcoded_format('BC6_SFLOAT'),
69 'VK_FORMAT_BC7_UNORM_BLOCK': hardcoded_format('BC7_UNORM'),
70 'VK_FORMAT_BC7_SRGB_BLOCK': hardcoded_format('BC7_SRGB'),
74 # ----------------------------------------------------------------------------
77 header_template
= mako
.template
.Template("""\
78 // DO NOT EDIT -- AUTOMATICALLY GENERATED
80 #define FMT(_img_format, ...) \
81 { .img_format = V_008F0C_IMG_FORMAT_##_img_format, \
84 static const struct gfx10_format gfx10_format_table[VK_FORMAT_RANGE_SIZE] = {
85 % for pipe_format, args in formats:
86 % if args is not None:
87 [${pipe_format}] = FMT(${args}),
89 /* ${pipe_format} is not supported */
95 class Gfx10Format(object):
96 RE_plain_channel
= re
.compile(r
'X?([0-9]+)')
98 def __init__(self
, enum_entry
):
99 self
.img_format
= enum_entry
.name
[11:]
100 self
.flags
= getattr(enum_entry
, 'flags', [])
102 code
= self
.img_format
.split('_')
104 self
.plain_chan_sizes
= []
105 for i
, chan_code
in enumerate(code
):
106 m
= self
.RE_plain_channel
.match(chan_code
)
109 self
.plain_chan_sizes
.append(int(m
.group(1)))
110 # Keep the bit sizes in little-endian order
111 self
.plain_chan_sizes
.reverse()
116 class Gfx10FormatMapping(object):
117 def __init__(self
, pipe_formats
, gfx10_formats
):
118 self
.pipe_formats
= pipe_formats
119 self
.gfx10_formats
= gfx10_formats
121 self
.plain_gfx10_formats
= dict(
122 (tuple(['_'.join(fmt
.code
)] + fmt
.plain_chan_sizes
), fmt
)
123 for fmt
in gfx10_formats
if fmt
.plain_chan_sizes
127 if fmt
.layout
== PLAIN
:
128 chan_type
= set([chan
.type for chan
in fmt
.le_channels
if chan
.type != VOID
])
129 chan_norm
= set([chan
.norm
for chan
in fmt
.le_channels
if chan
.type != VOID
])
130 chan_pure
= set([chan
.pure
for chan
in fmt
.le_channels
if chan
.type != VOID
])
131 if len(chan_type
) > 1 or len(chan_norm
) > 1 or len(chan_pure
) > 1:
132 print(('Format {fmt.name} has inconsistent channel types: ' +
133 '{chan_type} {chan_norm} {chan_pure}')
138 chan_type
= chan_type
.pop()
139 chan_norm
= chan_norm
.pop()
140 chan_pure
= chan_pure
.pop()
141 chan_sizes
= [chan
.size
for chan
in fmt
.le_channels
if chan
.size
!= 0]
145 if fmt
.colorspace
== SRGB
:
146 assert chan_type
== UNSIGNED
and chan_norm
149 if chan_type
== UNSIGNED
:
152 elif chan_sizes
[0] == 32:
153 # Shader-based work-around for 32-bit non-pure-integer
155 extra_flags
.append('buffers_only')
159 num_format
= 'USCALED'
160 elif chan_type
== SIGNED
:
163 elif chan_sizes
[0] == 32:
164 # Shader-based work-around for 32-bit non-pure-integer
166 extra_flags
.append('buffers_only')
170 num_format
= 'SSCALED'
171 elif chan_type
== FLOAT
:
174 if chan_sizes
[0] == 64:
175 # Shader-based work-around for doubles
176 if len(chan_sizes
) % 2 == 1:
177 # 1 or 3 loads for 1 or 3 double channels
178 chan_sizes
= [32, 32]
180 # 1 or 2 loads for 2 or 4 double channels
181 chan_sizes
= [32, 32, 32, 32]
182 extra_flags
.append('buffers_only')
184 # Shader-based work-around
185 assert chan_type
== FIXED
186 assert chan_sizes
[0] == 32
188 extra_flags
.append('buffers_only')
190 # These are not supported as render targets, so we don't support
191 # them as images either.
192 if (len(chan_sizes
) == 3 and chan_sizes
[0] in (8, 16, 32) and
193 chan_sizes
[0] == chan_sizes
[1]):
194 extra_flags
.append('buffers_only')
195 if chan_sizes
[0] in (8, 16):
196 # Shader-based work-around: one load per channel
197 chan_sizes
= [chan_sizes
[0]]
199 # Don't expose SRGB buffer formats
200 if 'buffers_only' in extra_flags
and fmt
.colorspace
== SRGB
:
203 # Don't support 4_4 because it's not supported as render targets
204 # and it's useless in other cases.
205 if len(chan_sizes
) == 2 and chan_sizes
[0] == 4:
208 key
= tuple([num_format
] + chan_sizes
)
209 if key
not in self
.plain_gfx10_formats
:
212 gfx10_fmt
= self
.plain_gfx10_formats
[key
]
214 img_format
=gfx10_fmt
.img_format
,
215 flags
=gfx10_fmt
.flags
+ extra_flags
,
221 if __name__
== '__main__':
222 pipe_formats
= parse(sys
.argv
[1])
224 with
open(sys
.argv
[2], 'r') as filp
:
225 db
= RegisterDatabase
.from_json(json
.load(filp
))
227 gfx10_formats
= [Gfx10Format(entry
) for entry
in db
.enum('IMG_FORMAT').entries
]
229 mapping
= Gfx10FormatMapping(pipe_formats
, gfx10_formats
)
232 for fmt
in pipe_formats
:
233 if fmt
.name
in HARDCODED
:
234 obj
= HARDCODED
[fmt
.name
]
236 obj
= mapping
.map(fmt
)
239 args
= obj
.img_format
240 if 'buffers_only' in obj
.flags
:
241 args
+= ', .buffers_only = 1'
244 formats
.append((fmt
.name
, args
))
246 print(header_template
.render(formats
=formats
))