@@ -158,22 +158,21 @@ namespace SR_UTILS_NS {
158158 }
159159
160160 uint8_t VertexAttributeDescription::GetAttributeSizeInBytes () const {
161+ return GetAttributeSizeInBytes (format, count);
162+ }
163+
164+ uint8_t VertexAttributeDescription::GetAttributeSizeInBytes (VertexAttributeFormat format, uint8_t count) {
161165 // Для packed форматов count игнорируем, так как они уже 32-битные
162166 if (format == VertexAttributeFormat::R10G10B10A2_UNorm || format == VertexAttributeFormat::R11G11B10_Float) {
163167 return 4 ;
164168 }
165169
166- return GetVertexAttributeFormatSize (format) * count;
170+ const uint8_t size = GetVertexAttributeFormatSize (format) * count;
171+ return size == 12 ? 16 : size; // GPU slot rule
167172 }
168173
169174 uint64_t VertexLayoutDescription::GetStride () const {
170- if (strideCache != 0 ) {
171- return strideCache;
172- }
173- for (uint8_t i = 0 ; i < attributesCount; ++i) {
174- strideCache += attributes[i].GetAttributeSizeInBytes () * attributes[i].count ;
175- }
176- return strideCache;
175+ return stride;
177176 }
178177
179178 const VertexAttributeDescription* VertexLayoutDescription::Find (VertexAttribute attribute) const {
@@ -185,15 +184,26 @@ namespace SR_UTILS_NS {
185184 return nullptr ;
186185 }
187186
187+ uint32_t VertexLayoutDescription::Align (uint32_t v, uint32_t a) {
188+ return (v + a - 1 ) & ~(a - 1 );
189+ }
190+
188191 VertexLayoutDescription& VertexLayoutDescription::AddAttribute (VertexAttribute attribute, VertexAttributeFormat format, uint8_t count) {
189192 if (attributesCount >= SR_MAX_VERTEX_ATTRIBUTES) {
190193 SRHalt (" VertexLayoutDescription::AddAttribute() : maximum vertex attributes count exceeded! Max count: {}" , SR_MAX_VERTEX_ATTRIBUTES);
191194 return *this ;
192195 }
193- const uint64_t offset = GetStride ();
196+
197+ uint32_t offset = stride;
198+
199+ // GPU-safe alignment
200+ offset = Align (offset, 16 );
194201 SRAssert (offset < std::numeric_limits<uint16_t >::max ());
195- attributes[attributesCount++] = VertexAttributeDescription{ attribute, format, count, static_cast <uint16_t >(offset) };
196- strideCache = 0 ;
202+
203+ uint32_t size = VertexAttributeDescription::GetAttributeSizeInBytes (format, count);
204+ attributes[attributesCount++] = VertexAttributeDescription{ attribute, format, count, (uint16_t )offset };
205+
206+ stride = offset + size;
197207 return *this ;
198208 }
199209
0 commit comments