| // Copyright 2013 The Flutter Authors. All rights reserved. |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| #include <string_view> |
| |
| namespace impeller { |
| namespace compiler { |
| |
| constexpr std::string_view kReflectionHeaderTemplate = |
| R"~~(// THIS FILE IS GENERATED BY impellerc. |
| // DO NOT EDIT OR CHECK THIS INTO SOURCE CONTROL |
| |
| #pragma once |
| |
| {# Note: The nogncheck decorations are only to make GN not mad at the template#} |
| {# this file is generated from. There are no GN rule violations in the generated#} |
| {# file itself and the no-check declarations will be stripped in generated files.#} |
| #include "impeller/core/buffer_view.h" {# // nogncheck #} |
| |
| #include "impeller/core/sampler.h" {# // nogncheck #} |
| |
| #include "impeller/core/shader_types.h" {# // nogncheck #} |
| |
| #include "impeller/core/resource_binder.h" {# // nogncheck #} |
| |
| #include "impeller/core/texture.h" {# // nogncheck #} |
| |
| |
| namespace impeller { |
| |
| struct {{camel_case(shader_name)}}{{camel_case(shader_stage)}}Shader { |
| // =========================================================================== |
| // Stage Info ================================================================ |
| // =========================================================================== |
| static constexpr std::string_view kLabel = "{{camel_case(shader_name)}}"; |
| static constexpr std::string_view kEntrypointName = "{{entrypoint}}"; |
| static constexpr ShaderStage kShaderStage = {{to_shader_stage(shader_stage)}}; |
| // The generator used to prepare these bindings. Metal generators may be used |
| // by GLES backends but GLES generators are unsuitable for the metal backend. |
| static constexpr std::string_view kGeneratorName = "{{get_generator_name()}}"; |
| {% if length(struct_definitions) > 0 %} |
| // =========================================================================== |
| // Struct Definitions ======================================================== |
| // =========================================================================== |
| {% for def in struct_definitions %} |
| |
| {% if last(def.members).array_elements == 0 %} |
| template <size_t FlexCount> |
| {% endif %} |
| struct {{def.name}} { |
| {% for member in def.members %} |
| {{" "}}{% if member.element_padding > 0 %}Padded<{{member.type}}, {{member.element_padding}}>{% else %}{{member.type}}{% endif %}{{" " + member.name}}{% if member.array_elements != "std::nullopt" %}[{% if member.array_elements == 0 %}FlexCount{% else %}{{member.array_elements}}{% endif %}]{% endif %}; // (offset {{member.offset}}, size {{member.byte_length}}) |
| {% endfor %} |
| }; // struct {{def.name}} (size {{def.byte_length}}) |
| {% endfor %} |
| {% endif %} |
| {% if length(buffers) > 0 %} |
| |
| // =========================================================================== |
| // Stage Uniform & Storage Buffers =========================================== |
| // =========================================================================== |
| {% for buffer in buffers %} |
| |
| static constexpr auto kResource{{camel_case(buffer.name)}} = ShaderUniformSlot { // {{buffer.name}} |
| "{{buffer.name}}", // name |
| {{buffer.ext_res_0}}u, // ext_res_0 |
| {{buffer.set}}u, // set |
| {{buffer.binding}}u, // binding |
| }; |
| static ShaderMetadata kMetadata{{camel_case(buffer.name)}}; |
| {% endfor %} |
| {% endif %} |
| |
| // =========================================================================== |
| // Stage Inputs ============================================================== |
| // =========================================================================== |
| {% if length(stage_inputs) > 0 %} |
| {% for stage_input in stage_inputs %} |
| |
| static constexpr auto kInput{{camel_case(stage_input.name)}} = ShaderStageIOSlot { // {{stage_input.name}} |
| "{{stage_input.name}}", // name |
| {{stage_input.location}}u, // attribute location |
| {{stage_input.descriptor_set}}u, // attribute set |
| {{stage_input.binding}}u, // attribute binding |
| {{stage_input.type.type_name}}, // type |
| {{stage_input.type.bit_width}}u, // bit width of type |
| {{stage_input.type.vec_size}}u, // vec size |
| {{stage_input.type.columns}}u, // number of columns |
| {{stage_input.offset}}u, // offset for interleaved layout |
| }; |
| {% endfor %} |
| {% endif %} |
| |
| static constexpr std::array<const ShaderStageIOSlot*, {{length(stage_inputs)}}> kAllShaderStageInputs = { |
| {% for stage_input in stage_inputs %} |
| &kInput{{camel_case(stage_input.name)}}, // {{stage_input.name}} |
| {% endfor %} |
| }; |
| |
| {% if shader_stage == "vertex" %} |
| static constexpr auto kInterleavedLayout = ShaderStageBufferLayout { |
| {% if length(stage_inputs) > 0 %} |
| sizeof(PerVertexData), // stride for interleaved layout |
| {% else %} |
| 0u, |
| {% endif %} |
| 0u, // attribute binding |
| }; |
| static constexpr std::array<const ShaderStageBufferLayout*, 1> kInterleavedBufferLayout = { |
| &kInterleavedLayout |
| }; |
| {% endif %} |
| |
| {% if length(sampled_images) > 0 %} |
| // =========================================================================== |
| // Sampled Images ============================================================ |
| // =========================================================================== |
| {% for sampled_image in sampled_images %} |
| |
| static constexpr auto kResource{{camel_case(sampled_image.name)}} = SampledImageSlot { // {{sampled_image.name}} |
| "{{sampled_image.name}}", // name |
| {{sampled_image.ext_res_0}}u, // ext_res_0 |
| {{sampled_image.set}}u, // set |
| {{sampled_image.binding}}u, // binding |
| }; |
| static ShaderMetadata kMetadata{{camel_case(sampled_image.name)}}; |
| {% endfor %} |
| {% endif %} |
| // =========================================================================== |
| // Stage Outputs ============================================================= |
| // =========================================================================== |
| {% if length(stage_outputs) > 0 %} |
| {% for stage_output in stage_outputs %} |
| static constexpr auto kOutput{{camel_case(stage_output.name)}} = ShaderStageIOSlot { // {{stage_output.name}} |
| "{{stage_output.name}}", // name |
| {{stage_output.location}}u, // attribute location |
| {{stage_output.descriptor_set}}u, // attribute set |
| {{stage_output.binding}}u, // attribute binding |
| {{stage_output.type.type_name}}, // type |
| {{stage_output.type.bit_width}}u, // bit width of type |
| {{stage_output.type.vec_size}}u, // vec size |
| {{stage_output.type.columns}}u // number of columns |
| }; |
| {% endfor %} |
| static constexpr std::array<const ShaderStageIOSlot*, {{length(stage_outputs)}}> kAllShaderStageOutputs = { |
| {% for stage_output in stage_outputs %} |
| &kOutput{{camel_case(stage_output.name)}}, // {{stage_output.name}} |
| {% endfor %} |
| }; |
| {% endif %} |
| |
| // =========================================================================== |
| // Resource Binding Utilities ================================================ |
| // =========================================================================== |
| |
| {% for proto in bind_prototypes %} |
| /// {{proto.docstring}} |
| static {{proto.return_type}} Bind{{proto.name}}({% for arg in proto.args %} |
| {{arg.type_name}} {{arg.argument_name}}{% if not loop.is_last %}, {% endif %} |
| {% endfor %}) { |
| return {{ proto.args.0.argument_name }}.BindResource({% for arg in proto.args %} |
| {% if loop.is_first %} |
| {{to_shader_stage(shader_stage)}}, {{ proto.descriptor_type }}, kResource{{ proto.name }}, kMetadata{{ proto.name }}, {% else %} |
| std::move({{ arg.argument_name }}){% if not loop.is_last %}, {% endif %} |
| {% endif %} |
| {% endfor %}); |
| } |
| |
| {% endfor %} |
| |
| // =========================================================================== |
| // Metadata for Vulkan ======================================================= |
| // =========================================================================== |
| static constexpr std::array<DescriptorSetLayout,{{length(buffers)+length(sampled_images)+length(subpass_inputs)}}> kDescriptorSetLayouts{ |
| {% for subpass_input in subpass_inputs %} |
| DescriptorSetLayout{ |
| {{subpass_input.binding}}, // binding = {{subpass_input.binding}} |
| {{subpass_input.descriptor_type}}, // descriptor_type = {{subpass_input.descriptor_type}} |
| {{to_shader_stage(shader_stage)}}, // shader_stage = {{to_shader_stage(shader_stage)}} |
| }, |
| {% endfor %} |
| {% for buffer in buffers %} |
| DescriptorSetLayout{ |
| {{buffer.binding}}, // binding = {{buffer.binding}} |
| {{buffer.descriptor_type}}, // descriptor_type = {{buffer.descriptor_type}} |
| {{to_shader_stage(shader_stage)}}, // shader_stage = {{to_shader_stage(shader_stage)}} |
| }, |
| {% endfor %} |
| {% for sampled_image in sampled_images %} |
| DescriptorSetLayout{ |
| {{sampled_image.binding}}, // binding = {{sampled_image.binding}} |
| {{sampled_image.descriptor_type}}, // descriptor_type = {{sampled_image.descriptor_type}} |
| {{to_shader_stage(shader_stage)}}, // shader_stage = {{to_shader_stage(shader_stage)}} |
| }, |
| {% endfor %} |
| }; |
| |
| }; // struct {{camel_case(shader_name)}}{{camel_case(shader_stage)}}Shader |
| |
| } // namespace impeller |
| )~~"; |
| |
| constexpr std::string_view kReflectionCCTemplate = |
| R"~~(// THIS FILE IS GENERATED BY impellerc. |
| // DO NOT EDIT OR CHECK THIS INTO SOURCE CONTROL |
| |
| #include "{{header_file_name}}" |
| |
| #include <type_traits> |
| |
| namespace impeller { |
| |
| using Shader = {{camel_case(shader_name)}}{{camel_case(shader_stage)}}Shader; |
| |
| {% for def in struct_definitions %} |
| // Sanity checks for {{def.name}} |
| {% if last(def.members).array_elements == 0 %} |
| static_assert(std::is_standard_layout_v<Shader::{{def.name}}<0>>); |
| {% for member in def.members %} |
| static_assert(offsetof(Shader::{{def.name}}<0>, {{member.name}}) == {{member.offset}}); |
| {% endfor %} |
| {% else %} |
| static_assert(std::is_standard_layout_v<Shader::{{def.name}}>); |
| static_assert(sizeof(Shader::{{def.name}}) == {{def.byte_length}}); |
| {% for member in def.members %} |
| static_assert(offsetof(Shader::{{def.name}}, {{member.name}}) == {{member.offset}}); |
| {% endfor %} |
| {% endif %} |
| {% endfor %} |
| |
| {% for buffer in buffers %} |
| ShaderMetadata Shader::kMetadata{{camel_case(buffer.name)}} = { |
| "{{buffer.name}}", // name |
| std::vector<ShaderStructMemberMetadata> { |
| {% for member in buffer.type.members %} |
| ShaderStructMemberMetadata { |
| {{ member.base_type }}, // type |
| "{{ member.name }}", // name |
| {{ member.offset }}, // offset |
| {{ member.size }}, // size |
| {{ member.byte_length }}, // byte_length |
| {{ member.array_elements }}, // array_elements |
| }, |
| {% endfor %} |
| } // members |
| }; |
| {% endfor %} |
| |
| {% for sampled_image in sampled_images %} |
| ShaderMetadata Shader::kMetadata{{camel_case(sampled_image.name)}} = { |
| "{{sampled_image.name}}", // name |
| std::vector<ShaderStructMemberMetadata> {}, // 0 members |
| }; |
| {% endfor %} |
| |
| } // namespace impeller |
| )~~"; |
| |
| } // namespace compiler |
| } // namespace impeller |