case MESA_SHADER_TESS_CTRL:
case MESA_SHADER_TESS_EVAL:
case MESA_SHADER_GEOMETRY:
- var->data.location = qual->location + VARYING_SLOT_VAR0;
+ if (var->data.patch)
+ var->data.location = qual->location + VARYING_SLOT_PATCH0;
+ else
+ var->data.location = qual->location + VARYING_SLOT_VAR0;
break;
case MESA_SHADER_FRAGMENT:
for (int i = 0; i < len; i++) {
bool dual_slot = is_dual_slot(var);
int idx = var->data.location + var->data.index + offset + i;
- GLbitfield64 bitfield = BITFIELD64_BIT(idx);
+ bool is_patch_generic = var->data.patch &&
+ idx != VARYING_SLOT_TESS_LEVEL_INNER &&
+ idx != VARYING_SLOT_TESS_LEVEL_OUTER;
+ GLbitfield64 bitfield;
+
+ if (is_patch_generic) {
+ assert(idx >= VARYING_SLOT_PATCH0 && idx < VARYING_SLOT_TESS_MAX);
+ bitfield = BITFIELD64_BIT(idx - VARYING_SLOT_PATCH0);
+ }
+ else {
+ assert(idx < VARYING_SLOT_MAX);
+ bitfield = BITFIELD64_BIT(idx);
+ }
if (var->data.mode == ir_var_shader_in) {
- prog->InputsRead |= bitfield;
+ if (is_patch_generic)
+ prog->PatchInputsRead |= bitfield;
+ else
+ prog->InputsRead |= bitfield;
+
if (dual_slot)
prog->DoubleInputsRead |= bitfield;
if (is_fragment_shader) {
prog->SystemValuesRead |= bitfield;
} else {
assert(var->data.mode == ir_var_shader_out);
- prog->OutputsWritten |= bitfield;
+ if (is_patch_generic)
+ prog->PatchOutputsWritten |= bitfield;
+ else
+ prog->OutputsWritten |= bitfield;
}
}
}
prog->InputsRead = 0;
prog->OutputsWritten = 0;
+ prog->PatchInputsRead = 0;
+ prog->PatchOutputsWritten = 0;
prog->SystemValuesRead = 0;
if (shader_stage == MESA_SHADER_FRAGMENT) {
gl_fragment_program *fprog = (gl_fragment_program *) prog;
&varying_matches::match_comparator);
unsigned generic_location = 0;
+ unsigned generic_patch_location = MAX_VARYING*4;
for (unsigned i = 0; i < this->num_matches; i++) {
+ unsigned *location = &generic_location;
+
+ if ((this->matches[i].consumer_var &&
+ this->matches[i].consumer_var->data.patch) ||
+ (this->matches[i].producer_var &&
+ this->matches[i].producer_var->data.patch))
+ location = &generic_patch_location;
+
/* Advance to the next slot if this varying has a different packing
* class than the previous one, and we're not already on a slot
* boundary.
if (i > 0 &&
this->matches[i - 1].packing_class
!= this->matches[i].packing_class) {
- generic_location = ALIGN(generic_location, 4);
+ *location = ALIGN(*location, 4);
}
- this->matches[i].generic_location = generic_location;
+ this->matches[i].generic_location = *location;
- generic_location += this->matches[i].num_components;
+ *location += this->matches[i].num_components;
}
return (generic_location + 3) / 4;
populate_consumer_input_sets(void *mem_ctx, exec_list *ir,
hash_table *consumer_inputs,
hash_table *consumer_interface_inputs,
- ir_variable *consumer_inputs_with_locations[VARYING_SLOT_MAX])
+ ir_variable *consumer_inputs_with_locations[VARYING_SLOT_TESS_MAX])
{
memset(consumer_inputs_with_locations,
0,
- sizeof(consumer_inputs_with_locations[0]) * VARYING_SLOT_MAX);
+ sizeof(consumer_inputs_with_locations[0]) * VARYING_SLOT_TESS_MAX);
foreach_in_list(ir_instruction, node, ir) {
ir_variable *const input_var = node->as_variable();
const ir_variable *output_var,
hash_table *consumer_inputs,
hash_table *consumer_interface_inputs,
- ir_variable *consumer_inputs_with_locations[VARYING_SLOT_MAX])
+ ir_variable *consumer_inputs_with_locations[VARYING_SLOT_TESS_MAX])
{
ir_variable *input_var;
= hash_table_ctor(0, hash_table_string_hash, hash_table_string_compare);
hash_table *consumer_interface_inputs
= hash_table_ctor(0, hash_table_string_hash, hash_table_string_compare);
- ir_variable *consumer_inputs_with_locations[VARYING_SLOT_MAX] = {
+ ir_variable *consumer_inputs_with_locations[VARYING_SLOT_TESS_MAX] = {
NULL,
};
VARYING_SLOT_TESS_LEVEL_OUTER, /* Only appears as TCS output. */
VARYING_SLOT_TESS_LEVEL_INNER, /* Only appears as TCS output. */
VARYING_SLOT_VAR0, /* First generic varying slot */
- VARYING_SLOT_MAX = VARYING_SLOT_VAR0 + MAX_VARYING
+ VARYING_SLOT_MAX = VARYING_SLOT_VAR0 + MAX_VARYING,
+ VARYING_SLOT_PATCH0 = VARYING_SLOT_MAX,
+ VARYING_SLOT_TESS_MAX = VARYING_SLOT_PATCH0 + MAX_VARYING
} gl_varying_slot;
GLbitfield64 InputsRead; /**< Bitmask of which input regs are read */
GLbitfield64 DoubleInputsRead; /**< Bitmask of which input regs are read and are doubles */
GLbitfield64 OutputsWritten; /**< Bitmask of which output regs are written */
+ GLbitfield PatchInputsRead; /**< VAR[0..31] usage for patch inputs (user-defined only) */
+ GLbitfield PatchOutputsWritten; /**< VAR[0..31] usage for patch outputs (user-defined only) */
GLbitfield SystemValuesRead; /**< Bitmask of SYSTEM_VALUE_x inputs used */
GLbitfield TexturesUsed[MAX_COMBINED_TEXTURE_IMAGE_UNITS]; /**< TEXTURE_x_BIT bitmask */
GLbitfield SamplersUsed; /**< Bitfield of which samplers are used */