Skip to content

Conversation

@hzqst
Copy link
Contributor

@hzqst hzqst commented Dec 7, 2025

HLSL prefix: [[vk::push_constant]]
GLSL counterpart prefix: layout(push_constant)

Note that I added a new flag PIPELINE_RESOURCE_FLAG_VULKAN_PUSH_CONSTANT to indicate that a inline constant is a "vulkan push constant".

I don't find a way to avoid explicitly specifying because it is not possible to determine whether a inline constant is a vulkan push constant or not in PipelineResourceSignature creation (SPIRV is not available there).

As for legacy ResourceLayout, it's okay to have SHADER_VARIABLE_FLAG_INLINE_CONSTANTS without explicitly specifying vulkan stuffs for vulkan push constant, the flag PIPELINE_RESOURCE_FLAG_VULKAN_PUSH_CONSTANT will be automatically added to signature in InitDefaultSignature

Also added a new API SetPushConstants to IDeviceContextVk to expose the underlying API vkCmdPushConstants directly to user.

Tested with #724, working fine so far, with either USE_STATIC_INLINE_CONSTANTS on / off, USE_VULKAN_PUSH_CONSTANT on / off, USE_PRS_TEST on / off.

overall doc: https://github.com/hzqst/DiligentCore/blob/vk_push_constants/doc/SetInlineConstants.md#vulkan-backend-implementation

TODO: the APITest on linux shows that InlineConstantTest image diffs from reference, further investigation needed. maybe issue with multiple dynamic-buffer-emulated inline constant? fixed

@hzqst
Copy link
Contributor Author

hzqst commented Dec 10, 2025

Bytecode is always patched when PSO is created. Decorating a buffer is inline constants is just one of the steps and should not change the logic.

That was me manipulating ShaderVkImpl::m_SPIRV which ruined everything. ShaderVkImpl::m_SPIRV should not be modified since pipeline creation as it can be shared between mutiple pipelines. I am going with ShaderStages[i].Shaders now.

Following changes were applied:

  1. Flags VULKAN_PUSH_CONSTANT removed .
  2. Promote first inline constant declared in pipeline to a true push constant if there is no push constant declared in SPIR-V.
  3. Added ShaderResource to PipelineStateVkImpl::ShaderStageInfo, to have a chance to update it in PatchShaderConvertUniformBufferToPushConstant, where we reconstruct ShaderResource from patched SPIRV.
  4. Buffer-emulated inline constants design aligned to D3D11 one
  5. PatchShaderConvertUniformBufferToPushConstant utilizes a custom opt pass ConvertUBOToPushConstantPass, ThirdParty/SPIRV-Tools need to be merged.

@TheMostDiligent
Copy link
Contributor

Why does ConvertUBOToPushConstantPass need to be in SPIRV-Tools? Keeping a fork of third-party dependencies is highly undesirable and creates a lot of problems.

@hzqst
Copy link
Contributor Author

hzqst commented Dec 10, 2025

Why does ConvertUBOToPushConstantPass need to be in SPIRV-Tools? Keeping a fork of third-party dependencies is highly undesirable and creates a lot of problems.

cuz it depends on :
source/opt/pass.h
source/opt/ir_context.h
source/opt/type_manager.h
source/opt/decoration_manager.h
which are SPIRV-Tools's private headers

some odd shenanigans need to done to our CMakeLists.txt to access SPIRV-Tools's private headers

@hzqst
Copy link
Contributor Author

hzqst commented Dec 11, 2025

Following changes were applied:

  1. ConvertUBOToPushConstantPass has been ported to SPIRVTools.cpp
  2. PatchShaderConvertUBOToPushConstant: now error out when DILIGENT_NO_HLSL is defined (SPIRVTools is not available at that time). the first inline constant in the input SPIRV should be with layout(push_constant) explicitly.

@TheMostDiligent
Copy link
Contributor

Looks like everything works now - this is really nice. 👍 Thanks for working on this!

Only the size of this PR got out of hands - merging change this big is very difficult.
I suggest we break it into parts and merge in steps.
The first thing I suggest is adding support for push constants to SPIRVShaderResources. We will need to add tests that will compile a simple shader with each resource type, create SPIRVShaderResources from byte code and test that the expected resource is properly reflected.

@TheMostDiligent
Copy link
Contributor

#733 is merged - this is very good, thank you.
One thing is that ideally we would want to also test DXC. Did you try it?

The next step is to add SPIRV patching to convert uniform block to push constants.
I see it requires SPIRV-Tools, which means it will not be possible to use push constants if GLSLang is disabled. This should be OK as it is expected that the app provides fully ready bytecode in this case e.g. from archiver.

Comment on lines +102 to +105
VIRTUAL void METHOD(SetPushConstants)(THIS_
const void* pData,
Uint32 Offset,
Uint32 Size) PURE;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This method is not needed. If the app wants to use Vulkan directly, it can request command buffer with GetVkCommandBuffer and then set push constants or do anything it needs.

@TheMostDiligent TheMostDiligent force-pushed the inline_constants branch 2 times, most recently from cd07435 to 5434a10 Compare December 16, 2025 07:50
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants