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
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
|
#ifndef VERTEX_DATA_H_
#define VERTEX_DATA_H_
#include "Runtime/Utilities/StrideIterator.h"
#include "Runtime/GfxDevice/GfxDeviceTypes.h"
#include "Runtime/BaseClasses/ObjectDefines.h"
#include "Runtime/Serialize/SerializeUtility.h"
#include "Runtime/Serialize/TransferFunctionFwd.h"
class VertexData;
void swap (VertexData& a, VertexData& b);
typedef struct StreamInfo
{
enum { kDividerOpDivide=0, kDividerOpModulo };
UInt32 channelMask;
UInt32 offset;
UInt16 frequency;
UInt8 stride;
UInt8 dividerOp;
// We use default constructors instead of memset()
StreamInfo() : channelMask(0), offset(0), frequency(0), stride(0), dividerOp(kDividerOpDivide) {}
void Reset() { *this = StreamInfo(); }
bool operator == (const StreamInfo& rhs) const { return (channelMask == rhs.channelMask) && (offset == rhs.offset) && (frequency == rhs.frequency) && (stride == rhs.stride) && (dividerOp == rhs.dividerOp); }
bool operator != (const StreamInfo& rhs) const { return !(*this == rhs); }
DECLARE_SERIALIZE_NO_PPTR (StreamInfo);
#if SUPPORT_SERIALIZED_TYPETREES
template<class TransferFunction>
void TransferWorkaround35SerializationFuckup (TransferFunction& transfer);
#endif
} StreamInfoArray [kMaxVertexStreams];
struct VertexStreamsLayout
{
UInt32 channelMasks[kMaxVertexStreams];
};
typedef struct ALIGN_TYPE(4) ChannelInfo
{
UInt8 stream;
UInt8 offset;
UInt8 format;
UInt8 dimension;
enum { kInvalidDimension = 0 };
// We use default constructors instead of memset()
ChannelInfo() : stream(0), offset(0), format(0), dimension(kInvalidDimension) {}
UInt32 CalcOffset(const StreamInfoArray streams) const { return streams[stream].offset + offset; }
UInt32 CalcStride(const StreamInfoArray streams) const { return streams[stream].stride; }
bool IsValid() const { return (kInvalidDimension != dimension); }
void Reset() { *this = ChannelInfo(); }
bool operator == (const ChannelInfo& rhs) const { return (stream == rhs.stream) && (offset == rhs.offset) && (format == rhs.format) && (dimension == rhs.dimension); }
bool operator != (const ChannelInfo& rhs) const { return !(*this == rhs); }
DECLARE_SERIALIZE_NO_PPTR (ChannelInfo);
} ChannelInfoArray [kShaderChannelCount];
struct VertexChannelsLayout
{
struct Channel
{
Channel(UInt8 fmt, UInt8 dim) : format(fmt), dimension(dim) {}
Channel() : format(0), dimension(0) {}
UInt8 format;
UInt8 dimension;
};
Channel channels[kShaderChannelCount];
};
template<class TransferFunc>
void StreamInfo::Transfer (TransferFunc& transfer)
{
#if SUPPORT_SERIALIZED_TYPETREES
if (transfer.GetFlags() & kWorkaround35MeshSerializationFuckup)
{
TransferWorkaround35SerializationFuckup (transfer);
return;
}
#endif
transfer.Transfer (channelMask, "channelMask", kHideInEditorMask);
transfer.Transfer (offset, "offset", kHideInEditorMask);
transfer.Transfer (stride, "stride", kHideInEditorMask);
transfer.Transfer (dividerOp, "dividerOp", kHideInEditorMask);
transfer.Transfer (frequency, "frequency", kHideInEditorMask);
}
#if SUPPORT_SERIALIZED_TYPETREES
template<class TransferFunc>
void StreamInfo::TransferWorkaround35SerializationFuckup (TransferFunc& transfer)
{
transfer.Transfer (channelMask, "channelMask", kHideInEditorMask);
transfer.Transfer (offset, "offset", kHideInEditorMask);
UInt32 align;
UInt32 stride32bit;
transfer.Transfer (stride32bit, "stride", kHideInEditorMask);
transfer.Transfer (align, "align", kHideInEditorMask);
stride = (UInt8) stride32bit;
}
#endif
template<class TransferFunc>
void ChannelInfo::Transfer (TransferFunc& transfer)
{
transfer.Transfer (stream, "stream", kHideInEditorMask);
transfer.Transfer (offset, "offset", kHideInEditorMask);
transfer.Transfer (format, "format", kHideInEditorMask);
transfer.Transfer (dimension, "dimension", kHideInEditorMask);
}
// Information about all vertex data, but does not own the memory
class VertexDataInfo
{
public:
enum
{
kVertexDataAlign = 32,
kVertexStreamAlign = 16,
kVertexDataPadding = 16
};
static VertexStreamsLayout kVertexStreamsDefault;
static VertexStreamsLayout kVertexStreamsSkinnedHotColdSplit;
static VertexChannelsLayout kVertexChannelsDefault;
static VertexChannelsLayout kVertexChannelsCompressed;
static VertexChannelsLayout kVertexChannelsCompressedAggressive;
#if UNITY_EDITOR
static VertexStreamsLayout kVertexStreamsSkinnedHotColdSplitPS3;
#endif
static size_t AlignStreamSize (size_t size) { return (size + (kVertexStreamAlign-1)) & ~(kVertexStreamAlign-1); }
friend void ::swap (VertexData& a, VertexData& b);
VertexDataInfo ();
bool HasChannel (ShaderChannel shaderChannelIndex) const
{
Assert ((m_Channels[shaderChannelIndex].dimension != 0) == (((m_CurrentChannels & (1 << shaderChannelIndex)) != 0)));
return m_Channels[shaderChannelIndex].dimension != 0;
}
void UpdateStreams(unsigned newChannelMask, size_t newVertexCount, const VertexStreamsLayout& streams = kVertexStreamsDefault, const VertexChannelsLayout& channels = kVertexChannelsDefault);
size_t GetActiveStreamCount() const ;
size_t GetStreamIndex(ShaderChannel channel) const ;
const StreamInfo* GetStreams() const { return m_Streams; }
const StreamInfo& GetStream(int index) const { return m_Streams[index]; }
const ChannelInfo* GetChannels() const { return m_Channels; }
const ChannelInfo& GetChannel(int index) const { return m_Channels[index]; }
VertexStreamsLayout GetStreamsLayout() const;
VertexChannelsLayout GetChannelsLayout() const;
bool ConformsToStreamsLayout(const VertexStreamsLayout& streams) const;
bool ConformsToChannelsLayout(const VertexChannelsLayout& channels) const;
unsigned GetChannelMask () const { return m_CurrentChannels; }
size_t GetDataSize () const { return m_DataSize; }
size_t GetVertexSize () const { return m_VertexSize; }
size_t GetVertexCount () const { return m_VertexCount; }
size_t GetChannelOffset (unsigned channel) const { return m_Channels[channel].CalcOffset(m_Streams); }
size_t GetChannelStride (unsigned channel) const { return m_Channels[channel].CalcStride(m_Streams); }
UInt8* GetDataPtr () const { return m_Data; }
template<class T>
StrideIterator<T> MakeStrideIterator (ShaderChannel shaderChannelIndex) const
{
Assert (shaderChannelIndex < kShaderChannelCount);
void* p = m_Data + GetChannelOffset(shaderChannelIndex);
return HasChannel (shaderChannelIndex) ? StrideIterator<T> (p, GetChannelStride (shaderChannelIndex)) : StrideIterator<T> (NULL, GetChannelStride (shaderChannelIndex));
}
template<class T>
StrideIterator<T> MakeEndIterator (ShaderChannel shaderChannelIndex) const
{
T* end = GetEndPointer<T> (shaderChannelIndex);
return StrideIterator<T> (end, GetChannelStride (shaderChannelIndex));
}
template<class T>
T* GetEndPointer (ShaderChannel shaderChannelIndex) const
{
Assert (shaderChannelIndex < kShaderChannelCount);
void* p = HasChannel (shaderChannelIndex) ? (m_Data + GetChannelOffset(shaderChannelIndex) + m_VertexCount * GetChannelStride (shaderChannelIndex)) : NULL;
return reinterpret_cast<T*> (p);
}
protected:
ChannelInfoArray m_Channels;
StreamInfoArray m_Streams;
size_t m_VertexSize; // must match m_CurrentChannels
UInt8* m_Data;
// The following are being serialized. Their size must match in both 32 and 64 bit platforms
UInt32 m_CurrentChannels; // kShaderChannel bitmask
UInt32 m_VertexCount;
unsigned m_DataSize;
};
// Owns the vertex memory
class VertexData : public VertexDataInfo
{
public:
DECLARE_SERIALIZE (VertexData)
VertexData () : VertexDataInfo() { }
VertexData (VertexData const& src, unsigned copyChannels, const VertexStreamsLayout& streams = kVertexStreamsDefault, const VertexChannelsLayout& channels = kVertexChannelsDefault);
~VertexData ();
static size_t GetAllocateDataSize (size_t accesibleBufferSize) { return accesibleBufferSize + kVertexDataPadding; }
void Deallocate ();
void Resize (size_t vertexCount, unsigned channelMask, const VertexStreamsLayout& streams = kVertexStreamsDefault, const VertexChannelsLayout& channels = kVertexChannelsDefault);
void SwapEndianess ();
private:
VertexData (const VertexData& o);
void operator= (const VertexData& o);
VertexData (const VertexDataInfo& o);
void operator= (const VertexDataInfo& o);
#if SUPPORT_SERIALIZED_TYPETREES
template<class TransferFunction>
void TransferWorkaround35SerializationFuckup (TransferFunction& transfer);
#endif
};
void CopyVertexDataChannels (size_t vertexCount, unsigned copyChannels, const VertexData& srcData, VertexData& dstData);
size_t GetChannelFormatSize(UInt8 format);
#endif
|