74 lines
		
	
	
		
			1.5 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
		
		
			
		
	
	
			74 lines
		
	
	
		
			1.5 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
| 
								 | 
							
								package buffer
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								import (
							 | 
						||
| 
								 | 
							
									"fmt"
							 | 
						||
| 
								 | 
							
									"reflect"
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									"zworld/engine/renderapi/device"
							 | 
						||
| 
								 | 
							
									"zworld/engine/util"
							 | 
						||
| 
								 | 
							
								)
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								// Strongly typed array buffer
							 | 
						||
| 
								 | 
							
								type Array[K any] interface {
							 | 
						||
| 
								 | 
							
									T
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									// Set the value of element i and flushes the buffer.
							 | 
						||
| 
								 | 
							
									Set(index int, data K)
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									// Sets a range of elements, starting at i and flushes the buffer.
							 | 
						||
| 
								 | 
							
									SetRange(index int, data []K)
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									// Count returns the number of items in the array
							 | 
						||
| 
								 | 
							
									Count() int
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									// Element returns the aligned byte size of a single element
							 | 
						||
| 
								 | 
							
									Element() int
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								type array[K any] struct {
							 | 
						||
| 
								 | 
							
									T
							 | 
						||
| 
								 | 
							
									element int
							 | 
						||
| 
								 | 
							
									count   int
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								// NewArray creates a new typed array buffer.
							 | 
						||
| 
								 | 
							
								// When allocating arrays, the Size argument is the number of elements
							 | 
						||
| 
								 | 
							
								func NewArray[K any](device device.T, args Args) Array[K] {
							 | 
						||
| 
								 | 
							
									align, maxSize := GetBufferLimits(device, args.Usage)
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									var empty K
							 | 
						||
| 
								 | 
							
									kind := reflect.TypeOf(empty)
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									element := util.Align(int(kind.Size()), align)
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									count := args.Size
							 | 
						||
| 
								 | 
							
									size := count * element
							 | 
						||
| 
								 | 
							
									if size > maxSize {
							 | 
						||
| 
								 | 
							
										panic(fmt.Sprintf("buffer is too large for the specified usage. size: %d, max: %d", size, maxSize))
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									args.Size = size
							 | 
						||
| 
								 | 
							
									buffer := New(device, args)
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									return &array[K]{
							 | 
						||
| 
								 | 
							
										T:       buffer,
							 | 
						||
| 
								 | 
							
										element: element,
							 | 
						||
| 
								 | 
							
										count:   count,
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								func (a *array[K]) Set(index int, data K) {
							 | 
						||
| 
								 | 
							
									a.Write(index*a.element, &data)
							 | 
						||
| 
								 | 
							
									a.Flush()
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								func (a *array[K]) SetRange(offset int, data []K) {
							 | 
						||
| 
								 | 
							
									for i, el := range data {
							 | 
						||
| 
								 | 
							
										a.Write((i+offset)*a.element, &el)
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
									a.Flush()
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								func (a *array[K]) Count() int   { return a.count }
							 | 
						||
| 
								 | 
							
								func (a *array[K]) Element() int { return a.element }
							 |