blob: dbef3017c0e41654694de65956e1b8a4bc24977a [file] [log] [blame]
// 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