11#include "impeller/fixtures/array.frag.h"
12#include "impeller/fixtures/array.vert.h"
13#include "impeller/fixtures/box_fade.frag.h"
14#include "impeller/fixtures/box_fade.vert.h"
15#include "impeller/fixtures/colors.frag.h"
16#include "impeller/fixtures/colors.vert.h"
17#include "impeller/fixtures/impeller.frag.h"
18#include "impeller/fixtures/impeller.vert.h"
19#include "impeller/fixtures/inactive_uniforms.frag.h"
20#include "impeller/fixtures/inactive_uniforms.vert.h"
21#include "impeller/fixtures/instanced_draw.frag.h"
22#include "impeller/fixtures/instanced_draw.vert.h"
23#include "impeller/fixtures/mipmaps.frag.h"
24#include "impeller/fixtures/mipmaps.vert.h"
25#include "impeller/fixtures/planet.frag.h"
26#include "impeller/fixtures/planet.vert.h"
27#include "impeller/fixtures/sepia.frag.h"
28#include "impeller/fixtures/sepia.vert.h"
29#include "impeller/fixtures/swizzle.frag.h"
30#include "impeller/fixtures/texture.frag.h"
31#include "impeller/fixtures/texture.vert.h"
40#include "third_party/imgui/imgui.h"
46std::pair<std::shared_ptr<impeller::HostBuffer>,
47 std::shared_ptr<impeller::HostBuffer>>
48createHostBuffers(
const std::shared_ptr<impeller::Context>& context) {
50 context->GetResourceAllocator(), context->GetIdleWaiter(),
51 context->GetCapabilities()->GetMinimumUniformAlignment());
52 auto indexes_host_buffer =
53 context->GetCapabilities()->NeedsPartitionedHostBuffer()
55 context->GetResourceAllocator(), context->GetIdleWaiter(),
56 context->GetCapabilities()->GetMinimumUniformAlignment())
58 return {data_host_buffer, indexes_host_buffer};
69 using VS = BoxFadeVertexShader;
70 using FS = BoxFadeFragmentShader;
71 auto context = GetContext();
74 auto desc = BoxPipelineBuilder::MakeDefaultPipelineDescriptor(*context);
75 ASSERT_TRUE(desc.has_value());
77 desc->SetStencilAttachmentDescriptors(std::nullopt);
83 {{100, 100, 0.0}, {0.0, 0.0}},
84 {{800, 100, 0.0}, {1.0, 0.0}},
85 {{800, 800, 0.0}, {1.0, 1.0}},
86 {{100, 100, 0.0}, {0.0, 0.0}},
87 {{800, 800, 0.0}, {1.0, 1.0}},
88 {{100, 800, 0.0}, {0.0, 1.0}},
90 auto bridge = CreateTextureForFixture(
"bay_bridge.jpg");
91 auto boston = CreateTextureForFixture(
"boston.jpg");
92 ASSERT_TRUE(bridge && boston);
96 auto [data_host_buffer, indexes_host_buffer] = createHostBuffers(context);
98 ImGui::Begin(
"Controls",
nullptr, ImGuiWindowFlags_AlwaysAutoResize);
99 static bool wireframe;
100 ImGui::Checkbox(
"Wireframe", &wireframe);
104 auto pipeline = context->GetPipelineLibrary()->GetPipeline(desc).Get();
106 assert(pipeline && pipeline->IsValid());
108 pass.SetCommandLabel(
"Box");
109 pass.SetPipeline(pipeline);
110 pass.SetVertexBuffer(
113 VS::UniformBuffer uniforms;
114 EXPECT_EQ(pass.GetOrthographicTransform(),
118 VS::BindUniformBuffer(pass, data_host_buffer->EmplaceUniform(uniforms));
120 FS::FrameInfo frame_info;
121 frame_info.current_time = GetSecondsElapsed();
122 frame_info.cursor_position = GetCursorPosition();
123 frame_info.window_size.x = GetWindowSize().width;
124 frame_info.window_size.y = GetWindowSize().height;
126 FS::BindFrameInfo(pass, data_host_buffer->EmplaceUniform(frame_info));
127 FS::BindContents1(pass, boston, sampler);
128 FS::BindContents2(pass, bridge, sampler);
130 data_host_buffer->Reset();
131 return pass.Draw().ok();
137 using VS = ColorsVertexShader;
138 using FS = ColorsFragmentShader;
139 auto context = GetContext();
140 ASSERT_TRUE(context);
142 ASSERT_TRUE(desc.has_value());
146 desc->ClearStencilAttachments();
150 auto vertex_desc = std::make_shared<VertexDescriptor>();
157 const std::vector<ShaderStageIOSlot> io_slots = {position_slot, color_slot};
158 const std::vector<ShaderStageBufferLayout> layouts = {
161 vertex_desc->RegisterDescriptorSetLayouts(VS::kDescriptorSetLayouts);
162 vertex_desc->RegisterDescriptorSetLayouts(FS::kDescriptorSetLayouts);
163 vertex_desc->SetStageInputs(io_slots, layouts);
164 desc->SetVertexDescriptor(std::move(vertex_desc));
166 context->GetPipelineLibrary()->GetPipeline(std::move(desc)).Get();
167 ASSERT_TRUE(pipeline);
183 Color::Red(), Color::Yellow(), Color::Green(), Color::Blue(),
184 Color::Green(), Color::Blue(), Color::Red(), Color::Yellow(),
186 uint16_t indices[36] = {
196 auto device_buffer = context->GetResourceAllocator()->CreateBufferWithCopy(
197 reinterpret_cast<uint8_t*
>(&cube),
sizeof(cube));
200 ASSERT_TRUE(sampler);
203 auto [data_host_buffer, indexes_host_buffer] = createHostBuffers(context);
206 static Scalar distance = 10;
208 ImGui::Begin(
"Controls",
nullptr, ImGuiWindowFlags_AlwaysAutoResize);
209 ImGui::SliderFloat(
"Field of view", &fov_y.
degrees, 0, 180);
210 ImGui::SliderFloat(
"Camera distance", &distance, 0, 30);
213 pass.SetCommandLabel(
"Perspective Cube");
214 pass.SetPipeline(pipeline);
216 std::array<BufferView, 2> vertex_buffers = {
218 Range(offsetof(Cube, positions),
sizeof(Cube::positions))),
220 Range(offsetof(Cube, colors),
sizeof(Cube::colors))),
224 device_buffer,
Range(offsetof(Cube, indices),
sizeof(Cube::indices)));
225 pass.SetVertexBuffer(vertex_buffers.data(), vertex_buffers.size());
226 pass.SetElementCount(36);
229 VS::UniformBuffer uniforms;
230 Scalar time = GetSecondsElapsed();
231 euler_angles =
Vector3(0.19 * time, 0.7 * time, 0.43 * time);
239 VS::BindUniformBuffer(pass, data_host_buffer->EmplaceUniform(uniforms));
241 data_host_buffer->Reset();
242 return pass.Draw().ok();
248 using VS = BoxFadeVertexShader;
249 using FS = BoxFadeFragmentShader;
250 auto context = GetContext();
251 ASSERT_TRUE(context);
253 auto desc = BoxPipelineBuilder::MakeDefaultPipelineDescriptor(*context);
254 ASSERT_TRUE(desc.has_value());
256 desc->SetStencilAttachmentDescriptors(std::nullopt);
258 context->GetPipelineLibrary()->GetPipeline(std::move(desc)).Get();
259 ASSERT_TRUE(box_pipeline);
265 {{100, 100, 0.0}, {0.0, 0.0}},
266 {{800, 100, 0.0}, {1.0, 0.0}},
267 {{800, 800, 0.0}, {1.0, 1.0}},
268 {{100, 100, 0.0}, {0.0, 0.0}},
269 {{800, 800, 0.0}, {1.0, 1.0}},
270 {{100, 800, 0.0}, {0.0, 1.0}},
274 ASSERT_TRUE(vertex_buffer);
276 auto bridge = CreateTextureForFixture(
"bay_bridge.jpg");
277 auto boston = CreateTextureForFixture(
"boston.jpg");
278 ASSERT_TRUE(bridge && boston);
280 ASSERT_TRUE(sampler);
282 auto [data_host_buffer, indexes_host_buffer] = createHostBuffers(context);
284 for (
size_t i = 0;
i < 1;
i++) {
285 for (
size_t j = 0; j < 1; j++) {
286 pass.SetCommandLabel(
"Box");
287 pass.SetPipeline(box_pipeline);
288 pass.SetVertexBuffer(vertex_buffer);
290 FS::FrameInfo frame_info;
291 frame_info.current_time = GetSecondsElapsed();
292 frame_info.cursor_position = GetCursorPosition();
293 frame_info.window_size.x = GetWindowSize().width;
294 frame_info.window_size.y = GetWindowSize().height;
296 FS::BindFrameInfo(pass, data_host_buffer->EmplaceUniform(frame_info));
297 FS::BindContents1(pass, boston, sampler);
298 FS::BindContents2(pass, bridge, sampler);
300 VS::UniformBuffer uniforms;
301 EXPECT_EQ(pass.GetOrthographicTransform(),
303 uniforms.mvp = pass.GetOrthographicTransform() *
306 VS::BindUniformBuffer(pass, data_host_buffer->EmplaceUniform(uniforms));
307 if (!pass.Draw().ok()) {
313 data_host_buffer->Reset();
320 using VS = BoxFadeVertexShader;
321 using FS = BoxFadeFragmentShader;
322 auto context = GetContext();
323 ASSERT_TRUE(context);
326 BoxPipelineBuilder::MakeDefaultPipelineDescriptor(*context);
328 pipeline_desc->ClearDepthAttachment();
331 ASSERT_TRUE(pipeline_desc.has_value());
333 context->GetPipelineLibrary()->GetPipeline(pipeline_desc).Get();
334 ASSERT_TRUE(box_pipeline);
335 auto [data_host_buffer, indexes_host_buffer] = createHostBuffers(context);
340 {{100, 100, 0.0}, {0.0, 0.0}},
341 {{800, 100, 0.0}, {1.0, 0.0}},
342 {{800, 800, 0.0}, {1.0, 1.0}},
343 {{100, 100, 0.0}, {0.0, 0.0}},
344 {{800, 800, 0.0}, {1.0, 1.0}},
345 {{100, 800, 0.0}, {0.0, 1.0}},
349 ASSERT_TRUE(vertex_buffer);
351 auto bridge = CreateTextureForFixture(
"bay_bridge.jpg");
352 auto boston = CreateTextureForFixture(
"boston.jpg");
353 ASSERT_TRUE(bridge && boston);
355 ASSERT_TRUE(sampler);
357 std::shared_ptr<RenderPass> r2t_pass;
358 auto cmd_buffer = context->CreateCommandBuffer();
359 ASSERT_TRUE(cmd_buffer);
366 ASSERT_NE(pipeline_desc->GetColorAttachmentDescriptor(0u),
nullptr);
367 texture_descriptor.
format =
368 pipeline_desc->GetColorAttachmentDescriptor(0u)->format;
370 texture_descriptor.
size = {400, 400};
375 context->GetResourceAllocator()->CreateTexture(texture_descriptor);
379 color0.
texture->SetLabel(
"r2t_target");
386 stencil_texture_desc.
size = texture_descriptor.
size;
390 context->GetResourceAllocator()->CreateTexture(stencil_texture_desc);
395 r2t_pass = cmd_buffer->CreateRenderPass(r2t_desc);
396 ASSERT_TRUE(r2t_pass && r2t_pass->IsValid());
399 r2t_pass->SetCommandLabel(
"Box");
400 r2t_pass->SetPipeline(box_pipeline);
401 r2t_pass->SetVertexBuffer(vertex_buffer);
403 FS::FrameInfo frame_info;
404 frame_info.current_time = GetSecondsElapsed();
405 frame_info.cursor_position = GetCursorPosition();
406 frame_info.window_size.x = GetWindowSize().width;
407 frame_info.window_size.y = GetWindowSize().height;
409 FS::BindFrameInfo(*r2t_pass, data_host_buffer->EmplaceUniform(frame_info));
410 FS::BindContents1(*r2t_pass, boston, sampler);
411 FS::BindContents2(*r2t_pass, bridge, sampler);
413 VS::UniformBuffer uniforms;
416 VS::BindUniformBuffer(*r2t_pass, data_host_buffer->EmplaceUniform(uniforms));
417 ASSERT_TRUE(r2t_pass->Draw().ok());
418 ASSERT_TRUE(r2t_pass->EncodeCommands());
423 GTEST_SKIP() <<
"Instancing is not supported on OpenGL.";
425 using VS = InstancedDrawVertexShader;
426 using FS = InstancedDrawFragmentShader;
430 VS::PerVertexData{
Point{10, 10}},
431 VS::PerVertexData{
Point{10, 110}},
432 VS::PerVertexData{
Point{110, 10}},
433 VS::PerVertexData{
Point{10, 110}},
434 VS::PerVertexData{
Point{110, 10}},
435 VS::PerVertexData{
Point{110, 110}},
438 ASSERT_NE(GetContext(),
nullptr);
441 ->GetPipelineLibrary()
445 .SetStencilAttachmentDescriptors(std::nullopt))
448 ASSERT_TRUE(pipeline && pipeline->IsValid());
450 static constexpr size_t kInstancesCount = 5u;
451 VS::InstanceInfo<kInstancesCount> instances;
452 for (
size_t i = 0;
i < kInstancesCount;
i++) {
456 auto [data_host_buffer, indexes_host_buffer] =
457 createHostBuffers(GetContext());
458 ASSERT_TRUE(OpenPlaygroundHere([&](
RenderPass& pass) ->
bool {
462 VS::FrameInfo frame_info;
467 VS::BindFrameInfo(pass, data_host_buffer->EmplaceUniform(frame_info));
468 VS::BindInstanceInfo(pass,
469 data_host_buffer->EmplaceStorageBuffer(instances));
476 data_host_buffer->Reset();
483 GTEST_SKIP() <<
"Mipmap test shader not supported on GLES.";
485 auto context = GetContext();
486 ASSERT_TRUE(context);
488 using VS = MipmapsVertexShader;
489 using FS = MipmapsFragmentShader;
491 ASSERT_TRUE(desc.has_value());
493 desc->SetStencilAttachmentDescriptors(std::nullopt);
494 auto mipmaps_pipeline =
495 context->GetPipelineLibrary()->GetPipeline(std::move(desc)).Get();
496 ASSERT_TRUE(mipmaps_pipeline);
501 texture_desc.
size = {800, 600};
504 auto texture = context->GetResourceAllocator()->CreateTexture(texture_desc);
507 auto bridge = CreateTextureForFixture(
"bay_bridge.jpg");
508 auto boston = CreateTextureForFixture(
"boston.jpg");
509 ASSERT_TRUE(bridge && boston);
511 ASSERT_TRUE(sampler);
518 {{0, 0}, {0.0, 0.0}},
519 {{
size.x, 0}, {1.0, 0.0}},
521 {{0, 0}, {0.0, 0.0}},
523 {{0,
size.y}, {0.0, 1.0}},
527 ASSERT_TRUE(vertex_buffer);
529 auto [data_host_buffer, indexes_host_buffer] = createHostBuffers(context);
531 auto buffer = context->CreateCommandBuffer();
535 buffer->SetLabel(
"Playground Command Buffer");
538 auto pass =
buffer->CreateBlitPass();
542 pass->SetLabel(
"Playground Blit Pass");
545 pass->AddCopy(bridge,
texture);
547 if (!pass->EncodeCommands()) {
553 auto pass =
buffer->CreateRenderPass(render_target);
557 pass->SetLabel(
"Playground Render Pass");
559 pass->SetCommandLabel(
"Image");
560 pass->SetPipeline(mipmaps_pipeline);
561 pass->SetVertexBuffer(vertex_buffer);
563 VS::FrameInfo frame_info;
564 EXPECT_EQ(pass->GetOrthographicTransform(),
566 frame_info.mvp = pass->GetOrthographicTransform() *
568 VS::BindFrameInfo(*pass, data_host_buffer->EmplaceUniform(frame_info));
570 FS::FragInfo frag_info;
572 FS::BindFragInfo(*pass, data_host_buffer->EmplaceUniform(frag_info));
574 auto sampler = context->GetSamplerLibrary()->GetSampler({});
575 FS::BindTex(*pass,
texture, sampler);
579 pass->EncodeCommands();
582 if (!context->GetCommandQueue()->Submit({buffer}).ok()) {
585 data_host_buffer->Reset();
593 GTEST_SKIP() <<
"Mipmap test shader not supported on GLES.";
595 auto context = GetContext();
596 ASSERT_TRUE(context);
598 using VS = MipmapsVertexShader;
599 using FS = MipmapsFragmentShader;
601 ASSERT_TRUE(desc.has_value());
603 desc->SetStencilAttachmentDescriptors(std::nullopt);
604 auto mipmaps_pipeline =
605 context->GetPipelineLibrary()->GetPipeline(std::move(desc)).Get();
606 ASSERT_TRUE(mipmaps_pipeline);
608 auto bridge = CreateTextureForFixture(
"bay_bridge.jpg");
609 auto boston = CreateTextureForFixture(
"boston.jpg");
610 ASSERT_TRUE(bridge && boston);
612 ASSERT_TRUE(sampler);
617 texture_desc.
size = bridge->GetTextureDescriptor().size;
623 device_buffer_desc.
size =
624 bridge->GetTextureDescriptor().GetByteSizeOfBaseMipLevel();
626 context->GetResourceAllocator()->CreateBuffer(device_buffer_desc);
633 {{0, 0}, {0.0, 0.0}},
634 {{
size.x, 0}, {1.0, 0.0}},
636 {{0, 0}, {0.0, 0.0}},
638 {{0,
size.y}, {0.0, 1.0}},
642 ASSERT_TRUE(vertex_buffer);
644 auto [data_host_buffer, indexes_host_buffer] = createHostBuffers(context);
647 auto buffer = context->CreateCommandBuffer();
651 buffer->SetLabel(
"Playground Command Buffer");
652 auto pass =
buffer->CreateBlitPass();
656 pass->SetLabel(
"Playground Blit Pass");
659 pass->AddCopy(bridge, device_buffer);
660 pass->EncodeCommands();
662 if (!context->GetCommandQueue()->Submit({
buffer}).ok()) {
668 auto buffer = context->CreateCommandBuffer();
672 buffer->SetLabel(
"Playground Command Buffer");
674 auto pass =
buffer->CreateRenderPass(render_target);
678 pass->SetLabel(
"Playground Render Pass");
680 pass->SetCommandLabel(
"Image");
681 pass->SetPipeline(mipmaps_pipeline);
682 pass->SetVertexBuffer(vertex_buffer);
684 VS::FrameInfo frame_info;
685 EXPECT_EQ(pass->GetOrthographicTransform(),
687 frame_info.mvp = pass->GetOrthographicTransform() *
689 VS::BindFrameInfo(*pass, data_host_buffer->EmplaceUniform(frame_info));
691 FS::FragInfo frag_info;
693 FS::BindFragInfo(*pass, data_host_buffer->EmplaceUniform(frag_info));
696 context->GetSamplerLibrary()->GetSampler({});
699 context->GetResourceAllocator()->CreateTexture(texture_desc);
700 if (!
texture->SetContents(device_buffer->OnGetContents(),
701 buffer_view.GetRange().length)) {
705 FS::BindTex(*pass,
texture, sampler);
709 pass->EncodeCommands();
710 if (!context->GetCommandQueue()->Submit({buffer}).ok()) {
714 data_host_buffer->Reset();
722 GTEST_SKIP() <<
"Mipmap test shader not supported on GLES.";
724 auto context = GetContext();
725 ASSERT_TRUE(context);
727 using VS = MipmapsVertexShader;
728 using FS = MipmapsFragmentShader;
730 ASSERT_TRUE(desc.has_value());
732 desc->SetStencilAttachmentDescriptors(std::nullopt);
733 auto mipmaps_pipeline =
734 context->GetPipelineLibrary()->GetPipeline(std::move(desc)).Get();
735 ASSERT_TRUE(mipmaps_pipeline);
737 auto boston = CreateTextureForFixture(
"boston.jpg",
true);
745 {{0, 0}, {0.0, 0.0}},
746 {{
size.x, 0}, {1.0, 0.0}},
748 {{0, 0}, {0.0, 0.0}},
750 {{0,
size.y}, {0.0, 1.0}},
754 ASSERT_TRUE(vertex_buffer);
756 bool first_frame =
true;
757 auto [data_host_buffer, indexes_host_buffer] = createHostBuffers(context);
759 const char* mip_filter_names[] = {
"Base",
"Nearest",
"Linear"};
762 const char* min_filter_names[] = {
"Nearest",
"Linear"};
767 static int selected_mip_filter = 1;
768 static int selected_min_filter = 0;
769 static float lod = 4.5;
771 ImGui::Begin(
"Controls",
nullptr, ImGuiWindowFlags_AlwaysAutoResize);
772 ImGui::Combo(
"Mip filter", &selected_mip_filter, mip_filter_names,
773 sizeof(mip_filter_names) /
sizeof(
char*));
774 ImGui::Combo(
"Min filter", &selected_min_filter, min_filter_names,
775 sizeof(min_filter_names) /
sizeof(
char*));
776 ImGui::SliderFloat(
"LOD", &lod, 0, boston->GetMipCount() - 1);
779 auto buffer = context->CreateCommandBuffer();
783 buffer->SetLabel(
"Playground Command Buffer");
786 auto pass =
buffer->CreateBlitPass();
790 pass->SetLabel(
"Playground Blit Pass");
792 pass->GenerateMipmap(boston,
"Boston Mipmap");
794 pass->EncodeCommands();
800 auto pass =
buffer->CreateRenderPass(render_target);
804 pass->SetLabel(
"Playground Render Pass");
806 pass->SetCommandLabel(
"Image LOD");
807 pass->SetPipeline(mipmaps_pipeline);
808 pass->SetVertexBuffer(vertex_buffer);
810 VS::FrameInfo frame_info;
811 EXPECT_EQ(pass->GetOrthographicTransform(),
813 frame_info.mvp = pass->GetOrthographicTransform() *
815 VS::BindFrameInfo(*pass, data_host_buffer->EmplaceUniform(frame_info));
817 FS::FragInfo frag_info;
819 FS::BindFragInfo(*pass, data_host_buffer->EmplaceUniform(frag_info));
822 sampler_desc.
mip_filter = mip_filters[selected_mip_filter];
823 sampler_desc.
min_filter = min_filters[selected_min_filter];
825 context->GetSamplerLibrary()->GetSampler(sampler_desc);
826 FS::BindTex(*pass, boston, sampler);
830 pass->EncodeCommands();
833 if (!context->GetCommandQueue()->Submit({buffer}).ok()) {
836 data_host_buffer->Reset();
843 using VS = ImpellerVertexShader;
844 using FS = ImpellerFragmentShader;
846 auto context = GetContext();
847 auto pipeline_descriptor =
849 ASSERT_TRUE(pipeline_descriptor.has_value());
851 pipeline_descriptor->SetStencilAttachmentDescriptors(std::nullopt);
853 context->GetPipelineLibrary()->GetPipeline(pipeline_descriptor).Get();
854 ASSERT_TRUE(pipeline && pipeline->IsValid());
856 auto blue_noise = CreateTextureForFixture(
"blue_noise.png");
861 context->GetSamplerLibrary()->GetSampler(noise_sampler_desc);
863 auto cube_map = CreateTextureCubeForFixture(
864 {
"table_mountain_px.png",
"table_mountain_nx.png",
865 "table_mountain_py.png",
"table_mountain_ny.png",
866 "table_mountain_pz.png",
"table_mountain_nz.png"});
868 context->GetSamplerLibrary()->GetSampler({});
870 auto [data_host_buffer, indexes_host_buffer] = createHostBuffers(context);
872 auto size = pass.GetRenderTargetSize();
874 pass.SetPipeline(pipeline);
875 pass.SetCommandLabel(
"Impeller SDF scene");
883 pass.SetVertexBuffer(
886 VS::FrameInfo frame_info;
888 frame_info.mvp = pass.GetOrthographicTransform();
889 VS::BindFrameInfo(pass, data_host_buffer->EmplaceUniform(frame_info));
891 FS::FragInfo fs_uniform;
893 fs_uniform.time = GetSecondsElapsed();
894 FS::BindFragInfo(pass, data_host_buffer->EmplaceUniform(fs_uniform));
895 FS::BindBlueNoise(pass, blue_noise, noise_sampler);
896 FS::BindCubeMap(pass, cube_map, cube_map_sampler);
899 data_host_buffer->Reset();
906 using VS = PlanetVertexShader;
907 using FS = PlanetFragmentShader;
909 auto context = GetContext();
910 auto pipeline_descriptor =
912 ASSERT_TRUE(pipeline_descriptor.has_value());
914 pipeline_descriptor->SetStencilAttachmentDescriptors(std::nullopt);
916 context->GetPipelineLibrary()->GetPipeline(pipeline_descriptor).Get();
917 ASSERT_TRUE(pipeline && pipeline->IsValid());
919 auto [data_host_buffer, indexes_host_buffer] = createHostBuffers(context);
921 static Scalar speed = 0.1;
922 static Scalar planet_size = 550.0;
923 static bool show_normals =
false;
924 static bool show_noise =
false;
925 static Scalar seed_value = 42.0;
927 auto size = pass.GetRenderTargetSize();
929 ImGui::Begin(
"Controls",
nullptr, ImGuiWindowFlags_AlwaysAutoResize);
930 ImGui::SliderFloat(
"Speed", &speed, 0.0, 10.0);
931 ImGui::SliderFloat(
"Planet Size", &planet_size, 0.1, 1000);
932 ImGui::Checkbox(
"Show Normals", &show_normals);
933 ImGui::Checkbox(
"Show Noise", &show_noise);
934 ImGui::InputFloat(
"Seed Value", &seed_value);
937 pass.SetPipeline(pipeline);
938 pass.SetCommandLabel(
"Planet scene");
946 pass.SetVertexBuffer(
949 VS::FrameInfo frame_info;
951 frame_info.mvp = pass.GetOrthographicTransform();
952 VS::BindFrameInfo(pass, data_host_buffer->EmplaceUniform(frame_info));
954 FS::FragInfo fs_uniform;
956 fs_uniform.time = GetSecondsElapsed();
957 fs_uniform.speed = speed;
958 fs_uniform.planet_size = planet_size;
959 fs_uniform.show_normals = show_normals ? 1.0 : 0.0;
960 fs_uniform.show_noise = show_noise ? 1.0 : 0.0;
961 fs_uniform.seed_value = seed_value;
962 FS::BindFragInfo(pass, data_host_buffer->EmplaceUniform(fs_uniform));
965 data_host_buffer->Reset();
972 using VS = ArrayVertexShader;
973 using FS = ArrayFragmentShader;
975 auto context = GetContext();
976 auto pipeline_descriptor =
978 ASSERT_TRUE(pipeline_descriptor.has_value());
980 pipeline_descriptor->SetStencilAttachmentDescriptors(std::nullopt);
982 context->GetPipelineLibrary()->GetPipeline(pipeline_descriptor).Get();
983 ASSERT_TRUE(pipeline && pipeline->IsValid());
985 auto [data_host_buffer, indexes_host_buffer] = createHostBuffers(context);
987 auto size = pass.GetRenderTargetSize();
989 pass.SetPipeline(pipeline);
990 pass.SetCommandLabel(
"Google Dots");
998 pass.SetVertexBuffer(
1001 VS::FrameInfo frame_info;
1005 VS::BindFrameInfo(pass, data_host_buffer->EmplaceUniform(frame_info));
1007 auto time = GetSecondsElapsed();
1008 auto y_pos = [&time](
float x) {
1009 return 400 + 10 * std::cos(time * 5 +
x / 6);
1012 FS::FragInfo fs_uniform = {
1013 .circle_positions = {
Point(430, y_pos(0)),
Point(480, y_pos(1)),
1020 FS::BindFragInfo(pass, data_host_buffer->EmplaceUniform(fs_uniform));
1023 data_host_buffer->Reset();
1030 using VS = InactiveUniformsVertexShader;
1031 using FS = InactiveUniformsFragmentShader;
1033 auto context = GetContext();
1034 auto pipeline_descriptor =
1036 ASSERT_TRUE(pipeline_descriptor.has_value());
1038 pipeline_descriptor->SetStencilAttachmentDescriptors(std::nullopt);
1040 context->GetPipelineLibrary()->GetPipeline(pipeline_descriptor).Get();
1041 ASSERT_TRUE(pipeline && pipeline->IsValid());
1043 auto [data_host_buffer, indexes_host_buffer] = createHostBuffers(context);
1045 auto size = pass.GetRenderTargetSize();
1047 pass.SetPipeline(pipeline);
1048 pass.SetCommandLabel(
"Inactive Uniform");
1057 pass.SetVertexBuffer(
1060 VS::FrameInfo frame_info;
1064 VS::BindFrameInfo(pass, data_host_buffer->EmplaceUniform(frame_info));
1066 FS::FragInfo fs_uniform = {.unused_color =
Color::Red(),
1068 FS::BindFragInfo(pass, data_host_buffer->EmplaceUniform(fs_uniform));
1071 data_host_buffer->Reset();
1078 using VS = BoxFadeVertexShader;
1088 using VS = BoxFadeVertexShader;
1097 using VS = BoxFadeVertexShader;
1101 {{100, 100, 0.0}, {0.0, 0.0}},
1102 {{800, 100, 0.0}, {1.0, 0.0}},
1103 {{800, 800, 0.0}, {1.0, 1.0}},
1104 {{100, 800, 0.0}, {0.0, 1.0}},
1120 labels_.push_back(
"Never");
1122 labels_.push_back(
"Always");
1124 labels_.push_back(
"Less");
1126 labels_.push_back(
"Equal");
1128 labels_.push_back(
"LessEqual");
1130 labels_.push_back(
"Greater");
1132 labels_.push_back(
"NotEqual");
1134 labels_.push_back(
"GreaterEqual");
1136 assert(labels_.size() == functions_.size());
1139 const char*
const*
labels()
const {
return &labels_[0]; }
1141 int size()
const {
return labels_.size(); }
1144 for (
size_t i = 0;
i < functions_.size();
i++) {
1145 if (functions_[
i] == func) {
1156 std::vector<const char*> labels_;
1157 std::vector<CompareFunction> functions_;
1166 using VS = BoxFadeVertexShader;
1167 using FS = BoxFadeFragmentShader;
1168 auto context = GetContext();
1169 ASSERT_TRUE(context);
1171 auto desc = BoxFadePipelineBuilder::MakeDefaultPipelineDescriptor(*context);
1172 ASSERT_TRUE(desc.has_value());
1178 {{100, 100, 0.0}, {0.0, 0.0}},
1179 {{800, 100, 0.0}, {1.0, 0.0}},
1180 {{800, 800, 0.0}, {1.0, 1.0}},
1181 {{100, 100, 0.0}, {0.0, 0.0}},
1182 {{800, 800, 0.0}, {1.0, 1.0}},
1183 {{100, 800, 0.0}, {0.0, 1.0}},
1185 auto vertex_buffer =
1187 ASSERT_TRUE(vertex_buffer);
1190 desc->SetStencilAttachmentDescriptors(std::nullopt);
1192 auto bridge = CreateTextureForFixture(
"bay_bridge.jpg");
1193 auto boston = CreateTextureForFixture(
"boston.jpg");
1194 ASSERT_TRUE(bridge && boston);
1196 ASSERT_TRUE(sampler);
1198 static bool mirror =
false;
1199 static int stencil_reference_write = 0xFF;
1200 static int stencil_reference_read = 0x1;
1201 std::vector<uint8_t> stencil_contents;
1202 static int last_stencil_contents_reference_value = 0;
1203 static int current_front_compare =
1205 static int current_back_compare =
1208 auto [data_host_buffer, indexes_host_buffer] = createHostBuffers(context);
1210 auto buffer = context->CreateCommandBuffer();
1214 buffer->SetLabel(
"Playground Command Buffer");
1222 render_target.SetupDepthStencilAttachments(
1223 *context, *context->GetResourceAllocator(),
1224 render_target.GetRenderTargetSize(),
true,
"stencil", stencil_config);
1226 const auto target_width = render_target.GetRenderTargetSize().width;
1227 const auto target_height = render_target.GetRenderTargetSize().height;
1228 const size_t target_size = target_width * target_height;
1229 if (stencil_contents.size() != target_size ||
1230 last_stencil_contents_reference_value != stencil_reference_write) {
1231 stencil_contents.resize(target_size);
1232 last_stencil_contents_reference_value = stencil_reference_write;
1233 for (
int y = 0;
y < target_height;
y++) {
1234 for (
int x = 0;
x < target_width;
x++) {
1235 const auto index =
y * target_width +
x;
1236 const auto kCheckSize = 64;
1238 (((
y / kCheckSize) + (
x / kCheckSize)) % 2 == 0) *
1239 stencil_reference_write;
1240 stencil_contents[index] =
value;
1244 if (!render_target.GetStencilAttachment()->texture->SetContents(
1245 stencil_contents.data(), stencil_contents.size(), 0,
false)) {
1246 VALIDATION_LOG <<
"Could not upload stencil contents to device memory";
1249 auto pass =
buffer->CreateRenderPass(render_target);
1253 pass->SetLabel(
"Stencil Buffer");
1254 ImGui::Begin(
"Controls",
nullptr, ImGuiWindowFlags_AlwaysAutoResize);
1255 ImGui::SliderInt(
"Stencil Write Value", &stencil_reference_write, 0,
1257 ImGui::SliderInt(
"Stencil Compare Value", &stencil_reference_read, 0,
1259 ImGui::Checkbox(
"Back face mode", &mirror);
1260 ImGui::ListBox(
"Front face compare function", ¤t_front_compare,
1262 ImGui::ListBox(
"Back face compare function", ¤t_back_compare,
1272 desc->SetStencilAttachmentDescriptors(front, back);
1273 auto pipeline = context->GetPipelineLibrary()->GetPipeline(desc).Get();
1275 assert(pipeline && pipeline->IsValid());
1277 pass->SetCommandLabel(
"Box");
1278 pass->SetPipeline(pipeline);
1279 pass->SetStencilReference(stencil_reference_read);
1280 pass->SetVertexBuffer(vertex_buffer);
1282 VS::UniformBuffer uniforms;
1283 EXPECT_EQ(pass->GetOrthographicTransform(),
1285 uniforms.mvp = pass->GetOrthographicTransform() *
1290 VS::BindUniformBuffer(*pass, data_host_buffer->EmplaceUniform(uniforms));
1292 FS::FrameInfo frame_info;
1293 frame_info.current_time = GetSecondsElapsed();
1294 frame_info.cursor_position = GetCursorPosition();
1295 frame_info.window_size.x = GetWindowSize().width;
1296 frame_info.window_size.y = GetWindowSize().height;
1298 FS::BindFrameInfo(*pass, data_host_buffer->EmplaceUniform(frame_info));
1299 FS::BindContents1(*pass, boston, sampler);
1300 FS::BindContents2(*pass, bridge, sampler);
1301 if (!pass->Draw().ok()) {
1304 pass->EncodeCommands();
1307 if (!context->GetCommandQueue()->Submit({buffer}).ok()) {
1310 data_host_buffer->Reset();
1317 auto context = GetContext();
1318 auto cmd_buffer = context->CreateCommandBuffer();
1319 auto render_target_cache = std::make_shared<RenderTargetAllocator>(
1320 GetContext()->GetResourceAllocator());
1322 auto render_target = render_target_cache->CreateOffscreen(
1323 *context, {100, 100}, 1);
1324 auto render_pass = cmd_buffer->CreateRenderPass(render_target);
1326 EXPECT_EQ(render_pass->GetSampleCount(), render_target.GetSampleCount());
1327 EXPECT_EQ(render_pass->GetRenderTargetPixelFormat(),
1328 render_target.GetRenderTargetPixelFormat());
1329 EXPECT_EQ(render_pass->HasStencilAttachment(),
1330 render_target.GetStencilAttachment().has_value());
1331 EXPECT_EQ(render_pass->GetRenderTargetSize(),
1332 render_target.GetRenderTargetSize());
1333 render_pass->EncodeCommands();
1337 RenderTargetCreateOffscreenMSAASetsDefaultDepthStencilFormat) {
1338 auto context = GetContext();
1339 auto render_target_cache = std::make_shared<RenderTargetAllocator>(
1340 GetContext()->GetResourceAllocator());
1342 RenderTarget render_target = render_target_cache->CreateOffscreenMSAA(
1343 *context, {100, 100}, 1);
1345 ->texture->GetTextureDescriptor()
1347 GetContext()->GetCapabilities()->GetDefaultDepthStencilFormat());
1350template <
class VertexShader,
class FragmentShader>
1352 const std::shared_ptr<Context>& context) {
1354 auto pipeline_desc =
1355 TexturePipelineBuilder::MakeDefaultPipelineDescriptor(*context);
1356 if (!pipeline_desc.has_value()) {
1360 pipeline_desc->SetStencilAttachmentDescriptors(std::nullopt);
1362 context->GetPipelineLibrary()->GetPipeline(pipeline_desc).Get();
1363 if (!pipeline || !pipeline->IsValid()) {
1371 using TextureVS = TextureVertexShader;
1372 using TextureFS = TextureFragmentShader;
1374 using SepiaVS = SepiaVertexShader;
1375 using SepiaFS = SepiaFragmentShader;
1377 auto context = GetContext();
1378 ASSERT_TRUE(context);
1380 if (!context->GetCapabilities()->SupportsFramebufferFetch()) {
1381 GTEST_SKIP() <<
"This test uses framebuffer fetch and the backend doesn't "
1387 auto texture_pipeline = CreateDefaultPipeline<TextureVS, TextureFS>(context);
1388 auto sepia_pipeline = CreateDefaultPipeline<SepiaVS, SepiaFS>(context);
1390 ASSERT_TRUE(texture_pipeline);
1391 ASSERT_TRUE(sepia_pipeline);
1396 {{100, 100, 0.0}, {0.0, 0.0}},
1397 {{800, 100, 0.0}, {1.0, 0.0}},
1398 {{800, 800, 0.0}, {1.0, 1.0}},
1399 {{100, 100, 0.0}, {0.0, 0.0}},
1400 {{800, 800, 0.0}, {1.0, 1.0}},
1401 {{100, 800, 0.0}, {0.0, 1.0}},
1414 auto boston = CreateTextureForFixture(
"boston.jpg");
1415 ASSERT_TRUE(boston);
1417 const auto& sampler = context->GetSamplerLibrary()->GetSampler({});
1418 ASSERT_TRUE(sampler);
1421 context->GetResourceAllocator(), context->GetIdleWaiter(),
1422 context->GetCapabilities()->GetMinimumUniformAlignment());
1426 pass.SetPipeline(texture_pipeline);
1428 *context->GetResourceAllocator()));
1429 TextureVS::UniformBuffer uniforms;
1432 TextureVS::BindUniformBuffer(pass,
buffer->EmplaceUniform(uniforms));
1433 TextureFS::BindTextureContents(pass, boston, sampler);
1434 if (!pass.Draw().ok()) {
1441 pass.SetPipeline(sepia_pipeline);
1443 *context->GetResourceAllocator()));
1444 SepiaVS::UniformBuffer uniforms;
1447 SepiaVS::BindUniformBuffer(pass,
buffer->EmplaceUniform(uniforms));
1448 if (!pass.Draw().ok()) {
1460 using TextureVS = TextureVertexShader;
1461 using TextureFS = TextureFragmentShader;
1463 using SwizzleVS = SepiaVertexShader;
1464 using SwizzleFS = SwizzleFragmentShader;
1466 using SepiaVS = SepiaVertexShader;
1467 using SepiaFS = SepiaFragmentShader;
1469 auto context = GetContext();
1470 ASSERT_TRUE(context);
1472 if (!context->GetCapabilities()->SupportsFramebufferFetch()) {
1473 GTEST_SKIP() <<
"This test uses framebuffer fetch and the backend doesn't "
1479 auto texture_pipeline = CreateDefaultPipeline<TextureVS, TextureFS>(context);
1480 auto swizzle_pipeline = CreateDefaultPipeline<SwizzleVS, SwizzleFS>(context);
1481 auto sepia_pipeline = CreateDefaultPipeline<SepiaVS, SepiaFS>(context);
1483 ASSERT_TRUE(texture_pipeline);
1484 ASSERT_TRUE(swizzle_pipeline);
1485 ASSERT_TRUE(sepia_pipeline);
1490 {{100, 100, 0.0}, {0.0, 0.0}},
1491 {{800, 100, 0.0}, {1.0, 0.0}},
1492 {{800, 800, 0.0}, {1.0, 1.0}},
1493 {{100, 100, 0.0}, {0.0, 0.0}},
1494 {{800, 800, 0.0}, {1.0, 1.0}},
1495 {{100, 800, 0.0}, {0.0, 1.0}},
1508 auto boston = CreateTextureForFixture(
"boston.jpg");
1509 ASSERT_TRUE(boston);
1511 const auto& sampler = context->GetSamplerLibrary()->GetSampler({});
1512 ASSERT_TRUE(sampler);
1515 context->GetResourceAllocator(), context->GetIdleWaiter(),
1516 context->GetCapabilities()->GetMinimumUniformAlignment());
1520 pass.SetPipeline(texture_pipeline);
1522 *context->GetResourceAllocator()));
1523 TextureVS::UniformBuffer uniforms;
1526 TextureVS::BindUniformBuffer(pass, data_buffer->EmplaceUniform(uniforms));
1527 TextureFS::BindTextureContents(pass, boston, sampler);
1528 if (!pass.Draw().ok()) {
1535 pass.SetPipeline(sepia_pipeline);
1537 *context->GetResourceAllocator()));
1538 SepiaVS::UniformBuffer uniforms;
1541 SepiaVS::BindUniformBuffer(pass, data_buffer->EmplaceUniform(uniforms));
1542 if (!pass.Draw().ok()) {
1549 pass.SetPipeline(swizzle_pipeline);
1551 *context->GetResourceAllocator()));
1552 SwizzleVS::UniformBuffer uniforms;
1555 SwizzleVS::BindUniformBuffer(pass, data_buffer->EmplaceUniform(uniforms));
1556 if (!pass.Draw().ok()) {
1567 using FS = BoxFadeFragmentShader;
1569 auto context = GetContext();
1571 auto command_buffer = context->CreateCommandBuffer();
1576 auto pass = command_buffer->CreateRenderPass(
target);
1577 EXPECT_FALSE(FS::BindContents2(*pass,
nullptr, sampler));
static BufferView AsBufferView(std::shared_ptr< DeviceBuffer > buffer)
Create a buffer view of this entire buffer.
static std::shared_ptr< HostBuffer > Create(const std::shared_ptr< Allocator > &allocator, const std::shared_ptr< const IdleWaiter > &idle_waiter, size_t minimum_uniform_alignment)
std::function< bool(RenderTarget &render_target)> RenderCallback
Render passes encode render commands directed as one specific render target into an underlying comman...
virtual bool SetVertexBuffer(VertexBuffer buffer)
Specify the vertex and index buffer to use for this command.
const Matrix & GetOrthographicTransform() const
virtual void SetPipeline(PipelineRef pipeline)
The pipeline to use for this command.
ISize GetRenderTargetSize() const
virtual void SetInstanceCount(size_t count)
virtual fml::Status Draw()
Record the currently pending command.
virtual void SetCommandLabel(std::string_view label)
The debugging label to use for the command.
a wrapper around the impeller [Allocator] instance that can be used to provide caching of allocated r...
RenderTarget & SetColorAttachment(const ColorAttachment &attachment, size_t index)
RenderTarget & SetStencilAttachment(std::optional< StencilAttachment > attachment)
const std::optional< DepthAttachment > & GetDepthAttachment() const
size_t GetVertexCount() const
size_t GetIndexCount() const
VertexBuffer CreateVertexBuffer(HostBuffer &data_host_buffer, HostBuffer &indexes_host_buffer) const
VertexBufferBuilder & AppendIndex(IndexType_ index)
void SetLabel(const std::string &label)
VertexBufferBuilder & AddVertices(std::initializer_list< VertexType_ > vertices)
constexpr impeller::IndexType GetIndexType() const
A wrapper around a raw ptr that adds additional unopt mode only checks.
CompareFunction FunctionOf(int index) const
const char *const * labels() const
int IndexOf(CompareFunction func) const
FlutterDesktopBinaryReply callback
#define FML_UNREACHABLE()
std::shared_ptr< ImpellerAllocator > allocator
it will be possible to load the file into Perfetto s trace viewer use test Running tests that layout and measure text will not yield consistent results across various platforms Enabling this option will make font resolution default to the Ahem test font on all disable asset Prevents usage of any non test fonts unless they were explicitly Loaded via prefetched default font Indicates whether the embedding started a prefetch of the default font manager before creating the engine run In non interactive keep the shell running after the Dart script has completed enable serial On low power devices with low core running concurrent GC tasks on threads can cause them to contend with the UI thread which could potentially lead to jank This option turns off all concurrent GC activities domain network JSON encoded network policy per domain This overrides the DisallowInsecureConnections switch Embedder can specify whether to allow or disallow insecure connections at a domain level old gen heap size
DEF_SWITCHES_START aot vmservice shared library Name of the *so containing AOT compiled Dart assets for launching the service isolate vm snapshot data
DEF_SWITCHES_START aot vmservice shared library Name of the *so containing AOT compiled Dart assets for launching the service isolate vm snapshot The VM snapshot data that will be memory mapped as read only SnapshotAssetPath must be present isolate snapshot The isolate snapshot data that will be memory mapped as read only SnapshotAssetPath must be present cache dir Path to the cache directory This is different from the persistent_cache_path in embedder which is used for Skia shader cache icu native lib Path to the library file that exports the ICU data vm service The hostname IP address on which the Dart VM Service should be served If not defaults to or::depending on whether ipv6 is specified disable vm Disable the Dart VM Service The Dart VM Service is never available in release mode Bind to the IPv6 localhost address for the Dart VM Service Ignored if vm service host is set profile Make the profiler discard new samples once the profiler sample buffer is full When this flag is not the profiler sample buffer is used as a ring buffer
PlaygroundTest RendererTest
static const CompareFunctionUIData & CompareFunctionUI()
TEST_P(AiksTest, DrawAtlasNoColor)
@ kNone
Does not use the index buffer.
LinePipeline::FragmentShader FS
@ kEqual
Comparison test passes if new_value == current_value.
@ kLessEqual
Comparison test passes if new_value <= current_value.
@ kGreaterEqual
Comparison test passes if new_value >= current_value.
@ kAlways
Comparison test passes always passes.
@ kLess
Comparison test passes if new_value < current_value.
@ kGreater
Comparison test passes if new_value > current_value.
@ kNotEqual
Comparison test passes if new_value != current_value.
@ kNever
Comparison test never passes.
MipFilter
Options for selecting and filtering between mipmap levels.
@ kLinear
Sample from the two nearest mip levels and linearly interpolate.
@ kBase
The texture is sampled as if it only had a single mipmap level.
@ kNearest
The nearst mipmap level is selected.
LinePipeline::VertexShader VS
static std::unique_ptr< PipelineT > CreateDefaultPipeline(const Context &context)
MinMagFilter
Describes how the texture should be sampled when the texture is being shrunk (minified) or expanded (...
@ kNearest
Select nearest to the sample point. Most widely supported.
#define INSTANTIATE_PLAYGROUND_SUITE(playground)
std::shared_ptr< Texture > texture
static constexpr Color Red()
static constexpr Color MakeRGBA8(uint8_t r, uint8_t g, uint8_t b, uint8_t a)
static constexpr Color Green()
static constexpr Matrix MakeOrthographic(TSize< T > size)
static constexpr Matrix MakeTranslation(const Vector3 &t)
static Matrix MakeRotationY(Radians r)
static Matrix MakePerspective(Radians fov_y, Scalar aspect_ratio, Scalar z_near, Scalar z_far)
static Matrix MakeRotationZ(Radians r)
static constexpr Matrix MakeScale(const Vector3 &s)
static Matrix MakeRotationX(Radians r)
An optional (but highly recommended) utility for creating pipelines from reflected shader information...
static std::optional< PipelineDescriptor > MakeDefaultPipelineDescriptor(const Context &context, const std::vector< Scalar > &constants={})
Create a default pipeline descriptor using the combination reflected shader information....
SamplerAddressMode width_address_mode
SamplerAddressMode height_address_mode
CompareFunction stencil_compare
A lightweight object that describes the attributes of a texture that can then used an allocator to cr...