Skip to content

push constant range validation doesn't check for static usage #340

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

Closed
jeffbolznv opened this issue Sep 21, 2018 · 12 comments
Closed

push constant range validation doesn't check for static usage #340

jeffbolznv opened this issue Sep 21, 2018 · 12 comments
Assignees
Labels
Bug Something isn't working
Milestone

Comments

@jeffbolznv
Copy link
Contributor

The CTS test dEQP-VK.pipeline.push_constant.graphics_pipeline.overlap_2_shaders_vert_frag (and a few similarly named tests) generate validation errors like:

ERROR:  [ UNASSIGNED-CoreValidation-Shader-PushConstantNotAccessibleFromStage ] Object: VK_NULL_HANDLE (Type = 0) | Push constant range covering variable starting at offset 12 not accessible from stage VK_SHADER_STAGE_FRAGMENT_BIT (code 0xffffffff from Validation at Unknown:0)

The fragment shader is:

#version 450
layout(location = 0) in highp vec4 vtxColor;
layout(location = 0) out highp vec4 fragColor;
layout(push_constant) uniform Material
{
    layout(offset = 12) int dummy1;
    layout(offset = 16) vec4 dummy2;
    layout(offset = 32) vec4 color;
} matInst;
void main (void)
{
    fragColor = vtxColor;
    fragColor += matInst.color;
    fragColor = min(mod(fragColor, 2.0), 2.0 - mod(fragColor, 2.0));
}

which doesn't statically use dummy1. It looks like MarkAccessibleIds is supposed to handle static usage, but I guess it probably isn't digging down into the structure's members.

@jzulauf-lunarg jzulauf-lunarg added the Bug Something isn't working label Sep 21, 2018
@jzulauf-lunarg
Copy link
Contributor

@chrisforbes -- I reviewed this code back a bit and came to the same conclusion. Getting the needed data is down in the guts of the spirv walker, do you have time to grab this?

@chrisforbes
Copy link
Contributor

Spec interpretation question first.

14.5.1 says this:

14.5.1. Push Constant Interface
The shader variables defined with a storage class of PushConstant that are statically used by the shader entry points for the pipeline define the push constant interface. They must be:

typed as OpTypeStruct,

identified with a Block decoration, and

laid out explicitly using the Offset, ArrayStride, and MatrixStride decorations as specified in Offset and Stride Assignment.

There must be no more than one push constant block statically used per shader entry point.

Each variable in a push constant block must be placed at an Offset such that the entire constant value is entirely contained within the VkPushConstantRange for each OpEntryPoint that uses it, and the stageFlags for that range must specify the appropriate VkShaderStageFlagBits for that stage. The Offset decoration for any variable in a push constant block must not cause the space required for that variable to extend outside the range [0, maxPushConstantsSize).

Any variable in a push constant block that is declared as an array must only be accessed with dynamically uniform indices.

I read this as defining the variables to be blocks (well, 0 or 1 blocks in a valid shader), and so that being the granularity at which static use is supposed to be evaluated, which we do already. This is also consistent with static use granularity for other things -- input/output interfaces, descriptor backed resources, etc.

I think we just say WAI?

@jzulauf-lunarg
Copy link
Contributor

"Each variable in a push constant block" -- the "each" makes it seem that more than one variable could be in a push constant block, but I don't know how that would be expressed in SPIR-V

@chrisforbes
Copy link
Contributor

Right, this is weirdly describing things both ways.

@chrisforbes
Copy link
Contributor

OK, I would prefer a world where none of the static use rules required reaching into the guts of block types, which we /almost/ have.

@jzulauf-lunarg
Copy link
Contributor

I don't think we can avoid it, though I know why you do.

@jeffbolznv
Copy link
Contributor Author

I see what you mean. I will file a spec bug to clarify this, however I believe the intent is to look at static use of members, otherwise the whole structure always starts at offset 0 (it's just structure padding) and mostly defeats the purpose of having the push constant ranges at all.

@chrisforbes
Copy link
Contributor

@jeffbolznv That doesn't seem quite true -- GLSL source language allows for layout(offset=N) decorations on the block members to get a particular layout.

oddhack added a commit to KhronosGroup/Vulkan-Docs that referenced this issue Oct 22, 2018
  * Update release number to 89.

Public Issues:

  * Clarify the reference to <<features-limits-mipmapPrecisionBits, mipmap
    precision bits>> in the <<textures-image-level-selection, Image Level(s)
    Selection>> section (public issue 660).
  * Update <<debugging-object-types,VkObjectType and Vulkan Handle
    Relationship>> table with missing types (public pull request 820).
  * Miscellaneous minor markup cleanup (public pull request 822).
  * Fix copy/paste bugs in the description of how implicit
    availability/visibility operations for atomics/barriers are ordered in
    the <<memory-model-availability-visibility-semantics, Availability and
    Visibility Semantics>> section (public issue 823).
  * Add missing shading_rate_image bit from mesh pipeline list in the
    <<synchronization-pipeline-stages-types>> list (public issue 824).

Internal Issues:

  * Clarify that only statically used members of a push constant block need
    to be in the push constant range, and stop referring to block members as
    "`variables`" in the <<interfaces-resources-pushconst, Push Constant
    Interface>> section. This is related to
    KhronosGroup/Vulkan-ValidationLayers#340
    (internal issue 1401).
  * Clarify interaction between flink:vkCmdSetDeviceMask and render pass
    control commands in the slink:VkDeviceGroupRenderPassBeginInfo section
    (internal issue 1416).
  * Miscellaneous minor markup cleanup.
  * Remove types defined by `"disabled"` extensions from
    validextensionstructs in the XML processing scripts, so downstream code
    generators don't emit them.
@tklajnscek
Copy link

Am I right in assuming that with the 1.1.89 spec clarification the validation layer should only complain if the shader actually uses the members that are out of range? If so, we could remove a bunch of #ifdef bloat from our push constant declarations.

Any thoughts appreciated :)

@jeffbolznv
Copy link
Contributor Author

@klajntib I think you are interpreting the spec update correctly, but I don't think the validation layers have been updated to reflect that.

@jzulauf-lunarg jzulauf-lunarg self-assigned this Jan 28, 2019
@jzulauf-lunarg
Copy link
Contributor

@chrisforbes -- you and I should re-triage this w.r.t. the new spec language. If we have to drill down to field scope in the static analysis it would be good to have a sense of "level of effort".

@mark-lunarg
Copy link
Contributor

This issue has been fixed by @jeremy-lunarg.

@shannon-lunarg shannon-lunarg added this to the sdk-1.2.148.0 milestone Jul 29, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Bug Something isn't working
Projects
None yet
Development

No branches or pull requests

7 participants