-
Notifications
You must be signed in to change notification settings - Fork 2.6k
/
MTLVertexFormat.mm
151 lines (145 loc) · 4.9 KB
/
MTLVertexFormat.mm
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
// Copyright 2022 Dolphin Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later
#include "VideoBackends/Metal/MTLVertexFormat.h"
#include "VideoCommon/VertexShaderGen.h"
static MTLVertexFormat ConvertFormat(ComponentFormat format, int count, bool int_format)
{
// clang-format off
if (int_format)
{
switch (format)
{
case ComponentFormat::UByte:
switch (count)
{
case 1: return MTLVertexFormatUChar;
case 2: return MTLVertexFormatUChar2;
case 3: return MTLVertexFormatUChar3;
case 4: return MTLVertexFormatUChar4;
default: return MTLVertexFormatInvalid;
}
case ComponentFormat::Byte:
switch (count)
{
case 1: return MTLVertexFormatChar;
case 2: return MTLVertexFormatChar2;
case 3: return MTLVertexFormatChar3;
case 4: return MTLVertexFormatChar4;
default: return MTLVertexFormatInvalid;
}
case ComponentFormat::UShort:
switch (count)
{
case 1: return MTLVertexFormatUShort;
case 2: return MTLVertexFormatUShort2;
case 3: return MTLVertexFormatUShort3;
case 4: return MTLVertexFormatUShort4;
default: return MTLVertexFormatInvalid;
}
case ComponentFormat::Short:
switch (count)
{
case 1: return MTLVertexFormatShort;
case 2: return MTLVertexFormatShort2;
case 3: return MTLVertexFormatShort3;
case 4: return MTLVertexFormatShort4;
default: return MTLVertexFormatInvalid;
}
case ComponentFormat::Float:
case ComponentFormat::InvalidFloat5:
case ComponentFormat::InvalidFloat6:
case ComponentFormat::InvalidFloat7:
switch (count)
{
case 1: return MTLVertexFormatFloat;
case 2: return MTLVertexFormatFloat2;
case 3: return MTLVertexFormatFloat3;
case 4: return MTLVertexFormatFloat4;
default: return MTLVertexFormatInvalid;
}
}
}
else
{
switch (format)
{
case ComponentFormat::UByte:
switch (count)
{
case 1: return MTLVertexFormatUCharNormalized;
case 2: return MTLVertexFormatUChar2Normalized;
case 3: return MTLVertexFormatUChar3Normalized;
case 4: return MTLVertexFormatUChar4Normalized;
default: return MTLVertexFormatInvalid;
}
case ComponentFormat::Byte:
switch (count)
{
case 1: return MTLVertexFormatCharNormalized;
case 2: return MTLVertexFormatChar2Normalized;
case 3: return MTLVertexFormatChar3Normalized;
case 4: return MTLVertexFormatChar4Normalized;
default: return MTLVertexFormatInvalid;
}
case ComponentFormat::UShort:
switch (count)
{
case 1: return MTLVertexFormatUShortNormalized;
case 2: return MTLVertexFormatUShort2Normalized;
case 3: return MTLVertexFormatUShort3Normalized;
case 4: return MTLVertexFormatUShort4Normalized;
default: return MTLVertexFormatInvalid;
}
case ComponentFormat::Short:
switch (count)
{
case 1: return MTLVertexFormatShortNormalized;
case 2: return MTLVertexFormatShort2Normalized;
case 3: return MTLVertexFormatShort3Normalized;
case 4: return MTLVertexFormatShort4Normalized;
default: return MTLVertexFormatInvalid;
}
case ComponentFormat::Float:
case ComponentFormat::InvalidFloat5:
case ComponentFormat::InvalidFloat6:
case ComponentFormat::InvalidFloat7:
switch (count)
{
case 1: return MTLVertexFormatFloat;
case 2: return MTLVertexFormatFloat2;
case 3: return MTLVertexFormatFloat3;
case 4: return MTLVertexFormatFloat4;
default: return MTLVertexFormatInvalid;
}
}
}
// clang-format on
}
static void SetAttribute(MTLVertexDescriptor* desc, ShaderAttrib attribute,
const AttributeFormat& format)
{
if (!format.enable)
return;
MTLVertexAttributeDescriptor* attr_desc =
[[desc attributes] objectAtIndexedSubscript:(u32)attribute];
[attr_desc setFormat:ConvertFormat(format.type, format.components, format.integer)];
[attr_desc setOffset:format.offset];
[attr_desc setBufferIndex:0];
}
template <size_t N>
static void SetAttributes(MTLVertexDescriptor* desc, ShaderAttrib attribute,
const std::array<AttributeFormat, N>& format)
{
for (size_t i = 0; i < N; ++i)
SetAttribute(desc, attribute + i, format[i]);
}
Metal::VertexFormat::VertexFormat(const PortableVertexDeclaration& vtx_decl)
: NativeVertexFormat(vtx_decl), m_desc(MRCTransfer([MTLVertexDescriptor new]))
{
[[[m_desc layouts] objectAtIndexedSubscript:0] setStride:vtx_decl.stride];
SetAttribute(m_desc, ShaderAttrib::Position, vtx_decl.position);
SetAttributes(m_desc, ShaderAttrib::Normal, vtx_decl.normals);
SetAttributes(m_desc, ShaderAttrib::Color0, vtx_decl.colors);
SetAttributes(m_desc, ShaderAttrib::TexCoord0, vtx_decl.texcoords);
SetAttribute(m_desc, ShaderAttrib::PositionMatrix, vtx_decl.posmtx);
}