mirror of
https://github.com/MobileGL-Dev/MobileGL
synced 2026-09-07 19:58:32 +09:00
[Docs] (ShaderTranspiler): record the byte-exact fp64 block-layout evidence and its one misleading artifact
This commit is contained in:
@@ -54,18 +54,42 @@ namespace MobileGL {
|
||||
// cases fail on BOTH backends and on both an Adreno 830 and a Mali G925 - i.e. on every
|
||||
// device, because no device has shaderFloat64 and the demotion therefore always runs:
|
||||
//
|
||||
// KHR-GL43.shader_storage_buffer_object.basic-stdLayout-case3
|
||||
// KHR-GL43.shader_storage_buffer_object.basic-stdLayout-case3-cs
|
||||
// KHR-GL43.shader_storage_buffer_object.basic-stdLayout-case3-vs
|
||||
// KHR-GL43.compute_shader.fp64-case1
|
||||
// KHR-GL43.compute_shader.fp64-case3
|
||||
// ...and the std430 half of the same stdLayout case.
|
||||
//
|
||||
// They fail in the two ways this comment predicts and in no other. stdLayout-case3
|
||||
// copies a block byte for byte: the output matches the input for bytes [0, 76) and is
|
||||
// zero from there on, which is exactly the block's size once every double became a
|
||||
// float and the layout repacked tightly. fp64-case1 reports ceil(2.2) as 2: the
|
||||
// uniform's double 2.0 is 0x4000000000000000, the demoted read takes its low 32 bits
|
||||
// (0.0), ceil(0.0 + 0.2) = 1.0f = 0x3F800000 lands in the low half of the 8-byte
|
||||
// output slot and the whole thing prints as 2.
|
||||
// fp64-case3 is NOT this pass's to fix, and is listed only so it stops being counted
|
||||
// against it: it is blocked on GLSL subroutines ("FP64 support - subroutines"), which
|
||||
// glslang deletes when targeting SPIR-V, and is out of scope by standing instruction.
|
||||
//
|
||||
// The other three fail in the two ways this comment predicts and in no other.
|
||||
// stdLayout-case3 copies a block byte for byte: the output matches the input for
|
||||
// bytes [0, 76) and is zero from there on, which is exactly the block's size once
|
||||
// every double became a float and the layout repacked tightly. Re-derived byte-exactly
|
||||
// in 2026-08: the block is `int data0; float data1[5]; mat3x2 data2; double data3;
|
||||
// double data4[2]; int data5; dvec3 data6`, and demoting every double to float and
|
||||
// repacking std430 gives data0@0, data1@4..23, data2@24..47, data3@48, data4@52..59,
|
||||
// data5@60, data6@64..75 - 76 bytes. EVERY mismatching byte the QPA reports is >= 76
|
||||
// and every expected-non-zero byte below 76 matched, on both the std140 output and the
|
||||
// std430 one.
|
||||
//
|
||||
// ONE TRAP FOR THE NEXT READER, because it reads as evidence AGAINST demotion and is
|
||||
// not: in the std430 output the doubles below the boundary appear to have round-tripped
|
||||
// BIT-EXACTLY, which looks like fp64 surviving. It is an artifact. The shader reads and
|
||||
// writes through the SAME demoted offset, so those four bytes are copied verbatim
|
||||
// whatever they are interpreted as - the copy proves nothing about the width.
|
||||
//
|
||||
// fp64-case1 reports ceil(2.2) as 2: the uniform's double 2.0 is 0x4000000000000000,
|
||||
// the demoted read takes its low 32 bits (0.0), ceil(0.0 + 0.2) = 1.0f = 0x3F800000
|
||||
// lands in the low half of the 8-byte output slot and the whole thing prints as 2.
|
||||
// Index 0 of the same case PASSES by accident, for the same reason - writing 0.0f into
|
||||
// the low half of 1.0 leaves it unchanged - so a partial pass here is not progress.
|
||||
//
|
||||
// Both backends produce a CHARACTER-FOR-CHARACTER identical QPA byte list, which is
|
||||
// the cheapest available proof that the defect is in this shared pass and in neither
|
||||
// backend. A future wave that wants to re-open this should start by re-checking that
|
||||
// identity rather than by re-deriving the layout.
|
||||
//
|
||||
// Fixing them means NOT demoting a double that lives in a buffer block, and carrying
|
||||
// it as a uvec2 word pair instead - preserving the application's byte layout exactly,
|
||||
@@ -73,9 +97,10 @@ namespace MobileGL {
|
||||
// the same dmat problem the paragraph above describes (a uvec2 representation cannot
|
||||
// express a matrix stride either, so it would have to decline dmat types), and the
|
||||
// default-uniform routing above reflects the demoted module, so a representation
|
||||
// change there ripples into every glUniform*d. Four of 16085 cases; deliberately not
|
||||
// attempted. compute_shader.fp64-case2 passes today and any attempt has to keep it
|
||||
// green.
|
||||
// change there ripples into every glUniform*d. THREE actionable cases of 16085 (the
|
||||
// fourth, fp64-case3, is subroutine-blocked and unreachable from here); deliberately
|
||||
// not attempted, and re-confirmed as not worth attempting in the 2026-08 wave.
|
||||
// compute_shader.fp64-case2 passes today and any attempt has to keep it green.
|
||||
//
|
||||
// Declines (leaves the module byte-identical, so the caller's existing "this module
|
||||
// still declares Float64" failure path reports it) when the module contains an
|
||||
|
||||
Reference in New Issue
Block a user