11#include "impeller/fixtures/array.frag.h"
12#include "impeller/fixtures/array.vert.h"
13#include "impeller/fixtures/baby.frag.h"
14#include "impeller/fixtures/baby.vert.h"
15#include "impeller/fixtures/box_fade.frag.h"
16#include "impeller/fixtures/box_fade.vert.h"
17#include "impeller/fixtures/colors.frag.h"
18#include "impeller/fixtures/colors.vert.h"
19#include "impeller/fixtures/impeller.frag.h"
20#include "impeller/fixtures/impeller.vert.h"
21#include "impeller/fixtures/inactive_uniforms.frag.h"
22#include "impeller/fixtures/inactive_uniforms.vert.h"
23#include "impeller/fixtures/instanced_draw.frag.h"
24#include "impeller/fixtures/instanced_draw.vert.h"
25#include "impeller/fixtures/mipmaps.frag.h"
26#include "impeller/fixtures/mipmaps.vert.h"
27#include "impeller/fixtures/planet.frag.h"
28#include "impeller/fixtures/planet.vert.h"
29#include "impeller/fixtures/sepia.frag.h"
30#include "impeller/fixtures/sepia.vert.h"
31#include "impeller/fixtures/swizzle.frag.h"
32#include "impeller/fixtures/texture.frag.h"
33#include "impeller/fixtures/texture.vert.h"
42#include "third_party/imgui/imgui.h"
48std::pair<std::shared_ptr<impeller::HostBuffer>,
49 std::shared_ptr<impeller::HostBuffer>>
50createHostBuffers(
const std::shared_ptr<impeller::Context>& context) {
52 context->GetResourceAllocator(), context->GetIdleWaiter(),
53 context->GetCapabilities()->GetMinimumUniformAlignment());
54 auto indexes_host_buffer =
55 context->GetCapabilities()->NeedsPartitionedHostBuffer()
57 context->GetResourceAllocator(), context->GetIdleWaiter(),
58 context->GetCapabilities()->GetMinimumUniformAlignment())
60 return {data_host_buffer, indexes_host_buffer};
71 using VS = BoxFadeVertexShader;
72 using FS = BoxFadeFragmentShader;
73 auto context = GetContext();
76 auto desc = BoxPipelineBuilder::MakeDefaultPipelineDescriptor(*context);
77 ASSERT_TRUE(desc.has_value());
79 desc->SetStencilAttachmentDescriptors(std::nullopt);
85 {{100, 100, 0.0}, {0.0, 0.0}},
86 {{800, 100, 0.0}, {1.0, 0.0}},
87 {{800, 800, 0.0}, {1.0, 1.0}},
88 {{100, 100, 0.0}, {0.0, 0.0}},
89 {{800, 800, 0.0}, {1.0, 1.0}},
90 {{100, 800, 0.0}, {0.0, 1.0}},
92 auto bridge = CreateTextureForFixture(
"bay_bridge.jpg");
93 auto boston = CreateTextureForFixture(
"boston.jpg");
94 ASSERT_TRUE(bridge && boston);
99 auto [data_host_buffer, indexes_host_buffer] = createHostBuffers(context);
100 ImGui::Begin(
"Controls",
nullptr, ImGuiWindowFlags_AlwaysAutoResize);
101 static bool wireframe;
102 ImGui::Checkbox(
"Wireframe", &wireframe);
106 auto pipeline = context->GetPipelineLibrary()->GetPipeline(desc).Get();
108 assert(pipeline && pipeline->IsValid());
110 pass.SetCommandLabel(
"Box");
111 pass.SetPipeline(pipeline);
112 pass.SetVertexBuffer(
115 VS::UniformBuffer uniforms;
116 EXPECT_EQ(pass.GetOrthographicTransform(),
120 VS::BindUniformBuffer(pass, data_host_buffer->EmplaceUniform(uniforms));
122 FS::FrameInfo frame_info;
123 frame_info.current_time = GetSecondsElapsed();
124 frame_info.cursor_position = GetCursorPosition();
125 frame_info.window_size.x = GetWindowSize().width;
126 frame_info.window_size.y = GetWindowSize().height;
128 FS::BindFrameInfo(pass, data_host_buffer->EmplaceUniform(frame_info));
129 FS::BindContents1(pass, boston, sampler);
130 FS::BindContents2(pass, bridge, sampler);
132 data_host_buffer->Reset();
133 return pass.Draw().ok();
139 auto context = GetContext();
140 ASSERT_TRUE(context);
143 using VS = BabyVertexShader;
144 using FS = BabyFragmentShader;
152 ASSERT_TRUE(desc.has_value());
156 desc->SetStencilAttachmentDescriptors(std::nullopt);
160 auto pipeline = context->GetPipelineLibrary()->GetPipeline(desc).Get();
171 *context->GetResourceAllocator());
174 pass.SetPipeline(pipeline);
175 pass.SetVertexBuffer(vertex_buffer);
177 FS::FragInfo frag_info;
180 auto [data_host_buffer, indexes_host_buffer] = createHostBuffers(context);
181 FS::BindFragInfo(pass, data_host_buffer->EmplaceUniform(frag_info));
183 return pass.Draw().ok();
189 using VS = ColorsVertexShader;
190 using FS = ColorsFragmentShader;
191 auto context = GetContext();
192 ASSERT_TRUE(context);
194 ASSERT_TRUE(desc.has_value());
198 desc->ClearStencilAttachments();
202 auto vertex_desc = std::make_shared<VertexDescriptor>();
209 const std::vector<ShaderStageIOSlot> io_slots = {position_slot, color_slot};
210 const std::vector<ShaderStageBufferLayout> layouts = {
213 vertex_desc->RegisterDescriptorSetLayouts(VS::kDescriptorSetLayouts);
214 vertex_desc->RegisterDescriptorSetLayouts(FS::kDescriptorSetLayouts);
215 vertex_desc->SetStageInputs(io_slots, layouts);
216 desc->SetVertexDescriptor(std::move(vertex_desc));
218 context->GetPipelineLibrary()->GetPipeline(std::move(desc)).Get();
219 ASSERT_TRUE(pipeline);
235 Color::Red(), Color::Yellow(), Color::Green(), Color::Blue(),
236 Color::Green(), Color::Blue(), Color::Red(), Color::Yellow(),
238 uint16_t indices[36] = {
248 auto device_buffer = context->GetResourceAllocator()->CreateBufferWithCopy(
249 reinterpret_cast<uint8_t*
>(&cube),
sizeof(cube));
252 ASSERT_TRUE(sampler);
256 auto [data_host_buffer, indexes_host_buffer] = createHostBuffers(context);
258 static Scalar distance = 10;
260 ImGui::Begin(
"Controls",
nullptr, ImGuiWindowFlags_AlwaysAutoResize);
261 ImGui::SliderFloat(
"Field of view", &fov_y.
degrees, 0, 180);
262 ImGui::SliderFloat(
"Camera distance", &distance, 0, 30);
265 pass.SetCommandLabel(
"Perspective Cube");
266 pass.SetPipeline(pipeline);
268 std::array<BufferView, 2> vertex_buffers = {
270 Range(offsetof(Cube, positions),
sizeof(Cube::positions))),
272 Range(offsetof(Cube, colors),
sizeof(Cube::colors))),
276 device_buffer,
Range(offsetof(Cube, indices),
sizeof(Cube::indices)));
277 pass.SetVertexBuffer(vertex_buffers.data(), vertex_buffers.size());
278 pass.SetElementCount(36);
281 VS::UniformBuffer uniforms;
282 Scalar time = GetSecondsElapsed();
283 euler_angles =
Vector3(0.19 * time, 0.7 * time, 0.43 * time);
291 VS::BindUniformBuffer(pass, data_host_buffer->EmplaceUniform(uniforms));
293 data_host_buffer->Reset();
294 return pass.Draw().ok();
300 using VS = BoxFadeVertexShader;
301 using FS = BoxFadeFragmentShader;
302 auto context = GetContext();
303 ASSERT_TRUE(context);
305 auto desc = BoxPipelineBuilder::MakeDefaultPipelineDescriptor(*context);
306 ASSERT_TRUE(desc.has_value());
308 desc->SetStencilAttachmentDescriptors(std::nullopt);
310 context->GetPipelineLibrary()->GetPipeline(std::move(desc)).Get();
311 ASSERT_TRUE(box_pipeline);
317 {{100, 100, 0.0}, {0.0, 0.0}},
318 {{800, 100, 0.0}, {1.0, 0.0}},
319 {{800, 800, 0.0}, {1.0, 1.0}},
320 {{100, 100, 0.0}, {0.0, 0.0}},
321 {{800, 800, 0.0}, {1.0, 1.0}},
322 {{100, 800, 0.0}, {0.0, 1.0}},
326 ASSERT_TRUE(vertex_buffer);
328 auto bridge = CreateTextureForFixture(
"bay_bridge.jpg");
329 auto boston = CreateTextureForFixture(
"boston.jpg");
330 ASSERT_TRUE(bridge && boston);
332 ASSERT_TRUE(sampler);
335 auto [data_host_buffer, indexes_host_buffer] = createHostBuffers(context);
336 for (
size_t i = 0;
i < 1;
i++) {
337 for (
size_t j = 0; j < 1; j++) {
338 pass.SetCommandLabel(
"Box");
339 pass.SetPipeline(box_pipeline);
340 pass.SetVertexBuffer(vertex_buffer);
342 FS::FrameInfo frame_info;
343 frame_info.current_time = GetSecondsElapsed();
344 frame_info.cursor_position = GetCursorPosition();
345 frame_info.window_size.x = GetWindowSize().width;
346 frame_info.window_size.y = GetWindowSize().height;
348 FS::BindFrameInfo(pass, data_host_buffer->EmplaceUniform(frame_info));
349 FS::BindContents1(pass, boston, sampler);
350 FS::BindContents2(pass, bridge, sampler);
352 VS::UniformBuffer uniforms;
353 EXPECT_EQ(pass.GetOrthographicTransform(),
355 uniforms.mvp = pass.GetOrthographicTransform() *
358 VS::BindUniformBuffer(pass, data_host_buffer->EmplaceUniform(uniforms));
359 if (!pass.Draw().ok()) {
365 data_host_buffer->Reset();
372 using VS = BoxFadeVertexShader;
373 using FS = BoxFadeFragmentShader;
374 auto context = GetContext();
375 ASSERT_TRUE(context);
378 BoxPipelineBuilder::MakeDefaultPipelineDescriptor(*context);
380 pipeline_desc->ClearDepthAttachment();
383 ASSERT_TRUE(pipeline_desc.has_value());
385 context->GetPipelineLibrary()->GetPipeline(pipeline_desc).Get();
386 ASSERT_TRUE(box_pipeline);
387 auto [data_host_buffer, indexes_host_buffer] = createHostBuffers(context);
392 {{100, 100, 0.0}, {0.0, 0.0}},
393 {{800, 100, 0.0}, {1.0, 0.0}},
394 {{800, 800, 0.0}, {1.0, 1.0}},
395 {{100, 100, 0.0}, {0.0, 0.0}},
396 {{800, 800, 0.0}, {1.0, 1.0}},
397 {{100, 800, 0.0}, {0.0, 1.0}},
401 ASSERT_TRUE(vertex_buffer);
403 auto bridge = CreateTextureForFixture(
"bay_bridge.jpg");
404 auto boston = CreateTextureForFixture(
"boston.jpg");
405 ASSERT_TRUE(bridge && boston);
407 ASSERT_TRUE(sampler);
409 std::shared_ptr<RenderPass> r2t_pass;
410 auto cmd_buffer = context->CreateCommandBuffer();
411 ASSERT_TRUE(cmd_buffer);
418 ASSERT_NE(pipeline_desc->GetColorAttachmentDescriptor(0u),
nullptr);
419 texture_descriptor.
format =
420 pipeline_desc->GetColorAttachmentDescriptor(0u)->format;
422 texture_descriptor.
size = {400, 400};
427 context->GetResourceAllocator()->CreateTexture(texture_descriptor);
431 color0.
texture->SetLabel(
"r2t_target");
438 stencil_texture_desc.
size = texture_descriptor.
size;
442 context->GetResourceAllocator()->CreateTexture(stencil_texture_desc);
447 r2t_pass = cmd_buffer->CreateRenderPass(r2t_desc);
448 ASSERT_TRUE(r2t_pass && r2t_pass->IsValid());
451 r2t_pass->SetCommandLabel(
"Box");
452 r2t_pass->SetPipeline(box_pipeline);
453 r2t_pass->SetVertexBuffer(vertex_buffer);
455 FS::FrameInfo frame_info;
456 frame_info.current_time = GetSecondsElapsed();
457 frame_info.cursor_position = GetCursorPosition();
458 frame_info.window_size.x = GetWindowSize().width;
459 frame_info.window_size.y = GetWindowSize().height;
461 FS::BindFrameInfo(*r2t_pass, data_host_buffer->EmplaceUniform(frame_info));
462 FS::BindContents1(*r2t_pass, boston, sampler);
463 FS::BindContents2(*r2t_pass, bridge, sampler);
465 VS::UniformBuffer uniforms;
468 VS::BindUniformBuffer(*r2t_pass, data_host_buffer->EmplaceUniform(uniforms));
469 ASSERT_TRUE(r2t_pass->Draw().ok());
470 ASSERT_TRUE(r2t_pass->EncodeCommands());
475 GTEST_SKIP() <<
"Instancing is not supported on OpenGL.";
477 using VS = InstancedDrawVertexShader;
478 using FS = InstancedDrawFragmentShader;
482 VS::PerVertexData{
Point{10, 10}},
483 VS::PerVertexData{
Point{10, 110}},
484 VS::PerVertexData{
Point{110, 10}},
485 VS::PerVertexData{
Point{10, 110}},
486 VS::PerVertexData{
Point{110, 10}},
487 VS::PerVertexData{
Point{110, 110}},
490 ASSERT_NE(GetContext(),
nullptr);
493 ->GetPipelineLibrary()
497 .SetStencilAttachmentDescriptors(std::nullopt))
500 ASSERT_TRUE(pipeline && pipeline->IsValid());
502 static constexpr size_t kInstancesCount = 5u;
503 VS::InstanceInfo<kInstancesCount> instances;
504 for (
size_t i = 0;
i < kInstancesCount;
i++) {
508 ASSERT_TRUE(OpenPlaygroundHere([&](
RenderPass& pass) ->
bool {
509 auto [data_host_buffer, indexes_host_buffer] =
510 createHostBuffers(GetContext());
514 VS::FrameInfo frame_info;
519 VS::BindFrameInfo(pass, data_host_buffer->EmplaceUniform(frame_info));
520 VS::BindInstanceInfo(pass,
521 data_host_buffer->EmplaceStorageBuffer(instances));
528 data_host_buffer->Reset();
535 GTEST_SKIP() <<
"Mipmap test shader not supported on GLES.";
537 auto context = GetContext();
538 ASSERT_TRUE(context);
540 using VS = MipmapsVertexShader;
541 using FS = MipmapsFragmentShader;
543 ASSERT_TRUE(desc.has_value());
545 desc->SetStencilAttachmentDescriptors(std::nullopt);
546 auto mipmaps_pipeline =
547 context->GetPipelineLibrary()->GetPipeline(std::move(desc)).Get();
548 ASSERT_TRUE(mipmaps_pipeline);
553 texture_desc.
size = {800, 600};
556 auto texture = context->GetResourceAllocator()->CreateTexture(texture_desc);
559 auto bridge = CreateTextureForFixture(
"bay_bridge.jpg");
560 auto boston = CreateTextureForFixture(
"boston.jpg");
561 ASSERT_TRUE(bridge && boston);
563 ASSERT_TRUE(sampler);
570 {{0, 0}, {0.0, 0.0}},
571 {{
size.x, 0}, {1.0, 0.0}},
573 {{0, 0}, {0.0, 0.0}},
575 {{0,
size.y}, {0.0, 1.0}},
579 ASSERT_TRUE(vertex_buffer);
582 auto [data_host_buffer, indexes_host_buffer] = createHostBuffers(context);
583 auto buffer = context->CreateCommandBuffer();
587 buffer->SetLabel(
"Playground Command Buffer");
590 auto pass =
buffer->CreateBlitPass();
594 pass->SetLabel(
"Playground Blit Pass");
597 pass->AddCopy(bridge,
texture);
599 if (!pass->EncodeCommands()) {
605 auto pass =
buffer->CreateRenderPass(render_target);
609 pass->SetLabel(
"Playground Render Pass");
611 pass->SetCommandLabel(
"Image");
612 pass->SetPipeline(mipmaps_pipeline);
613 pass->SetVertexBuffer(vertex_buffer);
615 VS::FrameInfo frame_info;
616 EXPECT_EQ(pass->GetOrthographicTransform(),
618 frame_info.mvp = pass->GetOrthographicTransform() *
620 VS::BindFrameInfo(*pass, data_host_buffer->EmplaceUniform(frame_info));
622 FS::FragInfo frag_info;
624 FS::BindFragInfo(*pass, data_host_buffer->EmplaceUniform(frag_info));
626 auto sampler = context->GetSamplerLibrary()->GetSampler({});
627 FS::BindTex(*pass,
texture, sampler);
631 pass->EncodeCommands();
634 if (!context->GetCommandQueue()->Submit({buffer}).ok()) {
637 data_host_buffer->Reset();
645 GTEST_SKIP() <<
"Mipmap test shader not supported on GLES.";
647 auto context = GetContext();
648 ASSERT_TRUE(context);
650 using VS = MipmapsVertexShader;
651 using FS = MipmapsFragmentShader;
653 ASSERT_TRUE(desc.has_value());
655 desc->SetStencilAttachmentDescriptors(std::nullopt);
656 auto mipmaps_pipeline =
657 context->GetPipelineLibrary()->GetPipeline(std::move(desc)).Get();
658 ASSERT_TRUE(mipmaps_pipeline);
660 auto bridge = CreateTextureForFixture(
"bay_bridge.jpg");
661 auto boston = CreateTextureForFixture(
"boston.jpg");
662 ASSERT_TRUE(bridge && boston);
664 ASSERT_TRUE(sampler);
669 texture_desc.
size = bridge->GetTextureDescriptor().size;
675 device_buffer_desc.
size =
676 bridge->GetTextureDescriptor().GetByteSizeOfBaseMipLevel();
678 context->GetResourceAllocator()->CreateBuffer(device_buffer_desc);
685 {{0, 0}, {0.0, 0.0}},
686 {{
size.x, 0}, {1.0, 0.0}},
688 {{0, 0}, {0.0, 0.0}},
690 {{0,
size.y}, {0.0, 1.0}},
694 ASSERT_TRUE(vertex_buffer);
697 auto [data_host_buffer, indexes_host_buffer] = createHostBuffers(context);
699 auto buffer = context->CreateCommandBuffer();
703 buffer->SetLabel(
"Playground Command Buffer");
704 auto pass =
buffer->CreateBlitPass();
708 pass->SetLabel(
"Playground Blit Pass");
711 pass->AddCopy(bridge, device_buffer);
712 pass->EncodeCommands();
714 if (!context->GetCommandQueue()->Submit({buffer}).ok()) {
720 auto buffer = context->CreateCommandBuffer();
724 buffer->SetLabel(
"Playground Command Buffer");
726 auto pass =
buffer->CreateRenderPass(render_target);
730 pass->SetLabel(
"Playground Render Pass");
732 pass->SetCommandLabel(
"Image");
733 pass->SetPipeline(mipmaps_pipeline);
734 pass->SetVertexBuffer(vertex_buffer);
736 VS::FrameInfo frame_info;
737 EXPECT_EQ(pass->GetOrthographicTransform(),
739 frame_info.mvp = pass->GetOrthographicTransform() *
741 VS::BindFrameInfo(*pass, data_host_buffer->EmplaceUniform(frame_info));
743 FS::FragInfo frag_info;
745 FS::BindFragInfo(*pass, data_host_buffer->EmplaceUniform(frag_info));
748 context->GetSamplerLibrary()->GetSampler({});
751 context->GetResourceAllocator()->CreateTexture(texture_desc);
752 if (!
texture->SetContents(device_buffer->OnGetContents(),
757 FS::BindTex(*pass,
texture, sampler);
761 pass->EncodeCommands();
762 if (!context->GetCommandQueue()->Submit({buffer}).ok()) {
766 data_host_buffer->Reset();
774 GTEST_SKIP() <<
"Mipmap test shader not supported on GLES.";
776 auto context = GetContext();
777 ASSERT_TRUE(context);
779 using VS = MipmapsVertexShader;
780 using FS = MipmapsFragmentShader;
782 ASSERT_TRUE(desc.has_value());
784 desc->SetStencilAttachmentDescriptors(std::nullopt);
785 auto mipmaps_pipeline =
786 context->GetPipelineLibrary()->GetPipeline(std::move(desc)).Get();
787 ASSERT_TRUE(mipmaps_pipeline);
789 auto boston = CreateTextureForFixture(
"boston.jpg",
true);
797 {{0, 0}, {0.0, 0.0}},
798 {{
size.x, 0}, {1.0, 0.0}},
800 {{0, 0}, {0.0, 0.0}},
802 {{0,
size.y}, {0.0, 1.0}},
806 ASSERT_TRUE(vertex_buffer);
808 bool first_frame =
true;
810 auto [data_host_buffer, indexes_host_buffer] = createHostBuffers(context);
811 const char* mip_filter_names[] = {
"Base",
"Nearest",
"Linear"};
814 const char* min_filter_names[] = {
"Nearest",
"Linear"};
819 static int selected_mip_filter = 1;
820 static int selected_min_filter = 0;
821 static float lod = 4.5;
823 ImGui::Begin(
"Controls",
nullptr, ImGuiWindowFlags_AlwaysAutoResize);
824 ImGui::Combo(
"Mip filter", &selected_mip_filter, mip_filter_names,
825 sizeof(mip_filter_names) /
sizeof(
char*));
826 ImGui::Combo(
"Min filter", &selected_min_filter, min_filter_names,
827 sizeof(min_filter_names) /
sizeof(
char*));
828 ImGui::SliderFloat(
"LOD", &lod, 0, boston->GetMipCount() - 1);
831 auto buffer = context->CreateCommandBuffer();
835 buffer->SetLabel(
"Playground Command Buffer");
838 auto pass =
buffer->CreateBlitPass();
842 pass->SetLabel(
"Playground Blit Pass");
844 pass->GenerateMipmap(boston,
"Boston Mipmap");
846 pass->EncodeCommands();
852 auto pass =
buffer->CreateRenderPass(render_target);
856 pass->SetLabel(
"Playground Render Pass");
858 pass->SetCommandLabel(
"Image LOD");
859 pass->SetPipeline(mipmaps_pipeline);
860 pass->SetVertexBuffer(vertex_buffer);
862 VS::FrameInfo frame_info;
863 EXPECT_EQ(pass->GetOrthographicTransform(),
865 frame_info.mvp = pass->GetOrthographicTransform() *
867 VS::BindFrameInfo(*pass, data_host_buffer->EmplaceUniform(frame_info));
869 FS::FragInfo frag_info;
871 FS::BindFragInfo(*pass, data_host_buffer->EmplaceUniform(frag_info));
874 sampler_desc.
mip_filter = mip_filters[selected_mip_filter];
875 sampler_desc.
min_filter = min_filters[selected_min_filter];
877 context->GetSamplerLibrary()->GetSampler(sampler_desc);
878 FS::BindTex(*pass, boston, sampler);
882 pass->EncodeCommands();
885 if (!context->GetCommandQueue()->Submit({buffer}).ok()) {
888 data_host_buffer->Reset();
895 using VS = ImpellerVertexShader;
896 using FS = ImpellerFragmentShader;
898 auto context = GetContext();
899 auto pipeline_descriptor =
901 ASSERT_TRUE(pipeline_descriptor.has_value());
903 pipeline_descriptor->SetStencilAttachmentDescriptors(std::nullopt);
905 context->GetPipelineLibrary()->GetPipeline(pipeline_descriptor).Get();
906 ASSERT_TRUE(pipeline && pipeline->IsValid());
908 auto blue_noise = CreateTextureForFixture(
"blue_noise.png");
913 context->GetSamplerLibrary()->GetSampler(noise_sampler_desc);
915 auto cube_map = CreateTextureCubeForFixture(
916 {
"table_mountain_px.png",
"table_mountain_nx.png",
917 "table_mountain_py.png",
"table_mountain_ny.png",
918 "table_mountain_pz.png",
"table_mountain_nz.png"});
920 context->GetSamplerLibrary()->GetSampler({});
923 auto [data_host_buffer, indexes_host_buffer] = createHostBuffers(context);
924 auto size = pass.GetRenderTargetSize();
926 pass.SetPipeline(pipeline);
927 pass.SetCommandLabel(
"Impeller SDF scene");
935 pass.SetVertexBuffer(
938 VS::FrameInfo frame_info;
940 frame_info.mvp = pass.GetOrthographicTransform();
941 VS::BindFrameInfo(pass, data_host_buffer->EmplaceUniform(frame_info));
943 FS::FragInfo fs_uniform;
945 fs_uniform.time = GetSecondsElapsed();
946 FS::BindFragInfo(pass, data_host_buffer->EmplaceUniform(fs_uniform));
947 FS::BindBlueNoise(pass, blue_noise, noise_sampler);
948 FS::BindCubeMap(pass, cube_map, cube_map_sampler);
951 data_host_buffer->Reset();
958 using VS = PlanetVertexShader;
959 using FS = PlanetFragmentShader;
961 auto context = GetContext();
962 auto pipeline_descriptor =
964 ASSERT_TRUE(pipeline_descriptor.has_value());
966 pipeline_descriptor->SetStencilAttachmentDescriptors(std::nullopt);
968 context->GetPipelineLibrary()->GetPipeline(pipeline_descriptor).Get();
969 ASSERT_TRUE(pipeline && pipeline->IsValid());
972 auto [data_host_buffer, indexes_host_buffer] = createHostBuffers(context);
973 static Scalar speed = 0.1;
974 static Scalar planet_size = 550.0;
975 static bool show_normals =
false;
976 static bool show_noise =
false;
977 static Scalar seed_value = 42.0;
979 auto size = pass.GetRenderTargetSize();
981 ImGui::Begin(
"Controls",
nullptr, ImGuiWindowFlags_AlwaysAutoResize);
982 ImGui::SliderFloat(
"Speed", &speed, 0.0, 10.0);
983 ImGui::SliderFloat(
"Planet Size", &planet_size, 0.1, 1000);
984 ImGui::Checkbox(
"Show Normals", &show_normals);
985 ImGui::Checkbox(
"Show Noise", &show_noise);
986 ImGui::InputFloat(
"Seed Value", &seed_value);
989 pass.SetPipeline(pipeline);
990 pass.SetCommandLabel(
"Planet scene");
998 pass.SetVertexBuffer(
1001 VS::FrameInfo frame_info;
1003 frame_info.mvp = pass.GetOrthographicTransform();
1004 VS::BindFrameInfo(pass, data_host_buffer->EmplaceUniform(frame_info));
1006 FS::FragInfo fs_uniform;
1008 fs_uniform.time = GetSecondsElapsed();
1009 fs_uniform.speed = speed;
1010 fs_uniform.planet_size = planet_size;
1011 fs_uniform.show_normals = show_normals ? 1.0 : 0.0;
1012 fs_uniform.show_noise = show_noise ? 1.0 : 0.0;
1013 fs_uniform.seed_value = seed_value;
1014 FS::BindFragInfo(pass, data_host_buffer->EmplaceUniform(fs_uniform));
1017 data_host_buffer->Reset();
1024 using VS = ArrayVertexShader;
1025 using FS = ArrayFragmentShader;
1027 auto context = GetContext();
1028 auto pipeline_descriptor =
1030 ASSERT_TRUE(pipeline_descriptor.has_value());
1032 pipeline_descriptor->SetStencilAttachmentDescriptors(std::nullopt);
1034 context->GetPipelineLibrary()->GetPipeline(pipeline_descriptor).Get();
1035 ASSERT_TRUE(pipeline && pipeline->IsValid());
1038 auto [data_host_buffer, indexes_host_buffer] = createHostBuffers(context);
1039 auto size = pass.GetRenderTargetSize();
1041 pass.SetPipeline(pipeline);
1042 pass.SetCommandLabel(
"Google Dots");
1050 pass.SetVertexBuffer(
1053 VS::FrameInfo frame_info;
1057 VS::BindFrameInfo(pass, data_host_buffer->EmplaceUniform(frame_info));
1059 auto time = GetSecondsElapsed();
1060 auto y_pos = [&time](
float x) {
1061 return 400 + 10 * std::cos(time * 5 +
x / 6);
1064 FS::FragInfo fs_uniform = {
1065 .circle_positions = {
Point(430, y_pos(0)),
Point(480, y_pos(1)),
1072 FS::BindFragInfo(pass, data_host_buffer->EmplaceUniform(fs_uniform));
1075 data_host_buffer->Reset();
1082 using VS = InactiveUniformsVertexShader;
1083 using FS = InactiveUniformsFragmentShader;
1085 auto context = GetContext();
1086 auto pipeline_descriptor =
1088 ASSERT_TRUE(pipeline_descriptor.has_value());
1090 pipeline_descriptor->SetStencilAttachmentDescriptors(std::nullopt);
1092 context->GetPipelineLibrary()->GetPipeline(pipeline_descriptor).Get();
1093 ASSERT_TRUE(pipeline && pipeline->IsValid());
1096 auto [data_host_buffer, indexes_host_buffer] = createHostBuffers(context);
1097 auto size = pass.GetRenderTargetSize();
1099 pass.SetPipeline(pipeline);
1100 pass.SetCommandLabel(
"Inactive Uniform");
1109 pass.SetVertexBuffer(
1112 VS::FrameInfo frame_info;
1116 VS::BindFrameInfo(pass, data_host_buffer->EmplaceUniform(frame_info));
1118 FS::FragInfo fs_uniform = {.unused_color =
Color::Red(),
1120 FS::BindFragInfo(pass, data_host_buffer->EmplaceUniform(fs_uniform));
1123 data_host_buffer->Reset();
1130 using VS = BoxFadeVertexShader;
1140 using VS = BoxFadeVertexShader;
1149 using VS = BoxFadeVertexShader;
1153 {{100, 100, 0.0}, {0.0, 0.0}},
1154 {{800, 100, 0.0}, {1.0, 0.0}},
1155 {{800, 800, 0.0}, {1.0, 1.0}},
1156 {{100, 800, 0.0}, {0.0, 1.0}},
1172 labels_.push_back(
"Never");
1174 labels_.push_back(
"Always");
1176 labels_.push_back(
"Less");
1178 labels_.push_back(
"Equal");
1180 labels_.push_back(
"LessEqual");
1182 labels_.push_back(
"Greater");
1184 labels_.push_back(
"NotEqual");
1186 labels_.push_back(
"GreaterEqual");
1188 assert(labels_.size() == functions_.size());
1191 const char*
const*
labels()
const {
return &labels_[0]; }
1193 int size()
const {
return labels_.size(); }
1196 for (
size_t i = 0;
i < functions_.size();
i++) {
1197 if (functions_[
i] == func) {
1208 std::vector<const char*> labels_;
1209 std::vector<CompareFunction> functions_;
1218 using VS = BoxFadeVertexShader;
1219 using FS = BoxFadeFragmentShader;
1220 auto context = GetContext();
1221 ASSERT_TRUE(context);
1223 auto desc = BoxFadePipelineBuilder::MakeDefaultPipelineDescriptor(*context);
1224 ASSERT_TRUE(desc.has_value());
1230 {{100, 100, 0.0}, {0.0, 0.0}},
1231 {{800, 100, 0.0}, {1.0, 0.0}},
1232 {{800, 800, 0.0}, {1.0, 1.0}},
1233 {{100, 100, 0.0}, {0.0, 0.0}},
1234 {{800, 800, 0.0}, {1.0, 1.0}},
1235 {{100, 800, 0.0}, {0.0, 1.0}},
1237 auto vertex_buffer =
1239 ASSERT_TRUE(vertex_buffer);
1242 desc->SetStencilAttachmentDescriptors(std::nullopt);
1244 auto bridge = CreateTextureForFixture(
"bay_bridge.jpg");
1245 auto boston = CreateTextureForFixture(
"boston.jpg");
1246 ASSERT_TRUE(bridge && boston);
1248 ASSERT_TRUE(sampler);
1250 static bool mirror =
false;
1251 static int stencil_reference_write = 0xFF;
1252 static int stencil_reference_read = 0x1;
1253 std::vector<uint8_t> stencil_contents;
1254 static int last_stencil_contents_reference_value = 0;
1255 static int current_front_compare =
1257 static int current_back_compare =
1261 auto [data_host_buffer, indexes_host_buffer] = createHostBuffers(context);
1262 auto buffer = context->CreateCommandBuffer();
1266 buffer->SetLabel(
"Playground Command Buffer");
1274 render_target.SetupDepthStencilAttachments(
1275 *context, *context->GetResourceAllocator(),
1276 render_target.GetRenderTargetSize(),
true,
"stencil", stencil_config);
1278 const auto target_width = render_target.GetRenderTargetSize().width;
1279 const auto target_height = render_target.GetRenderTargetSize().height;
1280 const size_t target_size = target_width * target_height;
1281 if (stencil_contents.size() != target_size ||
1282 last_stencil_contents_reference_value != stencil_reference_write) {
1283 stencil_contents.resize(target_size);
1284 last_stencil_contents_reference_value = stencil_reference_write;
1285 for (
int y = 0;
y < target_height;
y++) {
1286 for (
int x = 0;
x < target_width;
x++) {
1287 const auto index =
y * target_width +
x;
1288 const auto kCheckSize = 64;
1290 (((
y / kCheckSize) + (
x / kCheckSize)) % 2 == 0) *
1291 stencil_reference_write;
1292 stencil_contents[index] =
value;
1296 if (!render_target.GetStencilAttachment()->texture->SetContents(
1297 stencil_contents.data(), stencil_contents.size(), 0,
false)) {
1298 VALIDATION_LOG <<
"Could not upload stencil contents to device memory";
1301 auto pass =
buffer->CreateRenderPass(render_target);
1305 pass->SetLabel(
"Stencil Buffer");
1306 ImGui::Begin(
"Controls",
nullptr, ImGuiWindowFlags_AlwaysAutoResize);
1307 ImGui::SliderInt(
"Stencil Write Value", &stencil_reference_write, 0,
1309 ImGui::SliderInt(
"Stencil Compare Value", &stencil_reference_read, 0,
1311 ImGui::Checkbox(
"Back face mode", &mirror);
1312 ImGui::ListBox(
"Front face compare function", ¤t_front_compare,
1314 ImGui::ListBox(
"Back face compare function", ¤t_back_compare,
1324 desc->SetStencilAttachmentDescriptors(front, back);
1325 auto pipeline = context->GetPipelineLibrary()->GetPipeline(desc).Get();
1327 assert(pipeline && pipeline->IsValid());
1329 pass->SetCommandLabel(
"Box");
1330 pass->SetPipeline(pipeline);
1331 pass->SetStencilReference(stencil_reference_read);
1332 pass->SetVertexBuffer(vertex_buffer);
1334 VS::UniformBuffer uniforms;
1335 EXPECT_EQ(pass->GetOrthographicTransform(),
1337 uniforms.mvp = pass->GetOrthographicTransform() *
1342 VS::BindUniformBuffer(*pass, data_host_buffer->EmplaceUniform(uniforms));
1344 FS::FrameInfo frame_info;
1345 frame_info.current_time = GetSecondsElapsed();
1346 frame_info.cursor_position = GetCursorPosition();
1347 frame_info.window_size.x = GetWindowSize().width;
1348 frame_info.window_size.y = GetWindowSize().height;
1350 FS::BindFrameInfo(*pass, data_host_buffer->EmplaceUniform(frame_info));
1351 FS::BindContents1(*pass, boston, sampler);
1352 FS::BindContents2(*pass, bridge, sampler);
1353 if (!pass->Draw().ok()) {
1356 pass->EncodeCommands();
1359 if (!context->GetCommandQueue()->Submit({buffer}).ok()) {
1362 data_host_buffer->Reset();
1369 auto context = GetContext();
1370 auto cmd_buffer = context->CreateCommandBuffer();
1371 auto render_target_cache = std::make_shared<RenderTargetAllocator>(
1372 GetContext()->GetResourceAllocator());
1374 auto render_target = render_target_cache->CreateOffscreen(
1375 *context, {100, 100}, 1);
1376 auto render_pass = cmd_buffer->CreateRenderPass(render_target);
1378 EXPECT_EQ(render_pass->GetSampleCount(), render_target.GetSampleCount());
1379 EXPECT_EQ(render_pass->GetRenderTargetPixelFormat(),
1380 render_target.GetRenderTargetPixelFormat());
1381 EXPECT_EQ(render_pass->HasStencilAttachment(),
1382 render_target.GetStencilAttachment().has_value());
1383 EXPECT_EQ(render_pass->GetRenderTargetSize(),
1384 render_target.GetRenderTargetSize());
1385 render_pass->EncodeCommands();
1389 RenderTargetCreateOffscreenMSAASetsDefaultDepthStencilFormat) {
1390 auto context = GetContext();
1391 auto render_target_cache = std::make_shared<RenderTargetAllocator>(
1392 GetContext()->GetResourceAllocator());
1394 RenderTarget render_target = render_target_cache->CreateOffscreenMSAA(
1395 *context, {100, 100}, 1);
1397 ->texture->GetTextureDescriptor()
1399 GetContext()->GetCapabilities()->GetDefaultDepthStencilFormat());
1402template <
class VertexShader,
class FragmentShader>
1404 const std::shared_ptr<Context>& context) {
1406 auto pipeline_desc =
1407 TexturePipelineBuilder::MakeDefaultPipelineDescriptor(*context);
1408 if (!pipeline_desc.has_value()) {
1412 pipeline_desc->SetStencilAttachmentDescriptors(std::nullopt);
1414 context->GetPipelineLibrary()->GetPipeline(pipeline_desc).Get();
1415 if (!pipeline || !pipeline->IsValid()) {
1423 using TextureVS = TextureVertexShader;
1424 using TextureFS = TextureFragmentShader;
1426 using SepiaVS = SepiaVertexShader;
1427 using SepiaFS = SepiaFragmentShader;
1429 auto context = GetContext();
1430 ASSERT_TRUE(context);
1432 if (!context->GetCapabilities()->SupportsFramebufferFetch()) {
1433 GTEST_SKIP() <<
"This test uses framebuffer fetch and the backend doesn't "
1439 auto texture_pipeline = CreateDefaultPipeline<TextureVS, TextureFS>(context);
1440 auto sepia_pipeline = CreateDefaultPipeline<SepiaVS, SepiaFS>(context);
1442 ASSERT_TRUE(texture_pipeline);
1443 ASSERT_TRUE(sepia_pipeline);
1448 {{100, 100, 0.0}, {0.0, 0.0}},
1449 {{800, 100, 0.0}, {1.0, 0.0}},
1450 {{800, 800, 0.0}, {1.0, 1.0}},
1451 {{100, 100, 0.0}, {0.0, 0.0}},
1452 {{800, 800, 0.0}, {1.0, 1.0}},
1453 {{100, 800, 0.0}, {0.0, 1.0}},
1466 auto boston = CreateTextureForFixture(
"boston.jpg");
1467 ASSERT_TRUE(boston);
1469 const auto& sampler = context->GetSamplerLibrary()->GetSampler({});
1470 ASSERT_TRUE(sampler);
1474 context->GetResourceAllocator(), context->GetIdleWaiter(),
1475 context->GetCapabilities()->GetMinimumUniformAlignment());
1479 pass.SetPipeline(texture_pipeline);
1481 *context->GetResourceAllocator()));
1482 TextureVS::UniformBuffer uniforms;
1485 TextureVS::BindUniformBuffer(pass,
buffer->EmplaceUniform(uniforms));
1486 TextureFS::BindTextureContents(pass, boston, sampler);
1487 if (!pass.Draw().ok()) {
1494 pass.SetPipeline(sepia_pipeline);
1496 *context->GetResourceAllocator()));
1497 SepiaVS::UniformBuffer uniforms;
1500 SepiaVS::BindUniformBuffer(pass,
buffer->EmplaceUniform(uniforms));
1501 if (!pass.Draw().ok()) {
1513 using TextureVS = TextureVertexShader;
1514 using TextureFS = TextureFragmentShader;
1516 using SwizzleVS = SepiaVertexShader;
1517 using SwizzleFS = SwizzleFragmentShader;
1519 using SepiaVS = SepiaVertexShader;
1520 using SepiaFS = SepiaFragmentShader;
1522 auto context = GetContext();
1523 ASSERT_TRUE(context);
1525 if (!context->GetCapabilities()->SupportsFramebufferFetch()) {
1526 GTEST_SKIP() <<
"This test uses framebuffer fetch and the backend doesn't "
1532 auto texture_pipeline = CreateDefaultPipeline<TextureVS, TextureFS>(context);
1533 auto swizzle_pipeline = CreateDefaultPipeline<SwizzleVS, SwizzleFS>(context);
1534 auto sepia_pipeline = CreateDefaultPipeline<SepiaVS, SepiaFS>(context);
1536 ASSERT_TRUE(texture_pipeline);
1537 ASSERT_TRUE(swizzle_pipeline);
1538 ASSERT_TRUE(sepia_pipeline);
1543 {{100, 100, 0.0}, {0.0, 0.0}},
1544 {{800, 100, 0.0}, {1.0, 0.0}},
1545 {{800, 800, 0.0}, {1.0, 1.0}},
1546 {{100, 100, 0.0}, {0.0, 0.0}},
1547 {{800, 800, 0.0}, {1.0, 1.0}},
1548 {{100, 800, 0.0}, {0.0, 1.0}},
1561 auto boston = CreateTextureForFixture(
"boston.jpg");
1562 ASSERT_TRUE(boston);
1564 const auto& sampler = context->GetSamplerLibrary()->GetSampler({});
1565 ASSERT_TRUE(sampler);
1569 context->GetResourceAllocator(), context->GetIdleWaiter(),
1570 context->GetCapabilities()->GetMinimumUniformAlignment());
1574 pass.SetPipeline(texture_pipeline);
1576 *context->GetResourceAllocator()));
1577 TextureVS::UniformBuffer uniforms;
1580 TextureVS::BindUniformBuffer(pass, data_buffer->EmplaceUniform(uniforms));
1581 TextureFS::BindTextureContents(pass, boston, sampler);
1582 if (!pass.Draw().ok()) {
1589 pass.SetPipeline(sepia_pipeline);
1591 *context->GetResourceAllocator()));
1592 SepiaVS::UniformBuffer uniforms;
1595 SepiaVS::BindUniformBuffer(pass, data_buffer->EmplaceUniform(uniforms));
1596 if (!pass.Draw().ok()) {
1603 pass.SetPipeline(swizzle_pipeline);
1605 *context->GetResourceAllocator()));
1606 SwizzleVS::UniformBuffer uniforms;
1609 SwizzleVS::BindUniformBuffer(pass, data_buffer->EmplaceUniform(uniforms));
1610 if (!pass.Draw().ok()) {
1621 using FS = BoxFadeFragmentShader;
1623 auto context = GetContext();
1625 auto command_buffer = context->CreateCommandBuffer();
1630 auto pass = command_buffer->CreateRenderPass(
target);
1631 EXPECT_FALSE(FS::BindContents2(*pass,
nullptr, sampler));
constexpr double ToSecondsF() const
constexpr TimeDelta ToEpochDelta() const
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...
virtual RenderTarget CreateOffscreen(const Context &context, ISize size, int mip_count, std::string_view label="Offscreen", RenderTarget::AttachmentConfig color_attachment_config=RenderTarget::kDefaultColorAttachmentConfig, std::optional< RenderTarget::AttachmentConfig > stencil_attachment_config=RenderTarget::kDefaultStencilAttachmentConfig, const std::shared_ptr< Texture > &existing_color_texture=nullptr, const std::shared_ptr< Texture > &existing_depth_stencil_texture=nullptr)
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()
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 Blue()
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...