From 0af240e9401c12f4237f4a36a2474fe2cc590404 Mon Sep 17 00:00:00 2001 From: =?utf8?q?Marek=20Ol=C5=A1=C3=A1k?= Date: Sat, 13 Jun 2015 13:50:12 +0200 Subject: [PATCH] glsl: use separate varying slots for patch varyings The idea is to allow 32 normal varyings and 32 patch varyings, a total of 64. Previously, only a total of 32 was allowed. Reviewed-by: Kenneth Graunke --- src/glsl/ast_to_hir.cpp | 5 ++++- src/glsl/ir_set_program_inouts.cpp | 27 ++++++++++++++++++++++++--- src/glsl/link_varyings.cpp | 23 ++++++++++++++++------- src/mesa/main/mtypes.h | 6 +++++- 4 files changed, 49 insertions(+), 12 deletions(-) diff --git a/src/glsl/ast_to_hir.cpp b/src/glsl/ast_to_hir.cpp index 1cc0731e932..a45b6e8f026 100644 --- a/src/glsl/ast_to_hir.cpp +++ b/src/glsl/ast_to_hir.cpp @@ -2367,7 +2367,10 @@ validate_explicit_location(const struct ast_type_qualifier *qual, 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: diff --git a/src/glsl/ir_set_program_inouts.cpp b/src/glsl/ir_set_program_inouts.cpp index fe4d6da45db..b7a0f6e95ba 100644 --- a/src/glsl/ir_set_program_inouts.cpp +++ b/src/glsl/ir_set_program_inouts.cpp @@ -103,10 +103,26 @@ mark(struct gl_program *prog, ir_variable *var, int offset, int len, 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) { @@ -122,7 +138,10 @@ mark(struct gl_program *prog, ir_variable *var, int offset, int len, 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; } } } @@ -406,6 +425,8 @@ do_set_program_inouts(exec_list *instructions, struct gl_program *prog, 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; diff --git a/src/glsl/link_varyings.cpp b/src/glsl/link_varyings.cpp index 1104872ca3c..1c52ff35f44 100644 --- a/src/glsl/link_varyings.cpp +++ b/src/glsl/link_varyings.cpp @@ -985,8 +985,17 @@ varying_matches::assign_locations() &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. @@ -994,12 +1003,12 @@ varying_matches::assign_locations() 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; @@ -1213,11 +1222,11 @@ bool 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(); @@ -1273,7 +1282,7 @@ get_matching_input(void *mem_ctx, 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; @@ -1414,7 +1423,7 @@ assign_varying_locations(struct gl_context *ctx, = 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, }; diff --git a/src/mesa/main/mtypes.h b/src/mesa/main/mtypes.h index 85e04b5f18b..b13271bbd06 100644 --- a/src/mesa/main/mtypes.h +++ b/src/mesa/main/mtypes.h @@ -243,7 +243,9 @@ typedef enum 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; @@ -2103,6 +2105,8 @@ struct gl_program 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 */ -- 2.30.2