Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/mesa
Path: blob/21.2-virgl/src/freedreno/vulkan/tu_util.h
4565 views
1
/*
2
* Copyright 2020 Valve Corporation
3
* SPDX-License-Identifier: MIT
4
*
5
* Authors:
6
* Jonathan Marek <[email protected]>
7
*/
8
9
#ifndef TU_UTIL_H
10
#define TU_UTIL_H
11
12
#include <assert.h>
13
#include <stdint.h>
14
15
#include "util/macros.h"
16
#include "util/u_math.h"
17
#include "util/format/u_format_pack.h"
18
#include "util/format/u_format_zs.h"
19
#include "compiler/shader_enums.h"
20
21
#include "adreno_common.xml.h"
22
#include "adreno_pm4.xml.h"
23
#include "a6xx.xml.h"
24
25
#include <vulkan/vulkan.h>
26
#include "vk_util.h"
27
28
#define TU_STAGE_MASK ((1 << MESA_SHADER_STAGES) - 1)
29
30
#define tu_foreach_stage(stage, stage_bits) \
31
for (gl_shader_stage stage, \
32
__tmp = (gl_shader_stage)((stage_bits) &TU_STAGE_MASK); \
33
stage = __builtin_ffs(__tmp) - 1, __tmp; __tmp &= ~(1 << (stage)))
34
35
static inline enum a3xx_msaa_samples
36
tu_msaa_samples(uint32_t samples)
37
{
38
assert(__builtin_popcount(samples) == 1);
39
return util_logbase2(samples);
40
}
41
42
static inline uint32_t
43
tu6_stage2opcode(gl_shader_stage stage)
44
{
45
if (stage == MESA_SHADER_FRAGMENT || stage == MESA_SHADER_COMPUTE)
46
return CP_LOAD_STATE6_FRAG;
47
return CP_LOAD_STATE6_GEOM;
48
}
49
50
static inline enum a6xx_state_block
51
tu6_stage2texsb(gl_shader_stage stage)
52
{
53
return SB6_VS_TEX + stage;
54
}
55
56
static inline enum a6xx_state_block
57
tu6_stage2shadersb(gl_shader_stage stage)
58
{
59
return SB6_VS_SHADER + stage;
60
}
61
62
static inline enum a3xx_rop_code
63
tu6_rop(VkLogicOp op)
64
{
65
/* note: hw enum matches the VK enum, but with the 4 bits reversed */
66
static const uint8_t lookup[] = {
67
[VK_LOGIC_OP_CLEAR] = ROP_CLEAR,
68
[VK_LOGIC_OP_AND] = ROP_AND,
69
[VK_LOGIC_OP_AND_REVERSE] = ROP_AND_REVERSE,
70
[VK_LOGIC_OP_COPY] = ROP_COPY,
71
[VK_LOGIC_OP_AND_INVERTED] = ROP_AND_INVERTED,
72
[VK_LOGIC_OP_NO_OP] = ROP_NOOP,
73
[VK_LOGIC_OP_XOR] = ROP_XOR,
74
[VK_LOGIC_OP_OR] = ROP_OR,
75
[VK_LOGIC_OP_NOR] = ROP_NOR,
76
[VK_LOGIC_OP_EQUIVALENT] = ROP_EQUIV,
77
[VK_LOGIC_OP_INVERT] = ROP_INVERT,
78
[VK_LOGIC_OP_OR_REVERSE] = ROP_OR_REVERSE,
79
[VK_LOGIC_OP_COPY_INVERTED] = ROP_COPY_INVERTED,
80
[VK_LOGIC_OP_OR_INVERTED] = ROP_OR_INVERTED,
81
[VK_LOGIC_OP_NAND] = ROP_NAND,
82
[VK_LOGIC_OP_SET] = ROP_SET,
83
};
84
assert(op < ARRAY_SIZE(lookup));
85
return lookup[op];
86
}
87
88
static inline enum pc_di_primtype
89
tu6_primtype(VkPrimitiveTopology topology)
90
{
91
static const uint8_t lookup[] = {
92
[VK_PRIMITIVE_TOPOLOGY_POINT_LIST] = DI_PT_POINTLIST,
93
[VK_PRIMITIVE_TOPOLOGY_LINE_LIST] = DI_PT_LINELIST,
94
[VK_PRIMITIVE_TOPOLOGY_LINE_STRIP] = DI_PT_LINESTRIP,
95
[VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST] = DI_PT_TRILIST,
96
[VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP] = DI_PT_TRISTRIP,
97
[VK_PRIMITIVE_TOPOLOGY_TRIANGLE_FAN] = DI_PT_TRIFAN,
98
[VK_PRIMITIVE_TOPOLOGY_LINE_LIST_WITH_ADJACENCY] = DI_PT_LINE_ADJ,
99
[VK_PRIMITIVE_TOPOLOGY_LINE_STRIP_WITH_ADJACENCY] = DI_PT_LINESTRIP_ADJ,
100
[VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST_WITH_ADJACENCY] = DI_PT_TRI_ADJ,
101
[VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP_WITH_ADJACENCY] = DI_PT_TRISTRIP_ADJ,
102
/* Return PATCH0 and update in tu_pipeline_builder_parse_tessellation */
103
[VK_PRIMITIVE_TOPOLOGY_PATCH_LIST] = DI_PT_PATCHES0,
104
};
105
assert(topology < ARRAY_SIZE(lookup));
106
return lookup[topology];
107
}
108
109
static inline enum adreno_compare_func
110
tu6_compare_func(VkCompareOp op)
111
{
112
return (enum adreno_compare_func) op;
113
}
114
115
static inline enum adreno_stencil_op
116
tu6_stencil_op(VkStencilOp op)
117
{
118
return (enum adreno_stencil_op) op;
119
}
120
121
static inline enum adreno_rb_blend_factor
122
tu6_blend_factor(VkBlendFactor factor)
123
{
124
static const uint8_t lookup[] = {
125
[VK_BLEND_FACTOR_ZERO] = FACTOR_ZERO,
126
[VK_BLEND_FACTOR_ONE] = FACTOR_ONE,
127
[VK_BLEND_FACTOR_SRC_COLOR] = FACTOR_SRC_COLOR,
128
[VK_BLEND_FACTOR_ONE_MINUS_SRC_COLOR] = FACTOR_ONE_MINUS_SRC_COLOR,
129
[VK_BLEND_FACTOR_DST_COLOR] = FACTOR_DST_COLOR,
130
[VK_BLEND_FACTOR_ONE_MINUS_DST_COLOR] = FACTOR_ONE_MINUS_DST_COLOR,
131
[VK_BLEND_FACTOR_SRC_ALPHA] = FACTOR_SRC_ALPHA,
132
[VK_BLEND_FACTOR_ONE_MINUS_SRC_ALPHA] = FACTOR_ONE_MINUS_SRC_ALPHA,
133
[VK_BLEND_FACTOR_DST_ALPHA] = FACTOR_DST_ALPHA,
134
[VK_BLEND_FACTOR_ONE_MINUS_DST_ALPHA] = FACTOR_ONE_MINUS_DST_ALPHA,
135
[VK_BLEND_FACTOR_CONSTANT_COLOR] = FACTOR_CONSTANT_COLOR,
136
[VK_BLEND_FACTOR_ONE_MINUS_CONSTANT_COLOR]= FACTOR_ONE_MINUS_CONSTANT_COLOR,
137
[VK_BLEND_FACTOR_CONSTANT_ALPHA] = FACTOR_CONSTANT_ALPHA,
138
[VK_BLEND_FACTOR_ONE_MINUS_CONSTANT_ALPHA]= FACTOR_ONE_MINUS_CONSTANT_ALPHA,
139
[VK_BLEND_FACTOR_SRC_ALPHA_SATURATE] = FACTOR_SRC_ALPHA_SATURATE,
140
[VK_BLEND_FACTOR_SRC1_COLOR] = FACTOR_SRC1_COLOR,
141
[VK_BLEND_FACTOR_ONE_MINUS_SRC1_COLOR] = FACTOR_ONE_MINUS_SRC1_COLOR,
142
[VK_BLEND_FACTOR_SRC1_ALPHA] = FACTOR_SRC1_ALPHA,
143
[VK_BLEND_FACTOR_ONE_MINUS_SRC1_ALPHA] = FACTOR_ONE_MINUS_SRC1_ALPHA,
144
};
145
assert(factor < ARRAY_SIZE(lookup));
146
return lookup[factor];
147
}
148
149
static inline enum a3xx_rb_blend_opcode
150
tu6_blend_op(VkBlendOp op)
151
{
152
return (enum a3xx_rb_blend_opcode) op;
153
}
154
155
static inline enum a6xx_tex_type
156
tu6_tex_type(VkImageViewType type, bool storage)
157
{
158
switch (type) {
159
default:
160
case VK_IMAGE_VIEW_TYPE_1D:
161
case VK_IMAGE_VIEW_TYPE_1D_ARRAY:
162
return A6XX_TEX_1D;
163
case VK_IMAGE_VIEW_TYPE_2D:
164
case VK_IMAGE_VIEW_TYPE_2D_ARRAY:
165
return A6XX_TEX_2D;
166
case VK_IMAGE_VIEW_TYPE_3D:
167
return A6XX_TEX_3D;
168
case VK_IMAGE_VIEW_TYPE_CUBE:
169
case VK_IMAGE_VIEW_TYPE_CUBE_ARRAY:
170
return storage ? A6XX_TEX_2D : A6XX_TEX_CUBE;
171
}
172
}
173
174
static inline enum a6xx_tex_clamp
175
tu6_tex_wrap(VkSamplerAddressMode address_mode)
176
{
177
uint8_t lookup[] = {
178
[VK_SAMPLER_ADDRESS_MODE_REPEAT] = A6XX_TEX_REPEAT,
179
[VK_SAMPLER_ADDRESS_MODE_MIRRORED_REPEAT] = A6XX_TEX_MIRROR_REPEAT,
180
[VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE] = A6XX_TEX_CLAMP_TO_EDGE,
181
[VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_BORDER] = A6XX_TEX_CLAMP_TO_BORDER,
182
[VK_SAMPLER_ADDRESS_MODE_MIRROR_CLAMP_TO_EDGE] = A6XX_TEX_MIRROR_CLAMP,
183
};
184
assert(address_mode < ARRAY_SIZE(lookup));
185
return lookup[address_mode];
186
}
187
188
static inline enum a6xx_tex_filter
189
tu6_tex_filter(VkFilter filter, unsigned aniso)
190
{
191
switch (filter) {
192
case VK_FILTER_NEAREST:
193
return A6XX_TEX_NEAREST;
194
case VK_FILTER_LINEAR:
195
return aniso ? A6XX_TEX_ANISO : A6XX_TEX_LINEAR;
196
case VK_FILTER_CUBIC_EXT:
197
return A6XX_TEX_CUBIC;
198
default:
199
unreachable("illegal texture filter");
200
break;
201
}
202
}
203
204
static inline enum a6xx_reduction_mode
205
tu6_reduction_mode(VkSamplerReductionMode reduction_mode)
206
{
207
return (enum a6xx_reduction_mode) reduction_mode;
208
}
209
210
static inline enum a6xx_depth_format
211
tu6_pipe2depth(VkFormat format)
212
{
213
switch (format) {
214
case VK_FORMAT_D16_UNORM:
215
return DEPTH6_16;
216
case VK_FORMAT_X8_D24_UNORM_PACK32:
217
case VK_FORMAT_D24_UNORM_S8_UINT:
218
return DEPTH6_24_8;
219
case VK_FORMAT_D32_SFLOAT:
220
case VK_FORMAT_D32_SFLOAT_S8_UINT:
221
case VK_FORMAT_S8_UINT:
222
return DEPTH6_32;
223
default:
224
return ~0;
225
}
226
}
227
228
static inline enum a6xx_polygon_mode
229
tu6_polygon_mode(VkPolygonMode mode)
230
{
231
switch (mode) {
232
case VK_POLYGON_MODE_POINT:
233
return POLYMODE6_POINTS;
234
case VK_POLYGON_MODE_LINE:
235
return POLYMODE6_LINES;
236
case VK_POLYGON_MODE_FILL:
237
return POLYMODE6_TRIANGLES;
238
default:
239
unreachable("bad polygon mode");
240
}
241
}
242
243
struct bcolor_entry {
244
uint32_t fp32[4];
245
uint64_t ui16;
246
uint64_t si16;
247
uint64_t fp16;
248
uint16_t rgb565;
249
uint16_t rgb5a1;
250
uint16_t rgba4;
251
uint8_t __pad0[2];
252
uint32_t ui8;
253
uint32_t si8;
254
uint32_t rgb10a2;
255
uint32_t z24; /* also s8? */
256
uint64_t srgb;
257
uint8_t __pad1[56];
258
} __attribute__((aligned(128)));
259
260
/* vulkan does not want clamping of integer clear values, differs from u_format
261
* see spec for VkClearColorValue
262
*/
263
static inline void
264
pack_int8(uint32_t *dst, const uint32_t *val)
265
{
266
*dst = (val[0] & 0xff) |
267
(val[1] & 0xff) << 8 |
268
(val[2] & 0xff) << 16 |
269
(val[3] & 0xff) << 24;
270
}
271
272
static inline void
273
pack_int10_2(uint32_t *dst, const uint32_t *val)
274
{
275
*dst = (val[0] & 0x3ff) |
276
(val[1] & 0x3ff) << 10 |
277
(val[2] & 0x3ff) << 20 |
278
(val[3] & 0x3) << 30;
279
}
280
281
static inline void
282
pack_int16(uint32_t *dst, const uint32_t *val)
283
{
284
dst[0] = (val[0] & 0xffff) |
285
(val[1] & 0xffff) << 16;
286
dst[1] = (val[2] & 0xffff) |
287
(val[3] & 0xffff) << 16;
288
}
289
290
static inline void
291
tu6_pack_border_color(struct bcolor_entry *bcolor, const VkClearColorValue *val, bool is_int)
292
{
293
memcpy(bcolor->fp32, val, 4 * sizeof(float));
294
if (is_int) {
295
pack_int16((uint32_t*) &bcolor->fp16, val->uint32);
296
return;
297
}
298
#define PACK_F(x, type) util_format_##type##_pack_rgba_float \
299
( (uint8_t*) (&bcolor->x), 0, val->float32, 0, 1, 1)
300
PACK_F(ui16, r16g16b16a16_unorm);
301
PACK_F(si16, r16g16b16a16_snorm);
302
PACK_F(fp16, r16g16b16a16_float);
303
PACK_F(rgb565, r5g6b5_unorm);
304
PACK_F(rgb5a1, r5g5b5a1_unorm);
305
PACK_F(rgba4, r4g4b4a4_unorm);
306
PACK_F(ui8, r8g8b8a8_unorm);
307
PACK_F(si8, r8g8b8a8_snorm);
308
PACK_F(rgb10a2, r10g10b10a2_unorm);
309
util_format_x8z24_unorm_pack_z_float((uint8_t*) &bcolor->z24,
310
0, val->float32, 0, 1, 1);
311
PACK_F(srgb, r16g16b16a16_float); /* TODO: clamp? */
312
#undef PACK_F
313
}
314
315
#endif /* TU_UTIL_H */
316
317