set_mode_system_value(mode);
break;
case SpvBuiltInPrimitiveId:
- if (*mode == nir_var_shader_out) {
+ if (b->shader->stage == MESA_SHADER_FRAGMENT) {
+ assert(*mode == nir_var_shader_in);
+ *location = VARYING_SLOT_PRIMITIVE_ID;
+ } else if (*mode == nir_var_shader_out) {
*location = VARYING_SLOT_PRIMITIVE_ID;
} else {
*location = SYSTEM_VALUE_PRIMITIVE_ID;
vtn_get_builtin_location(b, builtin, &nir_var->data.location, &mode);
nir_var->data.mode = mode;
- if (builtin == SpvBuiltInTessLevelOuter ||
- builtin == SpvBuiltInTessLevelInner) {
+ switch (builtin) {
+ case SpvBuiltInTessLevelOuter:
+ case SpvBuiltInTessLevelInner:
nir_var->data.compact = true;
- }
-
- if (builtin == SpvBuiltInFragCoord || builtin == SpvBuiltInSamplePosition)
+ break;
+ case SpvBuiltInSamplePosition:
nir_var->data.origin_upper_left = b->origin_upper_left;
-
- if (builtin == SpvBuiltInFragCoord)
+ /* fallthrough */
+ case SpvBuiltInFragCoord:
nir_var->data.pixel_center_integer = b->pixel_center_integer;
- break;
+ break;
+ default:
+ break;
+ }
}
case SpvDecorationSpecId:
case SpvDecorationFPRoundingMode:
case SpvDecorationFPFastMathMode:
case SpvDecorationAlignment:
- vtn_warn("Decoraiton only allowed for CL-style kernels: %s",
+ vtn_warn("Decoration only allowed for CL-style kernels: %s",
spirv_decoration_to_string(dec->decoration));
break;
}
case vtn_variable_mode_input:
case vtn_variable_mode_output: {
+ /* In order to know whether or not we're a per-vertex inout, we need
+ * the patch qualifier. This means walking the variable decorations
+ * early before we actually create any variables. Not a big deal.
+ *
+ * GLSLang really likes to place decorations in the most interior
+ * thing it possibly can. In particular, if you have a struct, it
+ * will place the patch decorations on the struct members. This
+ * should be handled by the variable splitting below just fine.
+ *
+ * If you have an array-of-struct, things get even more weird as it
+ * will place the patch decorations on the struct even though it's
+ * inside an array and some of the members being patch and others not
+ * makes no sense whatsoever. Since the only sensible thing is for
+ * it to be all or nothing, we'll call it patch if any of the members
+ * are declared patch.
+ */
var->patch = false;
vtn_foreach_decoration(b, val, var_is_patch_cb, &var->patch);
+ if (glsl_type_is_array(var->type->type) &&
+ glsl_type_is_struct(without_array->type)) {
+ vtn_foreach_decoration(b, without_array->val,
+ var_is_patch_cb, &var->patch);
+ }
/* For inputs and outputs, we immediately split structures. This
* is for a couple of reasons. For one, builtins may all come in
var->members[i]->interface_type =
interface_type->members[i]->type;
var->members[i]->data.mode = nir_mode;
+ var->members[i]->data.patch = var->patch;
}
} else {
var->var = rzalloc(b->shader, nir_variable);
var->var->type = var->type->type;
var->var->interface_type = interface_type->type;
var->var->data.mode = nir_mode;
+ var->var->data.patch = var->patch;
}
/* For inputs and outputs, we need to grab locations and builtin