Skip to content

Commit 67a47b4

Browse files
committed
refac: split shader constants into vtx & idx buffers (v1.3.0)
1 parent e6e85fa commit 67a47b4

File tree

10 files changed

+191
-74
lines changed

10 files changed

+191
-74
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.2.1 (pl_graphics_ext.h)
63+
* Graphics v1.3.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_ext.h

Lines changed: 7 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, 2, 1}
117+
#define plGraphicsI_version {1, 3, 0}
118118

119119
//-----------------------------------------------------------------------------
120120
// [SECTION] includes
@@ -890,7 +890,6 @@ typedef struct _plGraphicsState
890890

891891
typedef struct _plShaderDesc
892892
{
893-
plSpecializationConstant atConstants[PL_MAX_SHADER_SPECIALIZATION_CONSTANTS];
894893
uint32_t uSubpassIndex;
895894
plGraphicsState tGraphicsState;
896895
plBlendState atBlendStates[PL_MAX_RENDER_TARGETS];
@@ -907,14 +906,18 @@ typedef struct _plShaderDesc
907906
plShaderModule tFragmentShader;
908907
#endif
909908

910-
const void* pTempConstantData;
909+
plSpecializationConstant atVertexConstants[PL_MAX_SHADER_SPECIALIZATION_CONSTANTS];
910+
plSpecializationConstant atFragmentConstants[PL_MAX_SHADER_SPECIALIZATION_CONSTANTS];
911+
const void* pVertexTempConstantData;
912+
const void* pFragmentTempConstantData;
911913
plBindGroupLayoutDesc atBindGroupLayouts[3];
912914
plRenderPassLayoutHandle tRenderPassLayout;
913915
plSampleCount tMSAASampleCount;
914916
const char* pcDebugName; // default: "unnamed shader"
915917

916918
// [INTERNAL]
917-
uint32_t _uConstantCount;
919+
uint32_t _uVertexConstantCount;
920+
uint32_t _uFragmentConstantCount;
918921
uint32_t _uBindGroupLayoutCount;
919922
plBindGroupLayoutHandle _atBindGroupLayouts[3];
920923
} plShaderDesc;

extensions/pl_graphics_metal.m

Lines changed: 35 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1279,7 +1279,8 @@
12791279
plShader* ptShader = pl__get_shader(ptDevice, tHandle);
12801280
ptShader->tDesc = *ptDescription;
12811281
ptShader->tDesc._uBindGroupLayoutCount = 0;
1282-
ptShader->tDesc._uConstantCount = 0;
1282+
ptShader->tDesc._uVertexConstantCount = 0;
1283+
ptShader->tDesc._uFragmentConstantCount = 0;
12831284

12841285
if(ptShader->tDesc.pcDebugName == NULL)
12851286
ptShader->tDesc.pcDebugName = "unnamed shader";
@@ -1382,14 +1383,24 @@
13821383
// renderpass stuff
13831384
const plRenderPassLayout* ptLayout = pl_get_render_pass_layout(ptDevice, ptShader->tDesc.tRenderPassLayout);
13841385

1385-
size_t uTotalConstantSize = 0;
1386+
size_t uTotalVertexConstantSize = 0;
13861387
for(uint32_t i = 0; i < PL_MAX_SHADER_SPECIALIZATION_CONSTANTS; i++)
13871388
{
1388-
const plSpecializationConstant* ptConstant = &ptShader->tDesc.atConstants[i];
1389+
const plSpecializationConstant* ptConstant = &ptShader->tDesc.atVertexConstants[i];
13891390
if(ptConstant->tType == PL_DATA_TYPE_UNSPECIFIED)
13901391
break;
1391-
uTotalConstantSize += pl_get_data_type_size(ptConstant->tType);
1392-
ptShader->tDesc._uConstantCount++;
1392+
uTotalVertexConstantSize += pl_get_data_type_size(ptConstant->tType);
1393+
ptShader->tDesc._uVertexConstantCount++;
1394+
}
1395+
1396+
size_t uTotalFragmentConstantSize = 0;
1397+
for(uint32_t i = 0; i < PL_MAX_SHADER_SPECIALIZATION_CONSTANTS; i++)
1398+
{
1399+
const plSpecializationConstant* ptConstant = &ptShader->tDesc.atFragmentConstants[i];
1400+
if(ptConstant->tType == PL_DATA_TYPE_UNSPECIFIED)
1401+
break;
1402+
uTotalFragmentConstantSize += pl_get_data_type_size(ptConstant->tType);
1403+
ptShader->tDesc._uFragmentConstantCount++;
13931404
}
13941405

13951406
for (uint32_t i = 0; i < 3; i++)
@@ -1403,20 +1414,32 @@
14031414
ptShader->tDesc._uBindGroupLayoutCount++;
14041415
}
14051416

1406-
MTLFunctionConstantValues* ptConstantValues = [MTLFunctionConstantValues new];
1417+
MTLFunctionConstantValues* ptVertexConstantValues = [MTLFunctionConstantValues new];
1418+
MTLFunctionConstantValues* ptFragmentConstantValues = [MTLFunctionConstantValues new];
14071419

1408-
const char* pcConstantData = ptDescription->pTempConstantData;
1420+
const char* pcVertexConstantData = ptDescription->pVertexTempConstantData;
14091421
uint32_t uConstantOffset = 0;
1410-
for(uint32_t i = 0; i < ptShader->tDesc._uConstantCount; i++)
1422+
for(uint32_t i = 0; i < ptShader->tDesc._uVertexConstantCount; i++)
14111423
{
1412-
const plSpecializationConstant* ptConstant = &ptShader->tDesc.atConstants[i];
1424+
const plSpecializationConstant* ptConstant = &ptShader->tDesc.atVertexConstants[i];
14131425
const uint32_t uConstantIndex = ptConstant->uID == 0 ? i : ptConstant->uID;
14141426
const uint32_t uAutoConstantOffset = ptConstant->uOffset == 0 ? uConstantOffset : ptConstant->uOffset;
1415-
[ptConstantValues setConstantValue:&pcConstantData[uAutoConstantOffset] type:pl__metal_data_type(ptConstant->tType) atIndex:uConstantIndex];
1427+
[ptVertexConstantValues setConstantValue:&pcVertexConstantData[uAutoConstantOffset] type:pl__metal_data_type(ptConstant->tType) atIndex:uConstantIndex];
1428+
uConstantOffset += (uint32_t)pl_get_data_type_size(ptConstant->tType);
1429+
}
1430+
1431+
const char* pcFragmentConstantData = ptDescription->pFragmentTempConstantData;
1432+
uConstantOffset = 0;
1433+
for(uint32_t i = 0; i < ptShader->tDesc._uVertexConstantCount; i++)
1434+
{
1435+
const plSpecializationConstant* ptConstant = &ptShader->tDesc.atFragmentConstants[i];
1436+
const uint32_t uConstantIndex = ptConstant->uID == 0 ? i : ptConstant->uID;
1437+
const uint32_t uAutoConstantOffset = ptConstant->uOffset == 0 ? uConstantOffset : ptConstant->uOffset;
1438+
[ptFragmentConstantValues setConstantValue:&pcFragmentConstantData[uAutoConstantOffset] type:pl__metal_data_type(ptConstant->tType) atIndex:uConstantIndex];
14161439
uConstantOffset += (uint32_t)pl_get_data_type_size(ptConstant->tType);
14171440
}
14181441

1419-
id<MTLFunction> vertexFunction = [ptMetalShader->tVertexLibrary newFunctionWithName:vertexEntry constantValues:ptConstantValues error:&error];
1442+
id<MTLFunction> vertexFunction = [ptMetalShader->tVertexLibrary newFunctionWithName:vertexEntry constantValues:ptVertexConstantValues error:&error];
14201443
id<MTLFunction> fragmentFunction = nil;
14211444

14221445
if (vertexFunction == nil)
@@ -1426,7 +1449,7 @@
14261449

14271450
if(ptShader->tDesc.tFragmentShader.puCode)
14281451
{
1429-
fragmentFunction = [ptMetalShader->tFragmentLibrary newFunctionWithName:fragmentEntry constantValues:ptConstantValues error:&error];
1452+
fragmentFunction = [ptMetalShader->tFragmentLibrary newFunctionWithName:fragmentEntry constantValues:ptFragmentConstantValues error:&error];
14301453
if (fragmentFunction == nil)
14311454
{
14321455
NSLog(@"Error: failed to find Metal shader functions in library: %@", error);

extensions/pl_graphics_vulkan.c

Lines changed: 42 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -126,8 +126,10 @@ typedef struct _plVulkanShader
126126
VkShaderModule tPixelShaderModule;
127127
VkShaderModule tVertexShaderModule;
128128
VkDescriptorSetLayout atDescriptorSetLayouts[4];
129-
VkSpecializationMapEntry atSpecializationEntries[PL_MAX_SHADER_SPECIALIZATION_CONSTANTS];
130-
size_t szSpecializationSize;
129+
VkSpecializationMapEntry atVertexSpecializationEntries[PL_MAX_SHADER_SPECIALIZATION_CONSTANTS];
130+
size_t szVertexSpecializationSize;
131+
VkSpecializationMapEntry atFragmentSpecializationEntries[PL_MAX_SHADER_SPECIALIZATION_CONSTANTS];
132+
size_t szFragmentSpecializationSize;
131133
} plVulkanShader;
132134

133135
typedef struct _plVulkanComputeShader
@@ -1586,27 +1588,50 @@ pl_create_shader(plDevice* ptDevice, const plShaderDesc* ptDescription)
15861588
};
15871589

15881590
// setup & count specilization constants
1589-
ptShader->tDesc._uConstantCount = 0;
1590-
ptVulkanShader->szSpecializationSize = 0;
1591+
ptShader->tDesc._uVertexConstantCount = 0;
1592+
ptShader->tDesc._uFragmentConstantCount = 0;
1593+
ptVulkanShader->szVertexSpecializationSize = 0;
1594+
ptVulkanShader->szFragmentSpecializationSize = 0;
15911595
uint32_t uConstantOffset = 0;
15921596
for (uint32_t i = 0; i < PL_MAX_SHADER_SPECIALIZATION_CONSTANTS; i++)
15931597
{
1594-
const plSpecializationConstant* ptConstant = &ptShader->tDesc.atConstants[i];
1598+
const plSpecializationConstant* ptConstant = &ptShader->tDesc.atVertexConstants[i];
15951599
if(ptConstant->tType == PL_DATA_TYPE_UNSPECIFIED)
15961600
break;
1597-
ptVulkanShader->atSpecializationEntries[i].constantID = ptConstant->uID == 0 ? ptShader->tDesc._uConstantCount : ptConstant->uID;
1598-
ptVulkanShader->atSpecializationEntries[i].offset = ptConstant->uOffset == 0 ? uConstantOffset : ptConstant->uOffset;
1601+
ptVulkanShader->atVertexSpecializationEntries[i].constantID = ptConstant->uID == 0 ? ptShader->tDesc._uVertexConstantCount : ptConstant->uID;
1602+
ptVulkanShader->atVertexSpecializationEntries[i].offset = ptConstant->uOffset == 0 ? uConstantOffset : ptConstant->uOffset;
15991603
uConstantOffset += (uint32_t)pl_get_data_type_size(ptConstant->tType);
1600-
ptVulkanShader->atSpecializationEntries[i].size = pl_get_data_type_size(ptConstant->tType);
1601-
ptVulkanShader->szSpecializationSize += ptVulkanShader->atSpecializationEntries[i].size;
1602-
ptShader->tDesc._uConstantCount++;
1604+
ptVulkanShader->atVertexSpecializationEntries[i].size = pl_get_data_type_size(ptConstant->tType);
1605+
ptVulkanShader->szVertexSpecializationSize += ptVulkanShader->atVertexSpecializationEntries[i].size;
1606+
ptShader->tDesc._uVertexConstantCount++;
16031607
}
16041608

1605-
const VkSpecializationInfo tSpecializationInfo = {
1606-
.mapEntryCount = ptShader->tDesc._uConstantCount,
1607-
.pMapEntries = ptVulkanShader->atSpecializationEntries,
1608-
.dataSize = ptVulkanShader->szSpecializationSize,
1609-
.pData = ptDescription->pTempConstantData
1609+
uConstantOffset = 0;
1610+
for (uint32_t i = 0; i < PL_MAX_SHADER_SPECIALIZATION_CONSTANTS; i++)
1611+
{
1612+
const plSpecializationConstant* ptConstant = &ptShader->tDesc.atFragmentConstants[i];
1613+
if(ptConstant->tType == PL_DATA_TYPE_UNSPECIFIED)
1614+
break;
1615+
ptVulkanShader->atFragmentSpecializationEntries[i].constantID = ptConstant->uID == 0 ? ptShader->tDesc._uFragmentConstantCount : ptConstant->uID;
1616+
ptVulkanShader->atFragmentSpecializationEntries[i].offset = ptConstant->uOffset == 0 ? uConstantOffset : ptConstant->uOffset;
1617+
uConstantOffset += (uint32_t)pl_get_data_type_size(ptConstant->tType);
1618+
ptVulkanShader->atFragmentSpecializationEntries[i].size = pl_get_data_type_size(ptConstant->tType);
1619+
ptVulkanShader->szFragmentSpecializationSize += ptVulkanShader->atFragmentSpecializationEntries[i].size;
1620+
ptShader->tDesc._uFragmentConstantCount++;
1621+
}
1622+
1623+
const VkSpecializationInfo tVertexSpecializationInfo = {
1624+
.mapEntryCount = ptShader->tDesc._uVertexConstantCount,
1625+
.pMapEntries = ptVulkanShader->atVertexSpecializationEntries,
1626+
.dataSize = ptVulkanShader->szVertexSpecializationSize,
1627+
.pData = ptDescription->pVertexTempConstantData
1628+
};
1629+
1630+
const VkSpecializationInfo tFragmentSpecializationInfo = {
1631+
.mapEntryCount = ptShader->tDesc._uFragmentConstantCount,
1632+
.pMapEntries = ptVulkanShader->atFragmentSpecializationEntries,
1633+
.dataSize = ptVulkanShader->szFragmentSpecializationSize,
1634+
.pData = ptDescription->pFragmentTempConstantData
16101635
};
16111636

16121637
// create pipeline layout
@@ -1623,7 +1648,7 @@ pl_create_shader(plDevice* ptDevice, const plShaderDesc* ptDescription)
16231648
.stage = VK_SHADER_STAGE_VERTEX_BIT,
16241649
.module = ptVulkanShader->tVertexShaderModule,
16251650
.pName = ptShader->tDesc.tVertexShader.pcEntryFunc,
1626-
.pSpecializationInfo = ptShader->tDesc._uConstantCount > 0 ? &tSpecializationInfo : NULL
1651+
.pSpecializationInfo = ptShader->tDesc._uVertexConstantCount > 0 ? &tVertexSpecializationInfo : NULL
16271652
};
16281653

16291654
// doesn't matter since dynamic
@@ -1668,7 +1693,7 @@ pl_create_shader(plDevice* ptDevice, const plShaderDesc* ptDescription)
16681693
.stage = VK_SHADER_STAGE_FRAGMENT_BIT,
16691694
.module = ptVulkanShader->tPixelShaderModule,
16701695
.pName = ptShader->tDesc.tFragmentShader.pcEntryFunc,
1671-
.pSpecializationInfo = &tSpecializationInfo
1696+
.pSpecializationInfo = ptShader->tDesc._uFragmentConstantCount > 0 ? &tFragmentSpecializationInfo : NULL
16721697
};
16731698

16741699
VkPipelineDepthStencilStateCreateInfo tDepthStencil = {

extensions/pl_renderer_ext.c

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1797,9 +1797,9 @@ pl_renderer_outline_entities(plScene* ptScene, uint32_t uCount, plEntity* atEnti
17971797
pl_sb_push(ptScene->sbtOutlineDrawablesOldEnvShaders, ptDrawable->tEnvShader);
17981798

17991799
if(ptDrawable->tFlags & PL_DRAWABLE_FLAG_FORWARD)
1800-
ptDrawable->tShader = gptShaderVariant->get_shader("forward", &tVariantTemp, aiConstantData0, NULL);
1800+
ptDrawable->tShader = gptShaderVariant->get_shader("forward", &tVariantTemp, aiConstantData0, aiConstantData0, NULL);
18011801
else if(ptDrawable->tFlags & PL_DRAWABLE_FLAG_DEFERRED)
1802-
ptDrawable->tShader = gptShaderVariant->get_shader("gbuffer_fill", &tVariantTemp, aiConstantData0, NULL);
1802+
ptDrawable->tShader = gptShaderVariant->get_shader("gbuffer_fill", &tVariantTemp, aiConstantData0, aiConstantData0, NULL);
18031803

18041804
if(ptDrawable->uInstanceCount == 0)
18051805
{
@@ -1874,9 +1874,9 @@ pl_renderer_reload_scene_shaders(plScene* ptScene)
18741874
plLightComponent* ptLights = NULL;
18751875
const uint32_t uLightCount = gptECS->get_components(ptScene->ptComponentLibrary, gptData->tLightComponentType, (void**)&ptLights, NULL);
18761876
int aiLightingConstantData[] = {iSceneWideRenderingFlags, pl_sb_capacity(ptScene->sbtLightData), pl_sb_size(ptScene->sbtProbeData)};
1877-
ptScene->tLightingShader = gptShaderVariant->get_shader("deferred_lighting", NULL, aiLightingConstantData, &gptData->tRenderPassLayout);
1877+
ptScene->tLightingShader = gptShaderVariant->get_shader("deferred_lighting", NULL, aiLightingConstantData, aiLightingConstantData, &gptData->tRenderPassLayout);
18781878
aiLightingConstantData[0] = gptData->tRuntimeOptions.bPunctualLighting ? (PL_RENDERING_FLAG_USE_PUNCTUAL | PL_RENDERING_FLAG_SHADOWS) : 0;
1879-
ptScene->tEnvLightingShader = gptShaderVariant->get_shader("deferred_lighting", NULL, aiLightingConstantData, &gptData->tRenderPassLayout);
1879+
ptScene->tEnvLightingShader = gptShaderVariant->get_shader("deferred_lighting", NULL, aiLightingConstantData, aiLightingConstantData, &gptData->tRenderPassLayout);
18801880

18811881
pl__renderer_unstage_drawables(ptScene);
18821882
pl__renderer_set_drawable_shaders(ptScene);
@@ -1960,9 +1960,9 @@ pl_renderer_finalize_scene(plScene* ptScene)
19601960

19611961
// create lighting shader
19621962
int aiLightingConstantData[] = {iSceneWideRenderingFlags, pl_sb_capacity(ptScene->sbtLightData), pl_sb_size(ptScene->sbtProbeData)};
1963-
ptScene->tLightingShader = gptShaderVariant->get_shader("deferred_lighting", NULL, aiLightingConstantData, &gptData->tRenderPassLayout);
1963+
ptScene->tLightingShader = gptShaderVariant->get_shader("deferred_lighting", NULL, aiLightingConstantData, aiLightingConstantData, &gptData->tRenderPassLayout);
19641964
aiLightingConstantData[0] = gptData->tRuntimeOptions.bPunctualLighting ? (PL_RENDERING_FLAG_USE_PUNCTUAL | PL_RENDERING_FLAG_SHADOWS) : 0;
1965-
ptScene->tEnvLightingShader = gptShaderVariant->get_shader("deferred_lighting", NULL, aiLightingConstantData, &gptData->tRenderPassLayout);
1965+
ptScene->tEnvLightingShader = gptShaderVariant->get_shader("deferred_lighting", NULL, aiLightingConstantData, aiLightingConstantData, &gptData->tRenderPassLayout);
19661966

19671967

19681968
for(uint32_t i = 0; i < gptGfx->get_frames_in_flight(); i++)
@@ -2755,7 +2755,7 @@ pl_renderer_render_view(plView* ptView, plCamera* ptCamera, plCamera* ptCullCame
27552755
gptGfx->reset_draw_stream(ptStream, 1);
27562756
pl_add_to_draw_stream(ptStream, (plDrawStreamData)
27572757
{
2758-
.tShader = gptShaderVariant->get_shader("skybox", NULL, NULL, &gptData->tRenderPassLayout),
2758+
.tShader = gptShaderVariant->get_shader("skybox", NULL, NULL, NULL, &gptData->tRenderPassLayout),
27592759
.auDynamicBuffers = {
27602760
tSkyboxDynamicData.uBufferHandle
27612761
},
@@ -2973,7 +2973,7 @@ pl_renderer_render_view(plView* ptView, plCamera* ptCamera, plCamera* ptCullCame
29732973
plRenderEncoder* ptUVEncoder = gptGfx->begin_render_pass(ptUVCmdBuffer, ptView->tUVRenderPass, NULL);
29742974

29752975
// submit nonindexed draw using basic API
2976-
plShaderHandle tUVShader = gptShaderVariant->get_shader("uvmap", NULL, NULL, &gptData->tUVRenderPassLayout);
2976+
plShaderHandle tUVShader = gptShaderVariant->get_shader("uvmap", NULL, NULL, NULL, &gptData->tUVRenderPassLayout);
29772977
gptGfx->bind_shader(ptUVEncoder, tUVShader);
29782978
gptGfx->bind_vertex_buffer(ptUVEncoder, gptData->tFullQuadVertexBuffer);
29792979

0 commit comments

Comments
 (0)