51 using VS = BoxFadeVertexShader;
52 using FS = BoxFadeFragmentShader;
53 auto context = GetContext();
56 auto desc = BoxPipelineBuilder::MakeDefaultPipelineDescriptor(*context);
57 ASSERT_TRUE(desc.has_value());
59 desc->SetStencilAttachmentDescriptors(std::nullopt);
65 {{100, 100, 0.0}, {0.0, 0.0}},
66 {{800, 100, 0.0}, {1.0, 0.0}},
67 {{800, 800, 0.0}, {1.0, 1.0}},
68 {{100, 100, 0.0}, {0.0, 0.0}},
69 {{800, 800, 0.0}, {1.0, 1.0}},
70 {{100, 800, 0.0}, {0.0, 1.0}},
72 auto bridge = CreateTextureForFixture(
"bay_bridge.jpg");
73 auto boston = CreateTextureForFixture(
"boston.jpg");
74 ASSERT_TRUE(bridge && boston);
75 const std::unique_ptr<const Sampler>& sampler =
76 context->GetSamplerLibrary()->GetSampler({});
81 ImGui::Begin(
"Controls",
nullptr, ImGuiWindowFlags_AlwaysAutoResize);
82 static bool wireframe;
83 ImGui::Checkbox(
"Wireframe", &wireframe);
87 auto pipeline = context->GetPipelineLibrary()->GetPipeline(desc).Get();
89 assert(pipeline && pipeline->IsValid());
91 pass.SetCommandLabel(
"Box");
92 pass.SetPipeline(pipeline);
96 VS::UniformBuffer uniforms;
97 EXPECT_EQ(pass.GetOrthographicTransform(),
101 VS::BindUniformBuffer(pass, host_buffer->EmplaceUniform(uniforms));
103 FS::FrameInfo frame_info;
104 frame_info.current_time = GetSecondsElapsed();
105 frame_info.cursor_position = GetCursorPosition();
106 frame_info.window_size.x = GetWindowSize().width;
107 frame_info.window_size.y = GetWindowSize().height;
109 FS::BindFrameInfo(pass, host_buffer->EmplaceUniform(frame_info));
110 FS::BindContents1(pass, boston, sampler);
111 FS::BindContents2(pass, bridge, sampler);
113 host_buffer->Reset();
114 return pass.Draw().ok();
120 using VS = ColorsVertexShader;
121 using FS = ColorsFragmentShader;
122 auto context = GetContext();
123 ASSERT_TRUE(context);
125 ASSERT_TRUE(desc.has_value());
129 desc->SetStencilAttachmentDescriptors(std::nullopt);
131 context->GetPipelineLibrary()->GetPipeline(std::move(desc)).Get();
132 ASSERT_TRUE(pipeline);
135 VS::PerVertexData vertices[8] = {
137 {{-1, -1, -1}, Color::Red()},
138 {{1, -1, -1}, Color::Yellow()},
139 {{1, 1, -1}, Color::Green()},
140 {{-1, 1, -1}, Color::Blue()},
142 {{-1, -1, 1}, Color::Green()},
143 {{1, -1, 1}, Color::Blue()},
144 {{1, 1, 1}, Color::Red()},
145 {{-1, 1, 1}, Color::Yellow()},
147 uint16_t indices[36] = {
159 auto device_buffer = context->GetResourceAllocator()->CreateBufferWithCopy(
160 reinterpret_cast<uint8_t*
>(&cube),
sizeof(cube));
163 .range =
Range(offsetof(Cube, vertices),
sizeof(Cube::vertices))};
166 .range =
Range(offsetof(Cube, indices),
sizeof(Cube::indices))};
171 const std::unique_ptr<const Sampler>& sampler =
172 context->GetSamplerLibrary()->GetSampler({});
173 ASSERT_TRUE(sampler);
179 static Scalar distance = 10;
181 ImGui::Begin(
"Controls",
nullptr, ImGuiWindowFlags_AlwaysAutoResize);
182 ImGui::SliderFloat(
"Field of view", &fov_y.
degrees, 0, 180);
183 ImGui::SliderFloat(
"Camera distance", &distance, 0, 30);
186 pass.SetCommandLabel(
"Perspective Cube");
187 pass.SetPipeline(pipeline);
188 pass.SetVertexBuffer(vertex_buffer);
190 VS::UniformBuffer uniforms;
191 Scalar time = GetSecondsElapsed();
192 euler_angles =
Vector3(0.19 * time, 0.7 * time, 0.43 * time);
200 VS::BindUniformBuffer(pass, host_buffer->EmplaceUniform(uniforms));
202 host_buffer->Reset();
203 return pass.Draw().ok();
209 using VS = BoxFadeVertexShader;
210 using FS = BoxFadeFragmentShader;
211 auto context = GetContext();
212 ASSERT_TRUE(context);
214 auto desc = BoxPipelineBuilder::MakeDefaultPipelineDescriptor(*context);
215 ASSERT_TRUE(desc.has_value());
217 desc->SetStencilAttachmentDescriptors(std::nullopt);
219 context->GetPipelineLibrary()->GetPipeline(std::move(desc)).Get();
220 ASSERT_TRUE(box_pipeline);
226 {{100, 100, 0.0}, {0.0, 0.0}},
227 {{800, 100, 0.0}, {1.0, 0.0}},
228 {{800, 800, 0.0}, {1.0, 1.0}},
229 {{100, 100, 0.0}, {0.0, 0.0}},
230 {{800, 800, 0.0}, {1.0, 1.0}},
231 {{100, 800, 0.0}, {0.0, 1.0}},
235 ASSERT_TRUE(vertex_buffer);
237 auto bridge = CreateTextureForFixture(
"bay_bridge.jpg");
238 auto boston = CreateTextureForFixture(
"boston.jpg");
239 ASSERT_TRUE(bridge && boston);
240 const std::unique_ptr<const Sampler>& sampler =
241 context->GetSamplerLibrary()->GetSampler({});
242 ASSERT_TRUE(sampler);
246 for (
size_t i = 0; i < 1; i++) {
247 for (
size_t j = 0; j < 1; j++) {
248 pass.SetCommandLabel(
"Box");
249 pass.SetPipeline(box_pipeline);
250 pass.SetVertexBuffer(vertex_buffer);
252 FS::FrameInfo frame_info;
253 frame_info.current_time = GetSecondsElapsed();
254 frame_info.cursor_position = GetCursorPosition();
255 frame_info.window_size.x = GetWindowSize().width;
256 frame_info.window_size.y = GetWindowSize().height;
258 FS::BindFrameInfo(pass, host_buffer->EmplaceUniform(frame_info));
259 FS::BindContents1(pass, boston, sampler);
260 FS::BindContents2(pass, bridge, sampler);
262 VS::UniformBuffer uniforms;
263 EXPECT_EQ(pass.GetOrthographicTransform(),
265 uniforms.mvp = pass.GetOrthographicTransform() *
268 VS::BindUniformBuffer(pass, host_buffer->EmplaceUniform(uniforms));
269 if (!pass.Draw().ok()) {
275 host_buffer->Reset();
282 using VS = BoxFadeVertexShader;
283 using FS = BoxFadeFragmentShader;
284 auto context = GetContext();
285 ASSERT_TRUE(context);
288 BoxPipelineBuilder::MakeDefaultPipelineDescriptor(*context);
290 pipeline_desc->ClearDepthAttachment();
293 ASSERT_TRUE(pipeline_desc.has_value());
295 context->GetPipelineLibrary()->GetPipeline(pipeline_desc).Get();
296 ASSERT_TRUE(box_pipeline);
302 {{100, 100, 0.0}, {0.0, 0.0}},
303 {{800, 100, 0.0}, {1.0, 0.0}},
304 {{800, 800, 0.0}, {1.0, 1.0}},
305 {{100, 100, 0.0}, {0.0, 0.0}},
306 {{800, 800, 0.0}, {1.0, 1.0}},
307 {{100, 800, 0.0}, {0.0, 1.0}},
311 ASSERT_TRUE(vertex_buffer);
313 auto bridge = CreateTextureForFixture(
"bay_bridge.jpg");
314 auto boston = CreateTextureForFixture(
"boston.jpg");
315 ASSERT_TRUE(bridge && boston);
316 const std::unique_ptr<const Sampler>& sampler =
317 context->GetSamplerLibrary()->GetSampler({});
318 ASSERT_TRUE(sampler);
320 std::shared_ptr<RenderPass> r2t_pass;
321 auto cmd_buffer = context->CreateCommandBuffer();
322 ASSERT_TRUE(cmd_buffer);
329 ASSERT_NE(pipeline_desc->GetColorAttachmentDescriptor(0u),
nullptr);
330 texture_descriptor.
format =
331 pipeline_desc->GetColorAttachmentDescriptor(0u)->format;
333 texture_descriptor.
size = {400, 400};
338 context->GetResourceAllocator()->CreateTexture(texture_descriptor);
342 color0.
texture->SetLabel(
"r2t_target");
349 stencil_texture_desc.
size = texture_descriptor.
size;
353 context->GetResourceAllocator()->CreateTexture(stencil_texture_desc);
358 r2t_pass = cmd_buffer->CreateRenderPass(r2t_desc);
359 ASSERT_TRUE(r2t_pass && r2t_pass->IsValid());
362 r2t_pass->SetCommandLabel(
"Box");
363 r2t_pass->SetPipeline(box_pipeline);
364 r2t_pass->SetVertexBuffer(vertex_buffer);
366 FS::FrameInfo frame_info;
367 frame_info.current_time = GetSecondsElapsed();
368 frame_info.cursor_position = GetCursorPosition();
369 frame_info.window_size.x = GetWindowSize().width;
370 frame_info.window_size.y = GetWindowSize().height;
372 FS::BindFrameInfo(*r2t_pass, host_buffer->EmplaceUniform(frame_info));
373 FS::BindContents1(*r2t_pass, boston, sampler);
374 FS::BindContents2(*r2t_pass, bridge, sampler);
376 VS::UniformBuffer uniforms;
379 VS::BindUniformBuffer(*r2t_pass, host_buffer->EmplaceUniform(uniforms));
380 ASSERT_TRUE(r2t_pass->Draw().ok());
381 ASSERT_TRUE(r2t_pass->EncodeCommands());
386 GTEST_SKIP_(
"Instancing is not supported on OpenGL.");
388 using VS = InstancedDrawVertexShader;
389 using FS = InstancedDrawFragmentShader;
399 [&builder](
const float* vertices,
size_t vertices_count,
400 const uint16_t* indices,
size_t indices_count) {
401 for (
auto i = 0u; i < vertices_count * 2; i += 2) {
402 VS::PerVertexData data;
403 data.vtx = {vertices[i], vertices[i + 1]};
404 builder.AppendVertex(data);
406 for (
auto i = 0u; i < indices_count; i++) {
407 builder.AppendIndex(indices[i]);
412 ASSERT_NE(GetContext(),
nullptr);
415 ->GetPipelineLibrary()
419 .SetStencilAttachmentDescriptors(std::nullopt))
422 ASSERT_TRUE(pipeline && pipeline->IsValid());
424 static constexpr size_t kInstancesCount = 5u;
425 VS::InstanceInfo<kInstancesCount> instances;
426 for (
size_t i = 0; i < kInstancesCount; i++) {
431 ASSERT_TRUE(OpenPlaygroundHere([&](
RenderPass& pass) ->
bool {
435 VS::FrameInfo frame_info;
440 VS::BindFrameInfo(pass, host_buffer->EmplaceUniform(frame_info));
441 VS::BindInstanceInfo(pass, host_buffer->EmplaceStorageBuffer(instances));
447 host_buffer->Reset();
454 GTEST_SKIP() <<
"Mipmap test shader not supported on GLES.";
456 auto context = GetContext();
457 ASSERT_TRUE(context);
459 using VS = MipmapsVertexShader;
460 using FS = MipmapsFragmentShader;
462 ASSERT_TRUE(desc.has_value());
464 desc->SetStencilAttachmentDescriptors(std::nullopt);
465 auto mipmaps_pipeline =
466 context->GetPipelineLibrary()->GetPipeline(std::move(desc)).Get();
467 ASSERT_TRUE(mipmaps_pipeline);
472 texture_desc.
size = {800, 600};
475 auto texture = context->GetResourceAllocator()->CreateTexture(texture_desc);
478 auto bridge = CreateTextureForFixture(
"bay_bridge.jpg");
479 auto boston = CreateTextureForFixture(
"boston.jpg");
480 ASSERT_TRUE(bridge && boston);
481 const std::unique_ptr<const Sampler>& sampler =
482 context->GetSamplerLibrary()->GetSampler({});
483 ASSERT_TRUE(sampler);
488 auto size =
Point(boston->GetSize());
490 {{0, 0}, {0.0, 0.0}},
491 {{size.x, 0}, {1.0, 0.0}},
492 {{size.x, size.y}, {1.0, 1.0}},
493 {{0, 0}, {0.0, 0.0}},
494 {{size.x, size.y}, {1.0, 1.0}},
495 {{0, size.y}, {0.0, 1.0}},
499 ASSERT_TRUE(vertex_buffer);
503 auto buffer = context->CreateCommandBuffer();
507 buffer->SetLabel(
"Playground Command Buffer");
510 auto pass =
buffer->CreateBlitPass();
514 pass->SetLabel(
"Playground Blit Pass");
516 if (render_target.GetColorAttachments().empty()) {
521 pass->AddCopy(bridge,
texture);
523 if (!pass->EncodeCommands(context->GetResourceAllocator())) {
529 auto pass =
buffer->CreateRenderPass(render_target);
533 pass->SetLabel(
"Playground Render Pass");
535 pass->SetCommandLabel(
"Image");
536 pass->SetPipeline(mipmaps_pipeline);
537 pass->SetVertexBuffer(vertex_buffer);
539 VS::FrameInfo frame_info;
540 EXPECT_EQ(pass->GetOrthographicTransform(),
542 frame_info.mvp = pass->GetOrthographicTransform() *
544 VS::BindFrameInfo(*pass, host_buffer->EmplaceUniform(frame_info));
546 FS::FragInfo frag_info;
548 FS::BindFragInfo(*pass, host_buffer->EmplaceUniform(frag_info));
550 auto& sampler = context->GetSamplerLibrary()->GetSampler({});
551 FS::BindTex(*pass,
texture, sampler);
555 pass->EncodeCommands();
558 if (!context->GetCommandQueue()->Submit({buffer}).ok()) {
561 host_buffer->Reset();
569 GTEST_SKIP() <<
"Mipmap test shader not supported on GLES.";
571 auto context = GetContext();
572 ASSERT_TRUE(context);
574 using VS = MipmapsVertexShader;
575 using FS = MipmapsFragmentShader;
577 ASSERT_TRUE(desc.has_value());
579 desc->SetStencilAttachmentDescriptors(std::nullopt);
580 auto mipmaps_pipeline =
581 context->GetPipelineLibrary()->GetPipeline(std::move(desc)).Get();
582 ASSERT_TRUE(mipmaps_pipeline);
584 auto bridge = CreateTextureForFixture(
"bay_bridge.jpg");
585 auto boston = CreateTextureForFixture(
"boston.jpg");
586 ASSERT_TRUE(bridge && boston);
587 const std::unique_ptr<const Sampler>& sampler =
588 context->GetSamplerLibrary()->GetSampler({});
589 ASSERT_TRUE(sampler);
594 texture_desc.
size = bridge->GetTextureDescriptor().size;
600 device_buffer_desc.
size =
601 bridge->GetTextureDescriptor().GetByteSizeOfBaseMipLevel();
603 context->GetResourceAllocator()->CreateBuffer(device_buffer_desc);
608 auto size =
Point(boston->GetSize());
610 {{0, 0}, {0.0, 0.0}},
611 {{size.x, 0}, {1.0, 0.0}},
612 {{size.x, size.y}, {1.0, 1.0}},
613 {{0, 0}, {0.0, 0.0}},
614 {{size.x, size.y}, {1.0, 1.0}},
615 {{0, size.y}, {0.0, 1.0}},
619 ASSERT_TRUE(vertex_buffer);
624 auto buffer = context->CreateCommandBuffer();
628 buffer->SetLabel(
"Playground Command Buffer");
629 auto pass =
buffer->CreateBlitPass();
633 pass->SetLabel(
"Playground Blit Pass");
635 if (render_target.GetColorAttachments().empty()) {
640 pass->AddCopy(bridge, device_buffer);
641 pass->EncodeCommands(context->GetResourceAllocator());
643 if (!context->GetCommandQueue()->Submit({
buffer}).
ok()) {
649 auto buffer = context->CreateCommandBuffer();
653 buffer->SetLabel(
"Playground Command Buffer");
655 auto pass =
buffer->CreateRenderPass(render_target);
659 pass->SetLabel(
"Playground Render Pass");
661 pass->SetCommandLabel(
"Image");
662 pass->SetPipeline(mipmaps_pipeline);
663 pass->SetVertexBuffer(vertex_buffer);
665 VS::FrameInfo frame_info;
666 EXPECT_EQ(pass->GetOrthographicTransform(),
668 frame_info.mvp = pass->GetOrthographicTransform() *
670 VS::BindFrameInfo(*pass, host_buffer->EmplaceUniform(frame_info));
672 FS::FragInfo frag_info;
674 FS::BindFragInfo(*pass, host_buffer->EmplaceUniform(frag_info));
676 const std::unique_ptr<const Sampler>& sampler =
677 context->GetSamplerLibrary()->GetSampler({});
680 context->GetResourceAllocator()->CreateTexture(texture_desc);
681 if (!
texture->SetContents(device_buffer->OnGetContents(),
682 buffer_view.range.length)) {
686 FS::BindTex(*pass,
texture, sampler);
690 pass->EncodeCommands();
691 if (!context->GetCommandQueue()->Submit({buffer}).ok()) {
695 host_buffer->Reset();
703 GTEST_SKIP() <<
"Mipmap test shader not supported on GLES.";
705 auto context = GetContext();
706 ASSERT_TRUE(context);
708 using VS = MipmapsVertexShader;
709 using FS = MipmapsFragmentShader;
711 ASSERT_TRUE(desc.has_value());
713 desc->SetStencilAttachmentDescriptors(std::nullopt);
714 auto mipmaps_pipeline =
715 context->GetPipelineLibrary()->GetPipeline(std::move(desc)).Get();
716 ASSERT_TRUE(mipmaps_pipeline);
718 auto boston = CreateTextureForFixture(
"boston.jpg",
true);
724 auto size =
Point(boston->GetSize());
726 {{0, 0}, {0.0, 0.0}},
727 {{size.x, 0}, {1.0, 0.0}},
728 {{size.x, size.y}, {1.0, 1.0}},
729 {{0, 0}, {0.0, 0.0}},
730 {{size.x, size.y}, {1.0, 1.0}},
731 {{0, size.y}, {0.0, 1.0}},
735 ASSERT_TRUE(vertex_buffer);
737 bool first_frame =
true;
740 const char* mip_filter_names[] = {
"Nearest",
"Linear"};
742 const char* min_filter_names[] = {
"Nearest",
"Linear"};
747 static int selected_mip_filter = 1;
748 static int selected_min_filter = 0;
749 static float lod = 4.5;
751 ImGui::Begin(
"Controls",
nullptr, ImGuiWindowFlags_AlwaysAutoResize);
752 ImGui::Combo(
"Mip filter", &selected_mip_filter, mip_filter_names,
753 sizeof(mip_filter_names) /
sizeof(
char*));
754 ImGui::Combo(
"Min filter", &selected_min_filter, min_filter_names,
755 sizeof(min_filter_names) /
sizeof(
char*));
756 ImGui::SliderFloat(
"LOD", &lod, 0, boston->GetMipCount() - 1);
759 auto buffer = context->CreateCommandBuffer();
763 buffer->SetLabel(
"Playground Command Buffer");
766 auto pass =
buffer->CreateBlitPass();
770 pass->SetLabel(
"Playground Blit Pass");
772 pass->GenerateMipmap(boston,
"Boston Mipmap");
774 pass->EncodeCommands(context->GetResourceAllocator());
780 auto pass =
buffer->CreateRenderPass(render_target);
784 pass->SetLabel(
"Playground Render Pass");
786 pass->SetCommandLabel(
"Image LOD");
787 pass->SetPipeline(mipmaps_pipeline);
788 pass->SetVertexBuffer(vertex_buffer);
790 VS::FrameInfo frame_info;
791 EXPECT_EQ(pass->GetOrthographicTransform(),
793 frame_info.mvp = pass->GetOrthographicTransform() *
795 VS::BindFrameInfo(*pass, host_buffer->EmplaceUniform(frame_info));
797 FS::FragInfo frag_info;
799 FS::BindFragInfo(*pass, host_buffer->EmplaceUniform(frag_info));
802 sampler_desc.
mip_filter = mip_filters[selected_mip_filter];
803 sampler_desc.
min_filter = min_filters[selected_min_filter];
804 const std::unique_ptr<const Sampler>& sampler =
805 context->GetSamplerLibrary()->GetSampler(sampler_desc);
806 FS::BindTex(*pass, boston, sampler);
810 pass->EncodeCommands();
813 if (!context->GetCommandQueue()->Submit({buffer}).ok()) {
816 host_buffer->Reset();
823 using VS = ImpellerVertexShader;
824 using FS = ImpellerFragmentShader;
826 auto context = GetContext();
827 auto pipeline_descriptor =
829 ASSERT_TRUE(pipeline_descriptor.has_value());
831 pipeline_descriptor->SetStencilAttachmentDescriptors(std::nullopt);
833 context->GetPipelineLibrary()->GetPipeline(pipeline_descriptor).Get();
834 ASSERT_TRUE(pipeline && pipeline->IsValid());
836 auto blue_noise = CreateTextureForFixture(
"blue_noise.png");
840 const std::unique_ptr<const Sampler>& noise_sampler =
841 context->GetSamplerLibrary()->GetSampler(noise_sampler_desc);
843 auto cube_map = CreateTextureCubeForFixture(
844 {
"table_mountain_px.png",
"table_mountain_nx.png",
845 "table_mountain_py.png",
"table_mountain_ny.png",
846 "table_mountain_pz.png",
"table_mountain_nz.png"});
847 const std::unique_ptr<const Sampler>& cube_map_sampler =
848 context->GetSamplerLibrary()->GetSampler({});
852 auto size = pass.GetRenderTargetSize();
854 pass.SetPipeline(pipeline);
855 pass.SetCommandLabel(
"Impeller SDF scene");
857 builder.AddVertices({{
Point()},
858 {
Point(0, size.height)},
859 {
Point(size.width, 0)},
860 {
Point(size.width, 0)},
861 {
Point(0, size.height)},
862 {
Point(size.width, size.height)}});
863 pass.SetVertexBuffer(builder.CreateVertexBuffer(*host_buffer));
865 VS::FrameInfo frame_info;
867 frame_info.mvp = pass.GetOrthographicTransform();
868 VS::BindFrameInfo(pass, host_buffer->EmplaceUniform(frame_info));
870 FS::FragInfo fs_uniform;
871 fs_uniform.texture_size =
Point(size);
872 fs_uniform.time = GetSecondsElapsed();
873 FS::BindFragInfo(pass, host_buffer->EmplaceUniform(fs_uniform));
874 FS::BindBlueNoise(pass, blue_noise, noise_sampler);
875 FS::BindCubeMap(pass, cube_map, cube_map_sampler);
878 host_buffer->Reset();
885 using VS = ArrayVertexShader;
886 using FS = ArrayFragmentShader;
888 auto context = GetContext();
889 auto pipeline_descriptor =
891 ASSERT_TRUE(pipeline_descriptor.has_value());
893 pipeline_descriptor->SetStencilAttachmentDescriptors(std::nullopt);
895 context->GetPipelineLibrary()->GetPipeline(pipeline_descriptor).Get();
896 ASSERT_TRUE(pipeline && pipeline->IsValid());
900 auto size = pass.GetRenderTargetSize();
902 pass.SetPipeline(pipeline);
903 pass.SetCommandLabel(
"Google Dots");
905 builder.AddVertices({{
Point()},
906 {
Point(0, size.height)},
907 {
Point(size.width, 0)},
908 {
Point(size.width, 0)},
909 {
Point(0, size.height)},
910 {
Point(size.width, size.height)}});
911 pass.SetVertexBuffer(builder.CreateVertexBuffer(*host_buffer));
913 VS::FrameInfo frame_info;
917 VS::BindFrameInfo(pass, host_buffer->EmplaceUniform(frame_info));
919 auto time = GetSecondsElapsed();
920 auto y_pos = [&time](
float x) {
921 return 400 + 10 * std::cos(time * 5 +
x / 6);
924 FS::FragInfo fs_uniform = {
925 .circle_positions = {
Point(430, y_pos(0)),
Point(480, y_pos(1)),
932 FS::BindFragInfo(pass, host_buffer->EmplaceUniform(fs_uniform));
935 host_buffer->Reset();
942 using VS = InactiveUniformsVertexShader;
943 using FS = InactiveUniformsFragmentShader;
945 auto context = GetContext();
946 auto pipeline_descriptor =
948 ASSERT_TRUE(pipeline_descriptor.has_value());
950 pipeline_descriptor->SetStencilAttachmentDescriptors(std::nullopt);
952 context->GetPipelineLibrary()->GetPipeline(pipeline_descriptor).Get();
953 ASSERT_TRUE(pipeline && pipeline->IsValid());
957 auto size = pass.GetRenderTargetSize();
959 pass.SetPipeline(pipeline);
960 pass.SetCommandLabel(
"Inactive Uniform");
963 builder.AddVertices({{
Point()},
964 {
Point(0, size.height)},
965 {
Point(size.width, 0)},
966 {
Point(size.width, 0)},
967 {
Point(0, size.height)},
968 {
Point(size.width, size.height)}});
969 pass.SetVertexBuffer(builder.CreateVertexBuffer(*host_buffer));
971 VS::FrameInfo frame_info;
975 VS::BindFrameInfo(pass, host_buffer->EmplaceUniform(frame_info));
977 FS::FragInfo fs_uniform = {.unused_color =
Color::Red(),
979 FS::BindFragInfo(pass, host_buffer->EmplaceUniform(fs_uniform));
982 host_buffer->Reset();
1114 using VS = BoxFadeVertexShader;
1115 using FS = BoxFadeFragmentShader;
1116 auto context = GetContext();
1117 ASSERT_TRUE(context);
1119 auto desc = BoxFadePipelineBuilder::MakeDefaultPipelineDescriptor(*context);
1120 ASSERT_TRUE(desc.has_value());
1126 {{100, 100, 0.0}, {0.0, 0.0}},
1127 {{800, 100, 0.0}, {1.0, 0.0}},
1128 {{800, 800, 0.0}, {1.0, 1.0}},
1129 {{100, 100, 0.0}, {0.0, 0.0}},
1130 {{800, 800, 0.0}, {1.0, 1.0}},
1131 {{100, 800, 0.0}, {0.0, 1.0}},
1133 auto vertex_buffer =
1135 ASSERT_TRUE(vertex_buffer);
1138 desc->SetStencilAttachmentDescriptors(std::nullopt);
1140 auto bridge = CreateTextureForFixture(
"bay_bridge.jpg");
1141 auto boston = CreateTextureForFixture(
"boston.jpg");
1142 ASSERT_TRUE(bridge && boston);
1143 const std::unique_ptr<const Sampler>& sampler =
1144 context->GetSamplerLibrary()->GetSampler({});
1145 ASSERT_TRUE(sampler);
1147 static bool mirror =
false;
1148 static int stencil_reference_write = 0xFF;
1149 static int stencil_reference_read = 0x1;
1150 std::vector<uint8_t> stencil_contents;
1151 static int last_stencil_contents_reference_value = 0;
1152 static int current_front_compare =
1154 static int current_back_compare =
1159 auto buffer = context->CreateCommandBuffer();
1163 buffer->SetLabel(
"Playground Command Buffer");
1171 render_target.SetupDepthStencilAttachments(
1172 *context, *context->GetResourceAllocator(),
1173 render_target.GetRenderTargetSize(),
true,
"stencil", stencil_config);
1175 const auto target_width = render_target.GetRenderTargetSize().width;
1176 const auto target_height = render_target.GetRenderTargetSize().height;
1177 const size_t target_size = target_width * target_height;
1178 if (stencil_contents.size() != target_size ||
1179 last_stencil_contents_reference_value != stencil_reference_write) {
1180 stencil_contents.resize(target_size);
1181 last_stencil_contents_reference_value = stencil_reference_write;
1182 for (
int y = 0;
y < target_height;
y++) {
1183 for (
int x = 0;
x < target_width;
x++) {
1184 const auto index =
y * target_width +
x;
1185 const auto kCheckSize = 64;
1187 (((
y / kCheckSize) + (
x / kCheckSize)) % 2 == 0) *
1188 stencil_reference_write;
1189 stencil_contents[index] =
value;
1193 if (!render_target.GetStencilAttachment()->texture->SetContents(
1194 stencil_contents.data(), stencil_contents.size(), 0,
false)) {
1195 VALIDATION_LOG <<
"Could not upload stencil contents to device memory";
1198 auto pass =
buffer->CreateRenderPass(render_target);
1202 pass->SetLabel(
"Stencil Buffer");
1203 ImGui::Begin(
"Controls",
nullptr, ImGuiWindowFlags_AlwaysAutoResize);
1204 ImGui::SliderInt(
"Stencil Write Value", &stencil_reference_write, 0,
1206 ImGui::SliderInt(
"Stencil Compare Value", &stencil_reference_read, 0,
1208 ImGui::Checkbox(
"Back face mode", &
mirror);
1209 ImGui::ListBox(
"Front face compare function", ¤t_front_compare,
1211 ImGui::ListBox(
"Back face compare function", ¤t_back_compare,
1221 desc->SetStencilAttachmentDescriptors(front, back);
1222 auto pipeline = context->GetPipelineLibrary()->GetPipeline(desc).Get();
1224 assert(pipeline && pipeline->IsValid());
1226 pass->SetCommandLabel(
"Box");
1227 pass->SetPipeline(pipeline);
1228 pass->SetStencilReference(stencil_reference_read);
1229 pass->SetVertexBuffer(vertex_buffer);
1231 VS::UniformBuffer uniforms;
1232 EXPECT_EQ(pass->GetOrthographicTransform(),
1234 uniforms.mvp = pass->GetOrthographicTransform() *
1239 VS::BindUniformBuffer(*pass, host_buffer->EmplaceUniform(uniforms));
1241 FS::FrameInfo frame_info;
1242 frame_info.current_time = GetSecondsElapsed();
1243 frame_info.cursor_position = GetCursorPosition();
1244 frame_info.window_size.x = GetWindowSize().width;
1245 frame_info.window_size.y = GetWindowSize().height;
1247 FS::BindFrameInfo(*pass, host_buffer->EmplaceUniform(frame_info));
1248 FS::BindContents1(*pass, boston, sampler);
1249 FS::BindContents2(*pass, bridge, sampler);
1250 if (!pass->Draw().ok()) {
1253 pass->EncodeCommands();
1256 if (!context->GetCommandQueue()->Submit({buffer}).ok()) {
1259 host_buffer->Reset();
1266 auto context = GetContext();
1267 auto cmd_buffer = context->CreateCommandBuffer();
1268 auto render_target_cache = std::make_shared<RenderTargetAllocator>(
1269 GetContext()->GetResourceAllocator());
1271 auto render_target = render_target_cache->CreateOffscreen(
1272 *context, {100, 100}, 1);
1273 auto render_pass = cmd_buffer->CreateRenderPass(render_target);
1275 EXPECT_EQ(render_pass->GetSampleCount(), render_target.GetSampleCount());
1276 EXPECT_EQ(render_pass->GetRenderTargetPixelFormat(),
1277 render_target.GetRenderTargetPixelFormat());
1278 EXPECT_EQ(render_pass->HasStencilAttachment(),
1279 render_target.GetStencilAttachment().has_value());
1280 EXPECT_EQ(render_pass->GetRenderTargetSize(),
1281 render_target.GetRenderTargetSize());
1282 render_pass->EncodeCommands();
1323 GTEST_SKIP_(
"Not supported on GLES.");
1327 using TextureVS = TextureVertexShader;
1328 using TextureFS = TextureFragmentShader;
1330 using SepiaVS = SepiaVertexShader;
1331 using SepiaFS = SepiaFragmentShader;
1333 auto context = GetContext();
1334 ASSERT_TRUE(context);
1336 if (!context->GetCapabilities()->SupportsFramebufferFetch()) {
1338 "This test uses framebuffer fetch and the backend doesn't support it.");
1343 auto texture_pipeline = CreateDefaultPipeline<TextureVS, TextureFS>(context);
1344 auto sepia_pipeline = CreateDefaultPipeline<SepiaVS, SepiaFS>(context);
1346 ASSERT_TRUE(texture_pipeline);
1347 ASSERT_TRUE(sepia_pipeline);
1352 {{100, 100, 0.0}, {0.0, 0.0}},
1353 {{800, 100, 0.0}, {1.0, 0.0}},
1354 {{800, 800, 0.0}, {1.0, 1.0}},
1355 {{100, 100, 0.0}, {0.0, 0.0}},
1356 {{800, 800, 0.0}, {1.0, 1.0}},
1357 {{100, 800, 0.0}, {0.0, 1.0}},
1370 auto boston = CreateTextureForFixture(
"boston.jpg");
1371 ASSERT_TRUE(boston);
1373 const auto& sampler = context->GetSamplerLibrary()->GetSampler({});
1374 ASSERT_TRUE(sampler);
1381 pass.SetPipeline(texture_pipeline);
1383 *context->GetResourceAllocator()));
1384 TextureVS::UniformBuffer uniforms;
1387 TextureVS::BindUniformBuffer(pass,
buffer->EmplaceUniform(uniforms));
1388 TextureFS::BindTextureContents(pass, boston, sampler);
1389 if (!pass.Draw().ok()) {
1396 pass.SetPipeline(sepia_pipeline);
1398 *context->GetResourceAllocator()));
1399 SepiaVS::UniformBuffer uniforms;
1402 SepiaVS::BindUniformBuffer(pass,
buffer->EmplaceUniform(uniforms));
1403 if (!pass.Draw().ok()) {
1418 GTEST_SKIP_(
"Not supported on GLES.");
1422 using TextureVS = TextureVertexShader;
1423 using TextureFS = TextureFragmentShader;
1425 using SwizzleVS = SepiaVertexShader;
1426 using SwizzleFS = SwizzleFragmentShader;
1428 using SepiaVS = SepiaVertexShader;
1429 using SepiaFS = SepiaFragmentShader;
1431 auto context = GetContext();
1432 ASSERT_TRUE(context);
1434 if (!context->GetCapabilities()->SupportsFramebufferFetch()) {
1436 "This test uses framebuffer fetch and the backend doesn't support it.");
1441 auto texture_pipeline = CreateDefaultPipeline<TextureVS, TextureFS>(context);
1442 auto swizzle_pipeline = CreateDefaultPipeline<SwizzleVS, SwizzleFS>(context);
1443 auto sepia_pipeline = CreateDefaultPipeline<SepiaVS, SepiaFS>(context);
1445 ASSERT_TRUE(texture_pipeline);
1446 ASSERT_TRUE(swizzle_pipeline);
1447 ASSERT_TRUE(sepia_pipeline);
1452 {{100, 100, 0.0}, {0.0, 0.0}},
1453 {{800, 100, 0.0}, {1.0, 0.0}},
1454 {{800, 800, 0.0}, {1.0, 1.0}},
1455 {{100, 100, 0.0}, {0.0, 0.0}},
1456 {{800, 800, 0.0}, {1.0, 1.0}},
1457 {{100, 800, 0.0}, {0.0, 1.0}},
1470 auto boston = CreateTextureForFixture(
"boston.jpg");
1471 ASSERT_TRUE(boston);
1473 const auto& sampler = context->GetSamplerLibrary()->GetSampler({});
1474 ASSERT_TRUE(sampler);
1481 pass.SetPipeline(texture_pipeline);
1483 *context->GetResourceAllocator()));
1484 TextureVS::UniformBuffer uniforms;
1487 TextureVS::BindUniformBuffer(pass,
buffer->EmplaceUniform(uniforms));
1488 TextureFS::BindTextureContents(pass, boston, sampler);
1489 if (!pass.Draw().ok()) {
1496 pass.SetPipeline(sepia_pipeline);
1498 *context->GetResourceAllocator()));
1499 SepiaVS::UniformBuffer uniforms;
1502 SepiaVS::BindUniformBuffer(pass,
buffer->EmplaceUniform(uniforms));
1503 if (!pass.Draw().ok()) {
1510 pass.SetPipeline(swizzle_pipeline);
1512 *context->GetResourceAllocator()));
1513 SwizzleVS::UniformBuffer uniforms;
1516 SwizzleVS::BindUniformBuffer(pass,
buffer->EmplaceUniform(uniforms));
1517 if (!pass.Draw().ok()) {
A lightweight object that describes the attributes of a texture that can then used an allocator to cr...