Bind a sized void payload as the bytes it is - #81
Conversation
|
The Linting the untouched base with the same tool reports the same 7, and master's |
|
Follow-up to the lint note above: the one finding that WAS in a file this branch
Measured with the branch's generated files in place so cross-module requires |
|
Verified the mechanism locally (merge with master, correct in-tree rig): regen is deterministic — the skip report and all four generated daslib files match a fresh generator run byte-for-byte — the new named skip refuses One finding, and it gates merge: <member noautovalidity="true" len="valueCount">const <type>void</type>* <name>pValues</name>
<comment>Values to pass for a setting</comment></member>with vk.valueCount = uint(length(b.pValues))so one FLOAT32 setting packed as 4 bytes advertises The fix is the same one-gate class as the arm itself: bind void-as-bytes only when the len member actually denotes bytes (in the registry that's exactly the |
|
Caught, and the premise was wrong exactly as you say. The arm now gates on the len MEANING bytes — Ratchet is 44 → 46, and the comment above the arm no longer says "always" — it I swept the registry independently before touching it, and it agrees with yours Lint after the change: |
The lane's lint step reports 7 findings on master, none newer than the rules that added them (STYLE040 and PERF031 postdate every file's last touch), so every PR opened today inherits a red step it didn't cause. - vulkan_boost: set_extent_2d absorbs the four 2D-extent runs, and push_memory_management_extensions the extension trio both device creators carry. - vulkan_imgui_app: the no-scene harness_end_frame delegates to the block overload with an empty scene - same frame, 11 fewer lines. - vk_model / vk_naming: the dim-scan and vendor-tag loops walk a peek_data view, so nothing re-strlens the source per iteration. Regenerated output is byte-identical, so the rewrites are proven behavior-preserving. The one finding left is vulkan_cmds' jagged-view STYLE040, which borisbat#81 removes in the emitter - the honest fix for a generated file. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
|
Merged master in ( The integration lane fails, and I think it is ours, but I cannot reproduce it What I can establish from here:
Beyond that I am blind: this box has no Vulkan device (the lint and generator Two ways forward, and I do not mind either: you run it on your rig, which has |
|
Correcting myself: I said I was blind here because this box has no Vulkan device. It does not settle it, for a reason worth stating: on that box What that trip did turn up is a gap in the baseline: master has not run the Two ways to cut it, and I will do whichever you prefer:
The lint lane is green on this branch, and master is merged in as of |
|
Reproduced the integration-lane failure locally (WSL, lavapipe, daslang at master Where it breaks: every creator up the test succeeds; the failing call is Root cause:
Probe at the PR head: after the first literal, Why it matters beyond this test: reusing a stage struct by value across create-infos is idiomatic Vulkan; any downstream caller doing it silently loses data. So the fix belongs in the emitter, not the test. Fix shape: don't embed the non-copyable clone scratch by value. Either marshal through the user's pointee directly (its |
|
Fixed at the emitter, and your agents' diagnosis was exactly right — the The fix. The scratch no longer embeds the boost pointee by value, so nothing @do_not_delete pSpecializationInfo : SpecializationInfo?
_vk_view_pSpecializationInfo_vk : VkSpecializationInfo
_vk_view_pSpecializationInfo_present : boolThe view marshals through the caller's pointee in place The consume semantics are unchanged: the field is still nulled after viewing, and Verified on our Windows box against a real driver, since our first pass at
The copyability report is in, as you suggested: Emitter and driver lint clean, |
borisbat
left a comment
There was a problem hiding this comment.
Verified the fix end-to-end on the lavapipe rig (daslang at master 2779541): the copyability probe shows the stage locals surviving both pStages <- [...] literals again, the full integration suite is 42 tests / 41 passed / 1 skipped / 0 failed — identical to the green master baseline — and regeneration is deterministic and byte-identical across all six daslib files, the skip report, and the new copyability report.
The in-place scheme is a genuine improvement over what it replaces, not just a patch: net −144 generated lines, and @do_not_delete also closes a latent master hazard (delete on a holder with a populated borrowed addr(local) pointer would have freed a non-chunk pointer). I also checked the copyability report's direct-array-field criterion for completeness — it's the full truth, since FieldKind has no boost-struct-by-value embed now that the clone scratch is gone. Nice work, and thanks for the fast turnaround on the round-2 finding.
Two tiny items we'll take as follow-ups on our side (no action needed): wiring copyability_report.txt into the CI ratchet diff, and the now-stale "cloned into scratch" doc-comment on FieldKind.opt_struct_ptr.
…comment Two follow-ups from the borisbat#81 review ledger: - The generator already writes copyability_report.txt beside the skip report; the ratchet step now diffs it against the committed copy, so a copyable -> non-copyable flip in the boost surface fails CI instead of relying on committed regen. Verified locally: today's regen matches both reports. - FieldKind.opt_struct_ptr said "(caller's addr; cloned into scratch)" - both halves stale since the view rework: the pointee is borrowed and raw-viewed into the parent view's scratch, and the raw pointer aims at that scratch. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
The generator skips a struct whole if any member is unmappable, and the most
common one left is a
const void*payload with alen. Where that len means asize in bytes — the registry spells it
*Size/size— it binds asarray<uint8>whose scratch pointer reinterprets into the rawvoid?slot, thesame move a flags array already makes.
That unskips 11 boost structs (57 → 46 in the ratchet report):
VkPipelineCacheCreateInfo,VkSpecializationInfo,VkShaderCreateInfoEXT,VkPushConstantsInfo,VkValidationCacheCreateInfoEXT,VkCuModuleCreateInfoNVX,VkWriteDescriptorSetInlineUniformBlock,VkHdrVividDynamicMetadataHUAWEI,VkHostAddressRangeConstEXTand bothObjectTagInfoforms.A count-shaped len is not bytes, and is refused by name.
VkLayerSettingEXTcarries
len="valueCount"— a count of typed values whose stride comes from asibling
typefield, and whicharray<uint8>cannot represent at all (its STRINGcase is a
char*per value). It re-skips with a named reason and takesVkLayerSettingsCreateInfoEXTby cascade. On a singleconst void*,valueCountis the registry's only count-shaped len;
VkCuLaunchInfoNVX/VkCudaLaunchInfoNVhave four more, but each is a double pointer this arm never reaches.
Non-const is refused too: the call writes it, and a view's scratch never
reaches the caller back.
The command side. A two-call enumerate whose out array is void returns
array<uint8>against its byte count —get_pipeline_cache_data,get_validation_cache_data_e_x_t,get_shader_info_a_m_d,get_shader_binary_data_e_x_t. Those counts aresize_t, which is what makes the64-bit spelling load-bearing rather than cosmetic: das promotes nothing, so a
vkcount > 0ucompare against a0ulcount does not compile, andresize(int(vkcount))truncates above 2^31. Both are now spelled fromplan.count_is_64. A command with an out VALUE beside an enumerated array isrefused with a named reason instead of emitting with the value dropped.
A borrowed opt-struct-ptr no longer costs its holder's copyability. Making
VkSpecializationInfomappable gavePipelineShaderStageCreateInfoapSpecializationInfofield, and the old scratch embedded the boost pointee byvalue — dragging its arrays in and flipping the holder from copyable to
non-copyable. das copies a copyable element out of an array literal and MOVES a
non-copyable one, so
gp.pStages <- [st_vert, st_frag]silently zeroed thecaller's locals and the second create-info got blank stages. The holder now keeps
only
@do_not_delete pX : T?, the PODVk*view and a_presentflag; the viewmarshals through the caller's pointee in place, and
@do_not_deleteis what keepsthe finalize off the caller's local — the job the clone was really doing. Consume
semantics are unchanged, as
test_opt_ptr_view_semanticsrequires.generator/copyability_report.txtis written beside the skip report on fullruns: every boost struct that is not copyable, with the array field responsible
(170 today). A flip like the one above now lands in a review diff rather than in a
driver crash.
A jagged argument's views build and release through one generic pair
(
vk_views2_create/vk_views2_destroyinvulkan_structs.das) instead of acopy inside each wrapper — 34 fewer generated lines, one definition of the
void?-interior-pointer rule, and it clears the
STYLE040the generated filecarried.
daslib/,generator/skip_report.txtand the new report are regenerated in thesame commit, and
utils/vulkan2rst.dasgroups the creators the unskips add so thedoc job stays quiet.
Verified against a real driver (our Windows box, whole integration suite):
upstream master is 40/42 there — only
test_gltf, which needs assets — and thisbranch is 40/42 with the same single failure. Whole-tree lint: 150 files, 0
issues, 0 errors. Regeneration is deterministic (a second run produces no diff).