Blender V4.3
draw_pass_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
7#include "BLI_math_matrix.hh"
8
9#include "draw_manager.hh"
10#include "draw_pass.hh"
11#include "draw_shader.hh"
12#include "draw_testing.hh"
13
14#include <bitset>
15
16namespace blender::draw {
17
19{
21 tex.ensure_2d(GPU_RGBA16, int2(1));
22
24 ubo.push_update();
25
27 ssbo.push_update();
28
29 /* Won't be dereferenced. */
30 gpu::VertBuf *vbo = (gpu::VertBuf *)1;
31 gpu::IndexBuf *ibo = (gpu::IndexBuf *)1;
32 GPUFrameBuffer *fb = nullptr;
33
34 float4 color(1.0f, 1.0f, 1.0f, 0.0f);
35 int3 dispatch_size(1);
36
37 PassSimple pass = {"test.all_commands"};
38 pass.init();
40 pass.clear_color_depth_stencil(float4(0.25f, 0.5f, 100.0f, -2000.0f), 0.5f, 0xF0);
41 pass.state_stencil(0x80, 0x0F, 0x8F);
43 const int color_location = GPU_shader_get_uniform(sh, "color");
44 const int mvp_location = GPU_shader_get_uniform(sh, "ModelViewProjectionMatrix");
45 pass.shader_set(sh);
46 pass.framebuffer_set(&fb);
48 pass.bind_texture("image", tex);
49 pass.bind_texture("image", &tex);
50 pass.bind_image("missing_image", tex); /* Should not crash. */
51 pass.bind_image("missing_image", &tex); /* Should not crash. */
52 pass.bind_ubo("missing_ubo", ubo); /* Should not crash. */
53 pass.bind_ubo("missing_ubo", &ubo); /* Should not crash. */
54 pass.bind_ssbo("missing_ssbo", ssbo); /* Should not crash. */
55 pass.bind_ssbo("missing_ssbo", &ssbo); /* Should not crash. */
56 pass.bind_ssbo("missing_vbo_as_ssbo", vbo); /* Should not crash. */
57 pass.bind_ssbo("missing_vbo_as_ssbo", &vbo); /* Should not crash. */
58 pass.bind_ssbo("missing_ibo_as_ssbo", ibo); /* Should not crash. */
59 pass.bind_ssbo("missing_ibo_as_ssbo", &ibo); /* Should not crash. */
60 pass.push_constant("color", color);
61 pass.push_constant("color", &color);
62 pass.push_constant("ModelViewProjectionMatrix", float4x4::identity());
63 pass.draw_procedural(GPU_PRIM_TRIS, 1, 3);
64
65 /* Should not crash even if shader is not a compute. This is because we only serialize. */
66 /* TODO(fclem): Use real compute shader. */
68 pass.dispatch(dispatch_size);
69 pass.dispatch(&dispatch_size);
71
72 /* Change references. */
73 color[3] = 1.0f;
74 dispatch_size = int3(2);
75
76 std::string result = pass.serialize();
77 std::stringstream expected;
78 expected << ".test.all_commands" << std::endl;
79 expected << " .state_set(6)" << std::endl;
80 expected << " .clear(color=(0.25, 0.5, 100, -2000), depth=0.5, stencil=0b11110000))"
81 << std::endl;
82 expected
83 << " .stencil_set(write_mask=0b10000000, reference=0b00001111, compare_mask=0b10001111)"
84 << std::endl;
85 expected << " .shader_bind(gpu_shader_3D_image_color)" << std::endl;
86 expected << " .framebuffer_bind(nullptr)" << std::endl;
87 expected << " .subpass_transition(" << std::endl;
88 expected << "depth=ignore," << std::endl;
89 expected << "color0=write," << std::endl;
90 expected << "color1=read," << std::endl;
91 expected << "color2=ignore," << std::endl;
92 expected << "color3=ignore," << std::endl;
93 expected << "color4=ignore," << std::endl;
94 expected << "color5=ignore," << std::endl;
95 expected << "color6=ignore," << std::endl;
96 expected << "color7=ignore" << std::endl;
97 expected << ")" << std::endl;
98 expected << " .bind_texture(0, sampler=internal)" << std::endl;
99 expected << " .bind_texture_ref(0, sampler=internal)" << std::endl;
100 expected << " .bind_image(-1)" << std::endl;
101 expected << " .bind_image_ref(-1)" << std::endl;
102 expected << " .bind_uniform_buf(-1)" << std::endl;
103 expected << " .bind_uniform_buf_ref(-1)" << std::endl;
104 expected << " .bind_storage_buf(-1)" << std::endl;
105 expected << " .bind_storage_buf_ref(-1)" << std::endl;
106 expected << " .bind_vertbuf_as_ssbo(-1)" << std::endl;
107 expected << " .bind_vertbuf_as_ssbo_ref(-1)" << std::endl;
108 expected << " .bind_indexbuf_as_ssbo(-1)" << std::endl;
109 expected << " .bind_indexbuf_as_ssbo_ref(-1)" << std::endl;
110 expected << " .push_constant(" << color_location << ", data=(1, 1, 1, 0))" << std::endl;
111 expected << " .push_constant(" << color_location << ", data=(1, 1, 1, 1))" << std::endl;
112 expected << " .push_constant(" << mvp_location << ", data=(" << std::endl;
113 expected << "(1, 0, 0, 0)," << std::endl;
114 expected << "(0, 1, 0, 0)," << std::endl;
115 expected << "(0, 0, 1, 0)," << std::endl;
116 expected << "(0, 0, 0, 1)" << std::endl;
117 expected << ")" << std::endl;
118 expected << ")" << std::endl;
119 expected << " .draw(inst_len=1, vert_len=3, vert_first=0, res_id=0)" << std::endl;
120 expected << " .shader_bind(gpu_shader_3D_image_color)" << std::endl;
121 expected << " .dispatch(1, 1, 1)" << std::endl;
122 expected << " .dispatch_ref(2, 2, 2)" << std::endl;
123 expected << " .barrier(2)" << std::endl;
124
125 EXPECT_EQ(result, expected.str());
126
128}
129DRAW_TEST(draw_pass_all_commands)
130
132{
133 PassSimple pass = {"test.sub_ordering"};
134 pass.init();
136 pass.push_constant("test_pass", 1);
137
138 PassSimple::Sub &sub1 = pass.sub("Sub1");
139 sub1.push_constant("test_sub1", 11);
140
141 PassSimple::Sub &sub2 = pass.sub("Sub2");
142 sub2.push_constant("test_sub2", 21);
143
144 /* Will execute after both sub. */
145 pass.push_constant("test_pass", 2);
146
147 /* Will execute after sub1. */
148 sub2.push_constant("test_sub2", 22);
149
150 /* Will execute before sub2. */
151 sub1.push_constant("test_sub1", 12);
152
153 /* Will execute before end of pass. */
154 sub2.push_constant("test_sub2", 23);
155
156 std::string result = pass.serialize();
157 std::stringstream expected;
158 expected << ".test.sub_ordering" << std::endl;
159 expected << " .shader_bind(gpu_shader_3D_image_color)" << std::endl;
160 expected << " .push_constant(-1, data=1)" << std::endl;
161 expected << " .Sub1" << std::endl;
162 expected << " .push_constant(-1, data=11)" << std::endl;
163 expected << " .push_constant(-1, data=12)" << std::endl;
164 expected << " .Sub2" << std::endl;
165 expected << " .push_constant(-1, data=21)" << std::endl;
166 expected << " .push_constant(-1, data=22)" << std::endl;
167 expected << " .push_constant(-1, data=23)" << std::endl;
168 expected << " .push_constant(-1, data=2)" << std::endl;
169
170 EXPECT_EQ(result, expected.str());
171}
172DRAW_TEST(draw_pass_sub_ordering)
173
175{
176 PassSimple pass = {"test.simple_draw"};
177 pass.init();
179 /* Each draw procedural type uses a different batch. Groups are drawn in correct order. */
180 pass.draw_procedural(GPU_PRIM_TRIS, 1, 10, 1, {1});
181 pass.draw_procedural(GPU_PRIM_POINTS, 4, 20, 2, {2});
182 pass.draw_procedural(GPU_PRIM_TRIS, 2, 30, 3, {3});
183 pass.draw_procedural(GPU_PRIM_POINTS, 5, 40, 4, ResourceHandle(4, true));
184 pass.draw_procedural(GPU_PRIM_LINES, 1, 50, 5, {5});
185 pass.draw_procedural(GPU_PRIM_POINTS, 6, 60, 6, {5});
186 pass.draw_procedural(GPU_PRIM_TRIS, 3, 70, 7, {6});
187
188 PassSimple::Sub &sub = pass.sub("sub");
189 sub.draw_procedural(GPU_PRIM_TRIS, 3, 80, 8, {8});
190
191 std::string result = pass.serialize();
192 std::stringstream expected;
193 expected << ".test.simple_draw" << std::endl;
194 expected << " .shader_bind(gpu_shader_3D_image_color)" << std::endl;
195 expected << " .draw(inst_len=1, vert_len=10, vert_first=1, res_id=1)" << std::endl;
196 expected << " .draw(inst_len=4, vert_len=20, vert_first=2, res_id=2)" << std::endl;
197 expected << " .draw(inst_len=2, vert_len=30, vert_first=3, res_id=3)" << std::endl;
198 expected << " .draw(inst_len=5, vert_len=40, vert_first=4, res_id=4)" << std::endl;
199 expected << " .draw(inst_len=1, vert_len=50, vert_first=5, res_id=5)" << std::endl;
200 expected << " .draw(inst_len=6, vert_len=60, vert_first=6, res_id=5)" << std::endl;
201 expected << " .draw(inst_len=3, vert_len=70, vert_first=7, res_id=6)" << std::endl;
202 expected << " .sub" << std::endl;
203 expected << " .draw(inst_len=3, vert_len=80, vert_first=8, res_id=8)" << std::endl;
204
205 EXPECT_EQ(result, expected.str());
206
208}
209DRAW_TEST(draw_pass_simple_draw)
210
212{
213 PassMain pass = {"test.multi_draw"};
214 pass.init();
216 /* Each draw procedural type uses a different batch. Groups are drawn in reverse order. */
217 pass.draw_procedural(GPU_PRIM_TRIS, 1, -1, -1, {1});
218 pass.draw_procedural(GPU_PRIM_POINTS, 4, -1, -1, {2});
219 pass.draw_procedural(GPU_PRIM_TRIS, 2, -1, -1, {3});
220 pass.draw_procedural(GPU_PRIM_POINTS, 5, -1, -1, ResourceHandle(4, true));
221 pass.draw_procedural(GPU_PRIM_LINES, 1, -1, -1, {5});
222 pass.draw_procedural(GPU_PRIM_POINTS, 6, -1, -1, {5});
223 pass.draw_procedural(GPU_PRIM_TRIS, 3, -1, -1, {6});
224 /* Custom calls should use their own group and never be batched. */
225 pass.draw_procedural(GPU_PRIM_TRIS, 2, 2, 2, {7});
226 pass.draw_procedural(GPU_PRIM_TRIS, 2, 2, 2, {8});
227
228 std::string result = pass.serialize();
229 std::stringstream expected;
230 expected << ".test.multi_draw" << std::endl;
231 expected << " .shader_bind(gpu_shader_3D_image_color)" << std::endl;
232 expected << " .draw_multi(5)" << std::endl;
233 expected << " .group(id=4, len=2)" << std::endl;
234 expected << " .proto(instance_len=2, resource_id=8, front_face)" << std::endl;
235 expected << " .group(id=3, len=2)" << std::endl;
236 expected << " .proto(instance_len=2, resource_id=7, front_face)" << std::endl;
237 expected << " .group(id=2, len=1)" << std::endl;
238 expected << " .proto(instance_len=1, resource_id=5, front_face)" << std::endl;
239 expected << " .group(id=1, len=15)" << std::endl;
240 expected << " .proto(instance_len=5, resource_id=4, back_face)" << std::endl;
241 expected << " .proto(instance_len=6, resource_id=5, front_face)" << std::endl;
242 expected << " .proto(instance_len=4, resource_id=2, front_face)" << std::endl;
243 expected << " .group(id=0, len=6)" << std::endl;
244 expected << " .proto(instance_len=3, resource_id=6, front_face)" << std::endl;
245 expected << " .proto(instance_len=2, resource_id=3, front_face)" << std::endl;
246 expected << " .proto(instance_len=1, resource_id=1, front_face)" << std::endl;
247
248 EXPECT_EQ(result, expected.str());
249
251}
252DRAW_TEST(draw_pass_multi_draw)
253
255{
256 PassSortable pass = {"test.sortable"};
257 pass.init();
258
259 pass.sub("Sub3", 3.0f);
260 pass.sub("Sub2", 2.0f);
261 pass.sub("Sub5", 4.0f);
262 pass.sub("Sub4", 3.0f);
263 pass.sub("Sub1", 1.0f);
264
265 std::string result = pass.serialize();
266 std::stringstream expected;
267 expected << ".test.sortable" << std::endl;
268 expected << " .Sub1" << std::endl;
269 expected << " .Sub2" << std::endl;
270 expected << " .Sub3" << std::endl;
271 expected << " .Sub4" << std::endl;
272 expected << " .Sub5" << std::endl;
273
274 EXPECT_EQ(result, expected.str());
275
277}
278DRAW_TEST(draw_pass_sortable)
279
281{
283 Texture color_attachment;
284 Framebuffer framebuffer;
285 color_attachment.ensure_2d(GPU_RGBA32F, int2(1));
286 framebuffer.ensure(GPU_ATTACHMENT_NONE, GPU_ATTACHMENT_TEXTURE(color_attachment));
287 framebuffer.bind();
288
289 float4x4 win_mat;
290 orthographic_m4(win_mat.ptr(), -1, 1, -1, 1, -1, 1);
291
292 View view("test_view");
293 view.sync(float4x4::identity(), win_mat);
294
295 Manager drw;
296
299
300 drw.begin_sync();
301 ResourceHandle handle1 = drw.resource_handle(obmat_1);
302 ResourceHandle handle2 = drw.resource_handle(obmat_1);
303 ResourceHandle handle3 = drw.resource_handle(obmat_2);
304 drw.resource_handle(obmat_2, float3(2), float3(1));
305 drw.end_sync();
306
307 {
308 /* Computed on CPU. */
309 PassSimple pass = {"test.resource_id"};
310 pass.init();
311 pass.shader_set(
313 pass.draw_procedural(GPU_PRIM_TRIS, 1, -1, -1, handle2);
314 pass.draw_procedural(GPU_PRIM_POINTS, 4, -1, -1, handle1);
315 pass.draw_procedural(GPU_PRIM_TRIS, 2, -1, -1, handle3);
316 pass.draw_procedural(GPU_PRIM_POINTS, 5, -1, -1, handle1);
317 pass.draw_procedural(GPU_PRIM_LINES, 1, -1, -1, handle3);
318 pass.draw_procedural(GPU_PRIM_POINTS, 6, -1, -1, handle2);
319 pass.draw_procedural(GPU_PRIM_TRIS, 3, -1, -1, handle1);
320
321 Manager::SubmitDebugOutput debug = drw.submit_debug(pass, view);
322
323 std::stringstream result;
324 for (auto val : debug.resource_id) {
325 result << val << " ";
326 }
327
328 StringRefNull expected_simple = "2 1 1 1 1 3 3 1 1 1 1 1 3 2 2 2 2 2 2 1 1 1 ";
329 EXPECT_EQ(result.str(), expected_simple);
330 }
331
332 {
333 /* Same thing with PassMain (computed on GPU) */
334 PassMain pass = {"test.resource_id"};
335 pass.init();
336 pass.shader_set(
338 pass.draw_procedural(GPU_PRIM_TRIS, 1, -1, -1, handle2);
339 pass.draw_procedural(GPU_PRIM_POINTS, 4, -1, -1, handle1);
340 pass.draw_procedural(GPU_PRIM_TRIS, 2, -1, -1, handle3);
341 pass.draw_procedural(GPU_PRIM_POINTS, 5, -1, -1, handle1);
342 pass.draw_procedural(GPU_PRIM_LINES, 1, -1, -1, handle3);
343 pass.draw_procedural(GPU_PRIM_POINTS, 6, -1, -1, handle2);
344 pass.draw_procedural(GPU_PRIM_TRIS, 3, -1, -1, handle1);
345
346 Manager::SubmitDebugOutput debug = drw.submit_debug(pass, view);
347
348 std::stringstream result;
349 for (auto val : debug.resource_id) {
350 result << val << " ";
351 }
352
353 /* When using PassMain the handles are sorted based on their handles and GPUBatches. Different
354 * primitives use different batches.
355 */
356 StringRefNull expected_main = "2 3 3 1 1 1 1 1 1 1 1 1 1 1 1 2 2 2 2 2 2 3 ";
357 EXPECT_EQ(result.str(), expected_main);
358 }
359
361
364}
365DRAW_TEST(draw_resource_id_gen)
366
368{
370 Texture color_attachment;
371 Framebuffer framebuffer;
372 color_attachment.ensure_2d(GPU_RGBA32F, int2(1));
373 framebuffer.ensure(GPU_ATTACHMENT_NONE, GPU_ATTACHMENT_TEXTURE(color_attachment));
374 framebuffer.bind();
375
376 float4x4 win_mat;
377 orthographic_m4(win_mat.ptr(), -1, 1, -1, 1, -1, 1);
378
379 View view("test_view");
380 view.sync(float4x4::identity(), win_mat);
381
382 Manager drw;
383
386
387 drw.begin_sync(); /* Default {0} always visible. */
388 drw.resource_handle(obmat_1); /* No bounds, always visible. */
389 drw.resource_handle(obmat_1, float3(3), float3(1)); /* Out of view. */
390 drw.resource_handle(obmat_2, float3(0), float3(1)); /* Inside view. */
391 drw.end_sync();
392
393 PassMain pass = {"test.visibility"};
394 pass.init();
396 pass.draw_procedural(GPU_PRIM_TRIS, 1, -1);
397
398 Manager::SubmitDebugOutput debug = drw.submit_debug(pass, view);
399 Vector<uint32_t> expected_visibility = {0};
400
401 std::stringstream result;
402 for (auto val : debug.visibility) {
404 }
405
406 EXPECT_EQ(result.str(), "11111111111111111111111111111011");
407
409
412}
413DRAW_TEST(draw_visibility)
414
416{
419
420 /* TODO find a way to create a minimum object to test resource handle creation on it. */
421 Manager drw;
422
423 drw.begin_sync();
424 drw.resource_handle(obmat_1);
425 drw.resource_handle(obmat_2, float3(2), float3(1));
426 drw.end_sync();
427
429
430 std::stringstream result;
431 for (const auto &val : debug.matrices) {
432 result << val;
433 }
434 for (const auto &val : debug.bounds) {
435 result << val;
436 }
437 for (const auto &val : debug.infos) {
438 result << val;
439 }
440
441 std::stringstream expected;
442 expected << "ObjectMatrices(" << std::endl;
443 expected << "model=(" << std::endl;
444 expected << "(1, 0, 0, 0)," << std::endl;
445 expected << "(0, 1, 0, 0)," << std::endl;
446 expected << "(0, 0, 1, 0)," << std::endl;
447 expected << "(0, 0, 0, 1)" << std::endl;
448 expected << ")" << std::endl;
449 expected << ", " << std::endl;
450 expected << "model_inverse=(" << std::endl;
451 expected << "(1, -0, 0, -0)," << std::endl;
452 expected << "(-0, 1, -0, 0)," << std::endl;
453 expected << "(0, -0, 1, -0)," << std::endl;
454 expected << "(-0, 0, -0, 1)" << std::endl;
455 expected << ")" << std::endl;
456 expected << ")" << std::endl;
457 expected << "ObjectMatrices(" << std::endl;
458 expected << "model=(" << std::endl;
459 expected << "(-0.5, 0, 0, 0)," << std::endl;
460 expected << "(0, -0.5, 0, 0)," << std::endl;
461 expected << "(0, 0, -0.5, 0)," << std::endl;
462 expected << "(0, 0, 0, 1)" << std::endl;
463 expected << ")" << std::endl;
464 expected << ", " << std::endl;
465 expected << "model_inverse=(" << std::endl;
466 expected << "(-2, -0, -0, 0)," << std::endl;
467 expected << "(-0, -2, 0, -0)," << std::endl;
468 expected << "(-0, 0, -2, 0)," << std::endl;
469 expected << "(0, -0, 0, 1)" << std::endl;
470 expected << ")" << std::endl;
471 expected << ")" << std::endl;
472 expected << "ObjectMatrices(" << std::endl;
473 expected << "model=(" << std::endl;
474 expected << "(0.5, 0, 0, 0)," << std::endl;
475 expected << "(0, 0.5, 0, 0)," << std::endl;
476 expected << "(0, 0, 0.5, 0)," << std::endl;
477 expected << "(0, 0, 0, 1)" << std::endl;
478 expected << ")" << std::endl;
479 expected << ", " << std::endl;
480 expected << "model_inverse=(" << std::endl;
481 expected << "(2, -0, 0, -0)," << std::endl;
482 expected << "(-0, 2, -0, 0)," << std::endl;
483 expected << "(0, -0, 2, -0)," << std::endl;
484 expected << "(-0, 0, -0, 1)" << std::endl;
485 expected << ")" << std::endl;
486 expected << ")" << std::endl;
487 expected << "ObjectBounds(skipped)" << std::endl;
488 expected << "ObjectBounds(skipped)" << std::endl;
489 expected << "ObjectBounds(" << std::endl;
490 expected << ".bounding_corners[0](0.5, 0.5, 0.5)" << std::endl;
491 expected << ".bounding_corners[1](1, 0, 0)" << std::endl;
492 expected << ".bounding_corners[2](0, 1, 0)" << std::endl;
493 expected << ".bounding_corners[3](0, 0, 1)" << std::endl;
494 expected << ".sphere=(pos=(1, 1, 1), rad=0.866025" << std::endl;
495 expected << ")" << std::endl;
496 expected << "ObjectInfos(skipped)" << std::endl;
497 expected << "ObjectInfos(skipped)" << std::endl;
498 expected << "ObjectInfos(skipped)" << std::endl;
499
500 EXPECT_EQ(result.str(), expected.str());
501
503}
504DRAW_TEST(draw_manager_sync)
505
506} // namespace blender::draw
EXPECT_EQ(BLI_expr_pylike_eval(expr, nullptr, 0, &result), EXPR_PYLIKE_INVALID)
void orthographic_m4(float mat[4][4], float left, float right, float bottom, float top, float nearClip, float farClip)
static AppView * view
@ GPU_ATTACHMENT_WRITE
@ GPU_ATTACHMENT_READ
@ GPU_ATTACHMENT_IGNORE
void GPU_render_end()
void GPU_render_begin()
#define GPU_ATTACHMENT_TEXTURE(_texture)
#define GPU_ATTACHMENT_NONE
@ GPU_PRIM_LINES
@ GPU_PRIM_POINTS
@ GPU_PRIM_TRIS
int GPU_shader_get_uniform(GPUShader *shader, const char *name)
GPUShader * GPU_shader_get_builtin_shader(eGPUBuiltinShader shader)
@ GPU_SHADER_3D_POINT_UNIFORM_SIZE_UNIFORM_COLOR_AA
@ GPU_SHADER_3D_IMAGE_COLOR
@ GPU_BARRIER_SHADER_IMAGE_ACCESS
Definition GPU_state.hh:35
@ GPU_RGBA16
struct GPUShader GPUShader
void ensure(GPUAttachment depth=GPU_ATTACHMENT_NONE, GPUAttachment color1=GPU_ATTACHMENT_NONE, GPUAttachment color2=GPU_ATTACHMENT_NONE, GPUAttachment color3=GPU_ATTACHMENT_NONE, GPUAttachment color4=GPU_ATTACHMENT_NONE, GPUAttachment color5=GPU_ATTACHMENT_NONE, GPUAttachment color6=GPU_ATTACHMENT_NONE, GPUAttachment color7=GPU_ATTACHMENT_NONE, GPUAttachment color8=GPU_ATTACHMENT_NONE)
SubmitDebugOutput submit_debug(PassSimple &pass, View &view)
ResourceHandle resource_handle(const ObjectRef &ref, float inflate_bounds=0.0f)
DataDebugOutput data_debug()
bool ensure_2d(eGPUTextureFormat format, int2 extent, eGPUTextureUsage usage=GPU_TEXTURE_USAGE_GENERAL, const float *data=nullptr, int mip_len=1)
void draw_procedural(GPUPrimType primitive, uint instance_len, uint vertex_len, uint vertex_first=-1, ResourceHandle handle={0}, uint custom_id=0)
Definition draw_pass.hh:833
PassBase< DrawCommandBufType > & sub(const char *name)
Definition draw_pass.hh:616
void push_constant(const char *name, const float &data)
additional_info("compositor_sum_float_shared") .push_constant(Type additional_info("compositor_sum_float_shared") .push_constant(Type GPU_RGBA32F
void DRW_shape_cache_free()
void DRW_shaders_free()
@ DRW_STATE_WRITE_COLOR
Definition draw_state.hh:30
@ DRW_STATE_WRITE_STENCIL
Definition draw_state.hh:32
#define DRAW_TEST(test_name)
BLI_INLINE float fb(float length, float L)
static void test_draw_pass_multi_draw()
static void test_draw_pass_all_commands()
static void test_draw_pass_simple_draw()
static void test_draw_visibility()
static void test_draw_manager_sync()
static void test_draw_resource_id_gen()
static void test_draw_pass_sub_ordering()
static void test_draw_pass_sortable()
MatT from_scale(const VecBase< typename MatT::base_type, ScaleDim > &scale)
VecBase< float, 4 > float4
VecBase< int32_t, 2 > int2
VecBase< int32_t, 3 > int3
VecBase< float, 3 > float3
const c_style_mat & ptr() const