mirror of
https://github.com/GayPizzaSpecifications/padlab.git
synced 2025-08-03 21:21:33 +00:00
metal: Simplify buffer management & sync before present
This commit is contained in:
@ -15,17 +15,14 @@
|
|||||||
- (id) init:(SDL_Window*)window;
|
- (id) init:(SDL_Window*)window;
|
||||||
- (void) dealloc;
|
- (void) dealloc;
|
||||||
|
|
||||||
- (unsigned) resizeBuffer:(void**)buf itemSize:(unsigned)nsz reserveLen:(unsigned)reserve requiredNum:(unsigned)count;
|
- (unsigned) resizeBuffer:(id <MTLBuffer>*)buf itemSize:(unsigned)nsz requiredNum:(unsigned)count;
|
||||||
- (void) resizeMtlBuffer:(id <MTLBuffer>*)buf length:(unsigned)length;
|
|
||||||
|
|
||||||
- (size) getDrawSize;
|
- (size) getDrawSize;
|
||||||
- (void) setClear:(uint32_t)colour;
|
|
||||||
- (void) setView:(size)viewportSize;
|
- (void) setView:(size)viewportSize;
|
||||||
- (void) clearVerticesAndIndices;
|
- (void) clear;
|
||||||
- (void) reserveVertices:(unsigned)count;
|
- (void) reserveVertices:(unsigned)count;
|
||||||
- (void) reserveIndices:(unsigned)count;
|
- (void) reserveIndices:(unsigned)count;
|
||||||
- (uint16_t) queueVertex:(int)x :(int)y;
|
- (uint16_t) queueVertex:(float)x :(float)y;
|
||||||
- (uint16_t) queueVertexF:(float)x :(float)y;
|
|
||||||
- (uint16_t) queueIndex:(uint16_t)idx;
|
- (uint16_t) queueIndex:(uint16_t)idx;
|
||||||
- (void) queueIndices:(uint16_t*)idcs count:(unsigned)count;
|
- (void) queueIndices:(uint16_t*)idcs count:(unsigned)count;
|
||||||
- (void) present;
|
- (void) present;
|
||||||
@ -47,8 +44,6 @@
|
|||||||
MTLViewport _viewport;
|
MTLViewport _viewport;
|
||||||
vector_float4 _drawColourF;
|
vector_float4 _drawColourF;
|
||||||
|
|
||||||
ShaderVertex* _vtxList;
|
|
||||||
uint16_t* _idxList;
|
|
||||||
unsigned _vtxListCount, _vtxListReserve, _idxListCount, _idxListReserve;
|
unsigned _vtxListCount, _vtxListReserve, _idxListCount, _idxListReserve;
|
||||||
id<MTLBuffer> _vtxMtlBuffer, _idxMtlBuffer;
|
id<MTLBuffer> _vtxMtlBuffer, _idxMtlBuffer;
|
||||||
}
|
}
|
||||||
@ -59,10 +54,6 @@
|
|||||||
return nil;
|
return nil;
|
||||||
|
|
||||||
self.drawColour = BLACK;
|
self.drawColour = BLACK;
|
||||||
_vtxList = NULL;
|
|
||||||
_idxList = NULL;
|
|
||||||
_vtxListCount = 0;
|
|
||||||
_idxListCount = 0;
|
|
||||||
_vtxListReserve = 0;
|
_vtxListReserve = 0;
|
||||||
_idxListReserve = 0;
|
_idxListReserve = 0;
|
||||||
_vtxMtlBuffer = nil;
|
_vtxMtlBuffer = nil;
|
||||||
@ -98,7 +89,7 @@
|
|||||||
_passDesc = [MTLRenderPassDescriptor new];
|
_passDesc = [MTLRenderPassDescriptor new];
|
||||||
_passDesc.colorAttachments[0].loadAction = MTLLoadActionClear;
|
_passDesc.colorAttachments[0].loadAction = MTLLoadActionClear;
|
||||||
_passDesc.colorAttachments[0].storeAction = MTLStoreActionStore;
|
_passDesc.colorAttachments[0].storeAction = MTLStoreActionStore;
|
||||||
[self setClear:self.drawColour]; // passDesc.colorAttachments[0].clearColor = curColour
|
[self clear]; // passDesc.colorAttachments[0].clearColor = curColour
|
||||||
|
|
||||||
// Compile shaders
|
// Compile shaders
|
||||||
__autoreleasing NSError* err = nil;
|
__autoreleasing NSError* err = nil;
|
||||||
@ -138,10 +129,12 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
- (unsigned) resizeBuffer:(void**)buf itemSize:(unsigned)nsz reserveLen:(unsigned)reserve requiredNum:(unsigned)count
|
- (unsigned) resizeBuffer:(id <MTLBuffer>*)buf itemSize:(unsigned)nsz requiredNum:(unsigned)count
|
||||||
{
|
{
|
||||||
if (*buf && count * nsz <= reserve)
|
unsigned reserve;
|
||||||
return reserve;
|
if (*buf)
|
||||||
|
if (count * nsz <= (reserve = [*buf length]))
|
||||||
|
return reserve;
|
||||||
|
|
||||||
// Calculate new capacity
|
// Calculate new capacity
|
||||||
unsigned newCapacity = (count + DRAWLIST_CHUNK_SIZE - 1) / DRAWLIST_CHUNK_SIZE * DRAWLIST_CHUNK_SIZE;
|
unsigned newCapacity = (count + DRAWLIST_CHUNK_SIZE - 1) / DRAWLIST_CHUNK_SIZE * DRAWLIST_CHUNK_SIZE;
|
||||||
@ -150,22 +143,15 @@
|
|||||||
|
|
||||||
// (Re)allocate and return new reserve size
|
// (Re)allocate and return new reserve size
|
||||||
unsigned newReserve = newCapacity * nsz;
|
unsigned newReserve = newCapacity * nsz;
|
||||||
*buf = realloc(*buf, newReserve);
|
id<MTLBuffer> new = [_dev newBufferWithLength:newReserve options:MTLResourceStorageModeManaged];
|
||||||
return newReserve;
|
|
||||||
}
|
|
||||||
|
|
||||||
- (void) resizeMtlBuffer:(id <MTLBuffer>*)buf length:(unsigned)length
|
|
||||||
{
|
|
||||||
if (*buf && length <= [*buf length])
|
|
||||||
return;
|
|
||||||
|
|
||||||
id<MTLBuffer> new = [_dev newBufferWithLength:length options:MTLResourceStorageModeManaged];
|
|
||||||
if (*buf)
|
if (*buf)
|
||||||
{
|
{
|
||||||
|
memcpy(new.contents, (*buf).contents, reserve);
|
||||||
[*buf setPurgeableState:MTLPurgeableStateEmpty];
|
[*buf setPurgeableState:MTLPurgeableStateEmpty];
|
||||||
[*buf release];
|
[*buf release];
|
||||||
}
|
}
|
||||||
*buf = new;
|
*buf = new;
|
||||||
|
return newReserve;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -176,7 +162,7 @@
|
|||||||
return out;
|
return out;
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)setDrawColour:(uint32_t)colour
|
- (void) setDrawColour:(uint32_t)colour
|
||||||
{
|
{
|
||||||
_drawColour = colour;
|
_drawColour = colour;
|
||||||
const float mul = 1.0f / 255.0f;
|
const float mul = 1.0f / 255.0f;
|
||||||
@ -187,16 +173,6 @@
|
|||||||
(float)((colour & 0x000000FF)) * mul };
|
(float)((colour & 0x000000FF)) * mul };
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void) setClear:(uint32_t)colour
|
|
||||||
{
|
|
||||||
const double mul = 1.0 / 255.0;
|
|
||||||
_passDesc.colorAttachments[0].clearColor = MTLClearColorMake(
|
|
||||||
(double)((colour & 0xFF000000) >> 24) * mul,
|
|
||||||
(double)((colour & 0x00FF0000) >> 16) * mul,
|
|
||||||
(double)((colour & 0x0000FF00) >> 8) * mul,
|
|
||||||
(double)((colour & 0x000000FF)) * mul);
|
|
||||||
}
|
|
||||||
|
|
||||||
- (void) setView:(size)viewportSize
|
- (void) setView:(size)viewportSize
|
||||||
{
|
{
|
||||||
_viewport = (MTLViewport){
|
_viewport = (MTLViewport){
|
||||||
@ -205,8 +181,10 @@
|
|||||||
.znear = 1.0, .zfar = -1.0 };
|
.znear = 1.0, .zfar = -1.0 };
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void) clearVerticesAndIndices
|
- (void) clear
|
||||||
{
|
{
|
||||||
|
_passDesc.colorAttachments[0].clearColor = MTLClearColorMake(
|
||||||
|
_drawColourF[0], _drawColourF[1], _drawColourF[2], _drawColourF[3]);
|
||||||
_vtxListCount = 0;
|
_vtxListCount = 0;
|
||||||
_idxListCount = 0;
|
_idxListCount = 0;
|
||||||
}
|
}
|
||||||
@ -215,33 +193,21 @@
|
|||||||
{
|
{
|
||||||
count += _vtxListCount;
|
count += _vtxListCount;
|
||||||
if (count * sizeof(ShaderVertex) > _vtxListReserve)
|
if (count * sizeof(ShaderVertex) > _vtxListReserve)
|
||||||
_vtxListReserve = [self resizeBuffer:(void**)&_vtxList
|
_vtxListReserve = [self resizeBuffer:&_vtxMtlBuffer itemSize:sizeof(ShaderVertex) requiredNum:count];
|
||||||
itemSize:sizeof(ShaderVertex) reserveLen:_vtxListReserve requiredNum:count];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void) reserveIndices:(unsigned)count
|
- (void) reserveIndices:(unsigned)count
|
||||||
{
|
{
|
||||||
count += _idxListCount;
|
count += _idxListCount;
|
||||||
if (count * sizeof(uint16_t) > _idxListReserve)
|
if (count * sizeof(uint16_t) > _idxListReserve)
|
||||||
_idxListReserve = [self resizeBuffer:(void**)&_idxList
|
_idxListReserve = [self resizeBuffer:&_idxMtlBuffer itemSize:sizeof(uint16_t) requiredNum:count];
|
||||||
itemSize:sizeof(uint16_t) reserveLen:_idxListReserve requiredNum:count];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
- (uint16_t) queueVertex:(int)x :(int)y
|
- (uint16_t) queueVertex:(float)x :(float)y
|
||||||
{
|
{
|
||||||
if (_vtxListCount * sizeof(ShaderVertex) >= _vtxListReserve)
|
if (_vtxListCount * sizeof(ShaderVertex) >= _vtxListReserve)
|
||||||
[self reserveVertices:1];
|
[self reserveVertices:1];
|
||||||
_vtxList[_vtxListCount] = (ShaderVertex){
|
((ShaderVertex*)_vtxMtlBuffer.contents)[_vtxListCount] = (ShaderVertex){
|
||||||
.position = { (float)x, (float)y },
|
|
||||||
.colour = _drawColourF };
|
|
||||||
return _vtxListCount++;
|
|
||||||
}
|
|
||||||
|
|
||||||
- (uint16_t) queueVertexF:(float)x :(float)y
|
|
||||||
{
|
|
||||||
if (_vtxListCount * sizeof(ShaderVertex) >= _vtxListReserve)
|
|
||||||
[self reserveVertices:1];
|
|
||||||
_vtxList[_vtxListCount] = (ShaderVertex){
|
|
||||||
.position = { x, y },
|
.position = { x, y },
|
||||||
.colour = _drawColourF };
|
.colour = _drawColourF };
|
||||||
return _vtxListCount++;
|
return _vtxListCount++;
|
||||||
@ -251,7 +217,7 @@
|
|||||||
{
|
{
|
||||||
if (_idxListCount * sizeof(uint16_t) >= _idxListReserve)
|
if (_idxListCount * sizeof(uint16_t) >= _idxListReserve)
|
||||||
[self reserveIndices:1];
|
[self reserveIndices:1];
|
||||||
_idxList[_idxListCount++] = idx;
|
((uint16_t*)_idxMtlBuffer.contents)[_idxListCount++] = idx;
|
||||||
return idx;
|
return idx;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -259,27 +225,15 @@
|
|||||||
{
|
{
|
||||||
if ((_idxListCount + count) * sizeof(uint16_t) >= _idxListReserve)
|
if ((_idxListCount + count) * sizeof(uint16_t) >= _idxListReserve)
|
||||||
[self reserveIndices:count];
|
[self reserveIndices:count];
|
||||||
memcpy(&_idxList[_idxListCount], idcs, count * sizeof(uint16_t));
|
memcpy(&((uint16_t*)_idxMtlBuffer.contents)[_idxListCount], idcs, count * sizeof(uint16_t));
|
||||||
_idxListCount += count;
|
_idxListCount += count;
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void) present
|
- (void) present
|
||||||
{
|
{
|
||||||
// Create or recreate buffers if needed & fill with data
|
// Synchronise buffers
|
||||||
if (_vtxListCount)
|
[_vtxMtlBuffer didModifyRange:(NSRange){ .location = 0, .length = _vtxListCount * sizeof(ShaderVertex) }];
|
||||||
{
|
[_idxMtlBuffer didModifyRange:(NSRange){ .location = 0, .length = _idxListCount * sizeof(uint16_t) }];
|
||||||
unsigned copyLen = _vtxListCount * sizeof(ShaderVertex);
|
|
||||||
if (_vtxMtlBuffer == nil || [_vtxMtlBuffer length] < copyLen)
|
|
||||||
[self resizeMtlBuffer:&_vtxMtlBuffer length:_vtxListReserve];
|
|
||||||
memcpy(_vtxMtlBuffer.contents, _vtxList, copyLen);
|
|
||||||
}
|
|
||||||
if (_idxListCount)
|
|
||||||
{
|
|
||||||
unsigned copyLen = _idxListCount * sizeof(uint16_t);
|
|
||||||
if (_idxMtlBuffer == nil || [_idxMtlBuffer length] < copyLen)
|
|
||||||
[self resizeMtlBuffer:&_idxMtlBuffer length:_idxListReserve];
|
|
||||||
memcpy(_idxMtlBuffer.contents, _idxList, copyLen);
|
|
||||||
}
|
|
||||||
|
|
||||||
@autoreleasepool
|
@autoreleasepool
|
||||||
{
|
{
|
||||||
@ -293,7 +247,7 @@
|
|||||||
[enc setCullMode:MTLCullModeNone];
|
[enc setCullMode:MTLCullModeNone];
|
||||||
[enc setRenderPipelineState:_pso];
|
[enc setRenderPipelineState:_pso];
|
||||||
|
|
||||||
if (_vtxMtlBuffer != nil && _idxMtlBuffer != nil)
|
if (_vtxMtlBuffer && _idxMtlBuffer)
|
||||||
{
|
{
|
||||||
[enc setVertexBuffer:_vtxMtlBuffer offset:0 atIndex:ShaderInputIdxVerticies];
|
[enc setVertexBuffer:_vtxMtlBuffer offset:0 atIndex:ShaderInputIdxVerticies];
|
||||||
const vector_float2 viewportScale = { (float)(1.0 / _viewport.width), (float)(1.0 / _viewport.height) };
|
const vector_float2 viewportScale = { (float)(1.0 / _viewport.width), (float)(1.0 / _viewport.height) };
|
||||||
@ -301,13 +255,14 @@
|
|||||||
[enc drawIndexedPrimitives:MTLPrimitiveTypeLine
|
[enc drawIndexedPrimitives:MTLPrimitiveTypeLine
|
||||||
indexCount:_idxListCount indexType:MTLIndexTypeUInt16
|
indexCount:_idxListCount indexType:MTLIndexTypeUInt16
|
||||||
indexBuffer:_idxMtlBuffer indexBufferOffset:0];
|
indexBuffer:_idxMtlBuffer indexBufferOffset:0];
|
||||||
|
|
||||||
|
_vtxListCount = 0;
|
||||||
|
_idxListCount = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
[enc endEncoding];
|
[enc endEncoding];
|
||||||
[cmdBuf presentDrawable:rt];
|
[cmdBuf presentDrawable:rt];
|
||||||
[cmdBuf commit];
|
[cmdBuf commit];
|
||||||
|
|
||||||
[self clearVerticesAndIndices];
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -354,8 +309,7 @@ void SetDrawColour(uint32_t c)
|
|||||||
|
|
||||||
void DrawClear(void)
|
void DrawClear(void)
|
||||||
{
|
{
|
||||||
[renderer setClear:renderer.drawColour];
|
[renderer clear];
|
||||||
[renderer clearVerticesAndIndices];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -368,10 +322,13 @@ void DrawPoint(int x, int y)
|
|||||||
void DrawRect(int x, int y, int w, int h)
|
void DrawRect(int x, int y, int w, int h)
|
||||||
{
|
{
|
||||||
[renderer reserveVertices:4];
|
[renderer reserveVertices:4];
|
||||||
uint16_t i00 = [renderer queueVertex:x :y];
|
vector_float2
|
||||||
uint16_t i10 = [renderer queueVertex:x + w :y];
|
f00 = { x, y }, f10 = { x + w, y },
|
||||||
uint16_t i11 = [renderer queueVertex:x + w :y + h];
|
f01 = { x, y + h}, f11 = { x + w, y + h };
|
||||||
uint16_t i01 = [renderer queueVertex:x :y + h];
|
uint16_t i00 = [renderer queueVertex:f00[0] :f00[1]];
|
||||||
|
uint16_t i10 = [renderer queueVertex:f10[0] :f10[1]];
|
||||||
|
uint16_t i11 = [renderer queueVertex:f11[0] :f11[1]];
|
||||||
|
uint16_t i01 = [renderer queueVertex:f01[0] :f01[1]];
|
||||||
uint16_t indices[] = { i00, i10, i10, i11, i11, i01, i01, i00 };
|
uint16_t indices[] = { i00, i10, i10, i11, i11, i01, i01, i00 };
|
||||||
[renderer queueIndices:indices count:sizeof(indices) / sizeof(uint16_t)];
|
[renderer queueIndices:indices count:sizeof(indices) / sizeof(uint16_t)];
|
||||||
}
|
}
|
||||||
@ -393,11 +350,11 @@ void DrawCircleSteps(int x, int y, int r, int steps)
|
|||||||
// Draw whole circle in a single loop
|
// Draw whole circle in a single loop
|
||||||
[renderer reserveVertices:steps];
|
[renderer reserveVertices:steps];
|
||||||
[renderer reserveIndices:steps * 2];
|
[renderer reserveIndices:steps * 2];
|
||||||
uint16_t base = [renderer queueIndex:[renderer queueVertex:x + r :y]];
|
uint16_t base = [renderer queueIndex:[renderer queueVertex:fx + mag :fy]];
|
||||||
for (int i = 1; i < steps; ++i)
|
for (int i = 1; i < steps; ++i)
|
||||||
{
|
{
|
||||||
const float theta = stepSz * (float)i;
|
const float theta = stepSz * (float)i;
|
||||||
uint16_t ii = [renderer queueVertexF:fx + cosf(theta) * mag :fy + sinf(theta) * mag];
|
uint16_t ii = [renderer queueVertex:fx + cosf(theta) * mag :fy + sinf(theta) * mag];
|
||||||
[renderer queueIndices:(uint16_t[]){ ii, ii } count:2];
|
[renderer queueIndices:(uint16_t[]){ ii, ii } count:2];
|
||||||
}
|
}
|
||||||
[renderer queueIndex:base];
|
[renderer queueIndex:base];
|
||||||
@ -413,11 +370,11 @@ void DrawArcSteps(int x, int y, int r, int startAng, int endAng, int steps)
|
|||||||
const float stepSz = (float)(endAng - startAng) / (float)abs(steps) * (float)DEG2RAD;
|
const float stepSz = (float)(endAng - startAng) / (float)abs(steps) * (float)DEG2RAD;
|
||||||
[renderer reserveVertices:steps];
|
[renderer reserveVertices:steps];
|
||||||
[renderer reserveIndices:steps * 2];
|
[renderer reserveIndices:steps * 2];
|
||||||
uint16_t ii = [renderer queueVertexF:fx + cosf(start) * magw :fy - sinf(start) * magh];
|
uint16_t ii = [renderer queueVertex:fx + cosf(start) * magw :fy - sinf(start) * magh];
|
||||||
for (int i = 1; i <= steps; ++i)
|
for (int i = 1; i <= steps; ++i)
|
||||||
{
|
{
|
||||||
const float theta = start + stepSz * (float)i;
|
const float theta = start + stepSz * (float)i;
|
||||||
uint16_t iii = [renderer queueVertexF:fx + cosf(theta) * magw :fy - sinf(theta) * magh];
|
uint16_t iii = [renderer queueVertex:fx + cosf(theta) * magw :fy - sinf(theta) * magh];
|
||||||
[renderer queueIndices:(uint16_t[]){ ii, iii } count:2];
|
[renderer queueIndices:(uint16_t[]){ ii, iii } count:2];
|
||||||
ii = iii;
|
ii = iii;
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user