#include #include #import id getMetalDevice(void); void kinc_g5_index_buffer_init(kinc_g5_index_buffer_t *buffer, int indexCount, kinc_g5_index_buffer_format_t format, bool gpuMemory) { buffer->impl.count = indexCount; buffer->impl.gpu_memory = gpuMemory; buffer->impl.format = format; buffer->impl.last_start = 0; buffer->impl.last_count = indexCount; id device = getMetalDevice(); MTLResourceOptions options = MTLResourceCPUCacheModeWriteCombined; #ifdef KINC_APPLE_SOC options |= MTLResourceStorageModeShared; #else if (gpuMemory) { options |= MTLResourceStorageModeManaged; } else { options |= MTLResourceStorageModeShared; } #endif buffer->impl.metal_buffer = (__bridge_retained void *)[device newBufferWithLength:(format == KINC_G5_INDEX_BUFFER_FORMAT_16BIT ? sizeof(uint16_t) * indexCount : sizeof(uint32_t) * indexCount) options:options]; } void kinc_g5_index_buffer_destroy(kinc_g5_index_buffer_t *buffer) { id buf = (__bridge_transfer id)buffer->impl.metal_buffer; buf = nil; buffer->impl.metal_buffer = NULL; } static int kinc_g5_internal_index_buffer_stride(kinc_g5_index_buffer_t *buffer) { return buffer->impl.format == KINC_G5_INDEX_BUFFER_FORMAT_16BIT ? 2 : 4; } void *kinc_g5_index_buffer_lock_all(kinc_g5_index_buffer_t *buffer) { return kinc_g5_index_buffer_lock(buffer, 0, kinc_g5_index_buffer_count(buffer)); } void *kinc_g5_index_buffer_lock(kinc_g5_index_buffer_t *buffer, int start, int count) { buffer->impl.last_start = start; buffer->impl.last_count = count; id metal_buffer = (__bridge id)buffer->impl.metal_buffer; uint8_t *data = (uint8_t *)[metal_buffer contents]; return &data[start * kinc_g5_internal_index_buffer_stride(buffer)]; } void kinc_g5_index_buffer_unlock_all(kinc_g5_index_buffer_t *buffer) { kinc_g5_index_buffer_unlock(buffer, buffer->impl.last_count); } void kinc_g5_index_buffer_unlock(kinc_g5_index_buffer_t *buffer, int count) { #ifndef KINC_APPLE_SOC if (buffer->impl.gpu_memory) { id metal_buffer = (__bridge id)buffer->impl.metal_buffer; NSRange range; range.location = buffer->impl.last_start * kinc_g5_internal_index_buffer_stride(buffer); range.length = count * kinc_g5_internal_index_buffer_stride(buffer); [metal_buffer didModifyRange:range]; } #endif } int kinc_g5_index_buffer_count(kinc_g5_index_buffer_t *buffer) { return buffer->impl.count; }