| Flutter Impeller |

vertex_descriptor_mtl.mm
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 #include "impeller/renderer/backend/metal/vertex_descriptor_mtl.h"
6
7 #include "flutter/fml/logging.h"
8 #include "impeller/base/validation.h"
9
10 namespace impeller {
11
12 VertexDescriptorMTL::VertexDescriptorMTL() = default;
13
14 VertexDescriptorMTL::~VertexDescriptorMTL() = default;
15
16 static MTLVertexFormat ReadStageInputFormat(const ShaderStageIOSlot& input) {
17 if (input.columns != 1) {
18 // All matrix types are unsupported as vertex inputs.
19 return MTLVertexFormatInvalid;
20 }
21
22 switch (input.type) {
23 case ShaderType::kFloat: {
24 if (input.bit_width == 8 * sizeof(float)) {
25 switch (input.vec_size) {
26 case 1:
27 return MTLVertexFormatFloat;
28 case 2:
29 return MTLVertexFormatFloat2;
30 case 3:
31 return MTLVertexFormatFloat3;
32 case 4:
33 return MTLVertexFormatFloat4;
34 }
35 }
36 return MTLVertexFormatInvalid;
37 }
38 case ShaderType::kHalfFloat: {
39 if (input.bit_width == 8 * sizeof(float) / 2) {
40 switch (input.vec_size) {
41 case 1:
42 return MTLVertexFormatHalf;
43 case 2:
44 return MTLVertexFormatHalf2;
45 case 3:
46 return MTLVertexFormatHalf3;
47 case 4:
48 return MTLVertexFormatHalf4;
49 }
50 }
51 return MTLVertexFormatInvalid;
52 }
53 case ShaderType::kDouble: {
54 // Unsupported.
55 return MTLVertexFormatInvalid;
56 }
57 case ShaderType::kBoolean: {
58 if (input.bit_width == 8 * sizeof(bool) && input.vec_size == 1) {
59 return MTLVertexFormatChar;
60 }
61 return MTLVertexFormatInvalid;
62 }
63 case ShaderType::kSignedByte: {
64 if (input.bit_width == 8 * sizeof(char)) {
65 switch (input.vec_size) {
66 case 1:
67 return MTLVertexFormatChar;
68 case 2:
69 return MTLVertexFormatChar2;
70 case 3:
71 return MTLVertexFormatChar3;
72 case 4:
73 return MTLVertexFormatChar4;
74 }
75 }
76 return MTLVertexFormatInvalid;
77 }
78 case ShaderType::kUnsignedByte: {
79 if (input.bit_width == 8 * sizeof(char)) {
80 switch (input.vec_size) {
81 case 1:
82 return MTLVertexFormatUChar;
83 case 2:
84 return MTLVertexFormatUChar2;
85 case 3:
86 return MTLVertexFormatUChar3;
87 case 4:
88 return MTLVertexFormatUChar4;
89 }
90 }
91 return MTLVertexFormatInvalid;
92 }
93 case ShaderType::kSignedShort: {
94 if (input.bit_width == 8 * sizeof(short)) {
95 switch (input.vec_size) {
96 case 1:
97 return MTLVertexFormatShort;
98 case 2:
99 return MTLVertexFormatShort2;
100 case 3:
101 return MTLVertexFormatShort3;
102 case 4:
103 return MTLVertexFormatShort4;
104 }
105 }
106 return MTLVertexFormatInvalid;
107 }
108 case ShaderType::kUnsignedShort: {
109 if (input.bit_width == 8 * sizeof(ushort)) {
110 switch (input.vec_size) {
111 case 1:
112 return MTLVertexFormatUShort;
113 case 2:
114 return MTLVertexFormatUShort2;
115 case 3:
116 return MTLVertexFormatUShort3;
117 case 4:
118 return MTLVertexFormatUShort4;
119 }
120 }
121 return MTLVertexFormatInvalid;
122 }
123 case ShaderType::kSignedInt: {
124 if (input.bit_width == 8 * sizeof(int32_t)) {
125 switch (input.vec_size) {
126 case 1:
127 return MTLVertexFormatInt;
128 case 2:
129 return MTLVertexFormatInt2;
130 case 3:
131 return MTLVertexFormatInt3;
132 case 4:
133 return MTLVertexFormatInt4;
134 }
135 }
136 return MTLVertexFormatInvalid;
137 }
138 case ShaderType::kUnsignedInt: {
139 if (input.bit_width == 8 * sizeof(uint32_t)) {
140 switch (input.vec_size) {
141 case 1:
142 return MTLVertexFormatUInt;
143 case 2:
144 return MTLVertexFormatUInt2;
145 case 3:
146 return MTLVertexFormatUInt3;
147 case 4:
148 return MTLVertexFormatUInt4;
149 }
150 }
151 return MTLVertexFormatInvalid;
152 }
153 case ShaderType::kSignedInt64: {
154 // Unsupported.
155 return MTLVertexFormatInvalid;
156 }
157 case ShaderType::kUnsignedInt64: {
158 // Unsupported.
159 return MTLVertexFormatInvalid;
160 }
161 case ShaderType::kAtomicCounter:
162 case ShaderType::kStruct:
163 case ShaderType::kImage:
164 case ShaderType::kSampledImage:
165 case ShaderType::kUnknown:
166 case ShaderType::kVoid:
167 case ShaderType::kSampler:
168 return MTLVertexFormatInvalid;
169 }
170 }
171
172 bool VertexDescriptorMTL::SetStageInputsAndLayout(
173 const std::vector<ShaderStageIOSlot>& inputs,
174 const std::vector<ShaderStageBufferLayout>& layouts) {
175 auto descriptor = descriptor_ = [MTLVertexDescriptor vertexDescriptor];
176
177 // TODO(jonahwilliams): its odd that we offset buffers from the max index on
178 // metal but not on GLES or Vulkan. We should probably consistently start
179 // these at zero?
180 for (size_t i = 0; i < inputs.size(); i++) {
181 const auto& input = inputs[i];
182 auto vertex_format = ReadStageInputFormat(input);
183 if (vertex_format == MTLVertexFormatInvalid) {
184 VALIDATION_LOG << "Format for input " << input.name << " not supported.";
185 return false;
186 }
187 auto attrib = descriptor.attributes[input.location];
188 attrib.format = vertex_format;
189 attrib.offset = input.offset;
190 attrib.bufferIndex =
191 VertexDescriptor::kReservedVertexBufferIndex - input.binding;
192 }
193
194 for (size_t i = 0; i < layouts.size(); i++) {
195 const auto& layout = layouts[i];
196 auto vertex_layout =
197 descriptor.layouts[VertexDescriptor::kReservedVertexBufferIndex -
198 layout.binding];
199 vertex_layout.stride = layout.stride;
200 vertex_layout.stepRate = 1u;
201 vertex_layout.stepFunction = MTLVertexStepFunctionPerVertex;
202 }
203 return true;
204 }
205
206 MTLVertexDescriptor* VertexDescriptorMTL::GetMTLVertexDescriptor() const {
207 return descriptor_;
208 }
209
210 } // namespace impeller
impeller::ShaderStageIOSlot
Definition: shader_types.h:112
impeller::ShaderType::kAtomicCounter
@ kAtomicCounter
impeller::ShaderStageIOSlot::columns
size_t columns
Definition: shader_types.h:120
impeller::ShaderType::kDouble
@ kDouble
impeller::ShaderType::kSignedInt64
@ kSignedInt64
impeller::ShaderType::kImage
@ kImage
impeller::ShaderType::kVoid
@ kVoid
impeller::ReadStageInputFormat
static MTLVertexFormat ReadStageInputFormat(const ShaderStageIOSlot &input)
Definition: vertex_descriptor_mtl.mm:16
impeller::ShaderType::kSignedByte
@ kSignedByte
impeller::VertexDescriptorMTL::~VertexDescriptorMTL
~VertexDescriptorMTL()
validation.h
impeller::ShaderType::kUnsignedShort
@ kUnsignedShort
impeller::VertexDescriptorMTL::SetStageInputsAndLayout
bool SetStageInputsAndLayout(const std::vector< ShaderStageIOSlot > &inputs, const std::vector< ShaderStageBufferLayout > &layouts)
Definition: vertex_descriptor_mtl.mm:172
impeller::ShaderType::kUnsignedInt64
@ kUnsignedInt64
impeller::ShaderType::kUnsignedByte
@ kUnsignedByte
impeller::ShaderType::kFloat
@ kFloat
impeller::ShaderStageIOSlot::bit_width
size_t bit_width
Definition: shader_types.h:118
impeller::ShaderType::kBoolean
@ kBoolean
impeller::ShaderType::kSampler
@ kSampler
impeller::VertexDescriptorMTL::VertexDescriptorMTL
VertexDescriptorMTL()
impeller::ShaderType::kSampledImage
@ kSampledImage
impeller::ShaderType::kUnsignedInt
@ kUnsignedInt
impeller::VertexDescriptorMTL::GetMTLVertexDescriptor
MTLVertexDescriptor * GetMTLVertexDescriptor() const
Definition: vertex_descriptor_mtl.mm:206
VALIDATION_LOG
#define VALIDATION_LOG
Definition: validation.h:67
impeller::ShaderType::kStruct
@ kStruct
impeller::ShaderType::kSignedShort
@ kSignedShort
impeller::ShaderType::kHalfFloat
@ kHalfFloat
impeller::ShaderType::kSignedInt
@ kSignedInt
impeller::ShaderStageIOSlot::type
ShaderType type
Definition: shader_types.h:117
impeller::VertexDescriptor::kReservedVertexBufferIndex
static constexpr size_t kReservedVertexBufferIndex
Definition: vertex_descriptor.h:25
vertex_descriptor_mtl.h
impeller::ShaderType::kUnknown
@ kUnknown
impeller
Definition: aiks_context.cc:10
impeller::ShaderStageIOSlot::vec_size
size_t vec_size
Definition: shader_types.h:119