Flutter Engine Uber Docs
Docs for the entire Flutter Engine repo.
 
Loading...
Searching...
No Matches
shader_types.h
Go to the documentation of this file.
1// Copyright 2013 The Flutter Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#ifndef FLUTTER_IMPELLER_CORE_SHADER_TYPES_H_
6#define FLUTTER_IMPELLER_CORE_SHADER_TYPES_H_
7
8#include <cstddef>
9#include <cstdint>
10#include <optional>
11#include <string_view>
12#include <vector>
13
15#include "flutter/fml/logging.h"
19
20namespace impeller {
21
22enum class ShaderStage {
24 kVertex,
27};
28
40
62
63// This is a separate type from ShaderType because ShaderType is used for
64// OpenGLES's attrib type which doesn't map to things like vec4.
65enum class ShaderFloatType {
66 kFloat,
67 kVec2,
68 kVec3,
69 kVec4,
70 kMat2,
71 kMat3,
72 kMat4,
73};
74
77 std::string name;
78 size_t offset;
79 size_t size;
81 std::optional<size_t> array_elements;
82 std::optional<ShaderFloatType> float_type;
83};
84
85/// @brief Derive the `ShaderFloatType` from the base `ShaderType` and
86/// the (vec_size, columns) dimensions reported by SPIR-V Cross.
87///
88/// `vec_size` is the component count of a single column (the vector length
89/// for non-matrix types, the row count for matrices). `columns` is 1 for
90/// vectors and N for an NxN matrix. Returns `std::nullopt` for non-float
91/// types and for shapes that don't map to a `ShaderFloatType`.
92constexpr std::optional<ShaderFloatType> DeriveShaderFloatType(ShaderType type,
93 size_t vec_size,
94 size_t columns) {
95 if (type != ShaderType::kFloat) {
96 return std::nullopt;
97 }
98 if (columns == 1) {
99 switch (vec_size) {
100 case 1:
102 case 2:
104 case 3:
106 case 4:
108 default:
109 return std::nullopt;
110 }
111 }
112 if (vec_size == columns) {
113 switch (vec_size) {
114 case 2:
116 case 3:
118 case 4:
120 default:
121 return std::nullopt;
122 }
123 }
124 return std::nullopt;
125}
126
128 // This must match the uniform name in the shader program.
129 std::string name;
130 std::vector<ShaderStructMemberMetadata> members;
131};
132
133/// @brief Metadata required to bind a buffer.
134///
135/// OpenGL binding requires the usage of the separate shader metadata struct.
137 /// @brief The name of the uniform slot.
138 const char* name;
139
140 /// @brief `ext_res_0` is the Metal binding value.
141 size_t ext_res_0;
142
143 /// @brief The Vulkan descriptor set index.
144 size_t set;
145
146 /// @brief The Vulkan binding value.
147 size_t binding;
148};
149
150/// @brief Metadata required to bind a combined texture and sampler.
151///
152/// OpenGL binding requires the usage of the separate shader metadata struct.
154 /// @brief The name of the uniform slot.
155 const char* name;
156
157 /// @brief `ext_res_0` is the Metal binding value.
159
160 /// @brief The Vulkan descriptor set index.
161 size_t set;
162
163 /// @brief The Vulkan binding value.
164 size_t binding;
165};
166
167/// @brief The format of a single vertex attribute, combining its scalar kind,
168/// bit width, and component count.
169///
170/// Each backend maps these values to its own native vertex format, so
171/// this is the shared vocabulary for vertex inputs. The values are
172/// currently derived from a reflected `ShaderStageIOSlot` (see
173/// `ShaderStageIOSlot::GetVertexAttributeFormat`), so only the kinds
174/// that reflection produces are reachable.
176 /// Not a valid vertex attribute (a matrix input, an unsupported scalar kind,
177 /// or a component count outside 1 to 4).
178 kInvalid,
179
180 kFloat32,
184
185 kFloat16,
189
190 kSInt8,
191 kSInt8x2,
192 kSInt8x3,
193 kSInt8x4,
194
195 kUInt8,
196 kUInt8x2,
197 kUInt8x3,
198 kUInt8x4,
199
200 kSInt16,
201 kSInt16x2,
202 kSInt16x3,
203 kSInt16x4,
204
205 kUInt16,
206 kUInt16x2,
207 kUInt16x3,
208 kUInt16x4,
209
210 kSInt32,
211 kSInt32x2,
212 kSInt32x3,
213 kSInt32x4,
214
215 kUInt32,
216 kUInt32x2,
217 kUInt32x3,
218 kUInt32x4,
219};
220
222 const char* name;
223 size_t location;
224 size_t set;
225 size_t binding;
227 size_t bit_width;
228 size_t vec_size;
229 size_t columns;
230 size_t offset;
232
233 constexpr size_t GetHash() const {
236 }
237
238 constexpr bool operator==(const ShaderStageIOSlot& other) const {
239 return name == other.name && //
240 location == other.location && //
241 set == other.set && //
242 binding == other.binding && //
243 type == other.type && //
244 bit_width == other.bit_width && //
245 vec_size == other.vec_size && //
246 columns == other.columns && //
247 offset == other.offset && //
249 ;
250 }
251
252 /// @brief Derives the flat vertex attribute format from this slot's scalar
253 /// type, bit width, and component count.
254 ///
255 /// Returns `kInvalid` for matrices, component counts outside 1 to 4,
256 /// mismatched bit widths, and scalar kinds that are not valid vertex
257 /// inputs (boolean, 64-bit integers, and doubles).
259 if (columns != 1u || vec_size < 1u || vec_size > 4u) {
261 }
262 auto pick = [vec_size = vec_size](
265 switch (vec_size) {
266 case 1:
267 return x1;
268 case 2:
269 return x2;
270 case 3:
271 return x3;
272 case 4:
273 return x4;
274 default:
276 }
277 };
278 switch (type) {
280 return bit_width == 32u ? pick(VertexAttributeFormat::kFloat32,
286 return bit_width == 16u ? pick(VertexAttributeFormat::kFloat16,
292 return bit_width == 8u ? pick(VertexAttributeFormat::kSInt8,
298 return bit_width == 8u ? pick(VertexAttributeFormat::kUInt8,
304 return bit_width == 16u ? pick(VertexAttributeFormat::kSInt16,
310 return bit_width == 16u ? pick(VertexAttributeFormat::kUInt16,
316 return bit_width == 32u ? pick(VertexAttributeFormat::kSInt32,
322 return bit_width == 32u ? pick(VertexAttributeFormat::kUInt32,
339 }
341 }
342};
343
344/// @brief Whether a vertex buffer binding advances its read position once
345/// per vertex or once per instance.
346///
347/// An instance-rate binding supplies per-instance data (such as a
348/// per-instance model transform) to an instanced draw. It maps to
349/// `MTLVertexStepFunctionPerInstance`, `VK_VERTEX_INPUT_RATE_INSTANCE`,
350/// and a `glVertexAttribDivisor` of 1.
351enum class VertexInputRate {
352 /// The binding is read once per vertex. This is the default.
353 kVertex,
354 /// The binding is read once per instance.
355 kInstance,
356};
357
359 size_t stride;
360 size_t binding;
361 /// The rate at which this binding advances during a draw. Defaults to
362 /// per-vertex; an instanced draw reads per-instance bindings once per
363 /// instance.
365
366 constexpr size_t GetHash() const {
368 }
369
370 constexpr bool operator==(const ShaderStageBufferLayout& other) const {
371 return stride == other.stride && //
372 binding == other.binding && //
373 input_rate == other.input_rate;
374 }
375};
376
377// These enum values were chosen to match the same values
378// in the VK Descriptor Type enum.
379enum class DescriptorType {
380 kSampler = 0,
381 kSampledImage = 1,
382 kImage = 2,
383 kUniformBuffer = 6,
384 kStorageBuffer = 7,
385 kInputAttachment = 10,
386};
387
393
394template <size_t Size>
395struct Padding {
396 private:
397 uint8_t pad_[Size];
398};
399
400/// @brief Struct used for padding uniform buffer array elements.
401template <typename T,
402 size_t Size,
403 class = std::enable_if_t<std::is_standard_layout_v<T>>>
404struct Padded {
407
408 Padded(T p_value) : value(p_value) {}; // NOLINT(google-explicit-constructor)
409};
410
411inline constexpr Vector4 ToVector(Color color) {
412 return {color.red, color.green, color.blue, color.alpha};
413}
414
415} // namespace impeller
416
417#endif // FLUTTER_IMPELLER_CORE_SHADER_TYPES_H_
uint32_t vec_size
uint32_t columns
#define FML_UNREACHABLE()
Definition logging.h:128
constexpr std::size_t HashCombine()
VertexInputRate
Whether a vertex buffer binding advances its read position once per vertex or once per instance.
@ kInstance
The binding is read once per instance.
@ kVertex
The binding is read once per vertex. This is the default.
constexpr std::optional< ShaderFloatType > DeriveShaderFloatType(ShaderType type, size_t vec_size, size_t columns)
Derive the ShaderFloatType from the base ShaderType and the (vec_size, columns) dimensions reported b...
constexpr ShaderStage ToShaderStage(RuntimeShaderStage stage)
VertexAttributeFormat
The format of a single vertex attribute, combining its scalar kind, bit width, and component count.
constexpr Vector4 ToVector(Color color)
TSize< Scalar > Size
Definition size.h:159
impeller::ShaderType type
Scalar blue
Definition color.h:138
Scalar alpha
Definition color.h:143
Scalar red
Definition color.h:128
Scalar green
Definition color.h:133
Struct used for padding uniform buffer array elements.
Padded(T p_value)
Padding< Size > _PADDING_
Metadata required to bind a combined texture and sampler.
size_t texture_index
ext_res_0 is the Metal binding value.
size_t set
The Vulkan descriptor set index.
const char * name
The name of the uniform slot.
size_t binding
The Vulkan binding value.
std::vector< ShaderStructMemberMetadata > members
constexpr size_t GetHash() const
constexpr bool operator==(const ShaderStageBufferLayout &other) const
constexpr bool operator==(const ShaderStageIOSlot &other) const
constexpr size_t GetHash() const
constexpr VertexAttributeFormat GetVertexAttributeFormat() const
Derives the flat vertex attribute format from this slot's scalar type, bit width, and component count...
std::optional< ShaderFloatType > float_type
std::optional< size_t > array_elements
Metadata required to bind a buffer.
size_t binding
The Vulkan binding value.
size_t ext_res_0
ext_res_0 is the Metal binding value.
size_t set
The Vulkan descriptor set index.
const char * name
The name of the uniform slot.