| 293 | } |
| 294 | |
| 295 | Result Create(uint32_t count, const StreamDeclaration* streams_decl, uint8_t streams_decl_count, HBuffer* out_buffer) |
| 296 | { |
| 297 | BufferContext* ctx = g_BufferContext; |
| 298 | assert(ctx && "Buffer context not initialized"); |
| 299 | |
| 300 | if (!streams_decl || !out_buffer) { |
| 301 | return RESULT_ALLOCATION_ERROR; |
| 302 | } |
| 303 | |
| 304 | // Verify streams count |
| 305 | if (streams_decl_count == 0) { |
| 306 | return RESULT_STREAM_SIZE_ERROR; |
| 307 | } |
| 308 | |
| 309 | // Calculate total data allocation size needed |
| 310 | uint32_t header_size = sizeof(Buffer) + sizeof(Buffer::Stream)*streams_decl_count; |
| 311 | uint32_t buffer_size = header_size; |
| 312 | |
| 313 | // Interleaved streams |
| 314 | uint32_t struct_size = 0; |
| 315 | uint32_t* offsets = (uint32_t*)alloca(streams_decl_count * sizeof(uint32_t)); |
| 316 | dmBuffer::Result res = CalcStructSize(streams_decl_count, streams_decl, &struct_size, offsets); |
| 317 | if (res != RESULT_OK) { |
| 318 | return res; |
| 319 | } |
| 320 | |
| 321 | // Make sure the data is aligned at the start |
| 322 | buffer_size = DM_ALIGN(buffer_size, ADDR_ALIGNMENT); |
| 323 | assert(buffer_size % ADDR_ALIGNMENT == 0); |
| 324 | |
| 325 | buffer_size += struct_size * count; |
| 326 | |
| 327 | // Add some guard bytes at the end |
| 328 | buffer_size += GUARD_SIZE; |
| 329 | |
| 330 | if (buffer_size == header_size) { |
| 331 | return RESULT_BUFFER_SIZE_ERROR; |
| 332 | } |
| 333 | |
| 334 | // TODO: Perhaps implement as an index pool |
| 335 | if (ctx->Full()) |
| 336 | { |
| 337 | if (!ctx->Allocate(64)) |
| 338 | { |
| 339 | return RESULT_ALLOCATION_ERROR; |
| 340 | } |
| 341 | } |
| 342 | |
| 343 | // Allocate buffer to fit Buffer-struct, Stream-array and buffer data |
| 344 | void* data_block = 0x0; |
| 345 | dmMemory::Result r = dmMemory::AlignedMalloc((void**)&data_block, ADDR_ALIGNMENT, buffer_size); |
| 346 | if (r != dmMemory::RESULT_OK) { |
| 347 | return RESULT_ALLOCATION_ERROR; |
| 348 | } |
| 349 | |
| 350 | // Get buffer from data block start |
| 351 | Buffer* buffer = (Buffer*)data_block; |
| 352 | buffer->m_Count = count; |