KhronosGroup / OpenGL-API

OpenGL and OpenGL ES API Issue Tracker
34 stars 5 forks source link

Should doubles count as 1 or 2 components each for vertex inputs and GL_ARB_enhanced_layouts #12

Closed imirkin closed 7 years ago

imirkin commented 7 years ago

I was recently reviewing the enhanced layout specs in connection with some failing CTS tests, and noticed that while e.g. a dvec4 takes up only a single location (instead of 2 as it would with inter-shader varyings), no similar provision is made for the component setting. From the GLSL 4.50 spec, section 4.4.1:

A scalar double will consume two of these components, and a dvec2 will consume all four components available within a location. A dvec3 or dvec4 can only be declared without specifying a component.

However for locations, vertex shader inputs are singled out:

If a vertex shader input is any scalar or vector type, it will consume a single location. If a non-vertex shader input is a scalar or vector type other than dvec3 or dvec4, it will consume a single location, while types dvec3 or dvec4 will consume two consecutive locations. Inputs of type double and dvec2 will consume only a single location, in all stages.

As it stands now, it's legal to have a vertex shader with

layout (location = 0) in dvec4 a;
layout (location = 1) in dvec4 b;

But it would not be legal to have a vertex shader with

layout (location = 0, component = 0) in dvec2 a;
layout (location = 0, component = 2) in dvec2 b;

This just seems somewhat inconsistent. Am I misinterpreting? Is this intentional?

johnkslang commented 7 years ago

Note glslang is consistent with what you report. It says this on the last line of code above:

ERROR: 'component' : type overflows the available 4 components

dgkoch commented 7 years ago

WG 2017-09-01. It does appear somewhat inconsistent, but it is intentional (mostly for historical reasons at this point). Note that as @johnkslang pointed out, the last line of your second example isn't actually legal in any shader state because it overflows components, so maybe it's not really as bad as it seems at initial glance.

As for the historical reasons -- on the API side, the double locations may count as either 1 or 2 locations - it's implementation dependent.

From 11.1.1 Vertex Attributes of the GL 4.6 spec)

There is an implementation-dependent limit on the number of active attribute variables in a vertex shader. A program with more than the value of MAX_VERTEX_ATTRIBS active attribute variables may fail to link, unless device-dependent optimizations are able to make the program fit within available hardware resources. For the purposes of this test, attribute variables of the type dvec3, dvec4, dmat2x3, dmat2x4, dmat3, dmat3x4, dmat4x3, and dmat4 may count as consuming twice as many attributes as equivalent single-precision types. While these types use the same number of generic attributes as their single-precision equivalents, implementations are permitted to consume two single-precision vectors of internal storage for each three- or four-component double-precision vector.

In order to make shaders work across implementations with double vertex input attributes, the shader locations are consecutive for dvec/dmat.

More background can be found in Issue 3 of https://www.khronos.org/registry/OpenGL/extensions/ARB/ARB_vertex_attrib_64bit.txt and also in the "Dependencies on ARB_explicit_attrib_location, ARB_separate_shader_objects, OpenGL 3.3, and OpenGL 4.1" section of that extension.

imirkin commented 7 years ago

Right... my point was mainly that vertex shader dvec4 input attributes take up a single location (at the API level), so it would make sense that a double would take up 1 component (again, at the API level, with implementations being free to allocate 2 "real" components). It's odd to say that you can have a dvec4 in a single API location, but not 2 dvec2's. If that's on purpose, then I guess that's fine.