Skip to content

Commit 5d531e7

Browse files
feat: add events & raw pipeline barriers to graphics ext (v1.5.0)
1 parent ffc1ec4 commit 5d531e7

File tree

7 files changed

+226
-6
lines changed

7 files changed

+226
-6
lines changed

docs/version.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,7 @@ the API is complete. It just means we won't break what currently exists.
6060
* Draw Backend v1.0.1 (pl_draw_backend_ext.h)
6161
* DXT v1.0.0 (pl_dxt_ext.h)
6262
* GPU Allocators v1.0.0 (pl_gpu_allocators_ext.h)
63-
* Graphics v1.4.1 (pl_graphics_ext.h)
63+
* Graphics v1.5.0 (pl_graphics_ext.h)
6464
* Image v1.0.0 (pl_image_ext.h)
6565
* Job v2.0.0 (pl_job_ext.h)
6666
* Atomics v1.0.0 (pl_platform_ext.h)

extensions/pl_graphics_cpu.c

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -164,6 +164,12 @@ typedef struct _plTimelineSemaphore
164164
plTimelineSemaphore* ptNext; // for linked list
165165
} plTimelineSemaphore;
166166

167+
typedef struct _plTimelineEvent
168+
{
169+
plDevice* ptDevice; // for convience
170+
plTimelineEvent* ptNext; // for linked list
171+
} plTimelineEvent;
172+
167173
typedef struct _plFrameContext
168174
{
169175
// VkSemaphore tRenderFinish;
@@ -188,6 +194,9 @@ typedef struct _plDevice
188194
// timeline semaphore free list
189195
plTimelineSemaphore* ptSemaphoreFreeList;
190196

197+
// timeline evene free list
198+
plTimelineEvent* ptEventFreeList;
199+
191200
// render pass layout generation pool
192201
plCpuRenderPassLayout* sbtRenderPassLayoutsHot;
193202
plRenderPassLayout* sbtRenderPassLayoutsCold;
@@ -326,6 +335,35 @@ pl_get_semaphore_value(plDevice* ptDevice, plTimelineSemaphore* ptSemaphore)
326335
return ulValue;
327336
}
328337

338+
plTimelineEvent*
339+
pl_create_event(plDevice* ptDevice)
340+
{
341+
plTimelineEvent* ptEvent = pl__get_new_event(ptDevice);
342+
return ptEvent;
343+
}
344+
345+
void
346+
pl_cleanup_event(plTimelineEvent* ptEvent)
347+
{
348+
pl__return_event(ptEvent->ptDevice, ptEvent);
349+
}
350+
351+
void
352+
pl_reset_event(plCommandBuffer* ptCmdBuffer, plTimelineEvent* ptEvent, plPipelineStageFlags tSrcStages)
353+
{
354+
}
355+
356+
void
357+
pl_set_event(plCommandBuffer* ptCmdBuffer, plTimelineEvent* ptEvent, plPipelineStageFlags tFlags)
358+
{
359+
}
360+
361+
void
362+
pl_wait_for_events(plCommandBuffer* ptCmdBuffer, plTimelineEvent** atEvents, uint32_t uEventCount, plPipelineStageFlags tSrcStages, plPipelineStageFlags tDstStages)
363+
{
364+
}
365+
366+
329367
plBufferHandle
330368
pl_create_buffer(plDevice* ptDevice, const plBufferDesc* ptDesc, plBuffer **ptBufferOut)
331369
{
@@ -700,6 +738,11 @@ pl_cleanup_device(plDevice* ptDevice)
700738
pl__cleanup_common_device(ptDevice);
701739
}
702740

741+
void
742+
pl_pipeline_barrier(plCommandBuffer* ptCommandBuffer, plPipelineStageFlags beforeStages, plAccessFlags beforeAccesses, plPipelineStageFlags afterStages, plAccessFlags afterAccesses)
743+
{
744+
}
745+
703746
void
704747
pl_pipeline_barrier_blit(plBlitEncoder* ptEncoder, plShaderStageFlags beforeStages, plAccessFlags beforeAccesses, plShaderStageFlags afterStages, plAccessFlags afterAccesses)
705748
{

extensions/pl_graphics_ext.c

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -968,6 +968,24 @@ pl__get_new_semaphore(plDevice* ptDevice)
968968
return ptSemaphore;
969969
}
970970

971+
static plTimelineEvent*
972+
pl__get_new_event(plDevice* ptDevice)
973+
{
974+
plTimelineEvent* ptEvent = ptDevice->ptEventFreeList;
975+
if(ptEvent)
976+
{
977+
ptDevice->ptEventFreeList = ptEvent->ptNext;
978+
}
979+
else
980+
{
981+
ptEvent = PL_ALLOC(sizeof(plTimelineEvent));
982+
memset(ptEvent, 0, sizeof(plTimelineEvent));
983+
}
984+
ptEvent->ptDevice = ptDevice;
985+
ptEvent->ptNext = NULL;
986+
return ptEvent;
987+
}
988+
971989
static void
972990
pl__return_render_encoder(plRenderEncoder* ptEncoder)
973991
{
@@ -996,6 +1014,13 @@ pl__return_semaphore(plDevice* ptDevice, plTimelineSemaphore* ptSemaphore)
9961014
ptDevice->ptSemaphoreFreeList = ptSemaphore;
9971015
}
9981016

1017+
static void
1018+
pl__return_event(plDevice* ptDevice, plTimelineEvent* ptEvent)
1019+
{
1020+
ptEvent->ptNext = ptDevice->ptEventFreeList;
1021+
ptDevice->ptEventFreeList = ptEvent;
1022+
}
1023+
9991024
static plRenderPassHandle
10001025
pl_get_encoder_render_pass(plRenderEncoder* ptEncoder)
10011026
{
@@ -1240,6 +1265,7 @@ pl_load_graphics_ext(plApiRegistryI* ptApiRegistry, bool bReload)
12401265
.create_bind_group_pool = pl_create_bind_group_pool,
12411266
.cleanup_bind_group_pool = pl_cleanup_bind_group_pool,
12421267
.reset_bind_group_pool = pl_reset_bind_group_pool,
1268+
.pipeline_barrier = pl_pipeline_barrier,
12431269
.pipeline_barrier_blit = pl_pipeline_barrier_blit,
12441270
.pipeline_barrier_render = pl_pipeline_barrier_render,
12451271
.pipeline_barrier_compute = pl_pipeline_barrier_compute,
@@ -1266,6 +1292,11 @@ pl_load_graphics_ext(plApiRegistryI* ptApiRegistry, bool bReload)
12661292
.push_compute_debug_group = pl_push_compute_debug_group,
12671293
.pop_compute_debug_group = pl_pop_compute_debug_group,
12681294
.insert_debug_label = pl_insert_debug_label,
1295+
.create_event = pl_create_event,
1296+
.cleanup_event = pl_cleanup_event,
1297+
.reset_event = pl_reset_event,
1298+
.set_event = pl_set_event,
1299+
.wait_for_events = pl_wait_for_events,
12691300

12701301
#if defined(PL_GRAPHICS_EXPOSE_VULKAN) && defined(PL_VULKAN_BACKEND)
12711302
.get_vulkan_instance = pl_get_vulkan_instance,

extensions/pl_graphics_ext.h

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -114,7 +114,7 @@ Index of this file:
114114
// [SECTION] apis
115115
//-----------------------------------------------------------------------------
116116

117-
#define plGraphicsI_version {1, 4, 1}
117+
#define plGraphicsI_version {1, 5, 0}
118118

119119
//-----------------------------------------------------------------------------
120120
// [SECTION] includes
@@ -149,6 +149,7 @@ typedef struct _plSampler plSampler; // sampler resource
149149
typedef struct _plTexture plTexture; // texture resource
150150
typedef struct _plBuffer plBuffer; // buffer resource
151151
typedef struct _plTimelineSemaphore plTimelineSemaphore; // timeline semaphore
152+
typedef struct _plTimelineEvent plTimelineEvent; // timeline event
152153

153154
// swapchains
154155
typedef struct _plSwapchain plSwapchain; // swapchain
@@ -360,6 +361,13 @@ typedef struct _plGraphicsI
360361
void (*end_command_recording) (plCommandBuffer*);
361362
void (*submit_command_buffer) (plCommandBuffer*, const plSubmitInfo*);
362363

364+
// timeline events
365+
plTimelineEvent* (*create_event) (plDevice*);
366+
void (*cleanup_event) (plTimelineEvent*);
367+
void (*reset_event) (plCommandBuffer*, plTimelineEvent*, plPipelineStageFlags srcStages);
368+
void (*set_event) (plCommandBuffer*, plTimelineEvent*, plPipelineStageFlags srcStages);
369+
void (*wait_for_events)(plCommandBuffer*, plTimelineEvent**, uint32_t eventCount, plPipelineStageFlags srcStages, plPipelineStageFlags dstStages);
370+
363371
// render encoder
364372
plRenderEncoder* (*begin_render_pass) (plCommandBuffer*, plRenderPassHandle, const plPassResources*); // do not store
365373
void (*next_subpass) (plRenderEncoder*, const plPassResources*);
@@ -409,9 +417,10 @@ typedef struct _plGraphicsI
409417
plCommandBuffer* (*get_blit_encoder_command_buffer)(plBlitEncoder*);
410418

411419
// global barriers
412-
void (*pipeline_barrier_blit) (plBlitEncoder*, plPipelineStageFlags beforeStages, plAccessFlags beforeAccesses, plPipelineStageFlags afterStages, plAccessFlags afterAccesses);
413-
void (*pipeline_barrier_compute)(plComputeEncoder*, plPipelineStageFlags beforeStages, plAccessFlags beforeAccesses, plPipelineStageFlags afterStages, plAccessFlags afterAccesses);
414-
void (*pipeline_barrier_render) (plRenderEncoder*, plPipelineStageFlags beforeStages, plAccessFlags beforeAccesses, plPipelineStageFlags afterStages, plAccessFlags afterAccesses);
420+
void (*pipeline_barrier) (plCommandBuffer*, plPipelineStageFlags beforeStages, plAccessFlags beforeAccesses, plPipelineStageFlags afterStages, plAccessFlags afterAccesses);
421+
void (*pipeline_barrier_blit) (plBlitEncoder*, plPipelineStageFlags beforeStages, plAccessFlags beforeAccesses, plPipelineStageFlags afterStages, plAccessFlags afterAccesses); // memory barrier only in Metal backend
422+
void (*pipeline_barrier_compute)(plComputeEncoder*, plPipelineStageFlags beforeStages, plAccessFlags beforeAccesses, plPipelineStageFlags afterStages, plAccessFlags afterAccesses); // memory barrier only in Metal backend
423+
void (*pipeline_barrier_render) (plRenderEncoder*, plPipelineStageFlags beforeStages, plAccessFlags beforeAccesses, plPipelineStageFlags afterStages, plAccessFlags afterAccesses); // memory barrier only in Metal backend
415424

416425
//-----------------------------------------------------------------------------
417426

extensions/pl_graphics_internal.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -95,11 +95,13 @@ static plRenderEncoder* pl__get_new_render_encoder(void);
9595
static plComputeEncoder* pl__get_new_compute_encoder(void);
9696
static plBlitEncoder* pl__get_new_blit_encoder(void);
9797
static plTimelineSemaphore* pl__get_new_semaphore(plDevice*);
98+
static plTimelineEvent* pl__get_new_event(plDevice*);
9899

99100
static void pl__return_render_encoder(plRenderEncoder*);
100101
static void pl__return_compute_encoder(plComputeEncoder*);
101102
static void pl__return_blit_encoder(plBlitEncoder*);
102103
static void pl__return_semaphore(plDevice*, plTimelineSemaphore*);
104+
static void pl__return_event(plDevice*, plTimelineEvent*);
103105

104106
// deletion
105107
static plFrameGarbage* pl__get_frame_garbage(plDevice*);

extensions/pl_graphics_metal.m

Lines changed: 61 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,8 @@
3636
plBeginCommandInfo tBeginInfo;
3737
plDevice* ptDevice;
3838
id<MTLCommandBuffer> tCmdBuffer;
39+
id<MTLEvent> tEvent;
40+
uint64_t uEventValue;
3941
plCommandBuffer* ptNext;
4042
} plCommandBuffer;
4143

@@ -141,6 +143,14 @@
141143
plTimelineSemaphore* ptNext;
142144
} plTimelineSemaphore;
143145

146+
typedef struct _plTimelineEvent
147+
{
148+
plDevice* ptDevice; // for convience
149+
id<MTLEvent> tEvent;
150+
plTimelineEvent* ptNext; // for linked list
151+
uint64_t uValue;
152+
} plTimelineEvent;
153+
144154
typedef struct _plMetalBindGroup
145155
{
146156
id<MTLBuffer> tShaderArgumentBuffer;
@@ -208,6 +218,9 @@
208218

209219
plTimelineSemaphore* ptSemaphoreFreeList;
210220

221+
// timeline evene free list
222+
plTimelineEvent* ptEventFreeList;
223+
211224
// render pass layouts
212225
plMetalRenderPassLayout* sbtRenderPassLayoutsHot;
213226
plRenderPassLayout* sbtRenderPassLayoutsCold;
@@ -738,6 +751,41 @@
738751
return 0;
739752
}
740753

754+
plTimelineEvent*
755+
pl_create_event(plDevice* ptDevice)
756+
{
757+
plTimelineEvent* ptEvent = pl__get_new_event(ptDevice);
758+
ptEvent->tEvent = [ptDevice->tDevice newEvent];
759+
return ptEvent;
760+
}
761+
762+
void
763+
pl_cleanup_event(plTimelineEvent* ptEvent)
764+
{
765+
pl__return_event(ptEvent->ptDevice, ptEvent);
766+
}
767+
768+
void
769+
pl_reset_event(plCommandBuffer* ptCmdBuffer, plTimelineEvent* ptEvent, plPipelineStageFlags tSrcStages)
770+
{
771+
ptEvent->uValue++;
772+
}
773+
774+
void
775+
pl_set_event(plCommandBuffer* ptCmdBuffer, plTimelineEvent* ptEvent, plPipelineStageFlags tFlags)
776+
{
777+
[ptCmdBuffer->tCmdBuffer encodeSignalEvent:ptEvent->tEvent value:ptEvent->uValue];
778+
}
779+
780+
void
781+
pl_wait_for_events(plCommandBuffer* ptCmdBuffer, plTimelineEvent** atEvents, uint32_t uEventCount, plPipelineStageFlags tSrcStages, plPipelineStageFlags tDstStages)
782+
{
783+
for(uint32_t i = 0; i < uEventCount; i++)
784+
{
785+
[ptCmdBuffer->tCmdBuffer encodeWaitForEvent:atEvents[i]->tEvent value:atEvents[i]->uValue];
786+
}
787+
}
788+
741789
static plBufferHandle
742790
pl_create_buffer(plDevice* ptDevice, const plBufferDesc* ptDesc, plBuffer** ptBufferOut)
743791
{
@@ -1876,6 +1924,7 @@
18761924
while(ptCurrentCommandBuffer)
18771925
{
18781926
plCommandBuffer* ptNextCommandBuffer = ptCurrentCommandBuffer->ptNext;
1927+
ptCurrentCommandBuffer->tEvent = nil;
18791928
PL_FREE(ptCurrentCommandBuffer);
18801929
ptCurrentCommandBuffer = ptNextCommandBuffer;
18811930
}
@@ -2254,9 +2303,20 @@
22542303
}
22552304

22562305
void
2257-
pl_pipeline_barrier_blit(plBlitEncoder* ptEncoder, plPipelineStageFlags beforeStages, plAccessFlags beforeAccesses, plPipelineStageFlags afterStages, plAccessFlags afterAccesses)
2306+
pl_pipeline_barrier(plCommandBuffer* ptCommandBuffer, plPipelineStageFlags beforeStages, plAccessFlags beforeAccesses, plPipelineStageFlags afterStages, plAccessFlags afterAccesses)
22582307
{
2308+
if(ptCommandBuffer->tEvent == nil)
2309+
{
2310+
ptCommandBuffer->tEvent = [ptCommandBuffer->ptDevice->tDevice newEvent];
2311+
}
2312+
2313+
[ptCommandBuffer->tCmdBuffer encodeSignalEvent:ptCommandBuffer->tEvent value:++ptCommandBuffer->uEventValue];
2314+
[ptCommandBuffer->tCmdBuffer encodeWaitForEvent:ptCommandBuffer->tEvent value:ptCommandBuffer->uEventValue];
2315+
}
22592316

2317+
void
2318+
pl_pipeline_barrier_blit(plBlitEncoder* ptEncoder, plPipelineStageFlags beforeStages, plAccessFlags beforeAccesses, plPipelineStageFlags afterStages, plAccessFlags afterAccesses)
2319+
{
22602320
}
22612321

22622322
void

0 commit comments

Comments
 (0)