5 #include "flutter/fml/logging.h"
6 #include "flutter/testing/testing.h"
12 #include "impeller/fixtures/array.frag.h"
13 #include "impeller/fixtures/array.vert.h"
14 #include "impeller/fixtures/box_fade.frag.h"
15 #include "impeller/fixtures/box_fade.vert.h"
16 #include "impeller/fixtures/colors.frag.h"
17 #include "impeller/fixtures/colors.vert.h"
18 #include "impeller/fixtures/impeller.frag.h"
19 #include "impeller/fixtures/impeller.vert.h"
20 #include "impeller/fixtures/inactive_uniforms.frag.h"
21 #include "impeller/fixtures/inactive_uniforms.vert.h"
22 #include "impeller/fixtures/instanced_draw.frag.h"
23 #include "impeller/fixtures/instanced_draw.vert.h"
24 #include "impeller/fixtures/mipmaps.frag.h"
25 #include "impeller/fixtures/mipmaps.vert.h"
26 #include "impeller/fixtures/test_texture.frag.h"
27 #include "impeller/fixtures/test_texture.vert.h"
41 #include "third_party/imgui/imgui.h"
53 using VS = BoxFadeVertexShader;
54 using FS = BoxFadeFragmentShader;
55 auto context = GetContext();
58 auto desc = BoxPipelineBuilder::MakeDefaultPipelineDescriptor(*context);
59 ASSERT_TRUE(desc.has_value());
61 desc->SetStencilAttachmentDescriptors(std::nullopt);
67 {{100, 100, 0.0}, {0.0, 0.0}},
68 {{800, 100, 0.0}, {1.0, 0.0}},
69 {{800, 800, 0.0}, {1.0, 1.0}},
70 {{100, 100, 0.0}, {0.0, 0.0}},
71 {{800, 800, 0.0}, {1.0, 1.0}},
72 {{100, 800, 0.0}, {0.0, 1.0}},
76 ASSERT_TRUE(vertex_buffer);
78 auto bridge = CreateTextureForFixture(
"bay_bridge.jpg");
79 auto boston = CreateTextureForFixture(
"boston.jpg");
80 ASSERT_TRUE(bridge && boston);
81 auto sampler = context->GetSamplerLibrary()->GetSampler({});
83 SinglePassCallback callback = [&](
RenderPass& pass) {
84 ImGui::Begin(
"Controls",
nullptr, ImGuiWindowFlags_AlwaysAutoResize);
85 static bool wireframe;
86 ImGui::Checkbox(
"Wireframe", &wireframe);
90 auto pipeline = context->GetPipelineLibrary()->GetPipeline(desc).Get();
92 assert(pipeline && pipeline->IsValid());
100 VS::UniformBuffer uniforms;
103 VS::BindUniformBuffer(cmd,
104 pass.GetTransientsBuffer().EmplaceUniform(uniforms));
106 FS::FrameInfo frame_info;
107 frame_info.current_time = GetSecondsElapsed();
108 frame_info.cursor_position = GetCursorPosition();
109 frame_info.window_size.x = GetWindowSize().width;
110 frame_info.window_size.y = GetWindowSize().height;
112 FS::BindFrameInfo(cmd,
113 pass.GetTransientsBuffer().EmplaceUniform(frame_info));
114 FS::BindContents1(cmd, boston, sampler);
115 FS::BindContents2(cmd, bridge, sampler);
116 if (!pass.AddCommand(std::move(cmd))) {
121 OpenPlaygroundHere(callback);
125 using VS = ColorsVertexShader;
126 using FS = ColorsFragmentShader;
127 auto context = GetContext();
128 ASSERT_TRUE(context);
130 ASSERT_TRUE(desc.has_value());
134 desc->SetStencilAttachmentDescriptors(std::nullopt);
136 context->GetPipelineLibrary()->GetPipeline(std::move(desc)).Get();
137 ASSERT_TRUE(pipeline);
140 VS::PerVertexData vertices[8] = {
152 uint16_t indices[36] = {
164 auto device_buffer = context->GetResourceAllocator()->CreateBufferWithCopy(
165 reinterpret_cast<uint8_t*
>(&cube),
sizeof(cube));
168 .range =
Range(offsetof(Cube, vertices),
sizeof(Cube::vertices))};
171 .range =
Range(offsetof(Cube, indices),
sizeof(Cube::indices))};
176 auto sampler = context->GetSamplerLibrary()->GetSampler({});
177 ASSERT_TRUE(sampler);
180 SinglePassCallback callback = [&](
RenderPass& pass) {
182 static Scalar distance = 10;
184 ImGui::Begin(
"Controls",
nullptr, ImGuiWindowFlags_AlwaysAutoResize);
185 ImGui::SliderFloat(
"Field of view", &fov_y.
degrees, 0, 180);
186 ImGui::SliderFloat(
"Camera distance", &distance, 0, 30);
195 VS::UniformBuffer uniforms;
196 Scalar time = GetSecondsElapsed();
197 euler_angles =
Vector3(0.19 * time, 0.7 * time, 0.43 * time);
205 VS::BindUniformBuffer(cmd,
206 pass.GetTransientsBuffer().EmplaceUniform(uniforms));
207 if (!pass.AddCommand(std::move(cmd))) {
212 OpenPlaygroundHere(callback);
216 using VS = BoxFadeVertexShader;
217 using FS = BoxFadeFragmentShader;
218 auto context = GetContext();
219 ASSERT_TRUE(context);
221 auto desc = BoxPipelineBuilder::MakeDefaultPipelineDescriptor(*context);
222 ASSERT_TRUE(desc.has_value());
224 desc->SetStencilAttachmentDescriptors(std::nullopt);
226 context->GetPipelineLibrary()->GetPipeline(std::move(desc)).Get();
227 ASSERT_TRUE(box_pipeline);
233 {{100, 100, 0.0}, {0.0, 0.0}},
234 {{800, 100, 0.0}, {1.0, 0.0}},
235 {{800, 800, 0.0}, {1.0, 1.0}},
236 {{100, 100, 0.0}, {0.0, 0.0}},
237 {{800, 800, 0.0}, {1.0, 1.0}},
238 {{100, 800, 0.0}, {0.0, 1.0}},
242 ASSERT_TRUE(vertex_buffer);
244 auto bridge = CreateTextureForFixture(
"bay_bridge.jpg");
245 auto boston = CreateTextureForFixture(
"boston.jpg");
246 ASSERT_TRUE(bridge && boston);
247 auto sampler = context->GetSamplerLibrary()->GetSampler({});
248 ASSERT_TRUE(sampler);
250 SinglePassCallback callback = [&](
RenderPass& pass) {
257 FS::FrameInfo frame_info;
258 frame_info.current_time = GetSecondsElapsed();
259 frame_info.cursor_position = GetCursorPosition();
260 frame_info.window_size.x = GetWindowSize().width;
261 frame_info.window_size.y = GetWindowSize().height;
263 FS::BindFrameInfo(cmd,
264 pass.GetTransientsBuffer().EmplaceUniform(frame_info));
265 FS::BindContents1(cmd, boston, sampler);
266 FS::BindContents2(cmd, bridge, sampler);
268 for (
size_t i = 0; i < 1; i++) {
269 for (
size_t j = 0; j < 1; j++) {
270 VS::UniformBuffer uniforms;
274 VS::BindUniformBuffer(
275 cmd, pass.GetTransientsBuffer().EmplaceUniform(uniforms));
276 if (!pass.AddCommand(std::move(cmd))) {
284 OpenPlaygroundHere(callback);
288 using VS = BoxFadeVertexShader;
289 using FS = BoxFadeFragmentShader;
290 auto context = GetContext();
291 ASSERT_TRUE(context);
294 BoxPipelineBuilder::MakeDefaultPipelineDescriptor(*context);
297 ASSERT_TRUE(pipeline_desc.has_value());
299 context->GetPipelineLibrary()->GetPipeline(pipeline_desc).Get();
300 ASSERT_TRUE(box_pipeline);
305 {{100, 100, 0.0}, {0.0, 0.0}},
306 {{800, 100, 0.0}, {1.0, 0.0}},
307 {{800, 800, 0.0}, {1.0, 1.0}},
308 {{100, 100, 0.0}, {0.0, 0.0}},
309 {{800, 800, 0.0}, {1.0, 1.0}},
310 {{100, 800, 0.0}, {0.0, 1.0}},
314 ASSERT_TRUE(vertex_buffer);
316 auto bridge = CreateTextureForFixture(
"bay_bridge.jpg");
317 auto boston = CreateTextureForFixture(
"boston.jpg");
318 ASSERT_TRUE(bridge && boston);
319 auto sampler = context->GetSamplerLibrary()->GetSampler({});
320 ASSERT_TRUE(sampler);
321 std::shared_ptr<RenderPass> r2t_pass;
322 auto cmd_buffer = context->CreateCommandBuffer();
323 ASSERT_TRUE(cmd_buffer);
330 ASSERT_NE(pipeline_desc->GetColorAttachmentDescriptor(0u),
nullptr);
331 texture_descriptor.
format =
332 pipeline_desc->GetColorAttachmentDescriptor(0u)->format;
334 texture_descriptor.
size = {400, 400};
336 texture_descriptor.
usage =
340 context->GetResourceAllocator()->CreateTexture(texture_descriptor);
344 color0.
texture->SetLabel(
"r2t_target");
351 stencil_texture_desc.
size = texture_descriptor.
size;
353 stencil_texture_desc.
usage =
356 context->GetResourceAllocator()->CreateTexture(stencil_texture_desc);
361 r2t_pass = cmd_buffer->CreateRenderPass(r2t_desc);
362 ASSERT_TRUE(r2t_pass && r2t_pass->IsValid());
371 FS::FrameInfo frame_info;
372 frame_info.current_time = GetSecondsElapsed();
373 frame_info.cursor_position = GetCursorPosition();
374 frame_info.window_size.x = GetWindowSize().width;
375 frame_info.window_size.y = GetWindowSize().height;
377 FS::BindFrameInfo(cmd,
378 r2t_pass->GetTransientsBuffer().EmplaceUniform(frame_info));
379 FS::BindContents1(cmd, boston, sampler);
380 FS::BindContents2(cmd, bridge, sampler);
382 VS::UniformBuffer uniforms;
385 VS::BindUniformBuffer(
386 cmd, r2t_pass->GetTransientsBuffer().EmplaceUniform(uniforms));
387 ASSERT_TRUE(r2t_pass->AddCommand(std::move(cmd)));
388 ASSERT_TRUE(r2t_pass->EncodeCommands());
393 GTEST_SKIP_(
"Instancing is not supported on OpenGL.");
395 using VS = InstancedDrawVertexShader;
396 using FS = InstancedDrawFragmentShader;
406 .CreatePolyline(1.0f),
407 [&builder](
const float* vertices,
size_t vertices_count,
408 const uint16_t* indices,
size_t indices_count) {
409 for (
auto i = 0u; i < vertices_count * 2; i += 2) {
410 VS::PerVertexData data;
411 data.vtx = {vertices[i], vertices[i + 1]};
414 for (
auto i = 0u; i < indices_count; i++) {
420 ASSERT_NE(GetContext(),
nullptr);
423 ->GetPipelineLibrary()
427 .SetStencilAttachmentDescriptors(std::nullopt))
430 ASSERT_TRUE(pipeline && pipeline->IsValid());
436 static constexpr
size_t kInstancesCount = 5u;
437 VS::InstanceInfo<kInstancesCount> instances;
438 for (
size_t i = 0; i < kInstancesCount; i++) {
442 ASSERT_TRUE(OpenPlaygroundHere([&](
RenderPass& pass) ->
bool {
443 VS::FrameInfo frame_info;
446 VS::BindFrameInfo(cmd,
448 VS::BindInstanceInfo(
459 auto context = GetContext();
460 ASSERT_TRUE(context);
462 using VS = MipmapsVertexShader;
463 using FS = MipmapsFragmentShader;
465 ASSERT_TRUE(desc.has_value());
467 desc->SetStencilAttachmentDescriptors(std::nullopt);
468 auto mipmaps_pipeline =
469 context->GetPipelineLibrary()->GetPipeline(std::move(desc)).Get();
470 ASSERT_TRUE(mipmaps_pipeline);
475 texture_desc.
size = {800, 600};
480 auto texture = context->GetResourceAllocator()->CreateTexture(texture_desc);
481 ASSERT_TRUE(texture);
483 auto bridge = CreateTextureForFixture(
"bay_bridge.jpg");
484 auto boston = CreateTextureForFixture(
"boston.jpg");
485 ASSERT_TRUE(bridge && boston);
486 auto sampler = context->GetSamplerLibrary()->GetSampler({});
487 ASSERT_TRUE(sampler);
492 auto size =
Point(boston->GetSize());
494 {{0, 0}, {0.0, 0.0}},
495 {{size.x, 0}, {1.0, 0.0}},
496 {{size.x, size.y}, {1.0, 1.0}},
497 {{0, 0}, {0.0, 0.0}},
498 {{size.x, size.y}, {1.0, 1.0}},
499 {{0, size.y}, {0.0, 1.0}},
503 ASSERT_TRUE(vertex_buffer);
506 auto buffer = context->CreateCommandBuffer();
510 buffer->SetLabel(
"Playground Command Buffer");
513 auto pass = buffer->CreateBlitPass();
517 pass->SetLabel(
"Playground Blit Pass");
519 if (render_target.GetColorAttachments().empty()) {
524 pass->AddCopy(bridge, texture);
526 if (!pass->EncodeCommands(context->GetResourceAllocator())) {
532 auto pass = buffer->CreateRenderPass(render_target);
536 pass->SetLabel(
"Playground Render Pass");
544 VS::FrameInfo frame_info;
548 cmd, pass->GetTransientsBuffer().EmplaceUniform(frame_info));
550 FS::FragInfo frag_info;
552 FS::BindFragInfo(cmd,
553 pass->GetTransientsBuffer().EmplaceUniform(frag_info));
555 auto sampler = context->GetSamplerLibrary()->GetSampler({});
556 FS::BindTex(cmd, texture, sampler);
558 pass->AddCommand(std::move(cmd));
560 pass->EncodeCommands();
563 if (!buffer->SubmitCommands()) {
568 OpenPlaygroundHere(callback);
572 auto context = GetContext();
573 ASSERT_TRUE(context);
575 using VS = MipmapsVertexShader;
576 using FS = MipmapsFragmentShader;
578 ASSERT_TRUE(desc.has_value());
580 desc->SetStencilAttachmentDescriptors(std::nullopt);
581 auto mipmaps_pipeline =
582 context->GetPipelineLibrary()->GetPipeline(std::move(desc)).Get();
583 ASSERT_TRUE(mipmaps_pipeline);
585 auto bridge = CreateTextureForFixture(
"bay_bridge.jpg");
586 auto boston = CreateTextureForFixture(
"boston.jpg");
587 ASSERT_TRUE(bridge && boston);
588 auto sampler = context->GetSamplerLibrary()->GetSampler({});
589 ASSERT_TRUE(sampler);
594 texture_desc.
size = bridge->GetTextureDescriptor().size;
602 device_buffer_desc.
size =
603 bridge->GetTextureDescriptor().GetByteSizeOfBaseMipLevel();
605 context->GetResourceAllocator()->CreateBuffer(device_buffer_desc);
610 auto size =
Point(boston->GetSize());
612 {{0, 0}, {0.0, 0.0}},
613 {{size.x, 0}, {1.0, 0.0}},
614 {{size.x, size.y}, {1.0, 1.0}},
615 {{0, 0}, {0.0, 0.0}},
616 {{size.x, size.y}, {1.0, 1.0}},
617 {{0, size.y}, {0.0, 1.0}},
621 ASSERT_TRUE(vertex_buffer);
625 auto buffer = context->CreateCommandBuffer();
629 buffer->SetLabel(
"Playground Command Buffer");
630 auto pass = buffer->CreateBlitPass();
634 pass->SetLabel(
"Playground Blit Pass");
636 if (render_target.GetColorAttachments().empty()) {
641 pass->AddCopy(bridge, device_buffer);
643 pass->EncodeCommands(context->GetResourceAllocator());
645 if (!buffer->SubmitCommands()) {
651 auto buffer = context->CreateCommandBuffer();
655 buffer->SetLabel(
"Playground Command Buffer");
657 auto pass = buffer->CreateRenderPass(render_target);
661 pass->SetLabel(
"Playground Render Pass");
669 VS::FrameInfo frame_info;
673 cmd, pass->GetTransientsBuffer().EmplaceUniform(frame_info));
675 FS::FragInfo frag_info;
677 FS::BindFragInfo(cmd,
678 pass->GetTransientsBuffer().EmplaceUniform(frag_info));
680 auto sampler = context->GetSamplerLibrary()->GetSampler({});
681 auto buffer_view = device_buffer->AsBufferView();
683 context->GetResourceAllocator()->CreateTexture(texture_desc);
684 if (!texture->SetContents(buffer_view.contents,
685 buffer_view.range.length)) {
689 FS::BindTex(cmd, texture, sampler);
691 pass->AddCommand(std::move(cmd));
693 pass->EncodeCommands();
694 if (!buffer->SubmitCommands()) {
700 OpenPlaygroundHere(callback);
704 auto context = GetContext();
705 ASSERT_TRUE(context);
707 using VS = MipmapsVertexShader;
708 using FS = MipmapsFragmentShader;
710 ASSERT_TRUE(desc.has_value());
712 desc->SetStencilAttachmentDescriptors(std::nullopt);
713 auto mipmaps_pipeline =
714 context->GetPipelineLibrary()->GetPipeline(std::move(desc)).Get();
715 ASSERT_TRUE(mipmaps_pipeline);
717 auto boston = CreateTextureForFixture(
"boston.jpg",
true);
723 auto size =
Point(boston->GetSize());
725 {{0, 0}, {0.0, 0.0}},
726 {{size.x, 0}, {1.0, 0.0}},
727 {{size.x, size.y}, {1.0, 1.0}},
728 {{0, 0}, {0.0, 0.0}},
729 {{size.x, size.y}, {1.0, 1.0}},
730 {{0, size.y}, {0.0, 1.0}},
734 ASSERT_TRUE(vertex_buffer);
736 bool first_frame =
true;
738 const char* mip_filter_names[] = {
"Nearest",
"Linear"};
740 const char* min_filter_names[] = {
"Nearest",
"Linear"};
745 static int selected_mip_filter = 1;
746 static int selected_min_filter = 0;
747 static float lod = 4.5;
749 ImGui::Begin(
"Controls",
nullptr, ImGuiWindowFlags_AlwaysAutoResize);
750 ImGui::Combo(
"Mip filter", &selected_mip_filter, mip_filter_names,
751 sizeof(mip_filter_names) /
sizeof(
char*));
752 ImGui::Combo(
"Min filter", &selected_min_filter, min_filter_names,
753 sizeof(min_filter_names) /
sizeof(
char*));
754 ImGui::SliderFloat(
"LOD", &lod, 0, boston->GetMipCount() - 1);
757 auto buffer = context->CreateCommandBuffer();
761 buffer->SetLabel(
"Playground Command Buffer");
764 auto pass = buffer->CreateBlitPass();
768 pass->SetLabel(
"Playground Blit Pass");
770 pass->GenerateMipmap(boston,
"Boston Mipmap");
772 pass->EncodeCommands(context->GetResourceAllocator());
778 auto pass = buffer->CreateRenderPass(render_target);
782 pass->SetLabel(
"Playground Render Pass");
790 VS::FrameInfo frame_info;
794 cmd, pass->GetTransientsBuffer().EmplaceUniform(frame_info));
796 FS::FragInfo frag_info;
798 FS::BindFragInfo(cmd,
799 pass->GetTransientsBuffer().EmplaceUniform(frag_info));
802 sampler_desc.
mip_filter = mip_filters[selected_mip_filter];
803 sampler_desc.
min_filter = min_filters[selected_min_filter];
804 auto sampler = context->GetSamplerLibrary()->GetSampler(sampler_desc);
805 FS::BindTex(cmd, boston, sampler);
807 pass->AddCommand(std::move(cmd));
809 pass->EncodeCommands();
812 if (!buffer->SubmitCommands()) {
817 OpenPlaygroundHere(callback);
821 using VS = ImpellerVertexShader;
822 using FS = ImpellerFragmentShader;
824 auto context = GetContext();
825 auto pipeline_descriptor =
827 ASSERT_TRUE(pipeline_descriptor.has_value());
829 pipeline_descriptor->SetStencilAttachmentDescriptors(std::nullopt);
831 context->GetPipelineLibrary()->GetPipeline(pipeline_descriptor).Get();
832 ASSERT_TRUE(pipeline && pipeline->IsValid());
834 auto blue_noise = CreateTextureForFixture(
"blue_noise.png");
839 context->GetSamplerLibrary()->GetSampler(noise_sampler_desc);
841 auto cube_map = CreateTextureCubeForFixture(
842 {
"table_mountain_px.png",
"table_mountain_nx.png",
843 "table_mountain_py.png",
"table_mountain_ny.png",
844 "table_mountain_pz.png",
"table_mountain_nz.png"});
845 auto cube_map_sampler = context->GetSamplerLibrary()->GetSampler({});
847 SinglePassCallback callback = [&](
RenderPass& pass) {
848 auto size = pass.GetRenderTargetSize();
855 {
Point(0, size.height)},
856 {
Point(size.width, 0)},
857 {
Point(size.width, 0)},
858 {
Point(0, size.height)},
859 {
Point(size.width, size.height)}});
862 VS::FrameInfo frame_info;
864 VS::BindFrameInfo(cmd,
865 pass.GetTransientsBuffer().EmplaceUniform(frame_info));
867 FS::FragInfo fs_uniform;
868 fs_uniform.texture_size =
Point(size);
869 fs_uniform.time = GetSecondsElapsed();
870 FS::BindFragInfo(cmd,
871 pass.GetTransientsBuffer().EmplaceUniform(fs_uniform));
872 FS::BindBlueNoise(cmd, blue_noise, noise_sampler);
873 FS::BindCubeMap(cmd, cube_map, cube_map_sampler);
875 pass.AddCommand(std::move(cmd));
878 OpenPlaygroundHere(callback);
882 using VS = ArrayVertexShader;
883 using FS = ArrayFragmentShader;
885 auto context = GetContext();
886 auto pipeline_descriptor =
888 ASSERT_TRUE(pipeline_descriptor.has_value());
890 pipeline_descriptor->SetStencilAttachmentDescriptors(std::nullopt);
892 context->GetPipelineLibrary()->GetPipeline(pipeline_descriptor).Get();
893 ASSERT_TRUE(pipeline && pipeline->IsValid());
895 SinglePassCallback callback = [&](
RenderPass& pass) {
896 auto size = pass.GetRenderTargetSize();
903 {
Point(0, size.height)},
904 {
Point(size.width, 0)},
905 {
Point(size.width, 0)},
906 {
Point(0, size.height)},
907 {
Point(size.width, size.height)}});
910 VS::FrameInfo frame_info;
913 VS::BindFrameInfo(cmd,
914 pass.GetTransientsBuffer().EmplaceUniform(frame_info));
916 auto time = GetSecondsElapsed();
917 auto y_pos = [&time](
float x) {
918 return 400 + 10 * std::cos(time * 5 + x / 6);
921 FS::FragInfo fs_uniform = {
922 .circle_positions = {
Point(430, y_pos(0)),
Point(480, y_pos(1)),
929 FS::BindFragInfo(cmd,
930 pass.GetTransientsBuffer().EmplaceUniform(fs_uniform));
932 pass.AddCommand(std::move(cmd));
935 OpenPlaygroundHere(callback);
939 using VS = InactiveUniformsVertexShader;
940 using FS = InactiveUniformsFragmentShader;
942 auto context = GetContext();
943 auto pipeline_descriptor =
945 ASSERT_TRUE(pipeline_descriptor.has_value());
947 pipeline_descriptor->SetStencilAttachmentDescriptors(std::nullopt);
949 context->GetPipelineLibrary()->GetPipeline(pipeline_descriptor).Get();
950 ASSERT_TRUE(pipeline && pipeline->IsValid());
952 SinglePassCallback callback = [&](
RenderPass& pass) {
953 auto size = pass.GetRenderTargetSize();
960 {
Point(0, size.height)},
961 {
Point(size.width, 0)},
962 {
Point(size.width, 0)},
963 {
Point(0, size.height)},
964 {
Point(size.width, size.height)}});
967 VS::FrameInfo frame_info;
970 VS::BindFrameInfo(cmd,
971 pass.GetTransientsBuffer().EmplaceUniform(frame_info));
973 FS::FragInfo fs_uniform = {.unused_color =
Color::Red(),
975 FS::BindFragInfo(cmd,
976 pass.GetTransientsBuffer().EmplaceUniform(fs_uniform));
978 pass.AddCommand(std::move(cmd));
981 OpenPlaygroundHere(callback);
986 GTEST_SKIP_(
"CPU backed textures are not supported on OpenGLES.");
989 auto context = GetContext();
990 auto allocator = context->GetResourceAllocator();
991 size_t dimension = 2;
994 ISize size(dimension, dimension);
998 texture_descriptor.
size = size;
1000 std::max(
static_cast<uint16_t
>(size.
width * 4),
1001 allocator->MinimumBytesPerRow(texture_descriptor.
format));
1002 auto buffer_size = size.
height * row_bytes;
1006 buffer_descriptor.
size = buffer_size;
1008 auto buffer = allocator->CreateBuffer(buffer_descriptor);
1010 ASSERT_TRUE(buffer);
1012 auto texture = buffer->AsTexture(*allocator, texture_descriptor, row_bytes);
1014 ASSERT_TRUE(texture);
1015 ASSERT_TRUE(texture->IsValid());
1018 }
while (dimension <= 8192);
1022 using VS = BoxFadeVertexShader;
1032 using VS = BoxFadeVertexShader;
1041 using VS = BoxFadeVertexShader;
1045 {{100, 100, 0.0}, {0.0, 0.0}},
1046 {{800, 100, 0.0}, {1.0, 0.0}},
1047 {{800, 800, 0.0}, {1.0, 1.0}},
1048 {{100, 800, 0.0}, {0.0, 1.0}},
1064 labels_.push_back(
"Never");
1066 labels_.push_back(
"Always");
1068 labels_.push_back(
"Less");
1070 labels_.push_back(
"Equal");
1072 labels_.push_back(
"LessEqual");
1074 labels_.push_back(
"Greater");
1076 labels_.push_back(
"NotEqual");
1078 labels_.push_back(
"GreaterEqual");
1080 assert(labels_.size() == functions_.size());
1083 const char*
const*
labels()
const {
return &labels_[0]; }
1085 int size()
const {
return labels_.size(); }
1088 for (
size_t i = 0; i < functions_.size(); i++) {
1089 if (functions_[i] == func) {
1100 std::vector<const char*> labels_;
1101 std::vector<CompareFunction> functions_;
1110 using VS = BoxFadeVertexShader;
1111 using FS = BoxFadeFragmentShader;
1112 auto context = GetContext();
1113 ASSERT_TRUE(context);
1115 auto desc = BoxFadePipelineBuilder::MakeDefaultPipelineDescriptor(*context);
1116 ASSERT_TRUE(desc.has_value());
1122 {{100, 100, 0.0}, {0.0, 0.0}},
1123 {{800, 100, 0.0}, {1.0, 0.0}},
1124 {{800, 800, 0.0}, {1.0, 1.0}},
1125 {{100, 100, 0.0}, {0.0, 0.0}},
1126 {{800, 800, 0.0}, {1.0, 1.0}},
1127 {{100, 800, 0.0}, {0.0, 1.0}},
1129 auto vertex_buffer =
1131 ASSERT_TRUE(vertex_buffer);
1134 desc->SetStencilAttachmentDescriptors(std::nullopt);
1136 auto bridge = CreateTextureForFixture(
"bay_bridge.jpg");
1137 auto boston = CreateTextureForFixture(
"boston.jpg");
1138 ASSERT_TRUE(bridge && boston);
1139 auto sampler = context->GetSamplerLibrary()->GetSampler({});
1140 ASSERT_TRUE(sampler);
1142 static bool mirror =
false;
1143 static int stencil_reference_write = 0xFF;
1144 static int stencil_reference_read = 0x1;
1145 std::vector<uint8_t> stencil_contents;
1146 static int last_stencil_contents_reference_value = 0;
1147 static int current_front_compare =
1149 static int current_back_compare =
1152 auto buffer = context->CreateCommandBuffer();
1156 buffer->SetLabel(
"Playground Command Buffer");
1164 auto render_target_allocator =
1166 render_target.SetupStencilAttachment(*context, render_target_allocator,
1167 render_target.GetRenderTargetSize(),
1168 true,
"stencil", stencil_config);
1170 const auto target_width = render_target.GetRenderTargetSize().width;
1171 const auto target_height = render_target.GetRenderTargetSize().height;
1172 const size_t target_size = target_width * target_height;
1173 if (stencil_contents.size() != target_size ||
1174 last_stencil_contents_reference_value != stencil_reference_write) {
1175 stencil_contents.resize(target_size);
1176 last_stencil_contents_reference_value = stencil_reference_write;
1177 for (
int y = 0; y < target_height; y++) {
1178 for (
int x = 0; x < target_width; x++) {
1179 const auto index = y * target_width + x;
1180 const auto kCheckSize = 64;
1182 (((y / kCheckSize) + (x / kCheckSize)) % 2 == 0) *
1183 stencil_reference_write;
1184 stencil_contents[index] = value;
1188 if (!render_target.GetStencilAttachment()->texture->SetContents(
1189 stencil_contents.data(), stencil_contents.size(), 0,
false)) {
1190 VALIDATION_LOG <<
"Could not upload stencil contents to device memory";
1193 auto pass = buffer->CreateRenderPass(render_target);
1197 pass->SetLabel(
"Stencil Buffer");
1198 ImGui::Begin(
"Controls",
nullptr, ImGuiWindowFlags_AlwaysAutoResize);
1199 ImGui::SliderInt(
"Stencil Write Value", &stencil_reference_write, 0,
1201 ImGui::SliderInt(
"Stencil Compare Value", &stencil_reference_read, 0,
1203 ImGui::Checkbox(
"Back face mode", &mirror);
1204 ImGui::ListBox(
"Front face compare function", ¤t_front_compare,
1206 ImGui::ListBox(
"Back face compare function", ¤t_back_compare,
1216 desc->SetStencilAttachmentDescriptors(front, back);
1217 auto pipeline = context->GetPipelineLibrary()->GetPipeline(desc).Get();
1219 assert(pipeline && pipeline->IsValid());
1228 VS::UniformBuffer uniforms;
1234 VS::BindUniformBuffer(
1235 cmd, pass->GetTransientsBuffer().EmplaceUniform(uniforms));
1237 FS::FrameInfo frame_info;
1238 frame_info.current_time = GetSecondsElapsed();
1239 frame_info.cursor_position = GetCursorPosition();
1240 frame_info.window_size.x = GetWindowSize().width;
1241 frame_info.window_size.y = GetWindowSize().height;
1243 FS::BindFrameInfo(cmd,
1244 pass->GetTransientsBuffer().EmplaceUniform(frame_info));
1245 FS::BindContents1(cmd, boston, sampler);
1246 FS::BindContents2(cmd, bridge, sampler);
1247 if (!pass->AddCommand(std::move(cmd))) {
1250 pass->EncodeCommands();
1253 if (!buffer->SubmitCommands()) {
1258 OpenPlaygroundHere(callback);