diff options
Diffstat (limited to 'src/glsl')
-rw-r--r-- | src/glsl/ir.h | 7 | ||||
-rw-r--r-- | src/glsl/link_uniforms.cpp | 9 | ||||
-rw-r--r-- | src/glsl/link_varyings.cpp | 9 | ||||
-rw-r--r-- | src/glsl/linker.cpp | 75 |
4 files changed, 77 insertions, 23 deletions
diff --git a/src/glsl/ir.h b/src/glsl/ir.h index a728c03..93e0734 100644 --- a/src/glsl/ir.h +++ b/src/glsl/ir.h @@ -1726,7 +1726,12 @@ public: operation == ir_binop_dot || operation == ir_binop_vector_extract || operation == ir_triop_vector_insert || - operation == ir_quadop_vector; + operation == ir_quadop_vector || + /* TODO: these can't currently be vectorized */ + operation == ir_quadop_bitfield_insert || + operation == ir_triop_bitfield_extract || + operation == ir_triop_bfi || + operation == ir_binop_bfm; } /** diff --git a/src/glsl/link_uniforms.cpp b/src/glsl/link_uniforms.cpp index 47bb771..33b2d4c 100644 --- a/src/glsl/link_uniforms.cpp +++ b/src/glsl/link_uniforms.cpp @@ -532,6 +532,8 @@ public: */ if (var->is_interface_instance()) { ubo_byte_offset = 0; + process(var->get_interface_type(), + var->get_interface_type()->name); } else { const struct gl_uniform_block *const block = &prog->BufferInterfaceBlocks[ubo_block_index]; @@ -542,13 +544,8 @@ public: &block->Uniforms[var->data.location]; ubo_byte_offset = ubo_var->Offset; - } - - if (var->is_interface_instance()) - process(var->get_interface_type(), - var->get_interface_type()->name); - else process(var); + } } else { /* Store any explicit location and reset data location so we can * reuse this variable for storing the uniform slot number. diff --git a/src/glsl/link_varyings.cpp b/src/glsl/link_varyings.cpp index 3853abd..7cc5880 100644 --- a/src/glsl/link_varyings.cpp +++ b/src/glsl/link_varyings.cpp @@ -1295,13 +1295,12 @@ public: void process(ir_variable *var) { + /* All named varying interface blocks should be flattened by now */ + assert(!var->is_interface_instance()); + this->toplevel_var = var; this->varying_floats = 0; - if (var->is_interface_instance()) - program_resource_visitor::process(var->get_interface_type(), - var->get_interface_type()->name); - else - program_resource_visitor::process(var); + program_resource_visitor::process(var); } private: diff --git a/src/glsl/linker.cpp b/src/glsl/linker.cpp index 418bd09..eb1bdc0 100644 --- a/src/glsl/linker.cpp +++ b/src/glsl/linker.cpp @@ -3130,6 +3130,7 @@ check_explicit_uniform_locations(struct gl_context *ctx, return; } + unsigned entries_total = 0; for (unsigned i = 0; i < MESA_SHADER_STAGES; i++) { struct gl_shader *sh = prog->_LinkedShaders[i]; @@ -3138,8 +3139,12 @@ check_explicit_uniform_locations(struct gl_context *ctx, foreach_in_list(ir_instruction, node, sh->ir) { ir_variable *var = node->as_variable(); - if (var && (var->data.mode == ir_var_uniform && - var->data.explicit_location)) { + if (!var || var->data.mode != ir_var_uniform) + continue; + + entries_total += var->type->uniform_locations(); + + if (var->data.explicit_location) { bool ret; if (var->type->is_subroutine()) ret = reserve_subroutine_explicit_locations(prog, sh, var); @@ -3153,6 +3158,14 @@ check_explicit_uniform_locations(struct gl_context *ctx, } } + /* Verify that total amount of entries for explicit and implicit locations + * is less than MAX_UNIFORM_LOCATIONS. + */ + if (entries_total >= ctx->Const.MaxUserAssignableUniformLocations) { + linker_error(prog, "count of uniform locations >= MAX_UNIFORM_LOCATIONS" + "(%u >= %u)", entries_total, + ctx->Const.MaxUserAssignableUniformLocations); + } delete uniform_map; } @@ -3349,6 +3362,30 @@ build_stageref(struct gl_shader_program *shProg, const char *name, return stages; } +/** + * Create gl_shader_variable from ir_variable class. + */ +static gl_shader_variable * +create_shader_variable(struct gl_shader_program *shProg, const ir_variable *in) +{ + gl_shader_variable *out = ralloc(shProg, struct gl_shader_variable); + if (!out) + return NULL; + + out->type = in->type; + out->name = ralloc_strdup(shProg, in->name); + + if (!out->name) + return NULL; + + out->location = in->data.location; + out->index = in->data.index; + out->patch = in->data.patch; + out->mode = in->data.mode; + + return out; +} + static bool add_interface_variables(struct gl_shader_program *shProg, exec_list *ir, GLenum programInterface) @@ -3400,9 +3437,13 @@ add_interface_variables(struct gl_shader_program *shProg, if (strncmp(var->name, "gl_out_FragData", 15) == 0) continue; - if (!add_program_resource(shProg, programInterface, var, - build_stageref(shProg, var->name, - var->data.mode) | mask)) + gl_shader_variable *sha_v = create_shader_variable(shProg, var); + if (!sha_v) + return false; + + if (!add_program_resource(shProg, programInterface, sha_v, + build_stageref(shProg, sha_v->name, + sha_v->mode) | mask)) return false; } return true; @@ -3432,9 +3473,12 @@ add_packed_varyings(struct gl_shader_program *shProg, int stage, GLenum type) } if (type == iface) { - if (!add_program_resource(shProg, iface, var, - build_stageref(shProg, var->name, - var->data.mode))) + gl_shader_variable *sha_v = create_shader_variable(shProg, var); + if (!sha_v) + return false; + if (!add_program_resource(shProg, iface, sha_v, + build_stageref(shProg, sha_v->name, + sha_v->mode))) return false; } } @@ -3454,7 +3498,10 @@ add_fragdata_arrays(struct gl_shader_program *shProg) ir_variable *var = node->as_variable(); if (var) { assert(var->data.mode == ir_var_shader_out); - if (!add_program_resource(shProg, GL_PROGRAM_OUTPUT, var, + gl_shader_variable *sha_v = create_shader_variable(shProg, var); + if (!sha_v) + return false; + if (!add_program_resource(shProg, GL_PROGRAM_OUTPUT, sha_v, 1 << MESA_SHADER_FRAGMENT)) return false; } @@ -3705,8 +3752,14 @@ build_program_resource_list(struct gl_shader_program *shProg) if (shProg->SeparateShader) { if (!add_packed_varyings(shProg, input_stage, GL_PROGRAM_INPUT)) return; - if (!add_packed_varyings(shProg, output_stage, GL_PROGRAM_OUTPUT)) - return; + + /* Only when dealing with multiple stages, otherwise we would have + * duplicate gl_shader_variable entries. + */ + if (input_stage != output_stage) { + if (!add_packed_varyings(shProg, output_stage, GL_PROGRAM_OUTPUT)) + return; + } } if (!add_fragdata_arrays(shProg)) |