Blender V4.5
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
35 GPUTexture *rgba32u = GPU_texture_create_2d("rgba32u", 1, 1, 1, GPU_RGBA32UI, usage, nullptr);
36 GPUTexture *rgba16u = GPU_texture_create_2d("rgba16u", 1, 1, 1, GPU_RGBA16UI, usage, nullptr);
37 GPUTexture *rgba32f = GPU_texture_create_2d("rgba32f", 1, 1, 1, GPU_RGBA32F, usage, nullptr);
38
39 const float4 fcol = {0.0f, 1.3f, -231.0f, 1000.0f};
40 const uint4 ucol = {0, 1, 2, 12223};
41 GPU_texture_clear(rgba32u, GPU_DATA_UINT, ucol);
42 GPU_texture_clear(rgba16u, GPU_DATA_UINT, ucol);
43 GPU_texture_clear(rgba32f, GPU_DATA_FLOAT, fcol);
44
46
47 uint4 *rgba32u_data = (uint4 *)GPU_texture_read(rgba32u, GPU_DATA_UINT, 0);
48 uint4 *rgba16u_data = (uint4 *)GPU_texture_read(rgba16u, GPU_DATA_UINT, 0);
49 float4 *rgba32f_data = (float4 *)GPU_texture_read(rgba32f, GPU_DATA_FLOAT, 0);
50
51 EXPECT_EQ(ucol, *rgba32u_data);
52 EXPECT_EQ(ucol, *rgba16u_data);
53 EXPECT_EQ(fcol, *rgba32f_data);
54
55 MEM_freeN(rgba32u_data);
56 MEM_freeN(rgba16u_data);
57 MEM_freeN(rgba32f_data);
58
59 GPU_texture_free(rgba32u);
60 GPU_texture_free(rgba16u);
61 GPU_texture_free(rgba32f);
62
64}
65GPU_TEST(texture_read)
66
67static void test_texture_1d()
68{
70 GTEST_SKIP() << "OpenGL texture clearing doesn't support 1d textures.";
71 }
72 const int SIZE = 32;
74
77 GPUTexture *tex = GPU_texture_create_1d("tex", SIZE, 1, GPU_RGBA32F, usage, nullptr);
78 float4 clear_color(0.9f, 0.7f, 0.2f, 1.0f);
79 GPU_texture_clear(tex, GPU_DATA_FLOAT, clear_color);
80
82
84 for (int index : IndexRange(SIZE)) {
85 EXPECT_EQ(clear_color, data[index]);
86 }
88
90
92}
93GPU_TEST(texture_1d)
94
96{
98 GTEST_SKIP() << "Read back of 1d texture arrays not supported by OpenGL";
99 }
100 const int LAYERS = 8;
101 const int SIZE = 32;
103
106 GPUTexture *tex = GPU_texture_create_1d_array(
107 "tex", SIZE, LAYERS, 1, GPU_RGBA32F, usage, nullptr);
108 float4 clear_color(1.0f, 0.5f, 0.2f, 1.0f);
109 GPU_texture_clear(tex, GPU_DATA_FLOAT, clear_color);
110
112
114 for (int index : IndexRange(SIZE * LAYERS)) {
115 EXPECT_EQ(clear_color, data[index]);
116 }
118
119 GPU_texture_free(tex);
120
122}
123GPU_TEST(texture_1d_array)
124
126{
128 GTEST_SKIP() << "Read back of 1d texture arrays not supported by OpenGL";
129 }
130 const int LAYERS = 8;
131 const int SIZE = 32;
133
134 int total_size = LAYERS * SIZE * 4;
135 float *data_in = MEM_calloc_arrayN<float>(total_size, __func__);
136
138 GPUTexture *tex = GPU_texture_create_1d_array(
139 "tex", SIZE, LAYERS, 1, GPU_RGBA32F, usage, data_in);
140
142
143 float *data_out = static_cast<float *>(GPU_texture_read(tex, GPU_DATA_FLOAT, 0));
144 GPU_texture_free(tex);
145
146 EXPECT_EQ(memcmp(data_in, data_out, sizeof(float) * total_size), 0);
147 MEM_freeN(data_in);
148 MEM_freeN(data_out);
149
151}
152GPU_TEST(texture_1d_array_upload)
153
155{
156 const int LAYERS = 8;
157 const int SIZE = 32;
159
161 GPUTexture *tex = GPU_texture_create_2d_array(
162 "tex", SIZE, SIZE, LAYERS, 1, GPU_RGBA32F, usage, nullptr);
163 float4 clear_color(1.0f, 0.5f, 0.2f, 1.0f);
164 GPU_texture_clear(tex, GPU_DATA_FLOAT, clear_color);
165
167
169 for (int index : IndexRange(SIZE * SIZE * LAYERS)) {
170 EXPECT_EQ(clear_color, data[index]);
171 }
173
174 GPU_texture_free(tex);
175
177}
178GPU_TEST(texture_2d_array)
179
181{
182 const int LAYERS = 8;
183 const int SIZE = 32;
185
186 int total_size = LAYERS * SIZE * SIZE * 4;
187 float *data_in = MEM_calloc_arrayN<float>(total_size, __func__);
188
190 GPUTexture *tex = GPU_texture_create_2d_array(
191 "tex", SIZE, SIZE, LAYERS, 1, GPU_RGBA32F, usage, data_in);
192
194
195 float *data_out = static_cast<float *>(GPU_texture_read(tex, GPU_DATA_FLOAT, 0));
196 GPU_texture_free(tex);
197
198 EXPECT_EQ(memcmp(data_in, data_out, sizeof(float) * total_size), 0);
199 MEM_freeN(data_in);
200 MEM_freeN(data_out);
201
203}
204GPU_TEST(texture_2d_array_upload)
205
206static void test_texture_cube()
207{
208 const int SIZE = 32;
210
212 GPUTexture *tex = GPU_texture_create_cube("tex", SIZE, 1, GPU_RGBA32F, usage, nullptr);
213 float4 clear_color(1.0f, 0.5f, 0.2f, 1.0f);
214 GPU_texture_clear(tex, GPU_DATA_FLOAT, clear_color);
215
217
219 for (int index : IndexRange(SIZE * SIZE * 6)) {
220 EXPECT_EQ(clear_color, data[index]);
221 }
223
224 GPU_texture_free(tex);
225
227}
228GPU_TEST(texture_cube)
229
231{
232 const int LAYERS = 2;
233 const int SIZE = 32;
235
237 GPUTexture *tex = GPU_texture_create_cube_array(
238 "tex", SIZE, LAYERS, 1, GPU_RGBA32F, usage, nullptr);
239 float4 clear_color(1.0f, 0.5f, 0.2f, 1.0f);
240 GPU_texture_clear(tex, GPU_DATA_FLOAT, clear_color);
241
243 for (int index : IndexRange(SIZE * SIZE * 6 * LAYERS)) {
244 EXPECT_EQ(clear_color, data[index]);
245 }
247
248 GPU_texture_free(tex);
249
251}
252GPU_TEST(texture_cube_array)
253
254static void test_texture_3d()
255{
256 const int SIZE = 32;
258
260 GPUTexture *tex = GPU_texture_create_3d("tex", SIZE, SIZE, SIZE, 1, GPU_RGBA32F, usage, nullptr);
261 float4 clear_color(1.0f, 0.5f, 0.2f, 1.0f);
262 GPU_texture_clear(tex, GPU_DATA_FLOAT, clear_color);
263
265
267 for (int index : IndexRange(SIZE * SIZE * SIZE)) {
268 EXPECT_EQ(clear_color, data[index]);
269 }
271
272 GPU_texture_free(tex);
273
275}
276GPU_TEST(texture_3d)
277
278static void test_texture_copy()
279{
280 const int SIZE = 128;
282
284 GPUTexture *src_tx = GPU_texture_create_2d("src", SIZE, SIZE, 1, GPU_RGBA32F, usage, nullptr);
285 GPUTexture *dst_tx = GPU_texture_create_2d("dst", SIZE, SIZE, 1, GPU_RGBA32F, usage, nullptr);
286
287 const float4 color(0.0, 1.0f, 2.0f, 123.0f);
288 const float4 clear_color(0.0f);
290 GPU_texture_clear(dst_tx, GPU_DATA_FLOAT, clear_color);
291
292 GPU_texture_copy(dst_tx, src_tx);
293
295
297 for (int index : IndexRange(SIZE * SIZE)) {
298 EXPECT_EQ(color, data[index]);
299 }
301
302 GPU_texture_free(src_tx);
303 GPU_texture_free(dst_tx);
304
306}
307GPU_TEST(texture_copy)
308
309template<typename DataType> static DataType *generate_test_data(size_t data_len)
310{
311 DataType *data = MEM_malloc_arrayN<DataType>(data_len, __func__);
312 for (int i : IndexRange(data_len)) {
313 if (std::is_same<DataType, float>()) {
314 data[i] = (DataType)(i % 8) / 8.0f;
315 }
316 else {
317 data[i] = (DataType)(i % 8);
318 }
319 }
320 return data;
321}
322
323template<eGPUTextureFormat DeviceFormat,
324 eGPUDataFormat HostFormat,
325 typename DataType,
326 int Size = 16>
328{
329 static_assert(!std::is_same<DataType, float>());
330 static_assert(validate_data_format(DeviceFormat, HostFormat));
332 GPUTexture *texture = GPU_texture_create_2d(
333 "texture", Size, Size, 1, DeviceFormat, usage, nullptr);
334 if (texture == nullptr) {
335 GTEST_SKIP() << "Platform doesn't support texture format [" << STRINGIFY(DeviceFormat) << "]";
336 }
337
338 size_t data_len = Size * Size *
339 (HostFormat == GPU_DATA_10_11_11_REV ? to_bytesize(HostFormat) :
340 to_component_len(DeviceFormat));
341
342 DataType *data = static_cast<DataType *>(generate_test_data<DataType>(data_len));
343 GPU_texture_update(texture, HostFormat, data);
344
345 DataType *read_data = static_cast<DataType *>(GPU_texture_read(texture, HostFormat, 0));
346 bool failed = false;
347 for (int i : IndexRange(data_len)) {
348 EXPECT_EQ(data[i], read_data[i]);
349 bool ok = (read_data[i] - data[i]) == 0;
350 failed |= !ok;
351 }
352 EXPECT_FALSE(failed);
353
354 MEM_freeN(read_data);
356
358}
359
360template<eGPUTextureFormat DeviceFormat, eGPUDataFormat HostFormat, int Size = 16>
361static void texture_create_upload_read_with_bias(float max_allowed_bias)
362{
363 static_assert(validate_data_format(DeviceFormat, HostFormat));
365 GPUTexture *texture = GPU_texture_create_2d(
366 "texture", Size, Size, 1, DeviceFormat, usage, nullptr);
367 if (texture == nullptr) {
368 GTEST_SKIP() << "Platform doesn't support texture format [" << STRINGIFY(DeviceFormat) << "]";
369 }
370
371 size_t data_len = Size * Size * to_component_len(DeviceFormat);
372 float *data = static_cast<float *>(generate_test_data<float>(data_len));
373 GPU_texture_update(texture, HostFormat, data);
374
375 float *read_data = static_cast<float *>(GPU_texture_read(texture, HostFormat, 0));
376 float max_used_bias = 0.0f;
377 for (int i : IndexRange(data_len)) {
378 float bias = abs(read_data[i] - data[i]);
379 max_used_bias = max_ff(max_used_bias, bias);
380 }
381 EXPECT_LE(max_used_bias, max_allowed_bias);
382
383 MEM_freeN(read_data);
385
387}
388
389/* Derivative of texture_create_upload_read_pixels that doesn't test each component, but a pixel at
390 * a time. This is needed to check the R11G11B10 and similar types. */
391template<eGPUTextureFormat DeviceFormat, eGPUDataFormat HostFormat, int Size = 16>
393{
394 using DataType = uint32_t;
395 static_assert(validate_data_format(DeviceFormat, HostFormat));
397 GPUTexture *texture = GPU_texture_create_2d(
398 "texture", Size, Size, 1, DeviceFormat, usage, nullptr);
399 ASSERT_NE(texture, nullptr);
400
401 size_t data_len = Size * Size;
402 DataType *data = static_cast<DataType *>(generate_test_data<DataType>(data_len));
403 GPU_texture_update(texture, HostFormat, data);
404
405 DataType *read_data = static_cast<DataType *>(GPU_texture_read(texture, HostFormat, 0));
406 bool failed = false;
407 for (int i : IndexRange(data_len)) {
408 bool ok = (read_data[i] - data[i]) == 0;
409 failed |= !ok;
410 }
411 EXPECT_FALSE(failed);
412
413 MEM_freeN(read_data);
415
417}
418
419/* -------------------------------------------------------------------- */
426GPU_TEST(texture_roundtrip__GPU_DATA_FLOAT__GPU_RGBA8);
427
432GPU_TEST(texture_roundtrip__GPU_DATA_FLOAT__GPU_RGBA16F);
433
438GPU_TEST(texture_roundtrip__GPU_DATA_FLOAT__GPU_RGBA16);
439
444GPU_TEST(texture_roundtrip__GPU_DATA_FLOAT__GPU_RGBA32F);
445
450GPU_TEST(texture_roundtrip__GPU_DATA_FLOAT__GPU_RG8);
451
456GPU_TEST(texture_roundtrip__GPU_DATA_FLOAT__GPU_RG16F);
457
462GPU_TEST(texture_roundtrip__GPU_DATA_FLOAT__GPU_RG16);
463
468GPU_TEST(texture_roundtrip__GPU_DATA_FLOAT__GPU_RG32F);
469
474GPU_TEST(texture_roundtrip__GPU_DATA_FLOAT__GPU_R8);
475
480GPU_TEST(texture_roundtrip__GPU_DATA_FLOAT__GPU_R16F);
481
486GPU_TEST(texture_roundtrip__GPU_DATA_FLOAT__GPU_R16);
487
492GPU_TEST(texture_roundtrip__GPU_DATA_FLOAT__GPU_R32F);
493
494#if RUN_NON_STANDARD_UNIMPLEMENTED
495static void test_texture_roundtrip__GPU_DATA_FLOAT__GPU_RGB10_A2()
496{
498}
499GPU_TEST(texture_roundtrip__GPU_DATA_FLOAT__GPU_RGB10_A2);
500
501static void test_texture_roundtrip__GPU_DATA_FLOAT__GPU_RGB10_A2UI()
502{
504}
505GPU_TEST(texture_roundtrip__GPU_DATA_FLOAT__GPU_RGB10_A2UI);
506#endif
507
512GPU_TEST(texture_roundtrip__GPU_DATA_FLOAT__GPU_R11F_G11F_B10F);
513
518GPU_TEST(texture_roundtrip__GPU_DATA_FLOAT__GPU_SRGB8_A8);
519
524GPU_TEST(texture_roundtrip__GPU_DATA_FLOAT__GPU_RGBA8_SNORM);
525
530GPU_TEST(texture_roundtrip__GPU_DATA_FLOAT__GPU_RGBA16_SNORM);
531
532#if RUN_UNSUPPORTED
533static void test_texture_roundtrip__GPU_DATA_FLOAT__GPU_RGB8()
534{
536}
537GPU_TEST(texture_roundtrip__GPU_DATA_FLOAT__GPU_RGB8);
538
539static void test_texture_roundtrip__GPU_DATA_FLOAT__GPU_RGB8_SNORM()
540{
542}
543GPU_TEST(texture_roundtrip__GPU_DATA_FLOAT__GPU_RGB8_SNORM);
544
545static void test_texture_roundtrip__GPU_DATA_FLOAT__GPU_RGB16F()
546{
548}
549GPU_TEST(texture_roundtrip__GPU_DATA_FLOAT__GPU_RGB16F);
550
551static void test_texture_roundtrip__GPU_DATA_FLOAT__GPU_RGB16()
552{
554}
555GPU_TEST(texture_roundtrip__GPU_DATA_FLOAT__GPU_RGB16);
556static void test_texture_roundtrip__GPU_DATA_FLOAT__GPU_RGB16_SNORM()
557{
559}
560GPU_TEST(texture_roundtrip__GPU_DATA_FLOAT__GPU_RGB16_SNORM);
561
562static void test_texture_roundtrip__GPU_DATA_FLOAT__GPU_RGB32F()
563{
565}
566GPU_TEST(texture_roundtrip__GPU_DATA_FLOAT__GPU_RGB32F);
567#endif
568
573GPU_TEST(texture_roundtrip__GPU_DATA_FLOAT__GPU_RG8_SNORM);
574
579GPU_TEST(texture_roundtrip__GPU_DATA_FLOAT__GPU_RG16_SNORM);
580
585GPU_TEST(texture_roundtrip__GPU_DATA_FLOAT__GPU_R8_SNORM);
586
591GPU_TEST(texture_roundtrip__GPU_DATA_FLOAT__GPU_R16_SNORM);
592
593#if RUN_NON_STANDARD_UNIMPLEMENTED
594static void test_texture_roundtrip__GPU_DATA_FLOAT__GPU_SRGB8_A8_DXT1()
595{
597}
598GPU_TEST(texture_roundtrip__GPU_DATA_FLOAT__GPU_SRGB8_A8_DXT1);
599
600static void test_texture_roundtrip__GPU_DATA_FLOAT__GPU_SRGB8_A8_DXT3()
601{
603}
604GPU_TEST(texture_roundtrip__GPU_DATA_FLOAT__GPU_SRGB8_A8_DXT3);
605
606static void test_texture_roundtrip__GPU_DATA_FLOAT__GPU_SRGB8_A8_DXT5()
607{
609}
610GPU_TEST(texture_roundtrip__GPU_DATA_FLOAT__GPU_SRGB8_A8_DXT5);
611
612static void test_texture_roundtrip__GPU_DATA_FLOAT__GPU_RGBA8_DXT1()
613{
615}
616GPU_TEST(texture_roundtrip__GPU_DATA_FLOAT__GPU_RGBA8_DXT1);
617
618static void test_texture_roundtrip__GPU_DATA_FLOAT__GPU_RGBA8_DXT3()
619{
621}
622GPU_TEST(texture_roundtrip__GPU_DATA_FLOAT__GPU_RGBA8_DXT3);
623
624static void test_texture_roundtrip__GPU_DATA_FLOAT__GPU_RGBA8_DXT5()
625{
627}
628GPU_TEST(texture_roundtrip__GPU_DATA_FLOAT__GPU_RGBA8_DXT5);
629#endif
630
631#if RUN_SRGB_UNIMPLEMENTED
632static void test_texture_roundtrip__GPU_DATA_FLOAT__GPU_SRGB8()
633{
635}
636GPU_TEST(texture_roundtrip__GPU_DATA_FLOAT__GPU_SRGB8);
637#endif
638
639#if RUN_NON_STANDARD_UNIMPLEMENTED
640static void test_texture_roundtrip__GPU_DATA_FLOAT__GPU_RGB9_E5()
641{
643}
644GPU_TEST(texture_roundtrip__GPU_DATA_FLOAT__GPU_RGB9_E5);
645#endif
646
651GPU_TEST(texture_roundtrip__GPU_DATA_FLOAT__GPU_DEPTH_COMPONENT32F);
652
657GPU_TEST(texture_roundtrip__GPU_DATA_FLOAT__GPU_DEPTH_COMPONENT24);
658
660{
662 GTEST_SKIP() << "Float based texture readback not supported on OpenGL";
663 }
665}
666GPU_TEST(texture_roundtrip__GPU_DATA_FLOAT__GPU_DEPTH24_STENCIL8);
667
669{
671 GTEST_SKIP() << "Float based texture readback not supported on OpenGL";
672 }
674}
675GPU_TEST(texture_roundtrip__GPU_DATA_FLOAT__GPU_DEPTH32F_STENCIL8);
676
677#if RUN_COMPONENT_UNIMPLEMENTED
678static void test_texture_roundtrip__GPU_DATA_FLOAT__GPU_DEPTH_COMPONENT16()
679{
681}
682GPU_TEST(texture_roundtrip__GPU_DATA_FLOAT__GPU_DEPTH_COMPONENT16);
683#endif
684
685/* \} */
686
687/* -------------------------------------------------------------------- */
690
695GPU_TEST(texture_roundtrip__GPU_DATA_HALF_FLOAT__GPU_RGBA16F);
696
701GPU_TEST(texture_roundtrip__GPU_DATA_HALF_FLOAT__GPU_RG16F);
702
707GPU_TEST(texture_roundtrip__GPU_DATA_HALF_FLOAT__GPU_R16F);
708
709#if RUN_UNSUPPORTED
710static void test_texture_roundtrip__GPU_DATA_HALF_FLOAT__GPU_RGB16F()
711{
713}
714GPU_TEST(texture_roundtrip__GPU_DATA_HALF_FLOAT__GPU_RGB16F);
715#endif
716
717/* \} */
718
719/* -------------------------------------------------------------------- */
722
727GPU_TEST(texture_roundtrip__GPU_DATA_INT__GPU_RGBA8I);
728
733GPU_TEST(texture_roundtrip__GPU_DATA_INT__GPU_RGBA16I);
734
739GPU_TEST(texture_roundtrip__GPU_DATA_INT__GPU_RGBA32I);
740
745GPU_TEST(texture_roundtrip__GPU_DATA_INT__GPU_RG8I);
746
747#if RUN_UNSUPPORTED
748static void test_texture_roundtrip__GPU_DATA_INT__GPU_RG16I()
749{
751}
752GPU_TEST(texture_roundtrip__GPU_DATA_INT__GPU_RG16I);
753#endif
754
759GPU_TEST(texture_roundtrip__GPU_DATA_INT__GPU_RG32I);
760
765GPU_TEST(texture_roundtrip__GPU_DATA_INT__GPU_R8I);
766
771GPU_TEST(texture_roundtrip__GPU_DATA_INT__GPU_R16I);
772
777GPU_TEST(texture_roundtrip__GPU_DATA_INT__GPU_R32I);
778
779#if RUN_UNSUPPORTED
780static void test_texture_roundtrip__GPU_DATA_INT__GPU_RGB8I()
781{
783}
784GPU_TEST(texture_roundtrip__GPU_DATA_INT__GPU_RGB8I);
785
786static void test_texture_roundtrip__GPU_DATA_INT__GPU_RGB16I()
787{
789}
790GPU_TEST(texture_roundtrip__GPU_DATA_INT__GPU_RGB16I);
791
792static void test_texture_roundtrip__GPU_DATA_INT__GPU_RGB32I()
793{
795}
796GPU_TEST(texture_roundtrip__GPU_DATA_INT__GPU_RGB32I);
797#endif
798
799/* \} */
800
801/* -------------------------------------------------------------------- */
804
809GPU_TEST(texture_roundtrip__GPU_DATA_UINT__GPU_RGBA8UI);
810
815GPU_TEST(texture_roundtrip__GPU_DATA_UINT__GPU_RGBA16UI);
816
821GPU_TEST(texture_roundtrip__GPU_DATA_UINT__GPU_RGBA32UI);
822
827GPU_TEST(texture_roundtrip__GPU_DATA_UINT__GPU_RG8UI);
828
833GPU_TEST(texture_roundtrip__GPU_DATA_UINT__GPU_RG16UI);
834
839GPU_TEST(texture_roundtrip__GPU_DATA_UINT__GPU_RG32UI);
840
845GPU_TEST(texture_roundtrip__GPU_DATA_UINT__GPU_R8UI);
846
851GPU_TEST(texture_roundtrip__GPU_DATA_UINT__GPU_R16UI);
852
857GPU_TEST(texture_roundtrip__GPU_DATA_UINT__GPU_R32UI);
858
859#if RUN_UNSUPPORTED
860static void test_texture_roundtrip__GPU_DATA_UINT__GPU_DEPTH32F_STENCIL8()
861{
863}
864GPU_TEST(texture_roundtrip__GPU_DATA_UINT__GPU_DEPTH32F_STENCIL8);
865
866static void test_texture_roundtrip__GPU_DATA_UINT__GPU_DEPTH24_STENCIL8()
867{
869}
870GPU_TEST(texture_roundtrip__GPU_DATA_UINT__GPU_DEPTH24_STENCIL8);
871
872static void test_texture_roundtrip__GPU_DATA_UINT__GPU_RGB8UI()
873{
875}
876GPU_TEST(texture_roundtrip__GPU_DATA_UINT__GPU_RGB8UI);
877
878static void test_texture_roundtrip__GPU_DATA_UINT__GPU_RGB16UI()
879{
881}
882GPU_TEST(texture_roundtrip__GPU_DATA_UINT__GPU_RGB16UI);
883
884static void test_texture_roundtrip__GPU_DATA_UINT__GPU_RGB32UI()
885{
887}
888GPU_TEST(texture_roundtrip__GPU_DATA_UINT__GPU_RGB32UI);
889
890static void test_texture_roundtrip__GPU_DATA_UINT__GPU_DEPTH_COMPONENT32F()
891{
893}
894GPU_TEST(texture_roundtrip__GPU_DATA_UINT__GPU_DEPTH_COMPONENT32F);
895
896static void test_texture_roundtrip__GPU_DATA_UINT__GPU_DEPTH_COMPONENT24()
897{
899}
900GPU_TEST(texture_roundtrip__GPU_DATA_UINT__GPU_DEPTH_COMPONENT24);
901#endif
902
903#if RUN_COMPONENT_UNIMPLEMENTED
904static void test_texture_roundtrip__GPU_DATA_UINT__GPU_DEPTH_COMPONENT16()
905{
907}
908GPU_TEST(texture_roundtrip__GPU_DATA_UINT__GPU_DEPTH_COMPONENT16);
909#endif
910
911/* \} */
912
913/* -------------------------------------------------------------------- */
916
921GPU_TEST(texture_roundtrip__GPU_DATA_UBYTE__GPU_RGBA8UI);
922
927GPU_TEST(texture_roundtrip__GPU_DATA_UBYTE__GPU_RGBA8);
928
933GPU_TEST(texture_roundtrip__GPU_DATA_UBYTE__GPU_RG8UI);
934
939GPU_TEST(texture_roundtrip__GPU_DATA_UBYTE__GPU_RG8);
940
945GPU_TEST(texture_roundtrip__GPU_DATA_UBYTE__GPU_R8UI);
946
951GPU_TEST(texture_roundtrip__GPU_DATA_UBYTE__GPU_R8);
952
957GPU_TEST(texture_roundtrip__GPU_DATA_UBYTE__GPU_SRGB8_A8);
958
959#if RUN_UNSUPPORTED
960static void test_texture_roundtrip__GPU_DATA_UBYTE__GPU_RGB8I()
961{
963}
964GPU_TEST(texture_roundtrip__GPU_DATA_UBYTE__GPU_RGB8I);
965
966static void test_texture_roundtrip__GPU_DATA_UBYTE__GPU_RGB8()
967{
969}
970GPU_TEST(texture_roundtrip__GPU_DATA_UBYTE__GPU_RGB8);
971
972static void test_texture_roundtrip__GPU_DATA_UBYTE__GPU_SRGB8()
973{
975}
976GPU_TEST(texture_roundtrip__GPU_DATA_UBYTE__GPU_SRGB8);
977#endif
978/* \} */
979
980/* -------------------------------------------------------------------- */
983
984#if RUN_UNSUPPORTED
985static void test_texture_roundtrip__GPU_DATA_UINT_24_8__GPU_DEPTH32F_STENCIL8()
986{
988}
989GPU_TEST(texture_roundtrip__GPU_DATA_UINT_24_8__GPU_DEPTH32F_STENCIL8);
990
991static void test_texture_roundtrip__GPU_DATA_UINT_24_8__GPU_DEPTH24_STENCIL8()
992{
994}
995GPU_TEST(texture_roundtrip__GPU_DATA_UINT_24_8__GPU_DEPTH24_STENCIL8);
996#endif
997
998/* \} */
999
1000/* -------------------------------------------------------------------- */
1003
1008GPU_TEST(texture_roundtrip__GPU_DATA_10_11_11_REV__GPU_R11F_G11F_B10F);
1009
1010/* \} */
1011
1012/* -------------------------------------------------------------------- */
1015
1020GPU_TEST(texture_roundtrip__GPU_DATA_2_10_10_10_REV__GPU_RGB10_A2);
1021
1023{
1025 GTEST_SKIP() << "Texture readback not supported on OpenGL";
1026 }
1028}
1029GPU_TEST(texture_roundtrip__GPU_DATA_2_10_10_10_REV__GPU_RGB10_A2UI);
1030
1031/* \} */
1032
1033/* -------------------------------------------------------------------- */
1036
1038{
1039 const int2 size(1024);
1040 const int2 sub_size(256);
1041 const int2 sub_offset(256);
1042
1043 GPUTexture *texture = GPU_texture_create_2d(
1044 __func__, UNPACK2(size), 2, GPU_RGBA32F, GPU_TEXTURE_USAGE_GENERAL, nullptr);
1045 const float4 clear_color(0.0f, 0.0f, 0.0f, 0.0f);
1047
1048 const float4 texture_color(0.0f, 1.0f, 0.0f, 1.0f);
1049 float4 *texture_data = MEM_malloc_arrayN<float4>(sub_size.x * sub_size.y, __func__);
1050 for (int i = 0; i < sub_size.x * sub_size.y; i++) {
1051 texture_data[i] = texture_color;
1052 }
1053
1055 texture, GPU_DATA_FLOAT, texture_data, UNPACK2(sub_offset), 0, UNPACK2(sub_size), 1);
1056 float4 *texture_data_read = static_cast<float4 *>(GPU_texture_read(texture, GPU_DATA_FLOAT, 0));
1057
1058 for (int x = 0; x < size.x; x++) {
1059 for (int y = 0; y < sub_offset.y; y++) {
1060 int index = x + y * size.x;
1061 ASSERT_EQ(texture_data_read[index], clear_color);
1062 }
1063 }
1064 for (int y = sub_offset.y; y < sub_offset.y + sub_size.y; y++) {
1065 for (int x = 0; x < sub_offset.x; x++) {
1066 int index = x + y * size.x;
1067 ASSERT_EQ(texture_data_read[index], clear_color);
1068 }
1069 for (int x = sub_offset.x; x < sub_offset.x + sub_size.x; x++) {
1070 int index = x + y * size.x;
1071 ASSERT_EQ(texture_data_read[index], texture_color);
1072 }
1073 for (int x = sub_offset.x + sub_size.x; x < size.x; x++) {
1074 int index = x + y * size.x;
1075 ASSERT_EQ(texture_data_read[index], clear_color);
1076 }
1077 }
1078 for (int x = 0; x < size.x; x++) {
1079 for (int y = sub_offset.y + sub_size.y; y < size.y; y++) {
1080 int index = x + y * size.x;
1081 ASSERT_EQ(texture_data_read[index], clear_color);
1082 }
1083 }
1084
1085 MEM_freeN(texture_data);
1086 MEM_freeN(texture_data_read);
1088}
1089GPU_TEST(texture_update_sub_no_unpack_row_length);
1090
1092{
1093 const int2 size(1024);
1094 const int2 sub_size(256);
1095 const int2 sub_offset(256);
1096
1097 GPUTexture *texture = GPU_texture_create_2d(
1098 __func__, UNPACK2(size), 2, GPU_RGBA32F, GPU_TEXTURE_USAGE_GENERAL, nullptr);
1099 const float4 clear_color(0.0f, 0.0f, 0.0f, 0.0f);
1101
1102 const float4 texture_color(0.0f, 1.0f, 0.0f, 1.0f);
1103 const float4 texture_color_off(1.0f, 0.0f, 0.0f, 1.0f);
1104 float4 *texture_data = MEM_malloc_arrayN<float4>(size.x * size.y, __func__);
1105 for (int x = 0; x < size.x; x++) {
1106 for (int y = 0; y < size.y; y++) {
1107 int index = x + y * size.x;
1108 texture_data[index] = ((x >= sub_offset.x && x < sub_offset.x + sub_size.x) &&
1109 (y >= sub_offset.y && y < sub_offset.y + sub_size.y)) ?
1110 texture_color :
1111 texture_color_off;
1112 }
1113 }
1114
1116 float4 *texture_data_offset = &texture_data[sub_offset.x + sub_offset.y * size.x];
1118 texture, GPU_DATA_FLOAT, texture_data_offset, UNPACK2(sub_offset), 0, UNPACK2(sub_size), 1);
1119 float4 *texture_data_read = static_cast<float4 *>(GPU_texture_read(texture, GPU_DATA_FLOAT, 0));
1121
1122 for (int x = 0; x < size.x; x++) {
1123 for (int y = 0; y < sub_offset.y; y++) {
1124 int index = x + y * size.x;
1125 ASSERT_EQ(texture_data_read[index], clear_color);
1126 }
1127 }
1128 for (int y = sub_offset.y; y < sub_offset.y + sub_size.y; y++) {
1129 for (int x = 0; x < sub_offset.x; x++) {
1130 int index = x + y * size.x;
1131 ASSERT_EQ(texture_data_read[index], clear_color);
1132 }
1133 for (int x = sub_offset.x; x < sub_offset.x + sub_size.x; x++) {
1134 int index = x + y * size.x;
1135 ASSERT_EQ(texture_data_read[index], texture_color);
1136 }
1137 for (int x = sub_offset.x + sub_size.x; x < size.x; x++) {
1138 int index = x + y * size.x;
1139 ASSERT_EQ(texture_data_read[index], clear_color);
1140 }
1141 }
1142 for (int x = 0; x < size.x; x++) {
1143 for (int y = sub_offset.y + sub_size.y; y < size.y; y++) {
1144 int index = x + y * size.x;
1145 ASSERT_EQ(texture_data_read[index], clear_color);
1146 }
1147 }
1148
1149 MEM_freeN(texture_data);
1150 MEM_freeN(texture_data_read);
1152}
1153GPU_TEST(texture_update_sub_unpack_row_length);
1154
1156{
1157 const int2 size1(10);
1158 const int2 size2(20);
1159 const int2 size3(30);
1160
1161 TexturePool &pool = TexturePool::get();
1162
1163 eGPUTextureFormat format1 = GPU_RGBA8;
1166
1168
1169 auto test_acquire =
1170 [&](int2 size, eGPUTextureFormat format, eGPUTextureUsage usage) -> GPUTexture * {
1171 GPUTexture *tex = pool.acquire_texture(size.x, size.y, format, usage);
1175 return tex;
1176 };
1177
1178 /* Tests multiple acquire. */
1179 GPUTexture *tex1 = test_acquire(size1, format1, usage);
1180 GPUTexture *tex2 = test_acquire(size2, format1, usage);
1181 GPUTexture *tex3 = test_acquire(size3, format2, usage);
1182 GPUTexture *tex4 = test_acquire(size3, format3, usage);
1183
1184 pool.release_texture(tex1);
1185
1186 /* Tests texture recycling. */
1187 /* Note we don't test if the same texture is reused as this is implementation dependent. */
1188 tex1 = test_acquire(size1, format1, usage);
1189
1190 pool.release_texture(tex1);
1191
1192 /* Tests missing release assert. */
1193 EXPECT_BLI_ASSERT(pool.reset(), "Missing texture release");
1194
1195 pool.release_texture(tex2);
1196 pool.release_texture(tex3);
1197 pool.release_texture(tex4);
1198
1199 /* Expects no assert. */
1200 pool.reset();
1201}
1202GPU_TEST(texture_pool);
1203
1204/* \} */
1205
1206} // 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()
eGPUBackendType GPU_backend_get_type()
void GPU_memory_barrier(eGPUBarrier barrier)
Definition gpu_state.cc:385
@ GPU_BARRIER_TEXTURE_UPDATE
Definition GPU_state.hh:39
int GPU_texture_height(const GPUTexture *texture)
GPUTexture * GPU_texture_create_2d(const char *name, int width, int height, int mip_len, eGPUTextureFormat format, eGPUTextureUsage usage, const float *data)
GPUTexture * GPU_texture_create_1d(const char *name, int width, int mip_len, eGPUTextureFormat format, eGPUTextureUsage usage, const float *data)
void GPU_texture_free(GPUTexture *texture)
int GPU_texture_width(const GPUTexture *texture)
void GPU_texture_clear(GPUTexture *texture, eGPUDataFormat data_format, const void *data)
void GPU_texture_copy(GPUTexture *dst, GPUTexture *src)
void * GPU_texture_read(GPUTexture *texture, eGPUDataFormat data_format, int mip_level)
GPUTexture * GPU_texture_create_cube_array(const char *name, int width, int layer_len, int mip_len, eGPUTextureFormat format, eGPUTextureUsage usage, const float *data)
eGPUDataFormat
@ GPU_DATA_10_11_11_REV
@ GPU_DATA_UINT
@ GPU_DATA_FLOAT
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_update_sub(GPUTexture *texture, eGPUDataFormat data_format, const void *pixels, int offset_x, int offset_y, int offset_z, int width, int height, int depth)
GPUTexture * GPU_texture_create_2d_array(const char *name, int width, int height, int layer_len, int mip_len, eGPUTextureFormat format, eGPUTextureUsage usage, const float *data)
GPUTexture * GPU_texture_create_3d(const char *name, int width, int height, int depth, int mip_len, eGPUTextureFormat format, eGPUTextureUsage usage, const void *data)
eGPUTextureFormat
@ GPU_RGBA32F
@ GPU_RGBA16F
@ GPU_RGBA32UI
@ GPU_RGBA16UI
@ GPU_RGBA8
GPUTexture * GPU_texture_create_cube(const char *name, int width, int mip_len, eGPUTextureFormat format, eGPUTextureUsage usage, const float *data)
GPUTexture * GPU_texture_create_1d_array(const char *name, int width, int layer_len, int mip_len, eGPUTextureFormat format, eGPUTextureUsage usage, const float *data)
void GPU_unpack_row_length_set(uint len)
void GPU_texture_update(GPUTexture *texture, eGPUDataFormat data_format, const void *data)
eGPUTextureFormat GPU_texture_format(const GPUTexture *texture)
Read Guarded memory(de)allocation.
BMesh const char void * data
static DBVT_INLINE btScalar size(const btDbvtVolume &a)
Definition btDbvt.cpp:52
void release_texture(GPUTexture *tmp_tex)
void reset(bool force_free=false)
static TexturePool & get()
GPUTexture * acquire_texture(int width, int height, eGPUTextureFormat format, eGPUTextureUsage usage)
TEX_TEMPLATE DataVec texture(T, FltCoord, float=0.0f) RET
#define abs
#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_roundtrip__GPU_DATA_FLOAT__GPU_DEPTH_COMPONENT24()
static void test_texture_roundtrip__GPU_DATA_FLOAT__GPU_DEPTH24_STENCIL8()
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()
constexpr bool validate_data_format(eGPUTextureFormat tex_format, eGPUDataFormat data_format)
int to_bytesize(const DataFormat format)
int to_component_len(eGPUTextureFormat format)
VecBase< uint32_t, 4 > uint4
VecBase< float, 4 > float4
VecBase< int32_t, 2 > int2
i
Definition text_draw.cc:230