Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/mesa
Path: blob/21.2-virgl/src/amd/common/gfx10_format_table.py
7136 views
1
#
2
# Copyright 2017 Advanced Micro Devices, Inc.
3
#
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:
10
#
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
13
# Software.
14
#
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.
22
#
23
"""
24
Script that generates the mapping from Gallium PIPE_FORMAT_xxx to GFX10_FORMAT_xxx enums.
25
"""
26
27
from __future__ import absolute_import, division, print_function, unicode_literals
28
29
import json
30
import mako.template
31
import os
32
import re
33
import sys
34
35
AMD_REGISTERS = os.path.abspath(os.path.join(os.path.dirname(sys.argv[0]), "../registers"))
36
UTIL_FORMAT = os.path.abspath(os.path.join(os.path.dirname(sys.argv[0]), "../../util/format"))
37
sys.path.extend([AMD_REGISTERS, UTIL_FORMAT])
38
39
from regdb import Object, RegisterDatabase
40
from u_format_parse import *
41
42
# ----------------------------------------------------------------------------
43
# Hard-coded mappings
44
45
def hardcoded_format(hw_enum):
46
return Object(img_format=hw_enum, flags=[])
47
48
HARDCODED = {
49
'PIPE_FORMAT_Z32_FLOAT_S8X24_UINT': hardcoded_format('X24_8_32_FLOAT'),
50
'PIPE_FORMAT_Z24_UNORM_S8_UINT': hardcoded_format('8_24_UNORM'),
51
'PIPE_FORMAT_S8_UINT_Z24_UNORM': hardcoded_format('24_8_UNORM'),
52
'PIPE_FORMAT_Z32_UNORM': None,
53
'PIPE_FORMAT_Z16_UNORM_S8_UINT': None,
54
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
57
58
'PIPE_FORMAT_R8G8_B8G8_UNORM': hardcoded_format('GB_GR_UNORM'),
59
'PIPE_FORMAT_G8R8_B8R8_UNORM': hardcoded_format('GB_GR_UNORM'),
60
61
'PIPE_FORMAT_R8G8_R8B8_UNORM': hardcoded_format('BG_RG_UNORM'),
62
'PIPE_FORMAT_G8R8_G8B8_UNORM': hardcoded_format('BG_RG_UNORM'),
63
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,
68
69
# Only R8G8_SRGB is supported, not L8A8_SRGB
70
'PIPE_FORMAT_L8A8_SRGB': None,
71
72
# S3TC
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'),
81
82
# RGTC
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'),
91
92
# BPTC
93
'PIPE_FORMAT_BPTC_RGB_UFLOAT': hardcoded_format('BC6_UFLOAT'),
94
'PIPE_FORMAT_BPTC_RGB_FLOAT': hardcoded_format('BC6_SFLOAT'),
95
96
'PIPE_FORMAT_BPTC_RGBA_UNORM': hardcoded_format('BC7_UNORM'),
97
'PIPE_FORMAT_BPTC_SRGBA': hardcoded_format('BC7_SRGB'),
98
99
'PIPE_FORMAT_R64_UINT': hardcoded_format('32_32_UINT'),
100
'PIPE_FORMAT_R64_SINT': hardcoded_format('32_32_SINT'),
101
}
102
103
104
# ----------------------------------------------------------------------------
105
# Main script
106
107
header_template = mako.template.Template("""\
108
// DO NOT EDIT -- AUTOMATICALLY GENERATED
109
110
#include "gfx10_format_table.h"
111
#include "amdgfxregs.h"
112
113
#define FMT(_img_format, ...) \
114
{ .img_format = V_008F0C_GFX10_FORMAT_##_img_format, \
115
##__VA_ARGS__ }
116
117
const struct gfx10_format gfx10_format_table[PIPE_FORMAT_COUNT] = {
118
% for pipe_format, args in formats:
119
% if args is not None:
120
[${pipe_format}] = FMT(${args}),
121
% else:
122
/* ${pipe_format} is not supported */
123
% endif
124
% endfor
125
};
126
""")
127
128
class Gfx10Format(object):
129
RE_plain_channel = re.compile(r'X?([0-9]+)')
130
131
def __init__(self, enum_entry):
132
self.img_format = enum_entry.name[13:]
133
self.flags = getattr(enum_entry, 'flags', [])
134
135
code = self.img_format.split('_')
136
137
self.plain_chan_sizes = []
138
for i, chan_code in enumerate(code):
139
m = self.RE_plain_channel.match(chan_code)
140
if m is None:
141
break
142
self.plain_chan_sizes.append(int(m.group(1)))
143
# Keep the bit sizes in little-endian order
144
self.plain_chan_sizes.reverse()
145
146
self.code = code[i:]
147
148
149
class Gfx10FormatMapping(object):
150
def __init__(self, pipe_formats, gfx10_formats):
151
self.pipe_formats = pipe_formats
152
self.gfx10_formats = gfx10_formats
153
154
self.plain_gfx10_formats = dict(
155
(tuple(['_'.join(fmt.code)] + fmt.plain_chan_sizes), fmt)
156
for fmt in gfx10_formats if fmt.plain_chan_sizes
157
)
158
159
def map(self, fmt):
160
if fmt.layout == PLAIN:
161
chan_type = set([chan.type for chan in fmt.le_channels if chan.type != VOID])
162
chan_norm = set([chan.norm for chan in fmt.le_channels if chan.type != VOID])
163
chan_pure = set([chan.pure for chan in fmt.le_channels if chan.type != VOID])
164
if len(chan_type) > 1 or len(chan_norm) > 1 or len(chan_pure) > 1:
165
print(('Format {fmt.name} has inconsistent channel types: ' +
166
'{chan_type} {chan_norm} {chan_pure}')
167
.format(**locals()),
168
file=sys.stderr)
169
return None
170
171
chan_type = chan_type.pop()
172
chan_norm = chan_norm.pop()
173
chan_pure = chan_pure.pop()
174
chan_sizes = [chan.size for chan in fmt.le_channels if chan.size != 0]
175
176
extra_flags = []
177
178
if fmt.colorspace == SRGB:
179
assert chan_type == UNSIGNED and chan_norm
180
num_format = 'SRGB'
181
else:
182
if chan_type == UNSIGNED:
183
if chan_pure:
184
num_format = 'UINT'
185
elif chan_sizes[0] == 32:
186
# Shader-based work-around for 32-bit non-pure-integer
187
num_format = 'UINT'
188
extra_flags.append('buffers_only')
189
elif chan_norm:
190
num_format = 'UNORM'
191
else:
192
num_format = 'USCALED'
193
elif chan_type == SIGNED:
194
if chan_pure:
195
num_format = 'SINT'
196
elif chan_sizes[0] == 32:
197
# Shader-based work-around for 32-bit non-pure-integer
198
num_format = 'SINT'
199
extra_flags.append('buffers_only')
200
elif chan_norm:
201
num_format = 'SNORM'
202
else:
203
num_format = 'SSCALED'
204
elif chan_type == FLOAT:
205
num_format = 'FLOAT'
206
207
if chan_sizes[0] == 64:
208
# Shader-based work-around for doubles
209
if len(chan_sizes) % 2 == 1:
210
# 1 or 3 loads for 1 or 3 double channels
211
chan_sizes = [32, 32]
212
else:
213
# 1 or 2 loads for 2 or 4 double channels
214
chan_sizes = [32, 32, 32, 32]
215
extra_flags.append('buffers_only')
216
else:
217
# Shader-based work-around
218
assert chan_type == FIXED
219
assert chan_sizes[0] == 32
220
num_format = 'SINT'
221
extra_flags.append('buffers_only')
222
223
# These are not supported as render targets, so we don't support
224
# them as images either.
225
if (len(chan_sizes) == 3 and chan_sizes[0] in (8, 16, 32) and
226
chan_sizes[0] == chan_sizes[1]):
227
extra_flags.append('buffers_only')
228
if chan_sizes[0] in (8, 16):
229
# Shader-based work-around: one load per channel
230
chan_sizes = [chan_sizes[0]]
231
232
# Don't expose SRGB buffer formats
233
if 'buffers_only' in extra_flags and fmt.colorspace == SRGB:
234
return None
235
236
# Don't support 4_4 because it's not supported as render targets
237
# and it's useless in other cases.
238
if len(chan_sizes) == 2 and chan_sizes[0] == 4:
239
return None
240
241
key = tuple([num_format] + chan_sizes)
242
if key not in self.plain_gfx10_formats:
243
return None
244
245
gfx10_fmt = self.plain_gfx10_formats[key]
246
return Object(
247
img_format=gfx10_fmt.img_format,
248
flags=gfx10_fmt.flags + extra_flags,
249
)
250
251
return None
252
253
254
if __name__ == '__main__':
255
pipe_formats = parse(sys.argv[1])
256
257
with open(sys.argv[2], 'r') as filp:
258
db = RegisterDatabase.from_json(json.load(filp))
259
260
gfx10_formats = [Gfx10Format(entry) for entry in db.enum('GFX10_FORMAT').entries]
261
262
mapping = Gfx10FormatMapping(pipe_formats, gfx10_formats)
263
264
formats = []
265
for fmt in pipe_formats:
266
if fmt.name in HARDCODED:
267
obj = HARDCODED[fmt.name]
268
else:
269
obj = mapping.map(fmt)
270
271
if obj is not None:
272
args = obj.img_format
273
if 'buffers_only' in obj.flags:
274
args += ', .buffers_only = 1'
275
else:
276
args = None
277
formats.append((fmt.name, args))
278
279
print(header_template.render(formats=formats))
280
281