linker: Allow consumer stage or producer stage to be NULL
When linking a separable program that contains only a fragment shader, the producer will be NULL. Similar cases will exist with geometry shaders and, eventually, tessellation shaders. Signed-off-by: Ian Romanick <ian.d.romanick@intel.com> Reviewed-by: Eric Anholt <eric@anholt.net>
This commit is contained in:
@@ -746,7 +746,10 @@ varying_matches::~varying_matches()
|
|||||||
void
|
void
|
||||||
varying_matches::record(ir_variable *producer_var, ir_variable *consumer_var)
|
varying_matches::record(ir_variable *producer_var, ir_variable *consumer_var)
|
||||||
{
|
{
|
||||||
if (!producer_var->data.is_unmatched_generic_inout) {
|
assert(producer_var != NULL || consumer_var != NULL);
|
||||||
|
|
||||||
|
if ((producer_var && !producer_var->data.is_unmatched_generic_inout)
|
||||||
|
|| (consumer_var && !consumer_var->data.is_unmatched_generic_inout)) {
|
||||||
/* Either a location already exists for this variable (since it is part
|
/* Either a location already exists for this variable (since it is part
|
||||||
* of fixed functionality), or it has already been recorded as part of a
|
* of fixed functionality), or it has already been recorded as part of a
|
||||||
* previous match.
|
* previous match.
|
||||||
@@ -781,23 +784,27 @@ varying_matches::record(ir_variable *producer_var, ir_variable *consumer_var)
|
|||||||
realloc(this->matches,
|
realloc(this->matches,
|
||||||
sizeof(*this->matches) * this->matches_capacity);
|
sizeof(*this->matches) * this->matches_capacity);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const ir_variable *const var = (producer_var != NULL)
|
||||||
|
? producer_var : consumer_var;
|
||||||
|
|
||||||
this->matches[this->num_matches].packing_class
|
this->matches[this->num_matches].packing_class
|
||||||
= this->compute_packing_class(producer_var);
|
= this->compute_packing_class(var);
|
||||||
this->matches[this->num_matches].packing_order
|
this->matches[this->num_matches].packing_order
|
||||||
= this->compute_packing_order(producer_var);
|
= this->compute_packing_order(var);
|
||||||
if (this->disable_varying_packing) {
|
if (this->disable_varying_packing) {
|
||||||
unsigned slots = producer_var->type->is_array()
|
unsigned slots = var->type->is_array()
|
||||||
? (producer_var->type->length
|
? (var->type->length * var->type->fields.array->matrix_columns)
|
||||||
* producer_var->type->fields.array->matrix_columns)
|
: var->type->matrix_columns;
|
||||||
: producer_var->type->matrix_columns;
|
|
||||||
this->matches[this->num_matches].num_components = 4 * slots;
|
this->matches[this->num_matches].num_components = 4 * slots;
|
||||||
} else {
|
} else {
|
||||||
this->matches[this->num_matches].num_components
|
this->matches[this->num_matches].num_components
|
||||||
= producer_var->type->component_slots();
|
= var->type->component_slots();
|
||||||
}
|
}
|
||||||
this->matches[this->num_matches].producer_var = producer_var;
|
this->matches[this->num_matches].producer_var = producer_var;
|
||||||
this->matches[this->num_matches].consumer_var = consumer_var;
|
this->matches[this->num_matches].consumer_var = consumer_var;
|
||||||
this->num_matches++;
|
this->num_matches++;
|
||||||
|
if (producer_var)
|
||||||
producer_var->data.is_unmatched_generic_inout = 0;
|
producer_var->data.is_unmatched_generic_inout = 0;
|
||||||
if (consumer_var)
|
if (consumer_var)
|
||||||
consumer_var->data.is_unmatched_generic_inout = 0;
|
consumer_var->data.is_unmatched_generic_inout = 0;
|
||||||
@@ -851,8 +858,11 @@ varying_matches::store_locations() const
|
|||||||
unsigned slot = generic_location / 4;
|
unsigned slot = generic_location / 4;
|
||||||
unsigned offset = generic_location % 4;
|
unsigned offset = generic_location % 4;
|
||||||
|
|
||||||
|
if (producer_var) {
|
||||||
producer_var->data.location = VARYING_SLOT_VAR0 + slot;
|
producer_var->data.location = VARYING_SLOT_VAR0 + slot;
|
||||||
producer_var->data.location_frac = offset;
|
producer_var->data.location_frac = offset;
|
||||||
|
}
|
||||||
|
|
||||||
if (consumer_var) {
|
if (consumer_var) {
|
||||||
assert(consumer_var->data.location == -1);
|
assert(consumer_var->data.location == -1);
|
||||||
consumer_var->data.location = VARYING_SLOT_VAR0 + slot;
|
consumer_var->data.location = VARYING_SLOT_VAR0 + slot;
|
||||||
@@ -1164,10 +1174,13 @@ assign_varying_locations(struct gl_context *ctx,
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (producer) {
|
||||||
foreach_list(node, producer->ir) {
|
foreach_list(node, producer->ir) {
|
||||||
ir_variable *const output_var = ((ir_instruction *) node)->as_variable();
|
ir_variable *const output_var =
|
||||||
|
((ir_instruction *) node)->as_variable();
|
||||||
|
|
||||||
if ((output_var == NULL) || (output_var->data.mode != ir_var_shader_out))
|
if ((output_var == NULL) ||
|
||||||
|
(output_var->data.mode != ir_var_shader_out))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
tfeedback_candidate_generator g(mem_ctx, tfeedback_candidates);
|
tfeedback_candidate_generator g(mem_ctx, tfeedback_candidates);
|
||||||
@@ -1176,10 +1189,16 @@ assign_varying_locations(struct gl_context *ctx,
|
|||||||
ir_variable *const input_var =
|
ir_variable *const input_var =
|
||||||
linker::get_matching_input(mem_ctx, output_var, consumer_inputs,
|
linker::get_matching_input(mem_ctx, output_var, consumer_inputs,
|
||||||
consumer_interface_inputs);
|
consumer_interface_inputs);
|
||||||
if (input_var) {
|
|
||||||
|
/* If a matching input variable was found, add this ouptut (and the
|
||||||
|
* input) to the set. If this is a separable program and there is no
|
||||||
|
* consumer stage, add the output.
|
||||||
|
*/
|
||||||
|
if (input_var || (prog->SeparateShader && consumer == NULL)) {
|
||||||
matches.record(output_var, input_var);
|
matches.record(output_var, input_var);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
for (unsigned i = 0; i < num_tfeedback_decls; ++i) {
|
for (unsigned i = 0; i < num_tfeedback_decls; ++i) {
|
||||||
if (!tfeedback_decls[i].is_varying())
|
if (!tfeedback_decls[i].is_varying())
|
||||||
@@ -1225,15 +1244,17 @@ assign_varying_locations(struct gl_context *ctx,
|
|||||||
*/
|
*/
|
||||||
assert(!ctx->Extensions.EXT_transform_feedback);
|
assert(!ctx->Extensions.EXT_transform_feedback);
|
||||||
} else {
|
} else {
|
||||||
|
if (producer) {
|
||||||
lower_packed_varyings(mem_ctx, slots_used, ir_var_shader_out,
|
lower_packed_varyings(mem_ctx, slots_used, ir_var_shader_out,
|
||||||
0, producer);
|
0, producer);
|
||||||
|
}
|
||||||
if (consumer) {
|
if (consumer) {
|
||||||
lower_packed_varyings(mem_ctx, slots_used, ir_var_shader_in,
|
lower_packed_varyings(mem_ctx, slots_used, ir_var_shader_in,
|
||||||
gs_input_vertices, consumer);
|
gs_input_vertices, consumer);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (consumer) {
|
if (consumer && producer) {
|
||||||
foreach_list(node, consumer->ir) {
|
foreach_list(node, consumer->ir) {
|
||||||
ir_variable *const var = ((ir_instruction *) node)->as_variable();
|
ir_variable *const var = ((ir_instruction *) node)->as_variable();
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user