5 #include "flutter/fml/logging.h"
10 #include "impeller/fixtures/array.frag.h"
11 #include "impeller/fixtures/array.vert.h"
12 #include "impeller/fixtures/box_fade.frag.h"
13 #include "impeller/fixtures/box_fade.vert.h"
14 #include "impeller/fixtures/colors.frag.h"
15 #include "impeller/fixtures/colors.vert.h"
16 #include "impeller/fixtures/impeller.frag.h"
17 #include "impeller/fixtures/impeller.vert.h"
18 #include "impeller/fixtures/inactive_uniforms.frag.h"
19 #include "impeller/fixtures/inactive_uniforms.vert.h"
20 #include "impeller/fixtures/instanced_draw.frag.h"
21 #include "impeller/fixtures/instanced_draw.vert.h"
22 #include "impeller/fixtures/mipmaps.frag.h"
23 #include "impeller/fixtures/mipmaps.vert.h"
35 #include "third_party/imgui/imgui.h"
47 using VS = BoxFadeVertexShader;
48 using FS = BoxFadeFragmentShader;
49 auto context = GetContext();
52 auto desc = BoxPipelineBuilder::MakeDefaultPipelineDescriptor(*context);
53 ASSERT_TRUE(desc.has_value());
55 desc->SetStencilAttachmentDescriptors(std::nullopt);
61 {{100, 100, 0.0}, {0.0, 0.0}},
62 {{800, 100, 0.0}, {1.0, 0.0}},
63 {{800, 800, 0.0}, {1.0, 1.0}},
64 {{100, 100, 0.0}, {0.0, 0.0}},
65 {{800, 800, 0.0}, {1.0, 1.0}},
66 {{100, 800, 0.0}, {0.0, 1.0}},
68 auto bridge = CreateTextureForFixture(
"bay_bridge.jpg");
69 auto boston = CreateTextureForFixture(
"boston.jpg");
70 ASSERT_TRUE(bridge && boston);
71 auto sampler = context->GetSamplerLibrary()->GetSampler({});
73 SinglePassCallback callback = [&](
RenderPass& pass) {
74 ImGui::Begin(
"Controls",
nullptr, ImGuiWindowFlags_AlwaysAutoResize);
75 static bool wireframe;
76 ImGui::Checkbox(
"Wireframe", &wireframe);
80 auto pipeline = context->GetPipelineLibrary()->GetPipeline(desc).Get();
82 assert(pipeline && pipeline->IsValid());
91 VS::UniformBuffer uniforms;
92 EXPECT_EQ(pass.GetOrthographicTransform(),
96 VS::BindUniformBuffer(cmd,
97 pass.GetTransientsBuffer().EmplaceUniform(uniforms));
99 FS::FrameInfo frame_info;
100 frame_info.current_time = GetSecondsElapsed();
101 frame_info.cursor_position = GetCursorPosition();
102 frame_info.window_size.x = GetWindowSize().width;
103 frame_info.window_size.y = GetWindowSize().height;
105 FS::BindFrameInfo(cmd,
106 pass.GetTransientsBuffer().EmplaceUniform(frame_info));
107 FS::BindContents1(cmd, boston, sampler);
108 FS::BindContents2(cmd, bridge, sampler);
109 if (!pass.AddCommand(std::move(cmd))) {
114 OpenPlaygroundHere(callback);
118 using VS = ColorsVertexShader;
119 using FS = ColorsFragmentShader;
120 auto context = GetContext();
121 ASSERT_TRUE(context);
123 ASSERT_TRUE(desc.has_value());
127 desc->SetStencilAttachmentDescriptors(std::nullopt);
129 context->GetPipelineLibrary()->GetPipeline(std::move(desc)).Get();
130 ASSERT_TRUE(pipeline);
133 VS::PerVertexData vertices[8] = {
145 uint16_t indices[36] = {
157 auto device_buffer = context->GetResourceAllocator()->CreateBufferWithCopy(
158 reinterpret_cast<uint8_t*
>(&cube),
sizeof(cube));
161 .range =
Range(offsetof(Cube, vertices),
sizeof(Cube::vertices))};
164 .range =
Range(offsetof(Cube, indices),
sizeof(Cube::indices))};
169 auto sampler = context->GetSamplerLibrary()->GetSampler({});
170 ASSERT_TRUE(sampler);
173 SinglePassCallback callback = [&](
RenderPass& pass) {
175 static Scalar distance = 10;
177 ImGui::Begin(
"Controls",
nullptr, ImGuiWindowFlags_AlwaysAutoResize);
178 ImGui::SliderFloat(
"Field of view", &fov_y.
degrees, 0, 180);
179 ImGui::SliderFloat(
"Camera distance", &distance, 0, 30);
188 VS::UniformBuffer uniforms;
189 Scalar time = GetSecondsElapsed();
190 euler_angles =
Vector3(0.19 * time, 0.7 * time, 0.43 * time);
198 VS::BindUniformBuffer(cmd,
199 pass.GetTransientsBuffer().EmplaceUniform(uniforms));
200 if (!pass.AddCommand(std::move(cmd))) {
205 OpenPlaygroundHere(callback);
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 auto sampler = context->GetSamplerLibrary()->GetSampler({});
241 ASSERT_TRUE(sampler);
243 SinglePassCallback callback = [&](
RenderPass& pass) {
250 FS::FrameInfo frame_info;
251 frame_info.current_time = GetSecondsElapsed();
252 frame_info.cursor_position = GetCursorPosition();
253 frame_info.window_size.x = GetWindowSize().width;
254 frame_info.window_size.y = GetWindowSize().height;
256 FS::BindFrameInfo(cmd,
257 pass.GetTransientsBuffer().EmplaceUniform(frame_info));
258 FS::BindContents1(cmd, boston, sampler);
259 FS::BindContents2(cmd, bridge, sampler);
261 for (
size_t i = 0; i < 1; i++) {
262 for (
size_t j = 0; j < 1; j++) {
263 VS::UniformBuffer uniforms;
264 EXPECT_EQ(pass.GetOrthographicTransform(),
266 uniforms.mvp = pass.GetOrthographicTransform() *
269 VS::BindUniformBuffer(
270 cmd, pass.GetTransientsBuffer().EmplaceUniform(uniforms));
271 if (!pass.AddCommand(std::move(cmd))) {
279 OpenPlaygroundHere(callback);
283 using VS = BoxFadeVertexShader;
284 using FS = BoxFadeFragmentShader;
285 auto context = GetContext();
286 ASSERT_TRUE(context);
289 BoxPipelineBuilder::MakeDefaultPipelineDescriptor(*context);
292 ASSERT_TRUE(pipeline_desc.has_value());
294 context->GetPipelineLibrary()->GetPipeline(pipeline_desc).Get();
295 ASSERT_TRUE(box_pipeline);
300 {{100, 100, 0.0}, {0.0, 0.0}},
301 {{800, 100, 0.0}, {1.0, 0.0}},
302 {{800, 800, 0.0}, {1.0, 1.0}},
303 {{100, 100, 0.0}, {0.0, 0.0}},
304 {{800, 800, 0.0}, {1.0, 1.0}},
305 {{100, 800, 0.0}, {0.0, 1.0}},
309 ASSERT_TRUE(vertex_buffer);
311 auto bridge = CreateTextureForFixture(
"bay_bridge.jpg");
312 auto boston = CreateTextureForFixture(
"boston.jpg");
313 ASSERT_TRUE(bridge && boston);
314 auto sampler = context->GetSamplerLibrary()->GetSampler({});
315 ASSERT_TRUE(sampler);
316 std::shared_ptr<RenderPass> r2t_pass;
317 auto cmd_buffer = context->CreateCommandBuffer();
318 ASSERT_TRUE(cmd_buffer);
325 ASSERT_NE(pipeline_desc->GetColorAttachmentDescriptor(0u),
nullptr);
326 texture_descriptor.
format =
327 pipeline_desc->GetColorAttachmentDescriptor(0u)->format;
329 texture_descriptor.
size = {400, 400};
331 texture_descriptor.
usage =
335 context->GetResourceAllocator()->CreateTexture(texture_descriptor);
339 color0.
texture->SetLabel(
"r2t_target");
346 stencil_texture_desc.
size = texture_descriptor.
size;
348 stencil_texture_desc.
usage =
351 context->GetResourceAllocator()->CreateTexture(stencil_texture_desc);
356 r2t_pass = cmd_buffer->CreateRenderPass(r2t_desc);
357 ASSERT_TRUE(r2t_pass && r2t_pass->IsValid());
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(cmd,
373 r2t_pass->GetTransientsBuffer().EmplaceUniform(frame_info));
374 FS::BindContents1(cmd, boston, sampler);
375 FS::BindContents2(cmd, bridge, sampler);
377 VS::UniformBuffer uniforms;
380 VS::BindUniformBuffer(
381 cmd, r2t_pass->GetTransientsBuffer().EmplaceUniform(uniforms));
382 ASSERT_TRUE(r2t_pass->AddCommand(std::move(cmd)));
383 ASSERT_TRUE(r2t_pass->EncodeCommands());
388 GTEST_SKIP_(
"Instancing is not supported on OpenGL.");
390 using VS = InstancedDrawVertexShader;
391 using FS = InstancedDrawFragmentShader;
401 [&builder](
const float* vertices,
size_t vertices_count,
402 const uint16_t* indices,
size_t indices_count) {
403 for (
auto i = 0u; i < vertices_count * 2; i += 2) {
404 VS::PerVertexData data;
405 data.vtx = {vertices[i], vertices[i + 1]};
408 for (
auto i = 0u; i < indices_count; i++) {
414 ASSERT_NE(GetContext(),
nullptr);
417 ->GetPipelineLibrary()
421 .SetStencilAttachmentDescriptors(std::nullopt))
424 ASSERT_TRUE(pipeline && pipeline->IsValid());
430 static constexpr
size_t kInstancesCount = 5u;
431 VS::InstanceInfo<kInstancesCount> instances;
432 for (
size_t i = 0; i < kInstancesCount; i++) {
436 ASSERT_TRUE(OpenPlaygroundHere([&](
RenderPass& pass) ->
bool {
437 VS::FrameInfo frame_info;
442 VS::BindFrameInfo(cmd,
444 VS::BindInstanceInfo(
455 auto context = GetContext();
456 ASSERT_TRUE(context);
458 using VS = MipmapsVertexShader;
459 using FS = MipmapsFragmentShader;
461 ASSERT_TRUE(desc.has_value());
463 desc->SetStencilAttachmentDescriptors(std::nullopt);
464 auto mipmaps_pipeline =
465 context->GetPipelineLibrary()->GetPipeline(std::move(desc)).Get();
466 ASSERT_TRUE(mipmaps_pipeline);
471 texture_desc.
size = {800, 600};
476 auto texture = context->GetResourceAllocator()->CreateTexture(texture_desc);
477 ASSERT_TRUE(texture);
479 auto bridge = CreateTextureForFixture(
"bay_bridge.jpg");
480 auto boston = CreateTextureForFixture(
"boston.jpg");
481 ASSERT_TRUE(bridge && boston);
482 auto sampler = 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);
502 auto buffer = context->CreateCommandBuffer();
506 buffer->SetLabel(
"Playground Command Buffer");
509 auto pass = buffer->CreateBlitPass();
513 pass->SetLabel(
"Playground Blit Pass");
515 if (render_target.GetColorAttachments().empty()) {
520 pass->AddCopy(bridge, texture);
522 if (!pass->EncodeCommands(context->GetResourceAllocator())) {
528 auto pass = buffer->CreateRenderPass(render_target);
532 pass->SetLabel(
"Playground Render Pass");
540 VS::FrameInfo frame_info;
541 EXPECT_EQ(pass->GetOrthographicTransform(),
543 frame_info.mvp = pass->GetOrthographicTransform() *
546 cmd, pass->GetTransientsBuffer().EmplaceUniform(frame_info));
548 FS::FragInfo frag_info;
550 FS::BindFragInfo(cmd,
551 pass->GetTransientsBuffer().EmplaceUniform(frag_info));
553 auto sampler = context->GetSamplerLibrary()->GetSampler({});
554 FS::BindTex(cmd, texture, sampler);
556 pass->AddCommand(std::move(cmd));
558 pass->EncodeCommands();
561 if (!buffer->SubmitCommands()) {
566 OpenPlaygroundHere(callback);
570 auto context = GetContext();
571 ASSERT_TRUE(context);
573 using VS = MipmapsVertexShader;
574 using FS = MipmapsFragmentShader;
576 ASSERT_TRUE(desc.has_value());
578 desc->SetStencilAttachmentDescriptors(std::nullopt);
579 auto mipmaps_pipeline =
580 context->GetPipelineLibrary()->GetPipeline(std::move(desc)).Get();
581 ASSERT_TRUE(mipmaps_pipeline);
583 auto bridge = CreateTextureForFixture(
"bay_bridge.jpg");
584 auto boston = CreateTextureForFixture(
"boston.jpg");
585 ASSERT_TRUE(bridge && boston);
586 auto sampler = context->GetSamplerLibrary()->GetSampler({});
587 ASSERT_TRUE(sampler);
592 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);
623 auto buffer = context->CreateCommandBuffer();
627 buffer->SetLabel(
"Playground Command Buffer");
628 auto pass = buffer->CreateBlitPass();
632 pass->SetLabel(
"Playground Blit Pass");
634 if (render_target.GetColorAttachments().empty()) {
639 pass->AddCopy(bridge, device_buffer);
641 pass->EncodeCommands(context->GetResourceAllocator());
643 if (!buffer->SubmitCommands()) {
649 auto buffer = context->CreateCommandBuffer();
653 buffer->SetLabel(
"Playground Command Buffer");
655 auto pass = buffer->CreateRenderPass(render_target);
659 pass->SetLabel(
"Playground Render Pass");
667 VS::FrameInfo frame_info;
668 EXPECT_EQ(pass->GetOrthographicTransform(),
670 frame_info.mvp = pass->GetOrthographicTransform() *
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;
791 EXPECT_EQ(pass->GetOrthographicTransform(),
793 frame_info.mvp = pass->GetOrthographicTransform() *
796 cmd, pass->GetTransientsBuffer().EmplaceUniform(frame_info));
798 FS::FragInfo frag_info;
800 FS::BindFragInfo(cmd,
801 pass->GetTransientsBuffer().EmplaceUniform(frag_info));
804 sampler_desc.
mip_filter = mip_filters[selected_mip_filter];
805 sampler_desc.
min_filter = min_filters[selected_min_filter];
806 auto sampler = context->GetSamplerLibrary()->GetSampler(sampler_desc);
807 FS::BindTex(cmd, boston, sampler);
809 pass->AddCommand(std::move(cmd));
811 pass->EncodeCommands();
814 if (!buffer->SubmitCommands()) {
819 OpenPlaygroundHere(callback);
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");
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 auto cube_map_sampler = context->GetSamplerLibrary()->GetSampler({});
849 SinglePassCallback callback = [&](
RenderPass& pass) {
850 auto size = pass.GetRenderTargetSize();
857 {
Point(0, size.height)},
858 {
Point(size.width, 0)},
859 {
Point(size.width, 0)},
860 {
Point(0, size.height)},
861 {
Point(size.width, size.height)}});
864 VS::FrameInfo frame_info;
866 frame_info.mvp = pass.GetOrthographicTransform();
867 VS::BindFrameInfo(cmd,
868 pass.GetTransientsBuffer().EmplaceUniform(frame_info));
870 FS::FragInfo fs_uniform;
871 fs_uniform.texture_size =
Point(size);
872 fs_uniform.time = GetSecondsElapsed();
873 FS::BindFragInfo(cmd,
874 pass.GetTransientsBuffer().EmplaceUniform(fs_uniform));
875 FS::BindBlueNoise(cmd, blue_noise, noise_sampler);
876 FS::BindCubeMap(cmd, cube_map, cube_map_sampler);
878 pass.AddCommand(std::move(cmd));
881 OpenPlaygroundHere(callback);
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());
898 SinglePassCallback callback = [&](
RenderPass& pass) {
899 auto size = pass.GetRenderTargetSize();
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)}});
913 VS::FrameInfo frame_info;
917 VS::BindFrameInfo(cmd,
918 pass.GetTransientsBuffer().EmplaceUniform(frame_info));
920 auto time = GetSecondsElapsed();
921 auto y_pos = [&time](
float x) {
922 return 400 + 10 * std::cos(time * 5 + x / 6);
925 FS::FragInfo fs_uniform = {
926 .circle_positions = {
Point(430, y_pos(0)),
Point(480, y_pos(1)),
933 FS::BindFragInfo(cmd,
934 pass.GetTransientsBuffer().EmplaceUniform(fs_uniform));
936 pass.AddCommand(std::move(cmd));
939 OpenPlaygroundHere(callback);
943 using VS = InactiveUniformsVertexShader;
944 using FS = InactiveUniformsFragmentShader;
946 auto context = GetContext();
947 auto pipeline_descriptor =
949 ASSERT_TRUE(pipeline_descriptor.has_value());
951 pipeline_descriptor->SetStencilAttachmentDescriptors(std::nullopt);
953 context->GetPipelineLibrary()->GetPipeline(pipeline_descriptor).Get();
954 ASSERT_TRUE(pipeline && pipeline->IsValid());
956 SinglePassCallback callback = [&](
RenderPass& pass) {
957 auto size = pass.GetRenderTargetSize();
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)}});
971 VS::FrameInfo frame_info;
975 VS::BindFrameInfo(cmd,
976 pass.GetTransientsBuffer().EmplaceUniform(frame_info));
978 FS::FragInfo fs_uniform = {.unused_color =
Color::Red(),
980 FS::BindFragInfo(cmd,
981 pass.GetTransientsBuffer().EmplaceUniform(fs_uniform));
983 pass.AddCommand(std::move(cmd));
986 OpenPlaygroundHere(callback);
991 GTEST_SKIP_(
"CPU backed textures are not supported on OpenGLES.");
994 auto context = GetContext();
995 auto allocator = context->GetResourceAllocator();
996 size_t dimension = 2;
999 ISize size(dimension, dimension);
1003 texture_descriptor.
size = size;
1005 std::max(
static_cast<uint16_t
>(size.
width * 4),
1006 allocator->MinimumBytesPerRow(texture_descriptor.
format));
1007 auto buffer_size = size.
height * row_bytes;
1011 buffer_descriptor.
size = buffer_size;
1013 auto buffer = allocator->CreateBuffer(buffer_descriptor);
1015 ASSERT_TRUE(buffer);
1017 auto texture = buffer->AsTexture(*allocator, texture_descriptor, row_bytes);
1019 ASSERT_TRUE(texture);
1020 ASSERT_TRUE(texture->IsValid());
1023 }
while (dimension <= 8192);
1027 using VS = BoxFadeVertexShader;
1037 using VS = BoxFadeVertexShader;
1046 using VS = BoxFadeVertexShader;
1050 {{100, 100, 0.0}, {0.0, 0.0}},
1051 {{800, 100, 0.0}, {1.0, 0.0}},
1052 {{800, 800, 0.0}, {1.0, 1.0}},
1053 {{100, 800, 0.0}, {0.0, 1.0}},
1069 labels_.push_back(
"Never");
1071 labels_.push_back(
"Always");
1073 labels_.push_back(
"Less");
1075 labels_.push_back(
"Equal");
1077 labels_.push_back(
"LessEqual");
1079 labels_.push_back(
"Greater");
1081 labels_.push_back(
"NotEqual");
1083 labels_.push_back(
"GreaterEqual");
1085 assert(labels_.size() == functions_.size());
1088 const char*
const*
labels()
const {
return &labels_[0]; }
1090 int size()
const {
return labels_.size(); }
1093 for (
size_t i = 0; i < functions_.size(); i++) {
1094 if (functions_[i] == func) {
1105 std::vector<const char*> labels_;
1106 std::vector<CompareFunction> functions_;
1115 using VS = BoxFadeVertexShader;
1116 using FS = BoxFadeFragmentShader;
1117 auto context = GetContext();
1118 ASSERT_TRUE(context);
1120 auto desc = BoxFadePipelineBuilder::MakeDefaultPipelineDescriptor(*context);
1121 ASSERT_TRUE(desc.has_value());
1127 {{100, 100, 0.0}, {0.0, 0.0}},
1128 {{800, 100, 0.0}, {1.0, 0.0}},
1129 {{800, 800, 0.0}, {1.0, 1.0}},
1130 {{100, 100, 0.0}, {0.0, 0.0}},
1131 {{800, 800, 0.0}, {1.0, 1.0}},
1132 {{100, 800, 0.0}, {0.0, 1.0}},
1134 auto vertex_buffer =
1136 ASSERT_TRUE(vertex_buffer);
1139 desc->SetStencilAttachmentDescriptors(std::nullopt);
1141 auto bridge = CreateTextureForFixture(
"bay_bridge.jpg");
1142 auto boston = CreateTextureForFixture(
"boston.jpg");
1143 ASSERT_TRUE(bridge && boston);
1144 auto sampler = 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 =
1157 auto buffer = context->CreateCommandBuffer();
1161 buffer->SetLabel(
"Playground Command Buffer");
1169 auto render_target_allocator =
1171 render_target.SetupStencilAttachment(*context, render_target_allocator,
1172 render_target.GetRenderTargetSize(),
1173 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());
1233 VS::UniformBuffer uniforms;
1234 EXPECT_EQ(pass->GetOrthographicTransform(),
1236 uniforms.mvp = pass->GetOrthographicTransform() *
1241 VS::BindUniformBuffer(
1242 cmd, pass->GetTransientsBuffer().EmplaceUniform(uniforms));
1244 FS::FrameInfo frame_info;
1245 frame_info.current_time = GetSecondsElapsed();
1246 frame_info.cursor_position = GetCursorPosition();
1247 frame_info.window_size.x = GetWindowSize().width;
1248 frame_info.window_size.y = GetWindowSize().height;
1250 FS::BindFrameInfo(cmd,
1251 pass->GetTransientsBuffer().EmplaceUniform(frame_info));
1252 FS::BindContents1(cmd, boston, sampler);
1253 FS::BindContents2(cmd, bridge, sampler);
1254 if (!pass->AddCommand(std::move(cmd))) {
1257 pass->EncodeCommands();
1260 if (!buffer->SubmitCommands()) {
1265 OpenPlaygroundHere(callback);
1269 auto context = GetContext();
1270 auto cmd_buffer = context->CreateCommandBuffer();
1271 auto render_target_cache = std::make_shared<RenderTargetAllocator>(
1272 GetContext()->GetResourceAllocator());
1274 auto render_target =
1276 auto render_pass = cmd_buffer->CreateRenderPass(render_target);
1278 render_pass->ReserveCommands(100u);
1280 EXPECT_EQ(render_pass->GetCommands().capacity(), 100u);
1284 auto context = GetContext();
1285 auto cmd_buffer = context->CreateCommandBuffer();
1286 auto render_target_cache = std::make_shared<RenderTargetAllocator>(
1287 GetContext()->GetResourceAllocator());
1289 auto render_target =
1291 auto render_pass = cmd_buffer->CreateRenderPass(render_target);
1293 EXPECT_EQ(render_pass->GetSampleCount(), render_target.GetSampleCount());
1294 EXPECT_EQ(render_pass->GetRenderTargetPixelFormat(),
1295 render_target.GetRenderTargetPixelFormat());
1296 EXPECT_EQ(render_pass->HasStencilAttachment(),
1297 render_target.GetStencilAttachment().has_value());
1298 EXPECT_EQ(render_pass->GetRenderTargetSize(),
1299 render_target.GetRenderTargetSize());