Blender V5.0
texture_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 "gpu_testing.hh"
6
7#include "MEM_guardedalloc.h"
8
10
11#include "GPU_context.hh"
12#include "GPU_state.hh"
13#include "GPU_texture.hh"
14#include "GPU_texture_pool.hh"
15
17
18/* Not all texture types are supported by all platforms. This define safe guards them until we have
19 * a working workaround or decided to remove support for those texture types. */
20#define RUN_UNSUPPORTED false
21
22/* Skip tests that haven't been developed yet due to non standard data types or it needs an
23 * frame-buffer to create the texture. */
24#define RUN_SRGB_UNIMPLEMENTED false
25#define RUN_NON_STANDARD_UNIMPLEMENTED false
26#define RUN_COMPONENT_UNIMPLEMENTED false
27
28namespace blender::gpu::tests {
29
30static void test_texture_read()
31{
33
36 "rgba32u", 1, 1, 1, TextureFormat::UINT_32_32_32_32, usage, nullptr);
38 "rgba16u", 1, 1, 1, TextureFormat::UINT_16_16_16_16, usage, nullptr);
40 "rgba32f", 1, 1, 1, TextureFormat::SFLOAT_32_32_32_32, usage, nullptr);
41
42 const float4 fcol = {0.0f, 1.3f, -231.0f, 1000.0f};
43 const uint4 ucol = {0, 1, 2, 12223};
44 GPU_texture_clear(rgba32u, GPU_DATA_UINT, ucol);
45 GPU_texture_clear(rgba16u, GPU_DATA_UINT, ucol);
46 GPU_texture_clear(rgba32f, GPU_DATA_FLOAT, fcol);
47
49
50 uint4 *rgba32u_data = (uint4 *)GPU_texture_read(rgba32u, GPU_DATA_UINT, 0);
51 uint4 *rgba16u_data = (uint4 *)GPU_texture_read(rgba16u, GPU_DATA_UINT, 0);
52 float4 *rgba32f_data = (float4 *)GPU_texture_read(rgba32f, GPU_DATA_FLOAT, 0);
53
54 EXPECT_EQ(ucol, *rgba32u_data);
55 EXPECT_EQ(ucol, *rgba16u_data);
56 EXPECT_EQ(fcol, *rgba32f_data);
57
58 MEM_freeN(rgba32u_data);
59 MEM_freeN(rgba16u_data);
60 MEM_freeN(rgba32f_data);
61
62 GPU_texture_free(rgba32u);
63 GPU_texture_free(rgba16u);
64 GPU_texture_free(rgba32f);
65
67}
68GPU_TEST(texture_read)
69
70static void test_texture_1d()
71{
73 GTEST_SKIP() << "OpenGL texture clearing doesn't support 1d textures.";
74 }
75 const int SIZE = 32;
77
81 "tex", SIZE, 1, TextureFormat::SFLOAT_32_32_32_32, usage, nullptr);
82 float4 clear_color(0.9f, 0.7f, 0.2f, 1.0f);
83 GPU_texture_clear(tex, GPU_DATA_FLOAT, clear_color);
84
86
88 for (int index : IndexRange(SIZE)) {
89 EXPECT_EQ(clear_color, data[index]);
90 }
92
94
96}
97GPU_TEST(texture_1d)
98
100{
102 GTEST_SKIP() << "Read back of 1d texture arrays not supported by OpenGL";
103 }
104 const int LAYERS = 8;
105 const int SIZE = 32;
107
111 "tex", SIZE, LAYERS, 1, TextureFormat::SFLOAT_32_32_32_32, usage, nullptr);
112 float4 clear_color(1.0f, 0.5f, 0.2f, 1.0f);
113 GPU_texture_clear(tex, GPU_DATA_FLOAT, clear_color);
114
116
118 for (int index : IndexRange(SIZE * LAYERS)) {
119 EXPECT_EQ(clear_color, data[index]);
120 }
122
123 GPU_texture_free(tex);
124
126}
127GPU_TEST(texture_1d_array)
128
130{
132 GTEST_SKIP() << "Read back of 1d texture arrays not supported by OpenGL";
133 }
134 const int LAYERS = 8;
135 const int SIZE = 32;
137
138 int total_size = LAYERS * SIZE * 4;
139 float *data_in = MEM_calloc_arrayN<float>(total_size, __func__);
140
143 "tex", SIZE, LAYERS, 1, TextureFormat::SFLOAT_32_32_32_32, usage, data_in);
144
146
147 float *data_out = static_cast<float *>(GPU_texture_read(tex, GPU_DATA_FLOAT, 0));
148 GPU_texture_free(tex);
149
150 EXPECT_EQ(memcmp(data_in, data_out, sizeof(float) * total_size), 0);
151 MEM_freeN(data_in);
152 MEM_freeN(data_out);
153
155}
156GPU_TEST(texture_1d_array_upload)
157
159{
160 const int LAYERS = 8;
161 const int SIZE = 32;
163
166 "tex", SIZE, SIZE, LAYERS, 1, TextureFormat::SFLOAT_32_32_32_32, usage, nullptr);
167 float4 clear_color(1.0f, 0.5f, 0.2f, 1.0f);
168 GPU_texture_clear(tex, GPU_DATA_FLOAT, clear_color);
169
171
173 for (int index : IndexRange(SIZE * SIZE * LAYERS)) {
174 EXPECT_EQ(clear_color, data[index]);
175 }
177
178 GPU_texture_free(tex);
179
181}
182GPU_TEST(texture_2d_array)
183
185{
186 const int LAYERS = 8;
187 const int SIZE = 32;
189
190 int total_size = LAYERS * SIZE * SIZE * 4;
191 float *data_in = MEM_calloc_arrayN<float>(total_size, __func__);
192
195 "tex", SIZE, SIZE, LAYERS, 1, TextureFormat::SFLOAT_32_32_32_32, usage, data_in);
196
198
199 float *data_out = static_cast<float *>(GPU_texture_read(tex, GPU_DATA_FLOAT, 0));
200 GPU_texture_free(tex);
201
202 EXPECT_EQ(memcmp(data_in, data_out, sizeof(float) * total_size), 0);
203 MEM_freeN(data_in);
204 MEM_freeN(data_out);
205
207}
208GPU_TEST(texture_2d_array_upload)
209
210static void test_texture_cube()
211{
212 const int SIZE = 32;
214
217 "tex", SIZE, 1, TextureFormat::SFLOAT_32_32_32_32, usage, nullptr);
218 float4 clear_color(1.0f, 0.5f, 0.2f, 1.0f);
219 GPU_texture_clear(tex, GPU_DATA_FLOAT, clear_color);
220
222
224 for (int index : IndexRange(SIZE * SIZE * 6)) {
225 EXPECT_EQ(clear_color, data[index]);
226 }
228
229 GPU_texture_free(tex);
230
232}
233GPU_TEST(texture_cube)
234
236{
237 const int LAYERS = 2;
238 const int SIZE = 32;
240
243 "tex", SIZE, LAYERS, 1, TextureFormat::SFLOAT_32_32_32_32, usage, nullptr);
244 float4 clear_color(1.0f, 0.5f, 0.2f, 1.0f);
245 GPU_texture_clear(tex, GPU_DATA_FLOAT, clear_color);
246
248 for (int index : IndexRange(SIZE * SIZE * 6 * LAYERS)) {
249 EXPECT_EQ(clear_color, data[index]);
250 }
252
253 GPU_texture_free(tex);
254
256}
257GPU_TEST(texture_cube_array)
258
259static void test_texture_3d()
260{
261 const int SIZE = 32;
263
266 "tex", SIZE, SIZE, SIZE, 1, TextureFormat::SFLOAT_32_32_32_32, usage, nullptr);
267 float4 clear_color(1.0f, 0.5f, 0.2f, 1.0f);
268 GPU_texture_clear(tex, GPU_DATA_FLOAT, clear_color);
269
271
273 for (int index : IndexRange(SIZE * SIZE * SIZE)) {
274 EXPECT_EQ(clear_color, data[index]);
275 }
277
278 GPU_texture_free(tex);
279
281}
282GPU_TEST(texture_3d)
283
284static void test_texture_copy()
285{
286 const int SIZE = 128;
288
291 "src", SIZE, SIZE, 1, TextureFormat::SFLOAT_32_32_32_32, usage, nullptr);
293 "dst", SIZE, SIZE, 1, TextureFormat::SFLOAT_32_32_32_32, usage, nullptr);
294
295 const float4 color(0.0, 1.0f, 2.0f, 123.0f);
296 const float4 clear_color(0.0f);
298 GPU_texture_clear(dst_tx, GPU_DATA_FLOAT, clear_color);
299
300 GPU_texture_copy(dst_tx, src_tx);
301
303
305 for (int index : IndexRange(SIZE * SIZE)) {
306 EXPECT_EQ(color, data[index]);
307 }
309
310 GPU_texture_free(src_tx);
311 GPU_texture_free(dst_tx);
312
314}
315GPU_TEST(texture_copy)
316
317template<typename DataType> static DataType *generate_test_data(size_t data_len)
318{
319 DataType *data = MEM_malloc_arrayN<DataType>(data_len, __func__);
320 for (int i : IndexRange(data_len)) {
321 if (std::is_same<DataType, float>()) {
322 data[i] = (DataType)(i % 8) / 8.0f;
323 }
324 else {
325 data[i] = (DataType)(i % 8);
326 }
327 }
328 return data;
329}
330
331template<TextureFormat DeviceFormat, eGPUDataFormat HostFormat, typename DataType, int Size = 16>
333{
334 static_assert(!std::is_same<DataType, float>());
335 static_assert(validate_data_format(DeviceFormat, HostFormat));
338 "texture", Size, Size, 1, DeviceFormat, usage, nullptr);
339 if (texture == nullptr) {
340 GTEST_SKIP() << "Platform doesn't support texture format [" << STRINGIFY(DeviceFormat) << "]";
341 }
342
343 size_t data_len = Size * Size *
344 (HostFormat == GPU_DATA_10_11_11_REV ? to_bytesize(HostFormat) :
345 to_component_len(DeviceFormat));
346
347 DataType *data = static_cast<DataType *>(generate_test_data<DataType>(data_len));
348 GPU_texture_update(texture, HostFormat, data);
349
350 DataType *read_data = static_cast<DataType *>(GPU_texture_read(texture, HostFormat, 0));
351 bool failed = false;
352 for (int i : IndexRange(data_len)) {
353 EXPECT_EQ(data[i], read_data[i]);
354 bool ok = (read_data[i] - data[i]) == 0;
355 failed |= !ok;
356 }
357 EXPECT_FALSE(failed);
358
359 MEM_freeN(read_data);
361
363}
364
365template<TextureFormat DeviceFormat, eGPUDataFormat HostFormat, int Size = 16>
366static void texture_create_upload_read_with_bias(float max_allowed_bias)
367{
368 static_assert(validate_data_format(DeviceFormat, HostFormat));
371 "texture", Size, Size, 1, DeviceFormat, usage, nullptr);
372 if (texture == nullptr) {
373 GTEST_SKIP() << "Platform doesn't support texture format [" << STRINGIFY(DeviceFormat) << "]";
374 }
375
376 size_t data_len = Size * Size * to_component_len(DeviceFormat);
377 float *data = static_cast<float *>(generate_test_data<float>(data_len));
378 GPU_texture_update(texture, HostFormat, data);
379
380 float *read_data = static_cast<float *>(GPU_texture_read(texture, HostFormat, 0));
381 float max_used_bias = 0.0f;
382 for (int i : IndexRange(data_len)) {
383 float bias = abs(read_data[i] - data[i]);
384 max_used_bias = max_ff(max_used_bias, bias);
385 }
386 EXPECT_LE(max_used_bias, max_allowed_bias);
387
388 MEM_freeN(read_data);
390
392}
393
394/* Derivative of texture_create_upload_read_pixels that doesn't test each component, but a pixel at
395 * a time. This is needed to check the R11G11B10 and similar types. */
396template<TextureFormat DeviceFormat, eGPUDataFormat HostFormat, int Size = 16>
398{
399 using DataType = uint32_t;
400 static_assert(validate_data_format(DeviceFormat, HostFormat));
403 "texture", Size, Size, 1, DeviceFormat, usage, nullptr);
404 ASSERT_NE(texture, nullptr);
405
406 size_t data_len = Size * Size;
407 DataType *data = static_cast<DataType *>(generate_test_data<DataType>(data_len));
408 GPU_texture_update(texture, HostFormat, data);
409
410 DataType *read_data = static_cast<DataType *>(GPU_texture_read(texture, HostFormat, 0));
411 bool failed = false;
412 for (int i : IndexRange(data_len)) {
413 bool ok = (read_data[i] - data[i]) == 0;
414 failed |= !ok;
415 }
416 EXPECT_FALSE(failed);
417
418 MEM_freeN(read_data);
420
422}
423
424/* -------------------------------------------------------------------- */
431GPU_TEST(texture_roundtrip__GPU_DATA_FLOAT__GPU_RGBA8);
432
437GPU_TEST(texture_roundtrip__GPU_DATA_FLOAT__GPU_RGBA16F);
438
443GPU_TEST(texture_roundtrip__GPU_DATA_FLOAT__GPU_RGBA16);
444
449GPU_TEST(texture_roundtrip__GPU_DATA_FLOAT__GPU_RGBA32F);
450
455GPU_TEST(texture_roundtrip__GPU_DATA_FLOAT__GPU_RG8);
456
461GPU_TEST(texture_roundtrip__GPU_DATA_FLOAT__GPU_RG16F);
462
467GPU_TEST(texture_roundtrip__GPU_DATA_FLOAT__GPU_RG16);
468
473GPU_TEST(texture_roundtrip__GPU_DATA_FLOAT__GPU_RG32F);
474
479GPU_TEST(texture_roundtrip__GPU_DATA_FLOAT__GPU_R8);
480
485GPU_TEST(texture_roundtrip__GPU_DATA_FLOAT__GPU_R16F);
486
491GPU_TEST(texture_roundtrip__GPU_DATA_FLOAT__GPU_R16);
492
497GPU_TEST(texture_roundtrip__GPU_DATA_FLOAT__GPU_R32F);
498
499#if RUN_NON_STANDARD_UNIMPLEMENTED
500static void test_texture_roundtrip__GPU_DATA_FLOAT__GPU_RGB10_A2()
501{
503}
504GPU_TEST(texture_roundtrip__GPU_DATA_FLOAT__GPU_RGB10_A2);
505
506static void test_texture_roundtrip__GPU_DATA_FLOAT__GPU_RGB10_A2UI()
507{
509}
510GPU_TEST(texture_roundtrip__GPU_DATA_FLOAT__GPU_RGB10_A2UI);
511#endif
512
517GPU_TEST(texture_roundtrip__GPU_DATA_FLOAT__GPU_R11F_G11F_B10F);
518
523GPU_TEST(texture_roundtrip__GPU_DATA_FLOAT__GPU_SRGB8_A8);
524
529GPU_TEST(texture_roundtrip__GPU_DATA_FLOAT__GPU_RGBA8_SNORM);
530
535GPU_TEST(texture_roundtrip__GPU_DATA_FLOAT__GPU_RGBA16_SNORM);
536
537#if RUN_UNSUPPORTED
538static void test_texture_roundtrip__GPU_DATA_FLOAT__GPU_RGB8()
539{
541}
542GPU_TEST(texture_roundtrip__GPU_DATA_FLOAT__GPU_RGB8);
543
544static void test_texture_roundtrip__GPU_DATA_FLOAT__GPU_RGB8_SNORM()
545{
547}
548GPU_TEST(texture_roundtrip__GPU_DATA_FLOAT__GPU_RGB8_SNORM);
549
550static void test_texture_roundtrip__GPU_DATA_FLOAT__GPU_RGB16F()
551{
553}
554GPU_TEST(texture_roundtrip__GPU_DATA_FLOAT__GPU_RGB16F);
555
556static void test_texture_roundtrip__GPU_DATA_FLOAT__GPU_RGB16()
557{
559}
560GPU_TEST(texture_roundtrip__GPU_DATA_FLOAT__GPU_RGB16);
561static void test_texture_roundtrip__GPU_DATA_FLOAT__GPU_RGB16_SNORM()
562{
564}
565GPU_TEST(texture_roundtrip__GPU_DATA_FLOAT__GPU_RGB16_SNORM);
566
567static void test_texture_roundtrip__GPU_DATA_FLOAT__GPU_RGB32F()
568{
570}
571GPU_TEST(texture_roundtrip__GPU_DATA_FLOAT__GPU_RGB32F);
572#endif
573
578GPU_TEST(texture_roundtrip__GPU_DATA_FLOAT__GPU_RG8_SNORM);
579
584GPU_TEST(texture_roundtrip__GPU_DATA_FLOAT__GPU_RG16_SNORM);
585
590GPU_TEST(texture_roundtrip__GPU_DATA_FLOAT__GPU_R8_SNORM);
591
596GPU_TEST(texture_roundtrip__GPU_DATA_FLOAT__GPU_R16_SNORM);
597
598#if RUN_NON_STANDARD_UNIMPLEMENTED
599static void test_texture_roundtrip__GPU_DATA_FLOAT__GPU_SRGB8_A8_DXT1()
600{
602}
603GPU_TEST(texture_roundtrip__GPU_DATA_FLOAT__GPU_SRGB8_A8_DXT1);
604
605static void test_texture_roundtrip__GPU_DATA_FLOAT__GPU_SRGB8_A8_DXT3()
606{
608}
609GPU_TEST(texture_roundtrip__GPU_DATA_FLOAT__GPU_SRGB8_A8_DXT3);
610
611static void test_texture_roundtrip__GPU_DATA_FLOAT__GPU_SRGB8_A8_DXT5()
612{
614}
615GPU_TEST(texture_roundtrip__GPU_DATA_FLOAT__GPU_SRGB8_A8_DXT5);
616
617static void test_texture_roundtrip__GPU_DATA_FLOAT__GPU_RGBA8_DXT1()
618{
620}
621GPU_TEST(texture_roundtrip__GPU_DATA_FLOAT__GPU_RGBA8_DXT1);
622
623static void test_texture_roundtrip__GPU_DATA_FLOAT__GPU_RGBA8_DXT3()
624{
626}
627GPU_TEST(texture_roundtrip__GPU_DATA_FLOAT__GPU_RGBA8_DXT3);
628
629static void test_texture_roundtrip__GPU_DATA_FLOAT__GPU_RGBA8_DXT5()
630{
632}
633GPU_TEST(texture_roundtrip__GPU_DATA_FLOAT__GPU_RGBA8_DXT5);
634#endif
635
636#if RUN_SRGB_UNIMPLEMENTED
637static void test_texture_roundtrip__GPU_DATA_FLOAT__GPU_SRGB8()
638{
640}
641GPU_TEST(texture_roundtrip__GPU_DATA_FLOAT__GPU_SRGB8);
642#endif
643
644#if RUN_NON_STANDARD_UNIMPLEMENTED
645static void test_texture_roundtrip__GPU_DATA_FLOAT__GPU_RGB9_E5()
646{
648}
649GPU_TEST(texture_roundtrip__GPU_DATA_FLOAT__GPU_RGB9_E5);
650#endif
651
656GPU_TEST(texture_roundtrip__GPU_DATA_FLOAT__GPU_DEPTH_COMPONENT32F);
657
659{
661 GTEST_SKIP() << "Float based texture readback not supported on OpenGL";
662 }
664 0.0f);
665}
666GPU_TEST(texture_roundtrip__GPU_DATA_FLOAT__GPU_DEPTH32F_STENCIL8);
667
668#if RUN_COMPONENT_UNIMPLEMENTED
669static void test_texture_roundtrip__GPU_DATA_FLOAT__GPU_DEPTH_COMPONENT16()
670{
672}
673GPU_TEST(texture_roundtrip__GPU_DATA_FLOAT__GPU_DEPTH_COMPONENT16);
674#endif
675
677
678/* -------------------------------------------------------------------- */
681
686GPU_TEST(texture_roundtrip__GPU_DATA_HALF_FLOAT__GPU_RGBA16F);
687
692GPU_TEST(texture_roundtrip__GPU_DATA_HALF_FLOAT__GPU_RG16F);
693
698GPU_TEST(texture_roundtrip__GPU_DATA_HALF_FLOAT__GPU_R16F);
699
700#if RUN_UNSUPPORTED
701static void test_texture_roundtrip__GPU_DATA_HALF_FLOAT__GPU_RGB16F()
702{
704}
705GPU_TEST(texture_roundtrip__GPU_DATA_HALF_FLOAT__GPU_RGB16F);
706#endif
707
709
710/* -------------------------------------------------------------------- */
713
718GPU_TEST(texture_roundtrip__GPU_DATA_INT__GPU_RGBA8I);
719
724GPU_TEST(texture_roundtrip__GPU_DATA_INT__GPU_RGBA16I);
725
730GPU_TEST(texture_roundtrip__GPU_DATA_INT__GPU_RGBA32I);
731
736GPU_TEST(texture_roundtrip__GPU_DATA_INT__GPU_RG8I);
737
738#if RUN_UNSUPPORTED
739static void test_texture_roundtrip__GPU_DATA_INT__GPU_RG16I()
740{
742}
743GPU_TEST(texture_roundtrip__GPU_DATA_INT__GPU_RG16I);
744#endif
745
750GPU_TEST(texture_roundtrip__GPU_DATA_INT__GPU_RG32I);
751
756GPU_TEST(texture_roundtrip__GPU_DATA_INT__GPU_R8I);
757
762GPU_TEST(texture_roundtrip__GPU_DATA_INT__GPU_R16I);
763
768GPU_TEST(texture_roundtrip__GPU_DATA_INT__GPU_R32I);
769
770#if RUN_UNSUPPORTED
771static void test_texture_roundtrip__GPU_DATA_INT__GPU_RGB8I()
772{
774}
775GPU_TEST(texture_roundtrip__GPU_DATA_INT__GPU_RGB8I);
776
777static void test_texture_roundtrip__GPU_DATA_INT__GPU_RGB16I()
778{
780}
781GPU_TEST(texture_roundtrip__GPU_DATA_INT__GPU_RGB16I);
782
783static void test_texture_roundtrip__GPU_DATA_INT__GPU_RGB32I()
784{
786}
787GPU_TEST(texture_roundtrip__GPU_DATA_INT__GPU_RGB32I);
788#endif
789
791
792/* -------------------------------------------------------------------- */
795
800GPU_TEST(texture_roundtrip__GPU_DATA_UINT__GPU_RGBA8UI);
801
806GPU_TEST(texture_roundtrip__GPU_DATA_UINT__GPU_RGBA16UI);
807
812GPU_TEST(texture_roundtrip__GPU_DATA_UINT__GPU_RGBA32UI);
813
818GPU_TEST(texture_roundtrip__GPU_DATA_UINT__GPU_RG8UI);
819
824GPU_TEST(texture_roundtrip__GPU_DATA_UINT__GPU_RG16UI);
825
830GPU_TEST(texture_roundtrip__GPU_DATA_UINT__GPU_RG32UI);
831
836GPU_TEST(texture_roundtrip__GPU_DATA_UINT__GPU_R8UI);
837
842GPU_TEST(texture_roundtrip__GPU_DATA_UINT__GPU_R16UI);
843
848GPU_TEST(texture_roundtrip__GPU_DATA_UINT__GPU_R32UI);
849
850#if RUN_UNSUPPORTED
851static void test_texture_roundtrip__GPU_DATA_UINT__GPU_DEPTH32F_STENCIL8()
852{
854}
855GPU_TEST(texture_roundtrip__GPU_DATA_UINT__GPU_DEPTH32F_STENCIL8);
856
857static void test_texture_roundtrip__GPU_DATA_UINT__GPU_RGB8UI()
858{
860}
861GPU_TEST(texture_roundtrip__GPU_DATA_UINT__GPU_RGB8UI);
862
863static void test_texture_roundtrip__GPU_DATA_UINT__GPU_RGB16UI()
864{
866}
867GPU_TEST(texture_roundtrip__GPU_DATA_UINT__GPU_RGB16UI);
868
869static void test_texture_roundtrip__GPU_DATA_UINT__GPU_RGB32UI()
870{
872}
873GPU_TEST(texture_roundtrip__GPU_DATA_UINT__GPU_RGB32UI);
874
875static void test_texture_roundtrip__GPU_DATA_UINT__GPU_DEPTH_COMPONENT32F()
876{
878}
879GPU_TEST(texture_roundtrip__GPU_DATA_UINT__GPU_DEPTH_COMPONENT32F);
880#endif
881
882#if RUN_COMPONENT_UNIMPLEMENTED
883static void test_texture_roundtrip__GPU_DATA_UINT__GPU_DEPTH_COMPONENT16()
884{
886}
887GPU_TEST(texture_roundtrip__GPU_DATA_UINT__GPU_DEPTH_COMPONENT16);
888#endif
889
891
892/* -------------------------------------------------------------------- */
895
900GPU_TEST(texture_roundtrip__GPU_DATA_UBYTE__GPU_RGBA8UI);
901
906GPU_TEST(texture_roundtrip__GPU_DATA_UBYTE__GPU_RGBA8);
907
912GPU_TEST(texture_roundtrip__GPU_DATA_UBYTE__GPU_RG8UI);
913
918GPU_TEST(texture_roundtrip__GPU_DATA_UBYTE__GPU_RG8);
919
924GPU_TEST(texture_roundtrip__GPU_DATA_UBYTE__GPU_R8UI);
925
930GPU_TEST(texture_roundtrip__GPU_DATA_UBYTE__GPU_R8);
931
936GPU_TEST(texture_roundtrip__GPU_DATA_UBYTE__GPU_SRGB8_A8);
937
938#if RUN_UNSUPPORTED
939static void test_texture_roundtrip__GPU_DATA_UBYTE__GPU_RGB8I()
940{
942}
943GPU_TEST(texture_roundtrip__GPU_DATA_UBYTE__GPU_RGB8I);
944
945static void test_texture_roundtrip__GPU_DATA_UBYTE__GPU_RGB8()
946{
948}
949GPU_TEST(texture_roundtrip__GPU_DATA_UBYTE__GPU_RGB8);
950
951static void test_texture_roundtrip__GPU_DATA_UBYTE__GPU_SRGB8()
952{
954}
955GPU_TEST(texture_roundtrip__GPU_DATA_UBYTE__GPU_SRGB8);
956#endif
957
959
960/* -------------------------------------------------------------------- */
963
964#if RUN_UNSUPPORTED
965static void test_texture_roundtrip__GPU_DATA_UINT_24_8__GPU_DEPTH32F_STENCIL8()
966{
967 texture_create_upload_read<TextureFormat::SFLOAT_32_DEPTH_UINT_8,
969 void>();
970}
971GPU_TEST(texture_roundtrip__GPU_DATA_UINT_24_8__GPU_DEPTH32F_STENCIL8);
972#endif
973
975
976/* -------------------------------------------------------------------- */
979
984GPU_TEST(texture_roundtrip__GPU_DATA_10_11_11_REV__GPU_R11F_G11F_B10F);
985
987
988/* -------------------------------------------------------------------- */
991
996GPU_TEST(texture_roundtrip__GPU_DATA_2_10_10_10_REV__GPU_RGB10_A2);
997
1005GPU_TEST(texture_roundtrip__GPU_DATA_2_10_10_10_REV__GPU_RGB10_A2UI);
1006
1008
1009/* -------------------------------------------------------------------- */
1012
1014{
1015 const int2 size(1024);
1016 const int2 sub_size(256);
1017 const int2 sub_offset(256);
1018
1020 UNPACK2(size),
1021 2,
1022 TextureFormat::SFLOAT_32_32_32_32,
1024 nullptr);
1025 const float4 clear_color(0.0f, 0.0f, 0.0f, 0.0f);
1027
1028 const float4 texture_color(0.0f, 1.0f, 0.0f, 1.0f);
1029 float4 *texture_data = MEM_malloc_arrayN<float4>(sub_size.x * sub_size.y, __func__);
1030 for (int i = 0; i < sub_size.x * sub_size.y; i++) {
1031 texture_data[i] = texture_color;
1032 }
1033
1035 texture, GPU_DATA_FLOAT, texture_data, UNPACK2(sub_offset), 0, UNPACK2(sub_size), 1);
1036 float4 *texture_data_read = static_cast<float4 *>(GPU_texture_read(texture, GPU_DATA_FLOAT, 0));
1037
1038 for (int x = 0; x < size.x; x++) {
1039 for (int y = 0; y < sub_offset.y; y++) {
1040 int index = x + y * size.x;
1041 ASSERT_EQ(texture_data_read[index], clear_color);
1042 }
1043 }
1044 for (int y = sub_offset.y; y < sub_offset.y + sub_size.y; y++) {
1045 for (int x = 0; x < sub_offset.x; x++) {
1046 int index = x + y * size.x;
1047 ASSERT_EQ(texture_data_read[index], clear_color);
1048 }
1049 for (int x = sub_offset.x; x < sub_offset.x + sub_size.x; x++) {
1050 int index = x + y * size.x;
1051 ASSERT_EQ(texture_data_read[index], texture_color);
1052 }
1053 for (int x = sub_offset.x + sub_size.x; x < size.x; x++) {
1054 int index = x + y * size.x;
1055 ASSERT_EQ(texture_data_read[index], clear_color);
1056 }
1057 }
1058 for (int x = 0; x < size.x; x++) {
1059 for (int y = sub_offset.y + sub_size.y; y < size.y; y++) {
1060 int index = x + y * size.x;
1061 ASSERT_EQ(texture_data_read[index], clear_color);
1062 }
1063 }
1064
1065 MEM_freeN(texture_data);
1066 MEM_freeN(texture_data_read);
1068}
1069GPU_TEST(texture_update_sub_no_unpack_row_length);
1070
1072{
1073 const int2 size(1024);
1074 const int2 sub_size(256);
1075 const int2 sub_offset(256);
1076
1078 UNPACK2(size),
1079 2,
1080 TextureFormat::SFLOAT_32_32_32_32,
1082 nullptr);
1083 const float4 clear_color(0.0f, 0.0f, 0.0f, 0.0f);
1085
1086 const float4 texture_color(0.0f, 1.0f, 0.0f, 1.0f);
1087 const float4 texture_color_off(1.0f, 0.0f, 0.0f, 1.0f);
1088 float4 *texture_data = MEM_malloc_arrayN<float4>(size.x * size.y, __func__);
1089 for (int x = 0; x < size.x; x++) {
1090 for (int y = 0; y < size.y; y++) {
1091 int index = x + y * size.x;
1092 texture_data[index] = ((x >= sub_offset.x && x < sub_offset.x + sub_size.x) &&
1093 (y >= sub_offset.y && y < sub_offset.y + sub_size.y)) ?
1094 texture_color :
1095 texture_color_off;
1096 }
1097 }
1098
1100 float4 *texture_data_offset = &texture_data[sub_offset.x + sub_offset.y * size.x];
1102 texture, GPU_DATA_FLOAT, texture_data_offset, UNPACK2(sub_offset), 0, UNPACK2(sub_size), 1);
1103 float4 *texture_data_read = static_cast<float4 *>(GPU_texture_read(texture, GPU_DATA_FLOAT, 0));
1105
1106 for (int x = 0; x < size.x; x++) {
1107 for (int y = 0; y < sub_offset.y; y++) {
1108 int index = x + y * size.x;
1109 ASSERT_EQ(texture_data_read[index], clear_color);
1110 }
1111 }
1112 for (int y = sub_offset.y; y < sub_offset.y + sub_size.y; y++) {
1113 for (int x = 0; x < sub_offset.x; x++) {
1114 int index = x + y * size.x;
1115 ASSERT_EQ(texture_data_read[index], clear_color);
1116 }
1117 for (int x = sub_offset.x; x < sub_offset.x + sub_size.x; x++) {
1118 int index = x + y * size.x;
1119 ASSERT_EQ(texture_data_read[index], texture_color);
1120 }
1121 for (int x = sub_offset.x + sub_size.x; x < size.x; x++) {
1122 int index = x + y * size.x;
1123 ASSERT_EQ(texture_data_read[index], clear_color);
1124 }
1125 }
1126 for (int x = 0; x < size.x; x++) {
1127 for (int y = sub_offset.y + sub_size.y; y < size.y; y++) {
1128 int index = x + y * size.x;
1129 ASSERT_EQ(texture_data_read[index], clear_color);
1130 }
1131 }
1132
1133 MEM_freeN(texture_data);
1134 MEM_freeN(texture_data_read);
1136}
1137GPU_TEST(texture_update_sub_unpack_row_length);
1138
1140{
1141 const int2 size1(10);
1142 const int2 size2(20);
1143 const int2 size3(30);
1144
1145 TexturePool &pool = TexturePool::get();
1146
1147 TextureFormat format1 = TextureFormat::UNORM_8_8_8_8;
1148 TextureFormat format2 = TextureFormat::SFLOAT_16_16_16_16;
1149 TextureFormat format3 = TextureFormat::SFLOAT_32_32_32_32;
1150
1152
1153 auto test_acquire =
1155 blender::gpu::Texture *tex = pool.acquire_texture(size.x, size.y, format, usage);
1159 return tex;
1160 };
1161
1162 /* Tests multiple acquire. */
1163 blender::gpu::Texture *tex1 = test_acquire(size1, format1, usage);
1164 blender::gpu::Texture *tex2 = test_acquire(size2, format1, usage);
1165 blender::gpu::Texture *tex3 = test_acquire(size3, format2, usage);
1166 blender::gpu::Texture *tex4 = test_acquire(size3, format3, usage);
1167
1168 pool.release_texture(tex1);
1169
1170 /* Tests texture recycling. */
1171 /* Note we don't test if the same texture is reused as this is implementation dependent. */
1172 tex1 = test_acquire(size1, format1, usage);
1173
1174 pool.release_texture(tex1);
1175
1176 /* Tests missing release assert. */
1177 EXPECT_BLI_ASSERT(pool.reset(), "Missing texture release");
1178
1179 pool.release_texture(tex2);
1180 pool.release_texture(tex3);
1181 pool.release_texture(tex4);
1182
1183 /* Expects no assert. */
1184 pool.reset();
1185}
1186GPU_TEST(texture_pool);
1187
1189
1190} // namespace blender::gpu::tests
EXPECT_EQ(BLI_expr_pylike_eval(expr, nullptr, 0, &result), EXPR_PYLIKE_INVALID)
MINLINE float max_ff(float a, float b)
#define UNPACK2(a)
#define STRINGIFY(x)
void GPU_render_end()
void GPU_render_begin()
GPUBackendType GPU_backend_get_type()
@ GPU_BARRIER_TEXTURE_UPDATE
Definition GPU_state.hh:39
void GPU_memory_barrier(GPUBarrier barrier)
Definition gpu_state.cc:326
void GPU_texture_clear(blender::gpu::Texture *texture, eGPUDataFormat data_format, const void *data)
void GPU_texture_update_sub(blender::gpu::Texture *texture, eGPUDataFormat data_format, const void *pixels, int offset_x, int offset_y, int offset_z, int width, int height, int depth)
void GPU_texture_copy(blender::gpu::Texture *dst, blender::gpu::Texture *src)
blender::gpu::Texture * GPU_texture_create_2d_array(const char *name, int width, int height, int layer_len, int mip_len, blender::gpu::TextureFormat format, eGPUTextureUsage usage, const float *data)
int GPU_texture_height(const blender::gpu::Texture *texture)
blender::gpu::Texture * GPU_texture_create_cube(const char *name, int width, int mip_len, blender::gpu::TextureFormat format, eGPUTextureUsage usage, const float *data)
blender::gpu::Texture * GPU_texture_create_1d_array(const char *name, int width, int layer_len, int mip_len, blender::gpu::TextureFormat format, eGPUTextureUsage usage, const float *data)
blender::gpu::TextureFormat GPU_texture_format(const blender::gpu::Texture *texture)
int GPU_texture_width(const blender::gpu::Texture *texture)
@ GPU_DATA_10_11_11_REV
@ GPU_DATA_UINT
@ GPU_DATA_UINT_24_8_DEPRECATED
@ GPU_DATA_FLOAT
blender::gpu::Texture * GPU_texture_create_cube_array(const char *name, int width, int layer_len, int mip_len, blender::gpu::TextureFormat format, eGPUTextureUsage usage, const float *data)
eGPUTextureUsage
@ GPU_TEXTURE_USAGE_SHADER_READ
@ GPU_TEXTURE_USAGE_SHADER_WRITE
@ GPU_TEXTURE_USAGE_HOST_READ
@ GPU_TEXTURE_USAGE_ATTACHMENT
@ GPU_TEXTURE_USAGE_GENERAL
void * GPU_texture_read(blender::gpu::Texture *texture, eGPUDataFormat data_format, int mip_level)
blender::gpu::Texture * GPU_texture_create_2d(const char *name, int width, int height, int mip_len, blender::gpu::TextureFormat format, eGPUTextureUsage usage, const float *data)
void GPU_unpack_row_length_set(uint len)
void GPU_texture_free(blender::gpu::Texture *texture)
blender::gpu::Texture * GPU_texture_create_3d(const char *name, int width, int height, int depth, int mip_len, blender::gpu::TextureFormat format, eGPUTextureUsage usage, const void *data)
blender::gpu::Texture * GPU_texture_create_1d(const char *name, int width, int mip_len, blender::gpu::TextureFormat format, eGPUTextureUsage usage, const float *data)
void GPU_texture_update(blender::gpu::Texture *texture, eGPUDataFormat data_format, const void *data)
Read Guarded memory(de)allocation.
BMesh const char void * data
static DBVT_INLINE btScalar size(const btDbvtVolume &a)
Definition btDbvt.cpp:52
void reset(bool force_free=false)
blender::gpu::Texture * acquire_texture(int width, int height, blender::gpu::TextureFormat format, eGPUTextureUsage usage)
static TexturePool & get()
void release_texture(blender::gpu::Texture *tmp_tex)
#define abs
TEX_TEMPLATE DataVec texture(T, FltCoord, float=0.0f) RET
#define GPU_TEST(test_name)
format
void * MEM_calloc_arrayN(size_t len, size_t size, const char *str)
Definition mallocn.cc:123
void * MEM_malloc_arrayN(size_t len, size_t size, const char *str)
Definition mallocn.cc:133
void MEM_freeN(void *vmemh)
Definition mallocn.cc:113
static void test_texture_roundtrip__GPU_DATA_UBYTE__GPU_R8()
static void test_texture_roundtrip__GPU_DATA_UINT__GPU_R32UI()
static void test_texture_roundtrip__GPU_DATA_INT__GPU_R16I()
static void test_texture_1d()
static void test_texture_1d_array_upload()
static void test_texture_roundtrip__GPU_DATA_INT__GPU_RGBA32I()
static void test_texture_roundtrip__GPU_DATA_UBYTE__GPU_RG8UI()
static void test_texture_cube()
static void test_texture_roundtrip__GPU_DATA_HALF_FLOAT__GPU_RGBA16F()
static void test_texture_3d()
static constexpr int Size
static void test_texture_roundtrip__GPU_DATA_UINT__GPU_RGBA16UI()
static DataType * generate_test_data(size_t data_len)
static void test_texture_roundtrip__GPU_DATA_UINT__GPU_RG8UI()
static void test_texture_roundtrip__GPU_DATA_INT__GPU_RG32I()
static void test_texture_copy()
static void test_texture_roundtrip__GPU_DATA_UBYTE__GPU_R8UI()
static void test_texture_2d_array_upload()
static void test_texture_roundtrip__GPU_DATA_FLOAT__GPU_RGBA16F()
static void test_texture_roundtrip__GPU_DATA_FLOAT__GPU_RGBA32F()
static void test_texture_roundtrip__GPU_DATA_FLOAT__GPU_R32F()
static void test_texture_roundtrip__GPU_DATA_INT__GPU_R8I()
static void texture_create_upload_read_with_bias(float max_allowed_bias)
static void test_texture_roundtrip__GPU_DATA_2_10_10_10_REV__GPU_RGB10_A2UI()
static void test_texture_roundtrip__GPU_DATA_FLOAT__GPU_R16F()
static void test_texture_roundtrip__GPU_DATA_HALF_FLOAT__GPU_R16F()
static void test_texture_update_sub_unpack_row_length()
static void test_texture_roundtrip__GPU_DATA_FLOAT__GPU_R16()
static void test_texture_roundtrip__GPU_DATA_UINT__GPU_RGBA32UI()
static void test_texture_roundtrip__GPU_DATA_10_11_11_REV__GPU_R11F_G11F_B10F()
static void test_texture_roundtrip__GPU_DATA_UBYTE__GPU_RG8()
static void test_texture_roundtrip__GPU_DATA_UINT__GPU_R8UI()
static void test_texture_1d_array()
static void test_texture_update_sub_no_unpack_row_length()
static void test_texture_roundtrip__GPU_DATA_FLOAT__GPU_R16_SNORM()
static void test_texture_roundtrip__GPU_DATA_FLOAT__GPU_DEPTH_COMPONENT32F()
static void test_texture_roundtrip__GPU_DATA_FLOAT__GPU_RG16_SNORM()
static void test_texture_read()
static void test_texture_roundtrip__GPU_DATA_UINT__GPU_R16UI()
static void test_texture_roundtrip__GPU_DATA_FLOAT__GPU_R11F_G11F_B10F()
static void test_texture_roundtrip__GPU_DATA_FLOAT__GPU_RGBA8_SNORM()
static void test_texture_roundtrip__GPU_DATA_FLOAT__GPU_RGBA16()
static void test_texture_roundtrip__GPU_DATA_FLOAT__GPU_DEPTH32F_STENCIL8()
static void test_texture_roundtrip__GPU_DATA_INT__GPU_RGBA8I()
static void test_texture_2d_array()
static void test_texture_roundtrip__GPU_DATA_FLOAT__GPU_RG32F()
static void test_texture_cube_array()
static void test_texture_roundtrip__GPU_DATA_FLOAT__GPU_RG16()
static void test_texture_roundtrip__GPU_DATA_UINT__GPU_RGBA8UI()
static void texture_create_upload_read_pixel()
static void test_texture_roundtrip__GPU_DATA_INT__GPU_R32I()
static void test_texture_roundtrip__GPU_DATA_FLOAT__GPU_SRGB8_A8()
static void test_texture_roundtrip__GPU_DATA_FLOAT__GPU_RGBA8()
static void test_texture_roundtrip__GPU_DATA_UBYTE__GPU_RGBA8UI()
static void test_texture_roundtrip__GPU_DATA_INT__GPU_RG8I()
static void texture_create_upload_read()
static void test_texture_roundtrip__GPU_DATA_UINT__GPU_RG16UI()
static void test_texture_roundtrip__GPU_DATA_FLOAT__GPU_RG16F()
static void test_texture_roundtrip__GPU_DATA_UBYTE__GPU_SRGB8_A8()
static void test_texture_roundtrip__GPU_DATA_2_10_10_10_REV__GPU_RGB10_A2()
static void test_texture_pool()
static void test_texture_roundtrip__GPU_DATA_FLOAT__GPU_R8()
static void test_texture_roundtrip__GPU_DATA_UBYTE__GPU_RGBA8()
static void test_texture_roundtrip__GPU_DATA_FLOAT__GPU_RG8_SNORM()
static void test_texture_roundtrip__GPU_DATA_HALF_FLOAT__GPU_RG16F()
static void test_texture_roundtrip__GPU_DATA_FLOAT__GPU_RG8()
static void test_texture_roundtrip__GPU_DATA_INT__GPU_RGBA16I()
static void test_texture_roundtrip__GPU_DATA_FLOAT__GPU_R8_SNORM()
static void test_texture_roundtrip__GPU_DATA_FLOAT__GPU_RGBA16_SNORM()
static void test_texture_roundtrip__GPU_DATA_UINT__GPU_RG32UI()
int to_bytesize(const DataFormat format)
int to_component_len(TextureFormat format)
constexpr bool validate_data_format(TextureFormat tex_format, eGPUDataFormat data_format)
VecBase< uint32_t, 4 > uint4
VecBase< float, 4 > float4
VecBase< int32_t, 2 > int2
i
Definition text_draw.cc:230