7
7
8
8
namespace Shader ::Gcn {
9
9
10
- u32 SwizzleMrtComponent (const FragmentRuntimeInfo::PsColorBuffer& color_buffer, u32 comp) {
11
- const auto [r, g, b, a] = color_buffer.swizzle ;
12
- const std::array swizzle_array = {r, g, b, a};
13
- const auto swizzled_comp_type = static_cast <u32 >(swizzle_array[comp]);
14
- constexpr auto min_comp_type = static_cast <u32 >(AmdGpu::CompSwizzle::Red);
15
- return swizzled_comp_type >= min_comp_type ? swizzled_comp_type - min_comp_type : comp;
16
- }
17
-
18
- void Translator::ExportMrtValue (IR::Attribute attribute, u32 comp, const IR::F32& value,
19
- const FragmentRuntimeInfo::PsColorBuffer& color_buffer) {
20
- const auto converted = ApplyWriteNumberConversion (ir, value, color_buffer.num_conversion );
21
- ir.SetAttribute (attribute, converted, comp);
22
- }
23
-
24
- void Translator::ExportMrtCompressed (IR::Attribute attribute, u32 idx, const IR::U32& value) {
25
- const u32 color_buffer_idx =
26
- static_cast <u32 >(attribute) - static_cast <u32 >(IR::Attribute::RenderTarget0);
27
- const auto color_buffer = runtime_info.fs_info .color_buffers [color_buffer_idx];
28
-
29
- IR::Value unpacked_value;
30
- bool is_integer = false ;
31
- switch (color_buffer.export_format ) {
32
- case AmdGpu::Liverpool::ShaderExportFormat::Zero:
33
- // No export
34
- return ;
35
- case AmdGpu::Liverpool::ShaderExportFormat::ABGR_FP16:
36
- unpacked_value = ir.UnpackHalf2x16 (value);
37
- break ;
38
- case AmdGpu::Liverpool::ShaderExportFormat::ABGR_UNORM16:
39
- unpacked_value = ir.UnpackUnorm2x16 (value);
40
- break ;
41
- case AmdGpu::Liverpool::ShaderExportFormat::ABGR_SNORM16:
42
- unpacked_value = ir.UnpackSnorm2x16 (value);
43
- break ;
44
- case AmdGpu::Liverpool::ShaderExportFormat::ABGR_UINT16:
45
- unpacked_value = ir.UnpackUint2x16 (value);
46
- is_integer = true ;
47
- break ;
48
- case AmdGpu::Liverpool::ShaderExportFormat::ABGR_SINT16:
49
- unpacked_value = ir.UnpackSint2x16 (value);
50
- is_integer = true ;
51
- break ;
52
- default :
53
- UNREACHABLE_MSG (" Unimplemented compressed MRT export format {}" ,
54
- static_cast <u32 >(color_buffer.export_format ));
55
- break ;
56
- }
57
-
58
- const auto r = ir.CompositeExtract (unpacked_value, 0 );
59
- const auto g = ir.CompositeExtract (unpacked_value, 1 );
60
- const IR::F32 float_r = is_integer ? ir.BitCast <IR::F32>(IR::U32{r}) : IR::F32{r};
61
- const IR::F32 float_g = is_integer ? ir.BitCast <IR::F32>(IR::U32{g}) : IR::F32{g};
62
-
63
- const auto swizzled_r = SwizzleMrtComponent (color_buffer, idx * 2 );
64
- const auto swizzled_g = SwizzleMrtComponent (color_buffer, idx * 2 + 1 );
65
-
66
- ExportMrtValue (attribute, swizzled_r, float_r, color_buffer);
67
- ExportMrtValue (attribute, swizzled_g, float_g, color_buffer);
68
- }
69
-
70
- void Translator::ExportMrtUncompressed (IR::Attribute attribute, u32 comp, const IR::F32& value) {
71
- const u32 color_buffer_idx =
72
- static_cast <u32 >(attribute) - static_cast <u32 >(IR::Attribute::RenderTarget0);
73
- const auto color_buffer = runtime_info.fs_info .color_buffers [color_buffer_idx];
74
- const auto swizzled_comp = SwizzleMrtComponent (color_buffer, comp);
75
-
76
- switch (color_buffer.export_format ) {
77
- case AmdGpu::Liverpool::ShaderExportFormat::Zero:
78
- // No export
79
- return ;
80
- case AmdGpu::Liverpool::ShaderExportFormat::R_32:
81
- // Red only
82
- if (swizzled_comp != 0 ) {
83
- return ;
84
- }
85
- break ;
86
- case AmdGpu::Liverpool::ShaderExportFormat::GR_32:
87
- // Red and Green only
88
- if (swizzled_comp != 0 && swizzled_comp != 1 ) {
89
- return ;
90
- }
91
- break ;
92
- case AmdGpu::Liverpool::ShaderExportFormat::AR_32:
93
- // Red and Alpha only
94
- if (swizzled_comp != 0 && swizzled_comp != 3 ) {
95
- return ;
96
- }
97
- break ;
98
- case AmdGpu::Liverpool::ShaderExportFormat::ABGR_32:
99
- // All components
100
- break ;
101
- default :
102
- UNREACHABLE_MSG (" Unimplemented uncompressed MRT export format {}" ,
103
- static_cast <u32 >(color_buffer.export_format ));
104
- break ;
105
- }
106
- ExportMrtValue (attribute, swizzled_comp, value, color_buffer);
107
- }
108
-
109
- void Translator::ExportCompressed (IR::Attribute attribute, u32 idx, const IR::U32& value) {
110
- if (IsMrt (attribute)) {
111
- ExportMrtCompressed (attribute, idx, value);
112
- return ;
113
- }
114
- const IR::Value unpacked_value = ir.UnpackHalf2x16 (value);
115
- const IR::F32 r = IR::F32{ir.CompositeExtract (unpacked_value, 0 )};
116
- const IR::F32 g = IR::F32{ir.CompositeExtract (unpacked_value, 1 )};
117
- ir.SetAttribute (attribute, r, idx * 2 );
118
- ir.SetAttribute (attribute, g, idx * 2 + 1 );
119
- }
120
-
121
- void Translator::ExportUncompressed (IR::Attribute attribute, u32 comp, const IR::F32& value) {
122
- if (IsMrt (attribute)) {
123
- ExportMrtUncompressed (attribute, comp, value);
124
- return ;
125
- }
126
- ir.SetAttribute (attribute, value, comp);
127
- }
128
-
129
10
void Translator::EmitExport (const GcnInst& inst) {
130
11
if (ir.block ->has_multiple_predecessors && info.stage == Stage::Fragment) {
131
12
ir.Discard (ir.LogicalNot (ir.GetExec ()));
@@ -145,15 +26,41 @@ void Translator::EmitExport(const GcnInst& inst) {
145
26
IR::VectorReg (inst.src [3 ].code ),
146
27
};
147
28
29
+ const auto set_attribute = [&](u32 comp, IR::F32 value) {
30
+ if (!IR::IsMrt (attrib)) {
31
+ ir.SetAttribute (attrib, value, comp);
32
+ return ;
33
+ }
34
+ const u32 index = u32 (attrib) - u32 (IR::Attribute::RenderTarget0);
35
+ const auto col_buf = runtime_info.fs_info .color_buffers [index];
36
+ const auto converted = IR::ApplyWriteNumberConversion (ir, value, col_buf.num_conversion );
37
+ const auto [r, g, b, a] = col_buf.swizzle ;
38
+ const std::array swizzle_array = {r, g, b, a};
39
+ const auto swizzled_comp = swizzle_array[comp];
40
+ if (u32 (swizzled_comp) < u32 (AmdGpu::CompSwizzle::Red)) {
41
+ ir.SetAttribute (attrib, converted, comp);
42
+ return ;
43
+ }
44
+ ir.SetAttribute (attrib, converted, u32 (swizzled_comp) - u32 (AmdGpu::CompSwizzle::Red));
45
+ };
46
+
47
+ const auto unpack = [&](u32 idx) {
48
+ const IR::Value value = ir.UnpackHalf2x16 (ir.GetVectorReg (vsrc[idx]));
49
+ const IR::F32 r = IR::F32{ir.CompositeExtract (value, 0 )};
50
+ const IR::F32 g = IR::F32{ir.CompositeExtract (value, 1 )};
51
+ set_attribute (idx * 2 , r);
52
+ set_attribute (idx * 2 + 1 , g);
53
+ };
54
+
148
55
// Components are float16 packed into a VGPR
149
56
if (exp.compr ) {
150
57
// Export R, G
151
58
if (exp.en & 1 ) {
152
- ExportCompressed (attrib, 0 , ir. GetVectorReg <IR::U32>(vsrc[ 0 ]) );
59
+ unpack ( 0 );
153
60
}
154
61
// Export B, A
155
62
if ((exp.en >> 2 ) & 1 ) {
156
- ExportCompressed (attrib, 1 , ir. GetVectorReg <IR::U32>(vsrc[ 1 ]) );
63
+ unpack ( 1 );
157
64
}
158
65
} else {
159
66
// Components are float32 into separate VGPRS
@@ -162,7 +69,8 @@ void Translator::EmitExport(const GcnInst& inst) {
162
69
if ((mask & 1 ) == 0 ) {
163
70
continue ;
164
71
}
165
- ExportUncompressed (attrib, i, ir.GetVectorReg <IR::F32>(vsrc[i]));
72
+ const IR::F32 comp = ir.GetVectorReg <IR::F32>(vsrc[i]);
73
+ set_attribute (i, comp);
166
74
}
167
75
}
168
76
if (IR::IsMrt (attrib)) {
0 commit comments