glsl: declare gl_Layer/gl_ViewportIndex/gl_ViewportMask as vs builtins

Otherwise a VS doing the following:

out gl_PerVertex {
    vec4 gl_Position;
    int gl_ViewportIndex;
};

cannot be compiled because of the following error:
  "redeclaration of gl_PerVertex must be a subset of the built-in
  members of gl_PerVertex"

v2: add GLSL_PRECISION_HIGH param to add_varying() for "gl_Layer" in
    generate_fs_special_vars.
v3: add GLSL_PRECISION_HIGH param to add_varying() for "gl_Layer" in
    generate_varyings.

Closes: https://gitlab.freedesktop.org/mesa/mesa/-/issues/2946
Tested-by: John Galt <johngalt@fake.mail>
Reviewed-by: Marek Olšák <marek.olsak@amd.com> (v3)
Reviewed-by: Ian Romanick <ian.d.romanick@intel.com> (v3)
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/5167>
This commit is contained in:
Pierre-Eric Pelloux-Prayer 2020-05-19 14:42:19 +02:00 committed by Marge Bot
parent 26b75daef5
commit 49d35f3d88

View file

@ -315,7 +315,7 @@ class per_vertex_accumulator
public: public:
per_vertex_accumulator(); per_vertex_accumulator();
void add_field(int slot, const glsl_type *type, int precision, void add_field(int slot, const glsl_type *type, int precision,
const char *name); const char *name, enum glsl_interp_mode interp);
const glsl_type *construct_interface_instance() const; const glsl_type *construct_interface_instance() const;
private: private:
@ -333,7 +333,8 @@ per_vertex_accumulator::per_vertex_accumulator()
void void
per_vertex_accumulator::add_field(int slot, const glsl_type *type, per_vertex_accumulator::add_field(int slot, const glsl_type *type,
int precision, const char *name) int precision, const char *name,
enum glsl_interp_mode interp)
{ {
assert(this->num_fields < ARRAY_SIZE(this->fields)); assert(this->num_fields < ARRAY_SIZE(this->fields));
this->fields[this->num_fields].type = type; this->fields[this->num_fields].type = type;
@ -341,7 +342,7 @@ per_vertex_accumulator::add_field(int slot, const glsl_type *type,
this->fields[this->num_fields].matrix_layout = GLSL_MATRIX_LAYOUT_INHERITED; this->fields[this->num_fields].matrix_layout = GLSL_MATRIX_LAYOUT_INHERITED;
this->fields[this->num_fields].location = slot; this->fields[this->num_fields].location = slot;
this->fields[this->num_fields].offset = -1; this->fields[this->num_fields].offset = -1;
this->fields[this->num_fields].interpolation = INTERP_MODE_NONE; this->fields[this->num_fields].interpolation = interp;
this->fields[this->num_fields].centroid = 0; this->fields[this->num_fields].centroid = 0;
this->fields[this->num_fields].sample = 0; this->fields[this->num_fields].sample = 0;
this->fields[this->num_fields].patch = 0; this->fields[this->num_fields].patch = 0;
@ -397,14 +398,16 @@ private:
} }
ir_variable *add_input(int slot, const glsl_type *type, int precision, ir_variable *add_input(int slot, const glsl_type *type, int precision,
const char *name) const char *name,
enum glsl_interp_mode interp = INTERP_MODE_NONE)
{ {
return add_variable(name, type, precision, ir_var_shader_in, slot); return add_variable(name, type, precision, ir_var_shader_in, slot, interp);
} }
ir_variable *add_input(int slot, const glsl_type *type, const char *name) ir_variable *add_input(int slot, const glsl_type *type, const char *name,
enum glsl_interp_mode interp = INTERP_MODE_NONE)
{ {
return add_input(slot, type, GLSL_PRECISION_NONE, name); return add_input(slot, type, GLSL_PRECISION_NONE, name, interp);
} }
ir_variable *add_output(int slot, const glsl_type *type, int precision, ir_variable *add_output(int slot, const glsl_type *type, int precision,
@ -438,7 +441,7 @@ private:
ir_variable *add_variable(const char *name, const glsl_type *type, ir_variable *add_variable(const char *name, const glsl_type *type,
int precision, enum ir_variable_mode mode, int precision, enum ir_variable_mode mode,
int slot); int slot, enum glsl_interp_mode interp = INTERP_MODE_NONE);
ir_variable *add_index_variable(const char *name, const glsl_type *type, ir_variable *add_index_variable(const char *name, const glsl_type *type,
int precision, enum ir_variable_mode mode, int precision, enum ir_variable_mode mode,
int slot, int index); int slot, int index);
@ -455,10 +458,12 @@ private:
} }
ir_variable *add_const_ivec3(const char *name, int x, int y, int z); ir_variable *add_const_ivec3(const char *name, int x, int y, int z);
void add_varying(int slot, const glsl_type *type, int precision, void add_varying(int slot, const glsl_type *type, int precision,
const char *name); const char *name,
void add_varying(int slot, const glsl_type *type, const char *name) enum glsl_interp_mode interp = INTERP_MODE_NONE);
void add_varying(int slot, const glsl_type *type, const char *name,
enum glsl_interp_mode interp = INTERP_MODE_NONE)
{ {
add_varying(slot, type, GLSL_PRECISION_NONE, name); add_varying(slot, type, GLSL_PRECISION_NONE, name, interp);
} }
exec_list * const instructions; exec_list * const instructions;
@ -553,7 +558,8 @@ ir_variable *
builtin_variable_generator::add_variable(const char *name, builtin_variable_generator::add_variable(const char *name,
const glsl_type *type, const glsl_type *type,
int precision, int precision,
enum ir_variable_mode mode, int slot) enum ir_variable_mode mode, int slot,
enum glsl_interp_mode interp)
{ {
ir_variable *var = new(symtab) ir_variable(type, name, mode); ir_variable *var = new(symtab) ir_variable(type, name, mode);
var->data.how_declared = ir_var_declared_implicitly; var->data.how_declared = ir_var_declared_implicitly;
@ -580,6 +586,7 @@ builtin_variable_generator::add_variable(const char *name,
var->data.location = slot; var->data.location = slot;
var->data.explicit_location = (slot >= 0); var->data.explicit_location = (slot >= 0);
var->data.explicit_index = 0; var->data.explicit_index = 0;
var->data.interpolation = interp;
if (state->es_shader) if (state->es_shader)
var->data.precision = precision; var->data.precision = precision;
@ -1073,8 +1080,6 @@ builtin_variable_generator::generate_special_vars()
void void
builtin_variable_generator::generate_vs_special_vars() builtin_variable_generator::generate_vs_special_vars()
{ {
ir_variable *var;
if (state->is_version(130, 300) || state->EXT_gpu_shader4_enable) { if (state->is_version(130, 300) || state->EXT_gpu_shader4_enable) {
add_system_value(SYSTEM_VALUE_VERTEX_ID, int_t, GLSL_PRECISION_HIGH, add_system_value(SYSTEM_VALUE_VERTEX_ID, int_t, GLSL_PRECISION_HIGH,
"gl_VertexID"); "gl_VertexID");
@ -1101,33 +1106,6 @@ builtin_variable_generator::generate_vs_special_vars()
add_system_value(SYSTEM_VALUE_BASE_INSTANCE, int_t, "gl_BaseInstanceARB"); add_system_value(SYSTEM_VALUE_BASE_INSTANCE, int_t, "gl_BaseInstanceARB");
add_system_value(SYSTEM_VALUE_DRAW_ID, int_t, "gl_DrawIDARB"); add_system_value(SYSTEM_VALUE_DRAW_ID, int_t, "gl_DrawIDARB");
} }
if (state->AMD_vertex_shader_layer_enable ||
state->ARB_shader_viewport_layer_array_enable ||
state->NV_viewport_array2_enable) {
var = add_output(VARYING_SLOT_LAYER, int_t, "gl_Layer");
var->data.interpolation = INTERP_MODE_FLAT;
}
if (state->AMD_vertex_shader_viewport_index_enable ||
state->ARB_shader_viewport_layer_array_enable ||
state->NV_viewport_array2_enable) {
var = add_output(VARYING_SLOT_VIEWPORT, int_t, "gl_ViewportIndex");
var->data.interpolation = INTERP_MODE_FLAT;
}
if (state->NV_viewport_array2_enable) {
/* From the NV_viewport_array2 specification:
*
* "The variable gl_ViewportMask[] is available as an output variable
* in the VTG languages. The array has ceil(v/32) elements where v is
* the maximum number of viewports supported by the implementation."
*
* Since no drivers expose more than 16 viewports, we can simply set the
* array size to 1 rather than computing it and dealing with varying
* slot complication.
*/
var = add_output(VARYING_SLOT_VIEWPORT_MASK, array(int_t, 1),
"gl_ViewportMask");
var->data.interpolation = INTERP_MODE_FLAT;
}
if (compatibility) { if (compatibility) {
add_input(VERT_ATTRIB_POS, vec4_t, "gl_Vertex"); add_input(VERT_ATTRIB_POS, vec4_t, "gl_Vertex");
add_input(VERT_ATTRIB_NORMAL, vec3_t, "gl_Normal"); add_input(VERT_ATTRIB_NORMAL, vec3_t, "gl_Normal");
@ -1405,16 +1383,14 @@ builtin_variable_generator::generate_fs_special_vars()
state->ARB_fragment_layer_viewport_enable || state->ARB_fragment_layer_viewport_enable ||
state->OES_geometry_shader_enable || state->OES_geometry_shader_enable ||
state->EXT_geometry_shader_enable) { state->EXT_geometry_shader_enable) {
var = add_input(VARYING_SLOT_LAYER, int_t, GLSL_PRECISION_HIGH, add_varying(VARYING_SLOT_LAYER, int_t, GLSL_PRECISION_HIGH,
"gl_Layer"); "gl_Layer", INTERP_MODE_FLAT);
var->data.interpolation = INTERP_MODE_FLAT;
} }
if (state->is_version(430, 0) || if (state->is_version(430, 0) ||
state->ARB_fragment_layer_viewport_enable || state->ARB_fragment_layer_viewport_enable ||
state->OES_viewport_array_enable) { state->OES_viewport_array_enable) {
var = add_input(VARYING_SLOT_VIEWPORT, int_t, "gl_ViewportIndex"); add_varying(VARYING_SLOT_VIEWPORT, int_t, "gl_ViewportIndex", INTERP_MODE_FLAT);
var->data.interpolation = INTERP_MODE_FLAT;
} }
if (state->is_version(450, 310) || state->ARB_ES3_1_compatibility_enable) if (state->is_version(450, 310) || state->ARB_ES3_1_compatibility_enable)
@ -1452,19 +1428,20 @@ builtin_variable_generator::generate_cs_special_vars()
*/ */
void void
builtin_variable_generator::add_varying(int slot, const glsl_type *type, builtin_variable_generator::add_varying(int slot, const glsl_type *type,
int precision, const char *name) int precision, const char *name,
enum glsl_interp_mode interp)
{ {
switch (state->stage) { switch (state->stage) {
case MESA_SHADER_TESS_CTRL: case MESA_SHADER_TESS_CTRL:
case MESA_SHADER_TESS_EVAL: case MESA_SHADER_TESS_EVAL:
case MESA_SHADER_GEOMETRY: case MESA_SHADER_GEOMETRY:
this->per_vertex_in.add_field(slot, type, precision, name); this->per_vertex_in.add_field(slot, type, precision, name, interp);
/* FALLTHROUGH */ /* FALLTHROUGH */
case MESA_SHADER_VERTEX: case MESA_SHADER_VERTEX:
this->per_vertex_out.add_field(slot, type, precision, name); this->per_vertex_out.add_field(slot, type, precision, name, interp);
break; break;
case MESA_SHADER_FRAGMENT: case MESA_SHADER_FRAGMENT:
add_input(slot, type, precision, name); add_input(slot, type, precision, name, interp);
break; break;
case MESA_SHADER_COMPUTE: case MESA_SHADER_COMPUTE:
/* Compute shaders don't have varyings. */ /* Compute shaders don't have varyings. */
@ -1504,6 +1481,34 @@ builtin_variable_generator::generate_varyings()
GLSL_PRECISION_MEDIUM, GLSL_PRECISION_MEDIUM,
"gl_PointSize"); "gl_PointSize");
} }
if (state->stage == MESA_SHADER_VERTEX) {
if (state->AMD_vertex_shader_viewport_index_enable ||
state->ARB_shader_viewport_layer_array_enable ||
state->NV_viewport_array2_enable) {
add_varying(VARYING_SLOT_VIEWPORT, int_t, "gl_ViewportIndex", INTERP_MODE_FLAT);
}
if (state->AMD_vertex_shader_layer_enable ||
state->ARB_shader_viewport_layer_array_enable ||
state->NV_viewport_array2_enable) {
add_varying(VARYING_SLOT_LAYER, int_t, GLSL_PRECISION_HIGH,
"gl_Layer", INTERP_MODE_FLAT);
}
/* From the NV_viewport_array2 specification:
*
* "The variable gl_ViewportMask[] is available as an output variable
* in the VTG languages. The array has ceil(v/32) elements where v is
* the maximum number of viewports supported by the implementation."
*
* Since no drivers expose more than 16 viewports, we can simply set the
* array size to 1 rather than computing it and dealing with varying
* slot complication.
*/
if (state->NV_viewport_array2_enable)
add_varying(VARYING_SLOT_VIEWPORT_MASK, array(int_t, 1),
"gl_ViewportMask", INTERP_MODE_FLAT);
}
} }
if (state->has_clip_distance()) { if (state->has_clip_distance()) {