Hello, a while ago I stated that I find the specification unclear in certain passages but I wouldn't give a concise description of what exactly I find unclear as a whole. I still can't, but I figured what I could do is collect those passages which a) I find unclear/ambiguously written and of which b) I still think they are unclear after their intended meaning has been explained to me (credits go to the fellow developers on IRC which patiently answer all of the many questions which I find). I'll refer to them as they appear in the 4.4 core spec and add a short commentary on each and what I think should be done better/differently.
As far as the forum permits it, I'll edit this post. Otherwise I'll just add new posts.
Please note that (although I do have my share of problems with how the API is designed by itself) my points attempt not to address design but just how the API (as it is) is described. If you think that at points I'm to blame for not understanding the meaning properly or that what I suggest is not suitable, please let me know.
4.4.1 WaitSync - Bug 1071 - It is unclear what exactly it means if the "server waits". Naively (and that's what I understood at first), one could interpret this as that everything on the "server side" (=== not client side) completely "freezes" until a condition is met (say, a FenceSync is passed). If one iterprets it like that, we could construct the following situation:
Client issues commands a( ), b( ), c( ), d( ), e( ), FenceSync( ), g( ) - they enter the server's command queue and are processed in order. When the server has reached, say, c( ) (it is currently processing c( )), the client issues a WaitSync( ) for the Fence after e( ). If the interpretation were correct, the server would now "hang" somewhere at c( ), waiting for itself to reach the FenceSync( ). Consequently the server would deadlock (or rather, timeout the wait). In either case, the WaitSync( ) would have no real purpose. As I was told, the meaning of WaitSync( ) relies on a specific notion of the hardware/driver processing commands (it continues to do so even after the WaitSync( ) was executed) and the server "stopping" (i.e. not feeding further instructions into the GPU). The fact that this notion is somewhat vague in itself aside, the spec should not require notion of these implementation-specific details.
6.2 Immutable vs. mutable storage as by BufferStorage vs. BufferData - The section does properly specify the restriction of BufferStorage( ), that is, one is not able to call that or BufferData( ) on the same buffer again. However, there is mention of "immutable" vs. "mutable" and it's neglected to specify that "mutability" in this context does not refer to the buffer's contents but only to their initial state (Table 6.3) as it is established by their creation.
2.6.1 Notion of buffer objects being "marked" - I understand that often the perspective of the implementer rather than that of the programmer/user of the API is reflected in the way the API is designed so although I'd rather have prefered a simple notion of "Defining a buffer object" and then "using it" like one does with variables in a language ("Define/declare an integer n"), I can understand that perhaps it's easier to use that concept of "Define a name" and only then "Define its usage" and then "Define its contents". However, it will probably help from the programmer's perspective if at least the notion of "a name being marked as used" could be removed. Why not simply speak of GenBuffers( ) creating buffer names and BindBuffer( ) creating their contents, instead of the cumbersome notion of "Creating unmarked names to buffer objects which only acquire state" (or something along those lines)?
6.3 Mapped pointer being passed to GL commands - It should be clarified how the demand that pointers returned MapBufferRange( ) must not be passed to GL commands is in accordance with 2.1 Execution model. It is explicitly stated that "Data binding occurs on call. This means that data passed to a GL command are interpreted when that command is received.". This is inconsistent because if it were like that, it musn't make any difference whether the data is some pointer returned by MapBufferRange( ) or not.