Blender V4.3
vk_data_conversion_test.cc
Go to the documentation of this file.
1/* SPDX-FileCopyrightText: 2023 Blender Authors
2 *
3 * SPDX-License-Identifier: Apache-2.0 */
4
5#include "testing/testing.h"
6
8#include "vk_device.hh"
9
11
12namespace blender::gpu::tests {
13
14TEST(VulkanDataConversion, clamp_negative_to_zero)
15{
16 const uint32_t f32_2 = 0b11000000000000000000000000000000;
17 const uint32_t f32_inf_min = 0b11111111100000000000000000000000;
18 const uint32_t f32_inf_max = 0b01111111100000000000000000000000;
19 const uint32_t f32_nan = 0b11111111111111111111111111111111;
20
21 /* F32(-2) doesn't fit in F11 as F11 only supports unsigned values. Clamp to zero. */
22 const uint32_t f11_0_expected = 0b00000000000;
23 const uint32_t f11_2_expected = 0b10000000000;
24 const uint32_t f11_inf_expected = 0b11111000000;
25 const uint32_t f11_nan_expected = 0b11111111111;
26 {
28 EXPECT_EQ(f11_0, f11_0_expected);
30 EXPECT_EQ(f11_0b, f11_0_expected);
32 EXPECT_EQ(f11_inf, f11_inf_expected);
34 EXPECT_EQ(f11_nan, f11_nan_expected);
35 }
36
37 /* F32(-2) doesn't fit in F11 as F11 only supports unsigned values. Make absolute. */
38 {
40 EXPECT_EQ(f11_2, f11_2_expected);
42 EXPECT_EQ(f11_inf, f11_inf_expected);
44 EXPECT_EQ(f11_infb, f11_inf_expected);
46 EXPECT_EQ(f11_nan, f11_nan_expected);
47 }
48}
49
50TEST(VulkanDataConversion, infinity_upper)
51{
52 const uint32_t f32_inf = 0b01111111100000000000000000000000;
53
54 const uint32_t f11_inf_expected = 0b11111000000;
56 EXPECT_EQ(f11_inf, f11_inf_expected);
57
58 const uint32_t f10_inf_expected = 0b1111100000;
60 EXPECT_EQ(f10_inf, f10_inf_expected);
61}
62
63TEST(VulkanDataConversion, vertex_format_i32_as_float)
64{
65 GPUVertFormat source_format;
66 GPU_vertformat_clear(&source_format);
68 VertexFormat_pack(&source_format);
69
70 union TestData {
71 int2 pos_i;
72 float2 pos_fl;
73 };
74 TestData test_data[4];
75 test_data[0].pos_i = int2(0, 1);
76 test_data[1].pos_i = int2(1, 2);
77 test_data[2].pos_i = int2(2, 3);
78 test_data[3].pos_i = int2(3, 4);
79
80 VKWorkarounds workarounds = {};
81 VertexFormatConverter converter;
82 converter.init(&source_format, workarounds);
83
84 EXPECT_TRUE(converter.needs_conversion());
85
86 converter.convert(&test_data, &test_data, 4);
87
88 EXPECT_EQ(test_data[0].pos_fl, float2(0.0, 1.0));
89 EXPECT_EQ(test_data[1].pos_fl, float2(1.0, 2.0));
90 EXPECT_EQ(test_data[2].pos_fl, float2(2.0, 3.0));
91 EXPECT_EQ(test_data[3].pos_fl, float2(3.0, 4.0));
92}
93
94TEST(VulkanDataConversion, vertex_format_u32_as_float)
95{
96 GPUVertFormat source_format;
97 GPU_vertformat_clear(&source_format);
99 VertexFormat_pack(&source_format);
100
101 union TestData {
102 uint3 pos_u;
103 float3 pos_fl;
104 };
105 TestData test_data[4];
106 test_data[0].pos_u = uint3(0, 1, 2);
107 test_data[1].pos_u = uint3(1, 2, 3);
108 test_data[2].pos_u = uint3(2, 3, 4);
109 test_data[3].pos_u = uint3(3, 4, 5);
110
111 VKWorkarounds workarounds = {};
112 VertexFormatConverter converter;
113 converter.init(&source_format, workarounds);
114
115 EXPECT_TRUE(converter.needs_conversion());
116
117 converter.convert(&test_data, &test_data, 4);
118
119 EXPECT_EQ(test_data[0].pos_fl, float3(0.0, 1.0, 2.0));
120 EXPECT_EQ(test_data[1].pos_fl, float3(1.0, 2.0, 3.0));
121 EXPECT_EQ(test_data[2].pos_fl, float3(2.0, 3.0, 4.0));
122 EXPECT_EQ(test_data[3].pos_fl, float3(3.0, 4.0, 5.0));
123}
124
125TEST(VulkanDataConversion, vertex_format_r8g8b8)
126{
127 GPUVertFormat source_format;
128 GPU_vertformat_clear(&source_format);
130 VertexFormat_pack(&source_format);
131
132 struct SourceData {
134 uint8_t _pad;
135 };
136 struct DeviceData {
138 };
139
140 SourceData test_data_in[4];
141 test_data_in[0].color = uchar3(255, 0, 0);
142 test_data_in[1].color = uchar3(255, 255, 255);
143 test_data_in[2].color = uchar3(255, 0, 0);
144 test_data_in[3].color = uchar3(255, 255, 255);
145
146 VKWorkarounds workarounds = {};
147 VertexFormatConverter converter;
148 converter.init(&source_format, workarounds);
149
150 EXPECT_FALSE(converter.needs_conversion());
151
152 /* Enable workaround for r8g8b8 vertex formats. */
153 workarounds.vertex_formats.r8g8b8 = true;
154
155 converter.init(&source_format, workarounds);
156 EXPECT_TRUE(converter.needs_conversion());
157
158 DeviceData test_data_out[4];
159 converter.convert(test_data_out, test_data_in, 4);
160
161 EXPECT_EQ(test_data_out[0].color, uchar4(255, 0, 0, 255));
162 EXPECT_EQ(test_data_out[1].color, uchar4(255, 255, 255, 255));
163 EXPECT_EQ(test_data_out[2].color, uchar4(255, 0, 0, 255));
164 EXPECT_EQ(test_data_out[3].color, uchar4(255, 255, 255, 255));
165}
166
167TEST(VulkanDataConversion, vertex_format_multiple_attributes)
168{
169 GPUVertFormat source_format;
170 GPU_vertformat_clear(&source_format);
171 GPU_vertformat_attr_add(&source_format, "pos", GPU_COMP_F32, 3, GPU_FETCH_FLOAT);
173 GPU_vertformat_attr_add(&source_format, "flag", GPU_COMP_U32, 1, GPU_FETCH_INT);
174 VertexFormat_pack(&source_format);
175
176 struct SourceData {
177 float3 pos;
179 uint8_t _pad;
180 uint flag;
181 };
182 struct DeviceData {
183 float3 pos;
185 uint flag;
186 };
187
188 SourceData test_data_in[4];
189 test_data_in[0] = {float3(1.0, 2.0, 3.0), uchar3(255, 0, 0), 0, 0};
190 test_data_in[1] = {float3(4.0, 5.0, 6.0), uchar3(0, 255, 0), 0, 1};
191 test_data_in[2] = {float3(7.0, 8.0, 9.0), uchar3(0, 0, 255), 0, 2};
192 test_data_in[3] = {float3(10.0, 11.0, 12.0), uchar3(255, 255, 255), 0, 3};
193
194 VKWorkarounds workarounds = {};
195 workarounds.vertex_formats.r8g8b8 = true;
196 VertexFormatConverter converter;
197 converter.init(&source_format, workarounds);
198 EXPECT_TRUE(converter.needs_conversion());
199
200 DeviceData test_data_out[4];
201 converter.convert(test_data_out, test_data_in, 4);
202
203 DeviceData expected_data[4];
204 expected_data[0] = {float3(1.0, 2.0, 3.0), uchar4(255, 0, 0, 255), 0};
205 expected_data[1] = {float3(4.0, 5.0, 6.0), uchar4(0, 255, 0, 255), 1};
206 expected_data[2] = {float3(7.0, 8.0, 9.0), uchar4(0, 0, 255, 255), 2};
207 expected_data[3] = {float3(10.0, 11.0, 12.0), uchar4(255, 255, 255, 255), 3};
208 for (int i : IndexRange(4)) {
209 EXPECT_EQ(test_data_out[i].pos, expected_data[i].pos);
210 EXPECT_EQ(test_data_out[i].color, expected_data[i].color);
211 EXPECT_EQ(test_data_out[i].flag, expected_data[i].flag);
212 }
213}
214
215TEST(VulkanDataConversion, texture_rgb16f_as_floats_to_rgba16f)
216{
217 const size_t num_pixels = 4;
218 const float input[] = {
219 1.0,
220 0.5,
221 0.2,
222
223 0.2,
224 1.0,
225 0.3,
226
227 0.4,
228 0.2,
229 1.0,
230
231 1.0,
232 1.0,
233 1.0,
234 };
235
236 uint64_t device[num_pixels];
237 convert_host_to_device(device, input, num_pixels, GPU_DATA_FLOAT, GPU_RGB16F, GPU_RGBA16F);
238
239 float read_back[num_pixels * 3];
240 convert_device_to_host(read_back, device, num_pixels, GPU_DATA_FLOAT, GPU_RGB16F, GPU_RGBA16F);
241
242 for (int i : IndexRange(num_pixels * 3)) {
243 EXPECT_NEAR(input[i], read_back[i], 0.01);
244 }
245}
246
247TEST(VulkanDataConversion, texture_rgb32f_as_floats_to_rgba32f)
248{
249 const size_t num_pixels = 4;
250 const float input[] = {
251 1.0,
252 0.5,
253 0.2,
254
255 0.2,
256 1.0,
257 0.3,
258
259 0.4,
260 0.2,
261 1.0,
262
263 1.0,
264 1.0,
265 1.0,
266 };
267
268 float device[num_pixels * 4];
269 convert_host_to_device(device, input, num_pixels, GPU_DATA_FLOAT, GPU_RGB32F, GPU_RGBA32F);
270
271 float read_back[num_pixels * 3];
272 convert_device_to_host(read_back, device, num_pixels, GPU_DATA_FLOAT, GPU_RGB32F, GPU_RGBA32F);
273
274 for (int i : IndexRange(num_pixels * 3)) {
275 EXPECT_NEAR(input[i], read_back[i], 0.01);
276 }
277}
278
279} // namespace blender::gpu::tests
EXPECT_EQ(BLI_expr_pylike_eval(expr, nullptr, 0, &result), EXPR_PYLIKE_INVALID)
unsigned int uint
@ GPU_DATA_FLOAT
@ GPU_RGB32F
@ GPU_RGB16F
@ GPU_FETCH_FLOAT
@ GPU_FETCH_INT_TO_FLOAT_UNIT
@ GPU_FETCH_INT
@ GPU_FETCH_INT_TO_FLOAT
uint GPU_vertformat_attr_add(GPUVertFormat *, const char *name, GPUVertCompType, uint comp_len, GPUVertFetchMode)
void GPU_vertformat_clear(GPUVertFormat *)
@ GPU_COMP_F32
@ GPU_COMP_I32
@ GPU_COMP_U32
@ GPU_COMP_U8
additional_info("compositor_sum_float_shared") .push_constant(Type additional_info("compositor_sum_float_shared") .push_constant(Type GPU_RGBA32F
void VertexFormat_pack(GPUVertFormat *format)
static Vector< int32_t > test_data()
TEST(VulkanDataConversion, clamp_negative_to_zero)
void convert_host_to_device(void *dst_buffer, const void *src_buffer, size_t buffer_size, eGPUDataFormat host_format, eGPUTextureFormat host_texture_format, eGPUTextureFormat device_format)
void convert_device_to_host(void *dst_buffer, const void *src_buffer, size_t buffer_size, eGPUDataFormat host_format, eGPUTextureFormat host_texture_format, eGPUTextureFormat device_format)
uint32_t convert_float_formats(uint32_t value)
blender::VecBase< uint8_t, 3 > uchar3
VecBase< uint32_t, 3 > uint3
blender::VecBase< uint8_t, 4 > uchar4
VecBase< int32_t, 2 > int2
VecBase< float, 2 > float2
VecBase< float, 3 > float3
unsigned int uint32_t
Definition stdint.h:80
unsigned char uint8_t
Definition stdint.h:78
unsigned __int64 uint64_t
Definition stdint.h:90
struct blender::gpu::VKWorkarounds::@146354041006053234141305266010270004245300304124 vertex_formats
void init(const GPUVertFormat *vertex_format, const VKWorkarounds &workarounds)
void convert(void *device_data, const void *src_data, const uint vertex_len) const
uint8_t flag
Definition wm_window.cc:138