Skip to content

Commit 1fc44b7

Browse files
committed
feat: add support for 2 vertex buffers in graphics ext
1 parent ab65c3a commit 1fc44b7

File tree

6 files changed

+115
-32
lines changed

6 files changed

+115
-32
lines changed

docs/version.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,7 @@ the API is complete. It just means we won't break what currently exists.
5959
* Draw v1.2.0 (pl_draw_ext.h)
6060
* Draw Backend v1.0.1 (pl_draw_backend_ext.h)
6161
* GPU Allocators v1.0.0 (pl_gpu_allocators_ext.h)
62-
* Graphics v1.1.5 (pl_graphics_ext.h)
62+
* Graphics v1.2.0 (pl_graphics_ext.h)
6363
* Image v1.0.0 (pl_image_ext.h)
6464
* Job v2.0.0 (pl_job_ext.h)
6565
* Atomics v1.0.0 (pl_platform_ext.h)

extensions/pl_graphics_cpu.c

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -473,6 +473,11 @@ pl_end_render_pass(plRenderEncoder* ptEncoder)
473473
{
474474
}
475475

476+
static void
477+
pl_bind_vertex_buffers(plRenderEncoder* ptEncoder, uint32_t uFirst, uint32_t uCount, const plBufferHandle* ptHandles, const size_t* pszOffsets)
478+
{
479+
}
480+
476481
void
477482
pl_bind_vertex_buffer(plRenderEncoder* ptEncoder, plBufferHandle tHandle)
478483
{

extensions/pl_graphics_ext.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -965,6 +965,7 @@ pl_load_graphics_ext(plApiRegistryI* ptApiRegistry, bool bReload)
965965
.set_scissor_region = pl_set_scissor_region,
966966
.set_viewport = pl_set_viewport,
967967
.bind_vertex_buffer = pl_bind_vertex_buffer,
968+
.bind_vertex_buffers = pl_bind_vertex_buffers,
968969
.bind_shader = pl_bind_shader,
969970
.bind_compute_shader = pl_bind_compute_shader,
970971
.cleanup = pl_cleanup_graphics,

extensions/pl_graphics_ext.h

Lines changed: 16 additions & 6 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, 1, 5}
117+
#define plGraphicsI_version {1, 2, 0}
118118

119119
//-----------------------------------------------------------------------------
120120
// [SECTION] includes
@@ -382,6 +382,7 @@ typedef struct _plGraphicsI
382382
void (*set_viewport) (plRenderEncoder*, const plRenderViewport*);
383383
void (*set_scissor_region) (plRenderEncoder*, const plScissor*);
384384
void (*bind_vertex_buffer) (plRenderEncoder*, plBufferHandle);
385+
void (*bind_vertex_buffers) (plRenderEncoder*, uint32_t first, uint32_t count, const plBufferHandle*, const size_t* offsets); // offsets can be NULL or array of "count" length
385386
void (*draw) (plRenderEncoder*, uint32_t count, const plDraw*);
386387
void (*draw_indexed) (plRenderEncoder*, uint32_t count, const plDrawIndex*);
387388
void (*bind_shader) (plRenderEncoder*, plShaderHandle);
@@ -888,7 +889,7 @@ typedef struct _plShaderDesc
888889
uint32_t uSubpassIndex;
889890
plGraphicsState tGraphicsState;
890891
plBlendState atBlendStates[PL_MAX_RENDER_TARGETS];
891-
plVertexBufferLayout atVertexBufferLayouts[1];
892+
plVertexBufferLayout atVertexBufferLayouts[2];
892893
plShaderModule tVertexShader;
893894
plShaderModule tPixelShader;
894895
const void* pTempConstantData;
@@ -1111,7 +1112,7 @@ typedef struct _plDrawStreamData
11111112
plBindGroupHandle atBindGroups[3];
11121113
uint16_t auDynamicBuffers[1];
11131114
plBufferHandle tIndexBuffer;
1114-
plBufferHandle atVertexBuffers[1];
1115+
plBufferHandle atVertexBuffers[2];
11151116
uint32_t uIndexOffset;
11161117
uint32_t uVertexOffset;
11171118
uint32_t uInstanceOffset;
@@ -1727,9 +1728,10 @@ enum plDrawStreamBits
17271728
PL_DRAW_STREAM_BIT_VERTEX_OFFSET = 1 << 7,
17281729
PL_DRAW_STREAM_BIT_INDEX_BUFFER = 1 << 8,
17291730
PL_DRAW_STREAM_BIT_VERTEX_BUFFER_0 = 1 << 9,
1730-
PL_DRAW_STREAM_BIT_TRIANGLES = 1 << 10,
1731-
PL_DRAW_STREAM_BIT_INSTANCE_OFFSET = 1 << 11,
1732-
PL_DRAW_STREAM_BIT_INSTANCE_COUNT = 1 << 12
1731+
PL_DRAW_STREAM_BIT_VERTEX_BUFFER_1 = 1 << 10,
1732+
PL_DRAW_STREAM_BIT_TRIANGLES = 1 << 11,
1733+
PL_DRAW_STREAM_BIT_INSTANCE_OFFSET = 1 << 12,
1734+
PL_DRAW_STREAM_BIT_INSTANCE_COUNT = 1 << 13
17331735
};
17341736

17351737
//-----------------------------------------------------------------------------
@@ -1819,6 +1821,12 @@ pl_add_to_draw_stream(plDrawStream* ptStream, plDrawStreamData tDraw)
18191821
uDirtyMask |= PL_DRAW_STREAM_BIT_VERTEX_BUFFER_0;
18201822
}
18211823

1824+
if(ptStream->_tCurrentDraw.atVertexBuffers[1].uData != tDraw.atVertexBuffers[1].uData)
1825+
{
1826+
ptStream->_tCurrentDraw.atVertexBuffers[1] = tDraw.atVertexBuffers[1];
1827+
uDirtyMask |= PL_DRAW_STREAM_BIT_VERTEX_BUFFER_1;
1828+
}
1829+
18221830
if(ptStream->_tCurrentDraw.uTriangleCount != tDraw.uTriangleCount)
18231831
{
18241832
ptStream->_tCurrentDraw.uTriangleCount = tDraw.uTriangleCount;
@@ -1858,6 +1866,8 @@ pl_add_to_draw_stream(plDrawStream* ptStream, plDrawStreamData tDraw)
18581866
ptStream->_auStream[ptStream->_uStreamCount++] = ptStream->_tCurrentDraw.tIndexBuffer.uData;
18591867
if(uDirtyMask & PL_DRAW_STREAM_BIT_VERTEX_BUFFER_0)
18601868
ptStream->_auStream[ptStream->_uStreamCount++] = ptStream->_tCurrentDraw.atVertexBuffers[0].uData;
1869+
if(uDirtyMask & PL_DRAW_STREAM_BIT_VERTEX_BUFFER_1)
1870+
ptStream->_auStream[ptStream->_uStreamCount++] = ptStream->_tCurrentDraw.atVertexBuffers[1].uData;
18611871
if(uDirtyMask & PL_DRAW_STREAM_BIT_TRIANGLES)
18621872
ptStream->_auStream[ptStream->_uStreamCount++] = ptStream->_tCurrentDraw.uTriangleCount;
18631873
if(uDirtyMask & PL_DRAW_STREAM_BIT_INSTANCE_OFFSET)

extensions/pl_graphics_metal.m

Lines changed: 42 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1276,19 +1276,30 @@
12761276

12771277
// vertex layout
12781278
MTLVertexDescriptor* vertexDescriptor = [MTLVertexDescriptor vertexDescriptor];
1279-
vertexDescriptor.layouts[4].stepRate = 1;
1280-
vertexDescriptor.layouts[4].stepFunction = MTLVertexStepFunctionPerVertex;
1281-
vertexDescriptor.layouts[4].stride = ptDescription->atVertexBufferLayouts[0].uByteStride;
12821279

1280+
uint32_t uVertexBufferCount = 0;
12831281
uint32_t uCurrentAttributeCount = 0;
1284-
for(uint32_t i = 0; i < PL_MAX_VERTEX_ATTRIBUTES; i++)
1282+
for(uint32_t uVtxBufferIdx = 0; uVtxBufferIdx < 2; uVtxBufferIdx++)
12851283
{
1286-
if(ptDescription->atVertexBufferLayouts[0].atAttributes[i].tFormat == PL_VERTEX_FORMAT_UNKNOWN)
1284+
if(ptDescription->atVertexBufferLayouts[uVtxBufferIdx].uByteStride == 0)
12871285
break;
1288-
vertexDescriptor.attributes[i].bufferIndex = 4;
1289-
vertexDescriptor.attributes[i].offset = ptDescription->atVertexBufferLayouts[0].atAttributes[i].uByteOffset;
1290-
vertexDescriptor.attributes[i].format = pl__metal_vertex_format(ptDescription->atVertexBufferLayouts[0].atAttributes[i].tFormat);
1291-
uCurrentAttributeCount++;
1286+
1287+
for (uint32_t i = 0; i < PL_MAX_VERTEX_ATTRIBUTES; i++)
1288+
{
1289+
if(ptDescription->atVertexBufferLayouts[uVtxBufferIdx].atAttributes[i].tFormat == PL_VERTEX_FORMAT_UNKNOWN)
1290+
break;
1291+
const uint32_t uLocation = ptDescription->atVertexBufferLayouts[uVtxBufferIdx].bExplicitLocation ? ptDescription->atVertexBufferLayouts[uVtxBufferIdx].atAttributes[i].uLocation : uCurrentAttributeCount;
1292+
vertexDescriptor.attributes[uLocation].bufferIndex = 4 + uVtxBufferIdx;
1293+
vertexDescriptor.attributes[uLocation].offset = ptDescription->atVertexBufferLayouts[uVtxBufferIdx].atAttributes[i].uByteOffset;
1294+
vertexDescriptor.attributes[uLocation].format = pl__metal_vertex_format(ptDescription->atVertexBufferLayouts[uVtxBufferIdx].atAttributes[i].tFormat);
1295+
uCurrentAttributeCount++;
1296+
1297+
}
1298+
1299+
vertexDescriptor.layouts[4 + uVtxBufferIdx].stepRate = 1;
1300+
vertexDescriptor.layouts[4 + uVtxBufferIdx].stepFunction = MTLVertexStepFunctionPerVertex;
1301+
vertexDescriptor.layouts[4 + uVtxBufferIdx].stride = ptDescription->atVertexBufferLayouts[uVtxBufferIdx].uByteStride;
1302+
uVertexBufferCount++;
12921303
}
12931304

12941305
// prepare preprocessor defines
@@ -2381,6 +2392,20 @@
23812392
atIndex:4];
23822393
}
23832394

2395+
static void
2396+
pl_bind_vertex_buffers(plRenderEncoder* ptEncoder, uint32_t uFirst, uint32_t uCount, const plBufferHandle* ptHandles, const size_t* pszOffsets)
2397+
{
2398+
plCommandBuffer* ptCmdBuffer = ptEncoder->ptCommandBuffer;
2399+
plDevice* ptDevice = ptCmdBuffer->ptDevice;
2400+
2401+
for(uint32_t i = 0; i < uCount; i++)
2402+
{
2403+
[ptEncoder->tEncoder setVertexBuffer:ptDevice->sbtBuffersHot[ptHandles[i].uIndex].tBuffer
2404+
offset:(pszOffsets == NULL) ? 0 : pszOffsets[i]
2405+
atIndex:4 + uFirst + i];
2406+
}
2407+
}
2408+
23842409
static void
23852410
pl_draw(plRenderEncoder* ptEncoder, uint32_t uCount, const plDraw* atDraws)
23862411
{
@@ -2668,6 +2693,14 @@
26682693
atIndex:4];
26692694
uCurrentStreamIndex++;
26702695
}
2696+
if(uDirtyMask & PL_DRAW_STREAM_BIT_VERTEX_BUFFER_1)
2697+
{
2698+
const plBufferHandle tBufferHandle = {.uData = ptStream->_auStream[uCurrentStreamIndex] };
2699+
[ptEncoder->tEncoder setVertexBuffer:ptDevice->sbtBuffersHot[tBufferHandle.uIndex].tBuffer
2700+
offset:0
2701+
atIndex:5];
2702+
uCurrentStreamIndex++;
2703+
}
26712704
if(uDirtyMask & PL_DRAW_STREAM_BIT_TRIANGLES)
26722705
{
26732706
uTriangleCount = ptStream->_auStream[uCurrentStreamIndex];

extensions/pl_graphics_vulkan.c

Lines changed: 50 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1505,30 +1505,39 @@ pl_create_shader(plDevice* ptDevice, const plShaderDesc* ptDescription)
15051505
}
15061506

15071507
// setup & count vertex attributes
1508-
VkVertexInputAttributeDescription atAttributeDescription[PL_MAX_VERTEX_ATTRIBUTES] = {0};
1508+
VkVertexInputBindingDescription atBindingDescription[2] = {0};
1509+
VkVertexInputAttributeDescription atAttributeDescription[PL_MAX_VERTEX_ATTRIBUTES * 2] = {0};
1510+
uint32_t uVertexBufferCount = 0;
15091511
uint32_t uCurrentAttributeCount = 0;
1510-
for (uint32_t i = 0; i < PL_MAX_VERTEX_ATTRIBUTES; i++)
1512+
1513+
for(uint32_t uVtxBufferIdx = 0; uVtxBufferIdx < 2; uVtxBufferIdx++)
15111514
{
1512-
if (ptDescription->atVertexBufferLayouts[0].atAttributes[i].tFormat == PL_VERTEX_FORMAT_UNKNOWN)
1515+
if(ptDescription->atVertexBufferLayouts[uVtxBufferIdx].uByteStride == 0)
15131516
break;
1514-
atAttributeDescription[i].binding = 0;
1515-
atAttributeDescription[i].location = i;
1516-
atAttributeDescription[i].offset = ptDescription->atVertexBufferLayouts[0].atAttributes[i].uByteOffset;
1517-
atAttributeDescription[i].format = pl__vulkan_vertex_format(ptDescription->atVertexBufferLayouts[0].atAttributes[i].tFormat);
1518-
uCurrentAttributeCount++;
1519-
}
15201517

1521-
VkVertexInputBindingDescription tBindingDescription = {
1522-
.binding = 0,
1523-
.stride = ptDescription->atVertexBufferLayouts[0].uByteStride,
1524-
.inputRate = VK_VERTEX_INPUT_RATE_VERTEX
1525-
};
1518+
1519+
for (uint32_t i = 0; i < PL_MAX_VERTEX_ATTRIBUTES; i++)
1520+
{
1521+
if (ptDescription->atVertexBufferLayouts[uVtxBufferIdx].atAttributes[i].tFormat == PL_VERTEX_FORMAT_UNKNOWN)
1522+
break;
1523+
atAttributeDescription[uCurrentAttributeCount].binding = uVtxBufferIdx;
1524+
atAttributeDescription[uCurrentAttributeCount].location = ptDescription->atVertexBufferLayouts[uVtxBufferIdx].bExplicitLocation ? ptDescription->atVertexBufferLayouts[uVtxBufferIdx].atAttributes[i].uLocation : uCurrentAttributeCount;
1525+
atAttributeDescription[uCurrentAttributeCount].offset = ptDescription->atVertexBufferLayouts[uVtxBufferIdx].atAttributes[i].uByteOffset;
1526+
atAttributeDescription[uCurrentAttributeCount].format = pl__vulkan_vertex_format(ptDescription->atVertexBufferLayouts[uVtxBufferIdx].atAttributes[i].tFormat);
1527+
uCurrentAttributeCount++;
1528+
}
1529+
1530+
atBindingDescription[uVtxBufferIdx].binding = uVtxBufferIdx;
1531+
atBindingDescription[uVtxBufferIdx].stride = ptDescription->atVertexBufferLayouts[uVtxBufferIdx].uByteStride;
1532+
atBindingDescription[uVtxBufferIdx].inputRate = VK_VERTEX_INPUT_RATE_VERTEX;
1533+
uVertexBufferCount++;
1534+
}
15261535

15271536
VkPipelineVertexInputStateCreateInfo tVertexInputInfo = {
15281537
.sType = VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO,
1529-
.vertexBindingDescriptionCount = 1,
1538+
.vertexBindingDescriptionCount = uVertexBufferCount,
15301539
.vertexAttributeDescriptionCount = uCurrentAttributeCount,
1531-
.pVertexBindingDescriptions = &tBindingDescription,
1540+
.pVertexBindingDescriptions = atBindingDescription,
15321541
.pVertexAttributeDescriptions = atAttributeDescription
15331542
};
15341543

@@ -2057,6 +2066,24 @@ pl_bind_vertex_buffer(plRenderEncoder* ptEncoder, plBufferHandle tHandle)
20572066
vkCmdBindVertexBuffers(ptCmdBuffer->tCmdBuffer, 0, 1, &ptVertexBuffer->tBuffer, &offsets);
20582067
}
20592068

2069+
void
2070+
pl_bind_vertex_buffers(plRenderEncoder* ptEncoder, uint32_t uFirst, uint32_t uCount, const plBufferHandle* ptHandles, const size_t* pszOffsets)
2071+
{
2072+
plCommandBuffer* ptCmdBuffer = ptEncoder->ptCommandBuffer;
2073+
plDevice* ptDevice = ptCmdBuffer->ptDevice;
2074+
2075+
VkBuffer atBuffers[8] = {0};
2076+
static VkDeviceSize atOffsets[8] = {0};
2077+
for(uint32_t i = 0; i < uCount; i++)
2078+
{
2079+
if(pszOffsets)
2080+
atOffsets[i] = pszOffsets[i];
2081+
plVulkanBuffer* ptVertexBuffer = &ptDevice->sbtBuffersHot[ptHandles[i].uIndex];
2082+
atBuffers[i] = ptVertexBuffer->tBuffer;
2083+
}
2084+
vkCmdBindVertexBuffers(ptCmdBuffer->tCmdBuffer, uFirst, uCount, atBuffers, atOffsets);
2085+
}
2086+
20602087
void
20612088
pl_draw(plRenderEncoder* ptEncoder, uint32_t uCount, const plDraw *atDraws)
20622089
{
@@ -2267,6 +2294,13 @@ pl_draw_stream(plRenderEncoder* ptEncoder, uint32_t uAreaCount, plDrawArea *atAr
22672294
vkCmdBindVertexBuffers(ptCmdBuffer->tCmdBuffer, 0, 1, &ptVertexBuffer->tBuffer, &offsets);
22682295
uCurrentStreamIndex++;
22692296
}
2297+
if (uDirtyMask & PL_DRAW_STREAM_BIT_VERTEX_BUFFER_1)
2298+
{
2299+
const plBufferHandle tBufferHandle = {.uData = ptStream->_auStream[uCurrentStreamIndex] };
2300+
plVulkanBuffer* ptVertexBuffer = &ptDevice->sbtBuffersHot[tBufferHandle.uIndex];
2301+
vkCmdBindVertexBuffers(ptCmdBuffer->tCmdBuffer, 1, 1, &ptVertexBuffer->tBuffer, &offsets);
2302+
uCurrentStreamIndex++;
2303+
}
22702304
if (uDirtyMask & PL_DRAW_STREAM_BIT_TRIANGLES)
22712305
{
22722306
uTriangleCount = ptStream->_auStream[uCurrentStreamIndex];

0 commit comments

Comments
 (0)