- From: David Neto <dneto@google.com>
- Date: Tue, 12 Dec 2017 21:42:21 +0000
- To: Corentin Wallez <cwallez@google.com>
- Cc: Gregg Tavares <w3c@greggman.com>, "Myles C. Maxfield" <mmaxfield@apple.com>, Dzmitry Malyshau <dmalyshau@mozilla.com>, public-gpu <public-gpu@w3.org>
- Message-ID: <CAPmVsJXkpaBVF1C6tLUJ++PcNABbpFthw-UuiLjO4GEhLP=KgQ@mail.gmail.com>
Myles, Thanks for posting something concrete we can talk about. I've pasted my notes from a first quick pass over the doc. I'm not looking for specific replies, but offer it for your consideration. Overall I find it underspecified, especially among the many new features, including how new features interact with each other. Separately, some things will incur a high cost. Some requirements appear to be unimplementable on GLSL or Vulkan (even extended with variable-pointers). thanks david ----- Variables: Where can you define a variable? Can you reference a variable before its declaration: { int y = x; int x; int z = y; } // Require that z = 0? Initializers: - Allow interedependence? - Initializers are constants? - Want to forbid calling a function in an initializer. (No constexpr) - Should say: re-initialzed each time execution enters the scope Share storage between different shader stages? - Haven't defined the lifetime of the program w.r.t. shader stages or the pipeline - Possible leakage of values across thread-groups - Possible leakage of values across shader stages Output variables: are they in thread memory space? (I assume so.) Pointers: What operations are permitted? Better to have a whitelist - E.g. Dereference for load and store - But not for null - Others: access-chain, "slide", compare? - Basically, need to define the algebra for pointers Array reference: - You introduced with full generality, and then restricted later. - Not knowing which underlying array - Requires variable-pointers extension, and only works with storage-buffer or workgroup-shared (depending on the exact capability) - various conversion operations on array references are not permitted in GLSL without extension - @ operator on a "value". ?? Did you mean variable? Otherwise you're forcing creation of a new storage location. "Safe" pointer: - Indexing into array reference can result in a pointer pointing at invalid storage. So you can't say it's always either null or pointing at a valid object Out of bounds accesses: - Requirement that all previous writes must complete: Therefore any possibly out-of-bounds operations can't be combined or reordered. That's a big hinderance to optimization, e.g vectorization. What use is a null pointer? - You can't access it, you can't compare it. - Sketch: Possible translation for "null" is a pointer to a phantom variable, per type. Except even then you can't detect if it's that special pointer, so I don't know how to enforce the requested early termination. - But with null in the language at least you get known result, i.e. requested early termination. - What is the type of null? - I assume this language is statically typed. "Semantic errors inside generic functions show up once regardless of the number of times the generic function is instantiated." - That's a tooling concern, not a language concern. Generics: Example T identity<T>(T value).... What are the lexical / symbol constraints on T. Can't be another keyword, already defined symbol, ..... ? Constant expressions passed as type arguments: "Only literals and references to other constant parameters qualify." - Which others? Earlier parameters? Apparent circularity here. What do protocols contain? - Just method declarations? - Member declarations? Operator overloading: - Casting syntax given as "type(vlaue)" What about arrays. Array references. - Are protocols types? How do templates mix with protocols? Operator overloading: - If prefix increment is same as postfix increment, just ban one of them. - The example for ++ for int is apparently wrong: does not modify the value. Default values: - Do functions have types? Compound overloads such as : foo.doubleValue *= 2 ; must specify order of evaluation Function overload resolution: - Are the usual arithmetic conversions peformed? And how do they figure into ranks of specificity? By usual arithmetic conversions, foo(1u) resolves to both foo<T>(T) and foo(float) (The latter by a single step in usual arith conversion lattice.) - What is the type of "1" If all you have is foo(uint), does foo(1) compile? Why? - "specificity rank" is a partial order. May as well say so. - With the single-most-specific overload requirement, it's possible to break code by introducing a new type or protocol. Very non-local effect. I think that could be ok. Concurrency: - Are there storage images in WebGPU? (Question for the community group.) - This section is thin. - "inteleaved or concurrent" Interleaving = sequential consistency, it seems. That's super-strong. "Concurrent" is underspecified. Defined behaviour in all cases for all writes? In real life, likely to have unspecified behaviour. Logical mode: - Pointers may never be assigned to. Is parameter passing different or the same? - Ternary expressions: This is the first and only mention in the doc that this exists. Denorm flushing: That's expensive to guarantee after every op. Divergent control flow: Haven't defined it, nor when reconvergence can reoccur. Nothing about textures or images: sampled images or storage images On Mon, Dec 11, 2017 at 3:02 PM Corentin Wallez <cwallez@google.com> wrote: > Thanks Myles for the document, here are my notes too, both on the document > and some of the discussions on this thread. > > ## Preprocessor and multiple entry-points > > Not having #includes seems ok because you can do it in Javascript easily. > I'd argue that for the same reasons the rest of the preprocessor isn't > needed either, in particular since there isn't a good spec for how the C > preprocessor works which would be a source of incompatibilities. > > Having multiple entry-points of different stages sounds ok, and is > supported in SPIR-V. > > My suggestion for code reuse it to expose linking at that API-level. Some > modules could be pure-libraries and contain no entry-points while others > contain entry-points but some declared symbols are unimplemented. Module > linking could produces fully implemented modules with entry-points which > can be used for pipeline creation. Such linking would allow factoring of > the validation and translation cost too, and maybe some of the native > shader compilation cost. > > ## Builtin types > > Why remove the [RW]ByteAddressBuffer? It is important to allow > heterogeneous data in buffers. It could be done with > StructuredBuffer<uint32_t> and casts but that's not ideal imho. > > ## Variables > > Having things "as-if" local variables have a global lifetime sounds ok. It > corresponds how things work in native APIs where program-global register > allocation happens, and allows taking pointers to the variables (which > would then have their lifetime extended to that of the pointer). > > ## Safe pointers and array references. > > The SPIR-V logical addressing mode doesn't allow null pointers, how would > this feature be translated? I suggest that pointers should always be > initialized and "null" doesn't exist. > > Array-references are syntactic sugar around global arrays so I don't think > they are needed. Also there's a way to implement them for "thread" and > "threadgroup" address spaces (the only spaces they can be used with in your > proposal) such that they are assignable and translate correctly to SPIR-V. > > It is unlikely that we can require KHR_variable_pointer anytime soon, so > the content of the "Logical Mode" could be merged in the pointer and > arre-ref sections and treated as a hard constraint. > > ## Out Of Bounds accesses > > The trapping behavior described sounds extremely expensive to implement > and doesn't even match with the "discard" fragment shader operation. > Penalizing correct shaders to implement the trapping doesn't sound good and > imo this is a place where having a "one of the following happens" statement > would be ok. Same thing for NaN propagation and denorm floats. > > ## Syntax features > > No comment on the design of these. Their complexity reinforces my concerns > about having incompatible implementations. > > ## High-level takeway > > The document presents an HLSL++ that removes some of the ancient stuff of > HLSL and adds both pure-syntax features and a safe-pointer feature. There's > a small incompatibility with SPIR-V that (null pointers) that would be easy > to resolve. > > Out of all the additional features, only the safe pointers are compelling > since they actually expose more features of the underlying platform. All > the others increase the complexity of the language compared to HLSL > resulting in even more interoperability concerns. >
Received on Tuesday, 12 December 2017 21:43:27 UTC