Skip to content

Commit

Permalink
refac: graphics update bind group API
Browse files Browse the repository at this point in the history
  • Loading branch information
hoffstadt committed Apr 22, 2024
1 parent fddd392 commit 4580a82
Show file tree
Hide file tree
Showing 7 changed files with 332 additions and 192 deletions.
13 changes: 2 additions & 11 deletions extensions/pl_graphics_ext.c
Original file line number Diff line number Diff line change
Expand Up @@ -496,7 +496,6 @@ enum plDrawStreamBits
PL_DRAW_STREAM_BIT_DYNAMIC_BUFFER = 1 << 2,
PL_DRAW_STREAM_BIT_BINDGROUP_2 = 1 << 3,
PL_DRAW_STREAM_BIT_BINDGROUP_1 = 1 << 4,
PL_DRAW_STREAM_BIT_BINDGROUP_0 = 1 << 5,
PL_DRAW_STREAM_BIT_INDEX_OFFSET = 1 << 6,
PL_DRAW_STREAM_BIT_VERTEX_OFFSET = 1 << 7,
PL_DRAW_STREAM_BIT_INDEX_BUFFER = 1 << 8,
Expand Down Expand Up @@ -558,12 +557,6 @@ pl_drawstream_draw(plDrawStream* ptStream, plDraw tDraw)
uDirtyMask |= PL_DRAW_STREAM_BIT_BINDGROUP_1;
}

if(ptStream->tCurrentDraw.uBindGroup0 != tDraw.uBindGroup0)
{
ptStream->tCurrentDraw.uBindGroup0 = tDraw.uBindGroup0;
uDirtyMask |= PL_DRAW_STREAM_BIT_BINDGROUP_0;
}

if(ptStream->tCurrentDraw.uIndexOffset != tDraw.uIndexOffset)
{
ptStream->tCurrentDraw.uIndexOffset = tDraw.uIndexOffset;
Expand Down Expand Up @@ -607,8 +600,6 @@ pl_drawstream_draw(plDrawStream* ptStream, plDraw tDraw)
}

pl_sb_push(ptStream->sbtStream, uDirtyMask);
if(uDirtyMask & PL_DRAW_STREAM_BIT_SHADER)
pl_sb_push(ptStream->sbtStream, ptStream->tCurrentDraw.uShaderVariant);
if(uDirtyMask & PL_DRAW_STREAM_BIT_DYNAMIC_OFFSET)
pl_sb_push(ptStream->sbtStream, ptStream->tCurrentDraw.uDynamicBufferOffset);
if(uDirtyMask & PL_DRAW_STREAM_BIT_DYNAMIC_BUFFER)
Expand All @@ -617,8 +608,8 @@ pl_drawstream_draw(plDrawStream* ptStream, plDraw tDraw)
pl_sb_push(ptStream->sbtStream, ptStream->tCurrentDraw.uBindGroup2);
if(uDirtyMask & PL_DRAW_STREAM_BIT_BINDGROUP_1)
pl_sb_push(ptStream->sbtStream, ptStream->tCurrentDraw.uBindGroup1);
if(uDirtyMask & PL_DRAW_STREAM_BIT_BINDGROUP_0)
pl_sb_push(ptStream->sbtStream, ptStream->tCurrentDraw.uBindGroup0);
if(uDirtyMask & PL_DRAW_STREAM_BIT_SHADER)
pl_sb_push(ptStream->sbtStream, ptStream->tCurrentDraw.uShaderVariant);
if(uDirtyMask & PL_DRAW_STREAM_BIT_INDEX_OFFSET)
pl_sb_push(ptStream->sbtStream, ptStream->tCurrentDraw.uIndexOffset);
if(uDirtyMask & PL_DRAW_STREAM_BIT_VERTEX_OFFSET)
Expand Down
124 changes: 75 additions & 49 deletions extensions/pl_graphics_ext.h
Original file line number Diff line number Diff line change
Expand Up @@ -99,50 +99,53 @@ typedef struct _plDrawStreamI plDrawStreamI;
//-----------------------------------------------------------------------------

// basic types
typedef struct _plDevice plDevice;
typedef struct _plBuffer plBuffer;
typedef struct _plSwapchain plSwapchain;
typedef struct _plGraphics plGraphics;
typedef struct _plDraw plDraw;
typedef struct _plDispatch plDispatch;
typedef struct _plDrawArea plDrawArea;
typedef struct _plDrawStream plDrawStream;
typedef struct _plGraphicsState plGraphicsState;
typedef struct _plBlendState plBlendState;
typedef struct _plSpecializationConstant plSpecializationConstant;
typedef struct _plShaderDescription plShaderDescription;
typedef struct _plShader plShader;
typedef struct _plComputeShaderDescription plComputeShaderDescription;
typedef struct _plComputeShader plComputeShader;
typedef struct _plBuffer plBuffer;
typedef struct _plBufferDescription plBufferDescription;
typedef struct _plDynamicBuffer plDynamicBuffer;
typedef struct _plSamplerDesc plSamplerDesc;
typedef struct _plSampler plSampler;
typedef struct _plTextureViewDesc plTextureViewDesc;
typedef struct _plTexture plTexture;
typedef struct _plTextureDesc plTextureDesc;
typedef struct _plBindGroupLayout plBindGroupLayout;
typedef struct _plBindGroup plBindGroup;
typedef struct _plVertexAttributes plVertexAttributes;
typedef struct _plVertexBufferBinding plVertexBufferBinding;
typedef struct _plBufferBinding plBufferBinding;
typedef struct _plTextureBinding plTextureBinding;
typedef struct _plSamplerBinding plSamplerBinding;
typedef struct _plDynamicBinding plDynamicBinding;
typedef struct _plRenderViewport plRenderViewport;
typedef struct _plScissor plScissor;
typedef struct _plExtent plExtent;
typedef struct _plFrameGarbage plFrameGarbage;
typedef struct _plBufferImageCopy plBufferImageCopy;
typedef struct _plCommandBuffer plCommandBuffer;
typedef struct _plRenderEncoder plRenderEncoder;
typedef struct _plComputeEncoder plComputeEncoder;
typedef struct _plBlitEncoder plBlitEncoder;
typedef struct _plTimelineSemaphore plTimelineSemaphore;
typedef struct _plBeginCommandInfo plBeginCommandInfo;
typedef struct _plSubmitInfo plSubmitInfo;
typedef struct _plBindGroupUpdateData plBindGroupUpdateData;
typedef struct _plDevice plDevice;
typedef struct _plBuffer plBuffer;
typedef struct _plSwapchain plSwapchain;
typedef struct _plGraphics plGraphics;
typedef struct _plDraw plDraw;
typedef struct _plDispatch plDispatch;
typedef struct _plDrawArea plDrawArea;
typedef struct _plDrawStream plDrawStream;
typedef struct _plGraphicsState plGraphicsState;
typedef struct _plBlendState plBlendState;
typedef struct _plSpecializationConstant plSpecializationConstant;
typedef struct _plShaderDescription plShaderDescription;
typedef struct _plShader plShader;
typedef struct _plComputeShaderDescription plComputeShaderDescription;
typedef struct _plComputeShader plComputeShader;
typedef struct _plBuffer plBuffer;
typedef struct _plBufferDescription plBufferDescription;
typedef struct _plDynamicBuffer plDynamicBuffer;
typedef struct _plSamplerDesc plSamplerDesc;
typedef struct _plSampler plSampler;
typedef struct _plTextureViewDesc plTextureViewDesc;
typedef struct _plTexture plTexture;
typedef struct _plTextureDesc plTextureDesc;
typedef struct _plBindGroupLayout plBindGroupLayout;
typedef struct _plBindGroup plBindGroup;
typedef struct _plVertexAttributes plVertexAttributes;
typedef struct _plVertexBufferBinding plVertexBufferBinding;
typedef struct _plBufferBinding plBufferBinding;
typedef struct _plTextureBinding plTextureBinding;
typedef struct _plSamplerBinding plSamplerBinding;
typedef struct _plDynamicBinding plDynamicBinding;
typedef struct _plRenderViewport plRenderViewport;
typedef struct _plScissor plScissor;
typedef struct _plExtent plExtent;
typedef struct _plFrameGarbage plFrameGarbage;
typedef struct _plBufferImageCopy plBufferImageCopy;
typedef struct _plCommandBuffer plCommandBuffer;
typedef struct _plRenderEncoder plRenderEncoder;
typedef struct _plComputeEncoder plComputeEncoder;
typedef struct _plBlitEncoder plBlitEncoder;
typedef struct _plTimelineSemaphore plTimelineSemaphore;
typedef struct _plBeginCommandInfo plBeginCommandInfo;
typedef struct _plSubmitInfo plSubmitInfo;
typedef struct _plBindGroupUpdateData plBindGroupUpdateData;
typedef struct _plBindGroupUpdateTextureData plBindGroupUpdateTextureData;
typedef struct _plBindGroupUpdateBufferData plBindGroupUpdateBufferData;
typedef struct _plBindGroupUpdateSamplerData plBindGroupUpdateSamplerData;

// render passes
typedef struct _plRenderTarget plRenderTarget;
Expand Down Expand Up @@ -361,12 +364,35 @@ typedef struct _plSubmitInfo
uint64_t auSignalSemaphoreValues[PL_MAX_SEMAPHORES + 1];
} plSubmitInfo;

typedef struct _plBindGroupUpdateTextureData
{
plTextureHandle tTexture;
plTextureBindingType tType;
uint32_t uSlot;
uint32_t uIndex;
} plBindGroupUpdateTextureData;

typedef struct _plBindGroupUpdateBufferData
{
plBufferHandle tBuffer;
uint32_t uSlot;
size_t szBufferRange;
} plBindGroupUpdateBufferData;

typedef struct _plBindGroupUpdateSamplerData
{
plSamplerHandle tSampler;
uint32_t uSlot;
} plBindGroupUpdateSamplerData;

typedef struct _plBindGroupUpdateData
{
plBufferHandle* atBuffers;
size_t* aszBufferRanges;
plTextureHandle* atTextureViews;
plSamplerHandle* atSamplers;
uint32_t uBufferCount;
uint32_t uTextureCount;
uint32_t uSamplerCount;
const plBindGroupUpdateBufferData* atBuffers;
const plBindGroupUpdateTextureData* atTextures;
const plBindGroupUpdateSamplerData* atSamplers;
} plBindGroupUpdateData;

typedef struct _plCommandBuffer
Expand Down Expand Up @@ -659,6 +685,7 @@ typedef struct _plDrawArea
{
plRenderViewport tViewport;
plScissor tScissor;
uint32_t uBindGroup0;
plDrawStream* ptDrawStream;
} plDrawArea;

Expand All @@ -683,7 +710,6 @@ typedef struct _plDraw
uint32_t uIndexOffset;
uint32_t uTriangleCount;
uint32_t uShaderVariant;
uint32_t uBindGroup0;
uint32_t uBindGroup1;
uint32_t uBindGroup2;
uint32_t uDynamicBufferOffset;
Expand Down
106 changes: 60 additions & 46 deletions extensions/pl_metal_ext.m
Original file line number Diff line number Diff line change
Expand Up @@ -1093,7 +1093,18 @@ - (instancetype)initWithBuffer:(id<MTLBuffer>)buffer
.tLayout = *ptLayout
};

NSUInteger argumentBufferLength = sizeof(uint64_t) * (ptLayout->uTextureCount + ptLayout->uBufferCount + ptLayout->uSamplerCount);
uint32_t uDescriptorCount = ptLayout->uTextureCount + ptLayout->uBufferCount + ptLayout->uSamplerCount;

for(uint32_t i = 0; i < ptLayout->uTextureCount; i++)
{
uint32_t uCurrentDescriptorCount = ptLayout->aTextures[i].uDescriptorCount;
if(uCurrentDescriptorCount== 0)
uCurrentDescriptorCount = 1;
if(uCurrentDescriptorCount > 1)
uDescriptorCount += ptLayout->aTextures[i].uDescriptorCount - 1;
}

NSUInteger argumentBufferLength = sizeof(uint64_t) * uDescriptorCount;
MTLSizeAndAlign tSizeAlign = [ptMetalDevice->tDevice heapBufferSizeAndAlignWithLength:argumentBufferLength options:MTLResourceStorageModeShared];

PL_ASSERT(ptFrame->ulDescriptorHeapOffset + tSizeAlign.size < PL_DEVICE_ALLOCATION_BLOCK_SIZE);
Expand Down Expand Up @@ -1125,28 +1136,31 @@ - (instancetype)initWithBuffer:(id<MTLBuffer>)buffer

uint64_t* pulDescriptorStart = (uint64_t*)&pcDescriptorStart[ptMetalBindGroup->uOffset];

for(uint32_t i = 0; i < ptBindGroup->tLayout.uBufferCount; i++)
for(uint32_t i = 0; i < ptData->uBufferCount; i++)
{
plMetalBuffer* ptMetalBuffer = &ptMetalGraphics->sbtBuffersHot[ptData->atBuffers[i].uIndex];
uint64_t* ppfDestination = &pulDescriptorStart[ptBindGroup->tLayout.aBuffers[i].uSlot];
const plBindGroupUpdateBufferData* ptUpdate = &ptData->atBuffers[i];
plMetalBuffer* ptMetalBuffer = &ptMetalGraphics->sbtBuffersHot[ptUpdate->tBuffer.uIndex];
uint64_t* ppfDestination = &pulDescriptorStart[ptUpdate->uSlot];
*ppfDestination = ptMetalBuffer->tBuffer.gpuAddress;
ptMetalBindGroup->aBuffers[i] = ptData->atBuffers[i];
ptMetalBindGroup->aBuffers[i] = ptUpdate->tBuffer;
}

for(uint32_t i = 0; i < ptBindGroup->tLayout.uTextureCount; i++)
for(uint32_t i = 0; i < ptData->uTextureCount; i++)
{
plMetalTexture* ptMetalTexture = &ptMetalGraphics->sbtTexturesHot[ptData->atTextureViews[i].uIndex];
MTLResourceID* pptDestination = (MTLResourceID*)&pulDescriptorStart[ptBindGroup->tLayout.aTextures[i].uSlot];
const plBindGroupUpdateTextureData* ptUpdate = &ptData->atTextures[i];
plMetalTexture* ptMetalTexture = &ptMetalGraphics->sbtTexturesHot[ptUpdate->tTexture.uIndex];
MTLResourceID* pptDestination = (MTLResourceID*)&pulDescriptorStart[ptUpdate->uSlot + ptUpdate->uIndex];
*pptDestination = ptMetalTexture->tTexture.gpuResourceID;
ptMetalBindGroup->aTextures[i] = ptData->atTextureViews[i];
ptMetalBindGroup->aTextures[i] = ptUpdate->tTexture;
}

for(uint32_t i = 0; i < ptBindGroup->tLayout.uSamplerCount; i++)
for(uint32_t i = 0; i < ptData->uSamplerCount; i++)
{
plMetalSampler* ptMetalSampler = &ptMetalGraphics->sbtSamplersHot[ptData->atSamplers[i].uIndex];
MTLResourceID* pptDestination = (MTLResourceID*)&pulDescriptorStart[ptBindGroup->tLayout.atSamplers[i].uSlot];
const plBindGroupUpdateSamplerData* ptUpdate = &ptData->atSamplers[i];
plMetalSampler* ptMetalSampler = &ptMetalGraphics->sbtSamplersHot[ptUpdate->tSampler.uIndex];
MTLResourceID* pptDestination = (MTLResourceID*)&pulDescriptorStart[ptUpdate->uSlot];
*pptDestination = ptMetalSampler->tSampler.gpuResourceID;
ptMetalBindGroup->atSamplers[i] = ptData->atSamplers[i];
ptMetalBindGroup->atSamplers[i] = ptUpdate->tSampler;
}
}

Expand Down Expand Up @@ -2029,25 +2043,33 @@ - (instancetype)initWithBuffer:(id<MTLBuffer>)buffer
uint32_t uInstanceCount = 1;
id<MTLDepthStencilState> tCurrentDepthStencilState = nil;

{
plMetalBindGroup* ptMetalBindGroup = &ptMetalGraphics->sbtBindGroupsHot[ptArea->uBindGroup0];

for(uint32_t k = 0; k < ptMetalBindGroup->tLayout.uTextureCount; k++)
{

const plTextureHandle tTextureHandle = ptMetalBindGroup->aTextures[k];
id<MTLHeap> tHeap = ptMetalGraphics->sbtTexturesHot[tTextureHandle.uIndex].tHeap;
[tRenderEncoder useResource:ptMetalGraphics->sbtTexturesHot[tTextureHandle.uIndex].tTexture
usage:MTLResourceUsageRead
stages:MTLRenderStageVertex | MTLRenderStageFragment];
}

[tRenderEncoder setVertexBuffer:ptMetalBindGroup->tShaderArgumentBuffer
offset:ptMetalBindGroup->uOffset
atIndex:1];

[tRenderEncoder setFragmentBuffer:ptMetalBindGroup->tShaderArgumentBuffer
offset:ptMetalBindGroup->uOffset
atIndex:1];
}

while(uCurrentStreamIndex < uTokens)
{
const uint32_t uDirtyMask = ptStream->sbtStream[uCurrentStreamIndex];
uCurrentStreamIndex++;

if(uDirtyMask & PL_DRAW_STREAM_BIT_SHADER)
{
plMetalShader* ptMetalShader = &ptMetalGraphics->sbtShadersHot[ptStream->sbtStream[uCurrentStreamIndex]];
[tRenderEncoder setCullMode:ptMetalShader->tCullMode];
[tRenderEncoder setFrontFacingWinding:MTLWindingCounterClockwise];
if(tCurrentDepthStencilState != ptMetalShader->tDepthStencilState)
{
[tRenderEncoder setDepthStencilState:ptMetalShader->tDepthStencilState];
}
tCurrentDepthStencilState = ptMetalShader->tDepthStencilState;
[tRenderEncoder setRenderPipelineState:ptMetalShader->tRenderPipelineState];
[tRenderEncoder setTriangleFillMode:ptMetalShader->tFillMode];
uCurrentStreamIndex++;
}
if(uDirtyMask & PL_DRAW_STREAM_BIT_DYNAMIC_OFFSET)
{
uDynamicBufferOffset = ptStream->sbtStream[uCurrentStreamIndex];
Expand Down Expand Up @@ -2095,30 +2117,22 @@ - (instancetype)initWithBuffer:(id<MTLBuffer>)buffer
[tRenderEncoder setFragmentBuffer:ptMetalBindGroup->tShaderArgumentBuffer offset:ptMetalBindGroup->uOffset atIndex:2];
uCurrentStreamIndex++;
}
if(uDirtyMask & PL_DRAW_STREAM_BIT_BINDGROUP_0)
{
plMetalBindGroup* ptMetalBindGroup = &ptMetalGraphics->sbtBindGroupsHot[ptStream->sbtStream[uCurrentStreamIndex]];

for(uint32_t k = 0; k < ptMetalBindGroup->tLayout.uTextureCount; k++)
if(uDirtyMask & PL_DRAW_STREAM_BIT_SHADER)
{
plMetalShader* ptMetalShader = &ptMetalGraphics->sbtShadersHot[ptStream->sbtStream[uCurrentStreamIndex]];
[tRenderEncoder setCullMode:ptMetalShader->tCullMode];
[tRenderEncoder setFrontFacingWinding:MTLWindingCounterClockwise];
if(tCurrentDepthStencilState != ptMetalShader->tDepthStencilState)
{

const plTextureHandle tTextureHandle = ptMetalBindGroup->aTextures[k];
id<MTLHeap> tHeap = ptMetalGraphics->sbtTexturesHot[tTextureHandle.uIndex].tHeap;
[tRenderEncoder useResource:ptMetalGraphics->sbtTexturesHot[tTextureHandle.uIndex].tTexture
usage:MTLResourceUsageRead
stages:MTLRenderStageVertex | MTLRenderStageFragment];
[tRenderEncoder setDepthStencilState:ptMetalShader->tDepthStencilState];
}

[tRenderEncoder setVertexBuffer:ptMetalBindGroup->tShaderArgumentBuffer
offset:ptMetalBindGroup->uOffset
atIndex:1];

[tRenderEncoder setFragmentBuffer:ptMetalBindGroup->tShaderArgumentBuffer
offset:ptMetalBindGroup->uOffset
atIndex:1];

tCurrentDepthStencilState = ptMetalShader->tDepthStencilState;
[tRenderEncoder setRenderPipelineState:ptMetalShader->tRenderPipelineState];
[tRenderEncoder setTriangleFillMode:ptMetalShader->tFillMode];
uCurrentStreamIndex++;
}

if(uDirtyMask & PL_DRAW_STREAM_BIT_INDEX_OFFSET)
{
uIndexBufferOffset = ptStream->sbtStream[uCurrentStreamIndex];
Expand Down
Loading

0 comments on commit 4580a82

Please sign in to comment.