-
Notifications
You must be signed in to change notification settings - Fork 170
Final changes to enable inline constants in Vulkan #750
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Final changes to enable inline constants in Vulkan #750
Conversation
| Uint32 ArraySize = Attribs.ArraySize; | ||
| if (Flags & PIPELINE_RESOURCE_FLAG_INLINE_CONSTANTS) | ||
| { | ||
| VERIFY(Flags == PIPELINE_RESOURCE_FLAG_INLINE_CONSTANTS, "INLINE_CONSTANTS flag cannot be combined with other flags."); |
Check warning
Code scanning / PREfast
Use 'bitwise and' to check if a flag is set. Warning
| ResCI.ShaderType = pShader->GetDesc().ShaderType; | ||
| ResCI.Name = pShader->GetDesc().Name; | ||
| ResCI.CombinedSamplerSuffix = pShader->GetDesc().UseCombinedTextureSamplers ? pShader->GetDesc().CombinedSamplerSuffix : nullptr; | ||
| ResCI.LoadShaderStageInputs = pShader->GetDesc().ShaderType == SHADER_TYPE_VERTEX; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Loading shader stage inputs is not needed.
It is used to patch Vertex Shader inputs, which is done when the shader is created.
They are already correct in the original SPIRV, and are the same in patched.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It is used to patch Vertex Shader inputs, which is done when the shader is created.
it can be a problem when ShaderVkImpl is asynchronously loaded, SPIRVShaderResources is not available at that time in ShaderVkImpl::Initialize. The ArchiverTest said that no SPIRVShaderResources is created when shader is created.
btw isn't shader patching done in RemapOrVerifyShaderResources?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There is an error somewhere. Asynchronous shaders must be created first before the pipeline is created. Querying anything from the shader while it is compiled is an error.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I haven't checked this code yet, but based on comment, this block is certainly not needed. InitPipelineLayout is only called after all asynchronous shader work is complete.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Reflection is only stripped from the final SPIRV after all patching, push constants conversion including
nvm I skipped the validation in 34af2e6. it works fine for stripped_reflection one now.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I refactored PipelineStateVkImpl::ShaderStageInfo, but now when I look at it I don't think ShaderResources are needed in ShaderStageInfo at all.
The problem is that right now, PatchShaderConvertUniformBufferToPushConstant is called separately from RemapOrVerifyShaderResources, but it should be part of RemapOrVerifyShaderResources.
RemapOrVerifyShaderResources should both patch bindings and push constants, if necessary.
If needed, it will created new resources and add them to pDvpShaderResources. If pDvpShaderResources is null, new resources are not needed.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I refactored
PipelineStateVkImpl::ShaderStageInfo, but now when I look at it I don't thinkShaderResourcesare needed inShaderStageInfoat all. The problem is that right now,PatchShaderConvertUniformBufferToPushConstantis called separately fromRemapOrVerifyShaderResources, but it should be part ofRemapOrVerifyShaderResources.RemapOrVerifyShaderResourcesshould both patch bindings and push constants, if necessary. If needed, it will created new resources and add them topDvpShaderResources. IfpDvpShaderResourcesis null, new resources are not needed.
but pDvpShaderResources is a DILIGENT_DEVELOPMENT-only variable which is not available in production build.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, which is why in production build there is no even need to create new shader resources after patching SPIRV.
| ResCI.Name = pShader->GetDesc().Name; | ||
| ResCI.CombinedSamplerSuffix = pShader->GetDesc().UseCombinedTextureSamplers ? pShader->GetDesc().CombinedSamplerSuffix : nullptr; | ||
| ResCI.LoadShaderStageInputs = pShader->GetDesc().ShaderType == SHADER_TYPE_VERTEX; | ||
| ResCI.LoadUniformBufferReflection = true; //LoadConstantBufferReflection; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why is uniform buffer reflection needed?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
we just leave it false or?
TheMostDiligent
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can you submit changes to PipelineLayoutVk.cpp/hpp as a separate PR - they are clean and isolated.
|
Seems that we have bool HasInlineConstants() const
{
// TODO
return false;
} |
e405c1f to
7be6864
Compare
This is a simple function that helps to avoid looping through all resources for all signatures even if there are no inline constants |
a022722 to
09a471d
Compare
9f79a40 to
75a4449
Compare
7a5328a to
1c5f655
Compare
Graphics/GraphicsEngineVulkan/include/ShaderResourceCacheVk.hpp
Outdated
Show resolved
Hide resolved
43e3d98 to
bd9769e
Compare
|
Take a look at how much simpler I made the inline constant initialization in the resource cache. |
will do next time |
a36c137 to
293f205
Compare
| float4 main(in PSInput PSIn) : SV_Target | ||
| { | ||
| return PSIn.Color; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why PS is not using the push constants block? It should to verify that the stages are properly merged.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why PS is not using the push constants block? It should to verify that the stages are properly merged.
That's what I mentioned before:
If we have [[vk::push_constant]] ConstantBuffer<PushConstants_t> PushConstants; declared both in VS and PS, they will be allocated as two resources instead of one, in PipelineStateVkImpl::GetDefaultResourceSignatureDesc.
Calling pPSO->GetStaticVariableByName(SHADER_TYPE_PIXEL, "PushConstants")->SetInlineConstants does nothing under the hood as data never get committed in m_CommandBuffer.PushConstants(Layout.GetVkPipelineLayout(), PushConstantInfo.vkRange, pPushConstantData);. The PushConstantInfo.vkRange goes with nothing more than VK_SHADER_STAGE_VERTEX_BIT.
I suggust ensure that [[vk::push_constant]] ConstantBuffer<PushConstants_t> PushConstants; has exact the same size in both VS and PS first, if they are both found in VS and PS.
We merge PCInfo.vkRange.stageFlags with ShaderTypesToVkShaderStageFlags(SHADER_TYPE_PIXEL) in the later pass in PipelineLayoutVk::GetPushConstantInfo then.
PS inline constants need to be merged into VS inline constants in PipelineStateVkImpl::GetDefaultResourceSignatureDesc as an identical resource also.
|
@hzqst Don't rebase on inline_constants yet - the tests will break due to incorrect memory size for SRB allocator. |
efe8f86 to
fbe3f5d
Compare
|
I am going to rebase and overwrite your branch - give me a few minutes. |
43ec87a to
3159a82
Compare
|
OK, done |
|
@TheMostDiligent we are now error out with 9aad908
If we have Calling
I suggust ensure that We should probably merge
|
Yes, this is what we need to do.
Can you work on this in a separate PR? |
|
I will also remove the test from this branch. |
base on DiligentGraphics:inline_constants or hzqst:inline_constants_747_fix? |
9aad908 to
9e12690
Compare
|
On hzqst:inline_constants_747_fix, DiligentGraphics:inline_constants don't have full implementation yet. |
|
Can you please create another PR? |
|
Done in b0e30b5 Next problem: what we gonna do with |
9e00a88 to
7b500ee
Compare
|
|
||
| const Uint32 SRBIndex = pResBindingVkImpl->GetBindingIndex(); | ||
| const PipelineResourceSignatureVkImpl* pSignature = pResBindingVkImpl->GetSignature(); | ||
|
|
||
| // PRS has no resources and thus PIPELINE_TYPE_INVALID ? | ||
| PIPELINE_TYPE SRBPipelineType = pResBindingVkImpl->GetPipelineType(); | ||
| if (SRBPipelineType == PIPELINE_TYPE_INVALID) | ||
| return; | ||
|
|
||
| ResourceBindInfo& BindInfo = GetBindInfo(SRBPipelineType); | ||
| ResourceBindInfo::DescriptorSetInfo& SetInfo = BindInfo.SetInfo[SRBIndex]; | ||
|
|
||
| // Always bind the SRB, even if it has no descriptor sets (e.g., only push constants) | ||
| // The resource cache is needed to store push constant data | ||
| BindInfo.Set(SRBIndex, pResBindingVkImpl); | ||
|
|
||
| // If there are no descriptor sets, we're done (SRB only contains push constants) | ||
| // Clear the stale flag since there are no descriptor sets to commit | ||
| if (ResourceCache.GetNumDescriptorSets() == 0) | ||
| { | ||
| // Ignore SRBs that contain no resources | ||
| // Clear the stale bit for this SRB since it has no descriptor sets to commit | ||
| // The SRB is still bound and ResourceCaches[SRBIndex] is set, so push constants can be accessed | ||
| const auto SRBBit = static_cast<ResourceBindInfo::SRBMaskType>(1u << SRBIndex); | ||
| BindInfo.StaleSRBMask &= ~SRBBit; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why are all these changed needed?
If I revert all of them, everything works fine.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Based on comments, it looks like this is remained from your earlier versions, since now all inline constants get descriptor sets, this does not make sense:
// Always bind the SRB, even if it has no descriptor sets (e.g., only push constants)
Also,
PIPELINE_TYPE SRBPipelineType = pResBindingVkImpl->GetPipelineType();
if (SRBPipelineType == PIPELINE_TYPE_INVALID)
return;
Should never happen.
7b500ee to
ba44fc8
Compare
…ffers and GetInlineConstantBuffers
…stants in CommitInlineConstants
ba44fc8 to
7cac8db
Compare
7cac8db
into
DiligentGraphics:inline_constants







No description provided.