diff options
Diffstat (limited to 'mesalib/src/glsl/link_varyings.cpp')
-rw-r--r-- | mesalib/src/glsl/link_varyings.cpp | 113 |
1 files changed, 86 insertions, 27 deletions
diff --git a/mesalib/src/glsl/link_varyings.cpp b/mesalib/src/glsl/link_varyings.cpp index 905621daf..4ba6d8a20 100644 --- a/mesalib/src/glsl/link_varyings.cpp +++ b/mesalib/src/glsl/link_varyings.cpp @@ -972,8 +972,8 @@ public: this->toplevel_var = var; this->varying_floats = 0; if (var->is_interface_instance()) - program_resource_visitor::process(var->interface_type, - var->interface_type->name); + program_resource_visitor::process(var->get_interface_type(), + var->get_interface_type()->name); else program_resource_visitor::process(var); } @@ -1083,10 +1083,10 @@ assign_varying_locations(struct gl_context *ctx, ((ir_instruction *) node)->as_variable(); if ((input_var != NULL) && (input_var->mode == ir_var_shader_in)) { - if (input_var->interface_type != NULL) { + if (input_var->get_interface_type() != NULL) { char *const iface_field_name = ralloc_asprintf(mem_ctx, "%s.%s", - input_var->interface_type->name, + input_var->get_interface_type()->name, input_var->name); hash_table_insert(consumer_interface_inputs, input_var, iface_field_name); @@ -1108,10 +1108,10 @@ assign_varying_locations(struct gl_context *ctx, g.process(output_var); ir_variable *input_var; - if (output_var->interface_type != NULL) { + if (output_var->get_interface_type() != NULL) { char *const iface_field_name = ralloc_asprintf(mem_ctx, "%s.%s", - output_var->interface_type->name, + output_var->get_interface_type()->name, output_var->name); input_var = (ir_variable *) hash_table_find(consumer_interface_inputs, @@ -1220,39 +1220,98 @@ assign_varying_locations(struct gl_context *ctx, } bool -check_against_varying_limit(struct gl_context *ctx, - struct gl_shader_program *prog, - gl_shader *consumer) +check_against_output_limit(struct gl_context *ctx, + struct gl_shader_program *prog, + gl_shader *producer) { - unsigned varying_vectors = 0; + unsigned output_vectors = 0; + + foreach_list(node, producer->ir) { + ir_variable *const var = ((ir_instruction *) node)->as_variable(); + + if (var && var->mode == ir_var_shader_out && + is_varying_var(producer->Type, var)) { + output_vectors += var->type->count_attribute_slots(); + } + } + + unsigned max_output_components; + switch (producer->Type) { + case GL_VERTEX_SHADER: + max_output_components = ctx->Const.VertexProgram.MaxOutputComponents; + break; + case GL_GEOMETRY_SHADER: + max_output_components = ctx->Const.GeometryProgram.MaxOutputComponents; + break; + case GL_FRAGMENT_SHADER: + default: + assert(!"Should not get here."); + return false; + } + + const unsigned output_components = output_vectors * 4; + if (output_components > max_output_components) { + if (ctx->API == API_OPENGLES2 || prog->IsES) + linker_error(prog, "shader uses too many output vectors " + "(%u > %u)\n", + output_vectors, + max_output_components / 4); + else + linker_error(prog, "shader uses too many output components " + "(%u > %u)\n", + output_components, + max_output_components); + + return false; + } + + return true; +} + +bool +check_against_input_limit(struct gl_context *ctx, + struct gl_shader_program *prog, + gl_shader *consumer) +{ + unsigned input_vectors = 0; foreach_list(node, consumer->ir) { ir_variable *const var = ((ir_instruction *) node)->as_variable(); if (var && var->mode == ir_var_shader_in && is_varying_var(consumer->Type, var)) { - /* The packing rules used for vertex shader inputs are also - * used for fragment shader inputs. - */ - varying_vectors += var->type->count_attribute_slots(); + input_vectors += var->type->count_attribute_slots(); } } - if (ctx->API == API_OPENGLES2 || prog->IsES) { - if (varying_vectors > ctx->Const.MaxVarying) { - linker_error(prog, "shader uses too many varying vectors " + unsigned max_input_components; + switch (consumer->Type) { + case GL_GEOMETRY_SHADER: + max_input_components = ctx->Const.GeometryProgram.MaxInputComponents; + break; + case GL_FRAGMENT_SHADER: + max_input_components = ctx->Const.FragmentProgram.MaxInputComponents; + break; + case GL_VERTEX_SHADER: + default: + assert(!"Should not get here."); + return false; + } + + const unsigned input_components = input_vectors * 4; + if (input_components > max_input_components) { + if (ctx->API == API_OPENGLES2 || prog->IsES) + linker_error(prog, "shader uses too many input vectors " "(%u > %u)\n", - varying_vectors, ctx->Const.MaxVarying); - return false; - } - } else { - const unsigned float_components = varying_vectors * 4; - if (float_components > ctx->Const.MaxVarying * 4) { - linker_error(prog, "shader uses too many varying components " + input_vectors, + max_input_components / 4); + else + linker_error(prog, "shader uses too many input components " "(%u > %u)\n", - float_components, ctx->Const.MaxVarying * 4); - return false; - } + input_components, + max_input_components); + + return false; } return true; |