diff options
Diffstat (limited to 'mesalib/src')
32 files changed, 756 insertions, 301 deletions
diff --git a/mesalib/src/gallium/Automake.inc b/mesalib/src/gallium/Automake.inc index fabc2af9a..b6b9b367a 100644 --- a/mesalib/src/gallium/Automake.inc +++ b/mesalib/src/gallium/Automake.inc @@ -3,3 +3,90 @@ GALLIUM_CFLAGS = \ -I$(top_srcdir)/src/gallium/include \ -I$(top_srcdir)/src/gallium/auxiliary \ $(DEFINES) + +# src/gallium/auxiliary must appear before src/gallium/drivers +# because there are stupidly two rbug_context.h files in +# different directories, and which one is included by the +# preprocessor is determined by the ordering of the -I flags. +GALLIUM_DRIVER_CFLAGS = \ + -I$(srcdir)/include \ + -I$(top_srcdir)/include \ + -I$(top_srcdir)/src/gallium/include \ + -I$(top_srcdir)/src/gallium/auxiliary \ + -I$(top_srcdir)/src/gallium/drivers \ + $(DEFINES) \ + $(VISIBILITY_CFLAGS) + +GALLIUM_DRIVER_CXXFLAGS = \ + -I$(srcdir)/include \ + -I$(top_srcdir)/include \ + -I$(top_srcdir)/src/gallium/include \ + -I$(top_srcdir)/src/gallium/auxiliary \ + -I$(top_srcdir)/src/gallium/drivers \ + $(DEFINES) \ + $(VISIBILITY_CXXFLAGS) + +GALLIUM_DRI_CFLAGS = \ + -I$(top_srcdir)/include \ + -I$(top_srcdir)/src/gallium/include \ + -I$(top_srcdir)/src/gallium/auxiliary \ + -I$(top_srcdir)/src/gallium/drivers \ + -I$(top_srcdir)/src/gallium/winsys \ + -I$(top_srcdir)/src/mesa \ + -I$(top_srcdir)/src/mapi \ + $(DEFINES) \ + $(PTHREAD_CFLAGS) \ + $(LIBDRM_CFLAGS) \ + $(VISIBILITY_CFLAGS) + +GALLIUM_VIDEO_CFLAGS = \ + -I$(top_srcdir)/include \ + -I$(top_srcdir)/src/gallium/include \ + -I$(top_srcdir)/src/gallium/auxiliary \ + -I$(top_srcdir)/src/gallium/drivers \ + -I$(top_srcdir)/src/gallium/winsys \ + $(DEFINES) \ + $(PTHREAD_CFLAGS) \ + $(LIBDRM_CFLAGS) \ + $(VISIBILITY_CFLAGS) + + +# TODO: add -export-symbols-regex +GALLIUM_DRI_LINKER_FLAGS = \ + -module \ + -avoid-version \ + -shared \ + -Wl,-Bsymbolic + +GALLIUM_VDPAU_LINKER_FLAGS = \ + -module \ + -version-number $(VDPAU_MAJOR):$(VDPAU_MINOR) \ + -export-symbols-regex $(VDPAU_EXPORTS) \ + -shared \ + -no-undefined + +# TODO: add -export-symbols-regex +GALLIUM_XVMC_LINKER_FLAGS = \ + -module \ + -version-number $(XVMC_MAJOR):$(XVMC_MINOR) \ + -shared \ + -no-undefined + +GALLIUM_VDPAU_LIB_DEPS = \ + $(top_builddir)/src/gallium/auxiliary/libgallium.la \ + $(top_builddir)/src/gallium/state_trackers/vdpau/libvdpautracker.la \ + $(VDPAU_LIBS) \ + $(LIBDRM_LIBS) + +GALLIUM_XVMC_LIB_DEPS = \ + $(top_builddir)/src/gallium/auxiliary/libgallium.la \ + $(top_builddir)/src/gallium/state_trackers/xvmc/libxvmctracker.la \ + $(XVMC_LIBS) \ + $(LIBDRM_LIBS) + +GALLIUM_WINSYS_CFLAGS = \ + -I$(top_srcdir)/include \ + -I$(top_srcdir)/src/gallium/include \ + -I$(top_srcdir)/src/gallium/auxiliary \ + $(DEFINES) \ + $(VISIBILITY_CFLAGS) diff --git a/mesalib/src/gallium/SConscript b/mesalib/src/gallium/SConscript index c68519df0..6e27be2c0 100644 --- a/mesalib/src/gallium/SConscript +++ b/mesalib/src/gallium/SConscript @@ -124,7 +124,6 @@ if not env['embedded']: if env['dri']: SConscript([ - 'targets/SConscript.dri', 'targets/dri-swrast/SConscript', 'targets/dri-vmwgfx/SConscript', ]) diff --git a/mesalib/src/glsl/Makefile.sources b/mesalib/src/glsl/Makefile.sources index 744b0adcf..2e81dedda 100644 --- a/mesalib/src/glsl/Makefile.sources +++ b/mesalib/src/glsl/Makefile.sources @@ -33,6 +33,7 @@ LIBGLSL_FILES = \ $(GLSL_SRCDIR)/ir_clone.cpp \ $(GLSL_SRCDIR)/ir_constant_expression.cpp \ $(GLSL_SRCDIR)/ir.cpp \ + $(GLSL_SRCDIR)/ir_equals.cpp \ $(GLSL_SRCDIR)/ir_expression_flattening.cpp \ $(GLSL_SRCDIR)/ir_function_can_inline.cpp \ $(GLSL_SRCDIR)/ir_function_detect_recursion.cpp \ diff --git a/mesalib/src/glsl/glsl_parser_extras.cpp b/mesalib/src/glsl/glsl_parser_extras.cpp index d922db9db..f401f03bc 100644 --- a/mesalib/src/glsl/glsl_parser_extras.cpp +++ b/mesalib/src/glsl/glsl_parser_extras.cpp @@ -1529,7 +1529,6 @@ _mesa_glsl_compile_shader(struct gl_context *ctx, struct gl_shader *shader, shader->CompileStatus = !state->error; shader->InfoLog = state->info_log; shader->Version = state->language_version; - shader->InfoLog = state->info_log; shader->IsES = state->es_shader; memcpy(shader->builtins_to_link, state->builtins_to_link, diff --git a/mesalib/src/glsl/ir.h b/mesalib/src/glsl/ir.h index 2f06fb9ea..7859702ed 100644 --- a/mesalib/src/glsl/ir.h +++ b/mesalib/src/glsl/ir.h @@ -139,6 +139,16 @@ public: virtual class ir_jump * as_jump() { return NULL; } /*@}*/ + /** + * IR equality method: Return true if the referenced instruction would + * return the same value as this one. + * + * This intended to be used for CSE and algebraic optimizations, on rvalues + * in particular. No support for other instruction types (assignments, + * jumps, calls, etc.) is planned. + */ + virtual bool equals(ir_instruction *ir); + protected: ir_instruction() { @@ -1405,6 +1415,8 @@ public: return this; } + virtual bool equals(ir_instruction *ir); + virtual ir_expression *clone(void *mem_ctx, struct hash_table *ht) const; /** @@ -1739,6 +1751,8 @@ public: virtual ir_visitor_status accept(ir_hierarchical_visitor *); + virtual bool equals(ir_instruction *ir); + /** * Return a string representing the ir_texture_opcode. */ @@ -1843,6 +1857,8 @@ public: virtual ir_visitor_status accept(ir_hierarchical_visitor *); + virtual bool equals(ir_instruction *ir); + bool is_lvalue() const { return val->is_lvalue() && !mask.has_duplicates; @@ -1907,6 +1923,8 @@ public: return this; } + virtual bool equals(ir_instruction *ir); + /** * Get the variable that is ultimately referenced by an r-value */ @@ -1965,6 +1983,8 @@ public: return this; } + virtual bool equals(ir_instruction *ir); + /** * Get the variable that is ultimately referenced by an r-value */ @@ -2099,6 +2119,8 @@ public: virtual ir_visitor_status accept(ir_hierarchical_visitor *); + virtual bool equals(ir_instruction *ir); + /** * Get a particular component of a constant as a specific type * diff --git a/mesalib/src/glsl/ir_equals.cpp b/mesalib/src/glsl/ir_equals.cpp new file mode 100644 index 000000000..7cfe1e66b --- /dev/null +++ b/mesalib/src/glsl/ir_equals.cpp @@ -0,0 +1,198 @@ +/* + * Copyright © 2013 Intel Corporation + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the next + * paragraph) shall be included in all copies or substantial portions of the + * Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ + +#include "ir.h" + +/** + * Helper for checking equality when one instruction might be NULL, since you + * can't access a's vtable in that case. + */ +static bool +possibly_null_equals(ir_instruction *a, ir_instruction *b) +{ + if (!a || !b) + return !a && !b; + + return a->equals(b); +} + +/** + * The base equality function: Return not equal for anything we don't know + * about. + */ +bool +ir_instruction::equals(ir_instruction *ir) +{ + return false; +} + +bool +ir_constant::equals(ir_instruction *ir) +{ + const ir_constant *other = ir->as_constant(); + if (!other) + return false; + + if (type != other->type) + return false; + + for (unsigned i = 0; i < type->components(); i++) { + if (value.u[i] != other->value.u[i]) + return false; + } + + return true; +} + +bool +ir_dereference_variable::equals(ir_instruction *ir) +{ + const ir_dereference_variable *other = ir->as_dereference_variable(); + if (!other) + return false; + + return var == other->var; +} + +bool +ir_dereference_array::equals(ir_instruction *ir) +{ + const ir_dereference_array *other = ir->as_dereference_array(); + if (!other) + return false; + + if (type != other->type) + return false; + + if (!array->equals(other->array)) + return false; + + if (!array_index->equals(other->array_index)) + return false; + + return true; +} + +bool +ir_swizzle::equals(ir_instruction *ir) +{ + const ir_swizzle *other = ir->as_swizzle(); + if (!other) + return false; + + if (type != other->type) + return false; + + if (mask.x != other->mask.x || + mask.y != other->mask.y || + mask.z != other->mask.z || + mask.w != other->mask.w) { + return false; + } + + return val->equals(other->val); +} + +bool +ir_texture::equals(ir_instruction *ir) +{ + const ir_texture *other = ir->as_texture(); + if (!other) + return false; + + if (type != other->type) + return false; + + if (op != other->op) + return false; + + if (!possibly_null_equals(coordinate, other->coordinate)) + return false; + + if (!possibly_null_equals(projector, other->projector)) + return false; + + if (!possibly_null_equals(shadow_comparitor, other->shadow_comparitor)) + return false; + + if (!possibly_null_equals(offset, other->offset)) + return false; + + if (!sampler->equals(other->sampler)) + return false; + + switch (op) { + case ir_tex: + case ir_lod: + case ir_query_levels: + break; + case ir_txb: + if (!lod_info.bias->equals(other->lod_info.bias)) + return false; + break; + case ir_txl: + case ir_txf: + case ir_txs: + if (!lod_info.lod->equals(other->lod_info.lod)) + return false; + break; + case ir_txd: + if (!lod_info.grad.dPdx->equals(other->lod_info.grad.dPdx) || + !lod_info.grad.dPdy->equals(other->lod_info.grad.dPdy)) + return false; + break; + case ir_txf_ms: + if (!lod_info.sample_index->equals(other->lod_info.sample_index)) + return false; + break; + case ir_tg4: + if (!lod_info.component->equals(other->lod_info.component)) + return false; + break; + default: + assert(!"Unrecognized texture op"); + } + + return true; +} + +bool +ir_expression::equals(ir_instruction *ir) +{ + const ir_expression *other = ir->as_expression(); + if (!other) + return false; + + if (type != other->type) + return false; + + if (operation != other->operation) + return false; + + for (unsigned i = 0; i < get_num_operands(); i++) { + if (!operands[i]->equals(other->operands[i])) + return false; + } + + return true; +} diff --git a/mesalib/src/glsl/link_interface_blocks.cpp b/mesalib/src/glsl/link_interface_blocks.cpp index 4f1c9d396..a7fceb9ba 100644 --- a/mesalib/src/glsl/link_interface_blocks.cpp +++ b/mesalib/src/glsl/link_interface_blocks.cpp @@ -30,13 +30,211 @@ #include "glsl_symbol_table.h" #include "linker.h" #include "main/macros.h" +#include "program/hash_table.h" + + +namespace { + +/** + * Information about a single interface block definition that we need to keep + * track of in order to check linkage rules. + * + * Note: this class is expected to be short lived, so it doesn't make copies + * of the strings it references; it simply borrows the pointers from the + * ir_variable class. + */ +struct interface_block_definition +{ + /** + * Extract an interface block definition from an ir_variable that + * represents either the interface instance (for named interfaces), or a + * member of the interface (for unnamed interfaces). + */ + explicit interface_block_definition(const ir_variable *var) + : type(var->get_interface_type()), + instance_name(NULL), + array_size(-1) + { + if (var->is_interface_instance()) { + instance_name = var->name; + if (var->type->is_array()) + array_size = var->type->length; + } + } + + /** + * Interface block type + */ + const glsl_type *type; + + /** + * For a named interface block, the instance name. Otherwise NULL. + */ + const char *instance_name; + + /** + * For an interface block array, the array size (or 0 if unsized). + * Otherwise -1. + */ + int array_size; +}; + + +/** + * Check if two interfaces match, according to intrastage interface matching + * rules. If they do, and the first interface uses an unsized array, it will + * be updated to reflect the array size declared in the second interface. + */ +bool +intrastage_match(interface_block_definition *a, + const interface_block_definition *b, + ir_variable_mode mode) +{ + /* Types must match. */ + if (a->type != b->type) + return false; + + /* Presence/absence of interface names must match. */ + if ((a->instance_name == NULL) != (b->instance_name == NULL)) + return false; + + /* For uniforms, instance names need not match. For shader ins/outs, + * it's not clear from the spec whether they need to match, but + * Mesa's implementation relies on them matching. + */ + if (a->instance_name != NULL && mode != ir_var_uniform && + strcmp(a->instance_name, b->instance_name) != 0) { + return false; + } + + /* Array vs. nonarray must be consistent, and sizes must be + * consistent, with the exception that unsized arrays match sized + * arrays. + */ + if ((a->array_size == -1) != (b->array_size == -1)) + return false; + if (b->array_size != 0) { + if (a->array_size == 0) + a->array_size = b->array_size; + else if (a->array_size != b->array_size) + return false; + } + + return true; +} + + +/** + * Check if two interfaces match, according to interstage (in/out) interface + * matching rules. + * + * If \c extra_array_level is true, then vertex-to-geometry shader matching + * rules are enforced (i.e. a successful match requires the consumer interface + * to be an array and the producer interface to be a non-array). + */ +bool +interstage_match(const interface_block_definition *producer, + const interface_block_definition *consumer, + bool extra_array_level) +{ + /* Unsized arrays should not occur during interstage linking. They + * should have all been assigned a size by link_intrastage_shaders. + */ + assert(consumer->array_size != 0); + assert(producer->array_size != 0); + + /* Types must match. */ + if (consumer->type != producer->type) + return false; + if (extra_array_level) { + /* Consumer must be an array, and producer must not. */ + if (consumer->array_size == -1) + return false; + if (producer->array_size != -1) + return false; + } else { + /* Array vs. nonarray must be consistent, and sizes must be consistent. + * Since unsized arrays have been ruled out, we can check this by just + * making sure the sizes are equal. + */ + if (consumer->array_size != producer->array_size) + return false; + } + return true; +} + + +/** + * This class keeps track of a mapping from an interface block name to the + * necessary information about that interface block to determine whether to + * generate a link error. + * + * Note: this class is expected to be short lived, so it doesn't make copies + * of the strings it references; it simply borrows the pointers from the + * ir_variable class. + */ +class interface_block_definitions +{ +public: + interface_block_definitions() + : mem_ctx(ralloc_context(NULL)), + ht(hash_table_ctor(0, hash_table_string_hash, + hash_table_string_compare)) + { + } + + ~interface_block_definitions() + { + hash_table_dtor(ht); + ralloc_free(mem_ctx); + } + + /** + * Lookup the interface definition having the given block name. Return + * NULL if none is found. + */ + interface_block_definition *lookup(const char *block_name) + { + return (interface_block_definition *) hash_table_find(ht, block_name); + } + + /** + * Add a new interface definition. + */ + void store(const interface_block_definition &def) + { + interface_block_definition *hash_entry = + rzalloc(mem_ctx, interface_block_definition); + *hash_entry = def; + hash_table_insert(ht, hash_entry, def.type->name); + } + +private: + /** + * Ralloc context for data structures allocated by this class. + */ + void *mem_ctx; + + /** + * Hash table mapping interface block name to an \c + * interface_block_definition struct. interface_block_definition structs + * are allocated using \c mem_ctx. + */ + hash_table *ht; +}; + + +}; /* anonymous namespace */ + void validate_intrastage_interface_blocks(struct gl_shader_program *prog, const gl_shader **shader_list, unsigned num_shaders) { - glsl_symbol_table interfaces; + interface_block_definitions in_interfaces; + interface_block_definitions out_interfaces; + interface_block_definitions uniform_interfaces; for (unsigned int i = 0; i < num_shaders; i++) { if (shader_list[i] == NULL) @@ -52,17 +250,36 @@ validate_intrastage_interface_blocks(struct gl_shader_program *prog, if (iface_type == NULL) continue; - const glsl_type *old_iface_type = - interfaces.get_interface(iface_type->name, - (enum ir_variable_mode) var->mode); + interface_block_definitions *definitions; + switch (var->mode) { + case ir_var_shader_in: + definitions = &in_interfaces; + break; + case ir_var_shader_out: + definitions = &out_interfaces; + break; + case ir_var_uniform: + definitions = &uniform_interfaces; + break; + default: + /* Only in, out, and uniform interfaces are legal, so we should + * never get here. + */ + assert(!"illegal interface type"); + continue; + } - if (old_iface_type == NULL) { + const interface_block_definition def(var); + interface_block_definition *prev_def = + definitions->lookup(iface_type->name); + + if (prev_def == NULL) { /* This is the first time we've seen the interface, so save - * it into our symbol table. + * it into the appropriate data structure. */ - interfaces.add_interface(iface_type->name, iface_type, - (enum ir_variable_mode) var->mode); - } else if (old_iface_type != iface_type) { + definitions->store(def); + } else if (!intrastage_match(prev_def, &def, + (ir_variable_mode) var->mode)) { linker_error(prog, "definitions of interface block `%s' do not" " match\n", iface_type->name); return; @@ -76,7 +293,9 @@ validate_interstage_interface_blocks(struct gl_shader_program *prog, const gl_shader *producer, const gl_shader *consumer) { - glsl_symbol_table interfaces; + interface_block_definitions inout_interfaces; + interface_block_definitions uniform_interfaces; + const bool extra_array_level = consumer->Type == GL_GEOMETRY_SHADER; /* Add non-output interfaces from the consumer to the symbol table. */ foreach_list(node, consumer->ir) { @@ -84,9 +303,9 @@ validate_interstage_interface_blocks(struct gl_shader_program *prog, if (!var || !var->get_interface_type() || var->mode == ir_var_shader_out) continue; - interfaces.add_interface(var->get_interface_type()->name, - var->get_interface_type(), - (enum ir_variable_mode) var->mode); + interface_block_definitions *definitions = var->mode == ir_var_uniform ? + &uniform_interfaces : &inout_interfaces; + definitions->store(interface_block_definition(var)); } /* Verify that the producer's interfaces match. */ @@ -95,17 +314,29 @@ validate_interstage_interface_blocks(struct gl_shader_program *prog, if (!var || !var->get_interface_type() || var->mode == ir_var_shader_in) continue; - enum ir_variable_mode consumer_mode = - var->mode == ir_var_uniform ? ir_var_uniform : ir_var_shader_in; - const glsl_type *expected_type = - interfaces.get_interface(var->get_interface_type()->name, - consumer_mode); + interface_block_definitions *definitions = var->mode == ir_var_uniform ? + &uniform_interfaces : &inout_interfaces; + interface_block_definition *consumer_def = + definitions->lookup(var->get_interface_type()->name); /* The consumer doesn't use this output block. Ignore it. */ - if (expected_type == NULL) + if (consumer_def == NULL) continue; - if (var->get_interface_type() != expected_type) { + const interface_block_definition producer_def(var); + bool match; + if (var->mode == ir_var_uniform) { + /* Uniform matching rules are the same for interstage and intrastage + * linking. + */ + match = intrastage_match(consumer_def, &producer_def, + (ir_variable_mode) var->mode); + } else { + match = interstage_match(&producer_def, consumer_def, + extra_array_level); + } + + if (!match) { linker_error(prog, "definitions of interface block `%s' do not " "match\n", var->get_interface_type()->name); return; diff --git a/mesalib/src/glsl/opt_algebraic.cpp b/mesalib/src/glsl/opt_algebraic.cpp index a07e153ae..05a589989 100644 --- a/mesalib/src/glsl/opt_algebraic.cpp +++ b/mesalib/src/glsl/opt_algebraic.cpp @@ -357,7 +357,6 @@ ir_algebraic_visitor::handle_expression(ir_expression *ir) break; case ir_binop_logic_and: - /* FINISHME: Also simplify (a && a) to (a). */ if (is_vec_one(op_const[0])) { return ir->operands[1]; } else if (is_vec_one(op_const[1])) { @@ -371,11 +370,13 @@ ir_algebraic_visitor::handle_expression(ir_expression *ir) */ return logic_not(logic_or(op_expr[0]->operands[0], op_expr[1]->operands[0])); + } else if (ir->operands[0]->equals(ir->operands[1])) { + /* (a && a) == a */ + return ir->operands[0]; } break; case ir_binop_logic_xor: - /* FINISHME: Also simplify (a ^^ a) to (false). */ if (is_vec_zero(op_const[0])) { return ir->operands[1]; } else if (is_vec_zero(op_const[1])) { @@ -384,11 +385,13 @@ ir_algebraic_visitor::handle_expression(ir_expression *ir) return logic_not(ir->operands[1]); } else if (is_vec_one(op_const[1])) { return logic_not(ir->operands[0]); + } else if (ir->operands[0]->equals(ir->operands[1])) { + /* (a ^^ a) == false */ + return ir_constant::zero(mem_ctx, ir->type); } break; case ir_binop_logic_or: - /* FINISHME: Also simplify (a || a) to (a). */ if (is_vec_zero(op_const[0])) { return ir->operands[1]; } else if (is_vec_zero(op_const[1])) { @@ -407,6 +410,9 @@ ir_algebraic_visitor::handle_expression(ir_expression *ir) */ return logic_not(logic_and(op_expr[0]->operands[0], op_expr[1]->operands[0])); + } else if (ir->operands[0]->equals(ir->operands[1])) { + /* (a || a) == a */ + return ir->operands[0]; } break; @@ -414,10 +420,11 @@ ir_algebraic_visitor::handle_expression(ir_expression *ir) if (op_expr[0] && op_expr[0]->operation == ir_unop_rcp) return op_expr[0]->operands[0]; - /* FINISHME: We should do rcp(rsq(x)) -> sqrt(x) for some - * backends, except that some backends will have done sqrt -> - * rcp(rsq(x)) and we don't want to undo it for them. + /* While ir_to_mesa.cpp will lower sqrt(x) to rcp(rsq(x)), it does so at + * its IR level, so we can always apply this transformation. */ + if (op_expr[0] && op_expr[0]->operation == ir_unop_rsq) + return sqrt(op_expr[0]->operands[0]); /* As far as we know, all backends are OK with rsq. */ if (op_expr[0] && op_expr[0]->operation == ir_unop_sqrt) { diff --git a/mesalib/src/glsl/opt_cse.cpp b/mesalib/src/glsl/opt_cse.cpp index c53b4c6e7..8f73940d8 100644 --- a/mesalib/src/glsl/opt_cse.cpp +++ b/mesalib/src/glsl/opt_cse.cpp @@ -243,184 +243,6 @@ is_cse_candidate(ir_rvalue *ir) return v.ok; } -static bool -equals(ir_rvalue *a, ir_rvalue *b); - -static bool -equals(ir_constant *a, ir_constant *b) -{ - if (!a || !b) - return false; - - if (a->type != b->type) - return false; - - for (unsigned i = 0; i < a->type->components(); i++) { - if (a->value.u[i] != b->value.u[i]) - return false; - } - - return true; -} - -static bool -equals(ir_dereference_variable *a, ir_dereference_variable *b) -{ - if (!a || !b) - return false; - - return a->var == b->var; -} - -static bool -equals(ir_dereference_array *a, ir_dereference_array *b) -{ - if (!a || !b) - return false; - - if (!equals(a->array, b->array)) - return false; - - if (!equals(a->array_index, b->array_index)) - return false; - - return true; -} - -static bool -equals(ir_swizzle *a, ir_swizzle *b) -{ - if (!a || !b) - return false; - - if (a->type != b->type) - return false; - - if (a->mask.x != b->mask.x || - a->mask.y != b->mask.y || - a->mask.z != b->mask.z || - a->mask.w != b->mask.w) { - return false; - } - - return equals(a->val, b->val); -} - -static bool -equals(ir_texture *a, ir_texture *b) -{ - if (!a || !b) - return false; - - if (a->type != b->type) - return false; - - if (a->op != b->op) - return false; - - if (!equals(a->coordinate, b->coordinate)) - return false; - - if (!equals(a->projector, b->projector)) - return false; - - if (!equals(a->shadow_comparitor, b->shadow_comparitor)) - return false; - - if (!equals(a->offset, b->offset)) - return false; - - if (!equals(a->sampler, b->sampler)) - return false; - - switch (a->op) { - case ir_tex: - case ir_lod: - case ir_query_levels: - break; - case ir_txb: - if (!equals(a->lod_info.bias, b->lod_info.bias)) - return false; - break; - case ir_txl: - case ir_txf: - case ir_txs: - if (!equals(a->lod_info.lod, b->lod_info.lod)) - return false; - break; - case ir_txd: - if (!equals(a->lod_info.grad.dPdx, b->lod_info.grad.dPdx) || - !equals(a->lod_info.grad.dPdy, b->lod_info.grad.dPdy)) - return false; - break; - case ir_txf_ms: - if (!equals(a->lod_info.sample_index, b->lod_info.sample_index)) - return false; - break; - case ir_tg4: - if (!equals(a->lod_info.component, b->lod_info.component)) - return false; - break; - default: - assert(!"Unrecognized texture op"); - } - - return true; -} - -static bool -equals(ir_expression *a, ir_expression *b) -{ - if (!a || !b) - return false; - - if (a->type != b->type) - return false; - - if (a->operation != b->operation) - return false; - - for (unsigned i = 0; i < a->get_num_operands(); i++) { - if (!equals(a->operands[i], b->operands[i])) - return false; - } - - return true; -} - -static bool -equals(ir_rvalue *a, ir_rvalue *b) -{ - if (!a || !b) - return !a && !b; - - if (a->type != b->type) - return false; - - switch (a->ir_type) { - case ir_type_texture: - return equals(a->as_texture(), b->as_texture()); - - case ir_type_constant: - return equals(a->as_constant(), b->as_constant()); - - case ir_type_expression: - return equals(a->as_expression(), b->as_expression()); - - case ir_type_dereference_variable: - return equals(a->as_dereference_variable(), b->as_dereference_variable()); - - case ir_type_dereference_array: - return equals(a->as_dereference_array(), b->as_dereference_array()); - - case ir_type_swizzle: - return equals(a->as_swizzle(), b->as_swizzle()); - - default: - return false; - } -} - /** * Tries to find and return a reference to a previous computation of a given * expression. @@ -441,7 +263,7 @@ cse_visitor::try_cse(ir_rvalue *rvalue) printf("\n"); } - if (!equals(rvalue, *entry->val)) + if (!rvalue->equals(*entry->val)) continue; if (debug) { diff --git a/mesalib/src/mesa/Android.libmesa_dricore.mk b/mesalib/src/mesa/Android.libmesa_dricore.mk index 3679b50ba..0db5825de 100644 --- a/mesalib/src/mesa/Android.libmesa_dricore.mk +++ b/mesalib/src/mesa/Android.libmesa_dricore.mk @@ -38,8 +38,6 @@ include $(CLEAR_VARS) LOCAL_MODULE := libmesa_dricore LOCAL_MODULE_CLASS := STATIC_LIBRARIES -MESA_ENABLED_APIS := ES1 ES2 GL - LOCAL_SRC_FILES := \ $(MESA_FILES) diff --git a/mesalib/src/mesa/Android.libmesa_st_mesa.mk b/mesalib/src/mesa/Android.libmesa_st_mesa.mk index e7203c41d..e6374a6d8 100644 --- a/mesalib/src/mesa/Android.libmesa_st_mesa.mk +++ b/mesalib/src/mesa/Android.libmesa_st_mesa.mk @@ -37,8 +37,6 @@ include $(CLEAR_VARS) LOCAL_MODULE := libmesa_st_mesa -MESA_ENABLED_APIS := ES1 ES2 - LOCAL_SRC_FILES := \ $(MESA_GALLIUM_FILES) diff --git a/mesalib/src/mesa/SConscript b/mesalib/src/mesa/SConscript index 42134983c..a2bb9f131 100644 --- a/mesalib/src/mesa/SConscript +++ b/mesalib/src/mesa/SConscript @@ -18,9 +18,6 @@ env.Append(CPPPATH = [ Dir('.'), # src/mesa build path ]) -enabled_apis = [] -enabled_apis += ['GL'] - if env['platform'] == 'windows': env.Append(CPPDEFINES = [ '_GDI32_', # prevent gl* being declared __declspec(dllimport) in MS headers @@ -340,10 +337,6 @@ mesa_sources = ( GLAPI = '#src/mapi/glapi/' -if env['gles']: - - enabled_apis += ['ES1', 'ES2'] - get_hash_header = env.CodeGenerate( target = 'main/get_hash.h', script = 'main/get_hash_generator.py', diff --git a/mesalib/src/mesa/drivers/SConscript b/mesalib/src/mesa/drivers/SConscript index 86aa868e5..9888e3306 100644 --- a/mesalib/src/mesa/drivers/SConscript +++ b/mesalib/src/mesa/drivers/SConscript @@ -6,7 +6,10 @@ if env['x11']: SConscript('x11/SConscript') if env['dri']: - SConscript('dri/common/xmlpool/SConscript') + SConscript([ + 'dri/common/xmlpool/SConscript', + 'dri/common/SConscript', + ]) if env['platform'] == 'windows': SConscript('windows/gdi/SConscript') diff --git a/mesalib/src/mesa/drivers/dri/common/Android.mk b/mesalib/src/mesa/drivers/dri/common/Android.mk index b3dac29dd..0489a32de 100644 --- a/mesalib/src/mesa/drivers/dri/common/Android.mk +++ b/mesalib/src/mesa/drivers/dri/common/Android.mk @@ -40,7 +40,7 @@ LOCAL_C_INCLUDES := \ $(intermediates) \ $(MESA_DRI_C_INCLUDES) -LOCAL_SRC_FILES := $(mesa_dri_common_SOURCES) +LOCAL_SRC_FILES := $(DRI_COMMON_FILES) LOCAL_GENERATED_SOURCES := \ $(intermediates)/xmlpool/options.h diff --git a/mesalib/src/mesa/drivers/dri/common/Makefile.am b/mesalib/src/mesa/drivers/dri/common/Makefile.am index 7f87ed6f5..e500bdb30 100644 --- a/mesalib/src/mesa/drivers/dri/common/Makefile.am +++ b/mesalib/src/mesa/drivers/dri/common/Makefile.am @@ -21,6 +21,8 @@ SUBDIRS = xmlpool +include Makefile.sources + AM_CFLAGS = \ -I$(top_srcdir)/include \ -I$(top_srcdir)/src/ \ @@ -35,13 +37,9 @@ noinst_LTLIBRARIES = \ libmegadriver_stub.la \ libdri_test_stubs.la -libdricommon_la_SOURCES = \ - utils.c \ - dri_util.c \ - xmlconfig.c +libdricommon_la_SOURCES = $(DRI_COMMON_FILES) -libdri_test_stubs_la_SOURCES = \ - dri_test.c +libdri_test_stubs_la_SOURCES = $(test_stubs_FILES) libdri_test_stubs_la_CFLAGS = $(AM_CFLAGS) -DNO_MAIN libmegadriver_stub_la_SOURCES = megadriver_stub.c diff --git a/mesalib/src/mesa/drivers/dri/common/Makefile.sources b/mesalib/src/mesa/drivers/dri/common/Makefile.sources index 040b71725..8469b4950 100644 --- a/mesalib/src/mesa/drivers/dri/common/Makefile.sources +++ b/mesalib/src/mesa/drivers/dri/common/Makefile.sources @@ -1,11 +1,8 @@ -mesa_dri_common_gallium_SOURCES := \ +DRI_COMMON_FILES := \ utils.c \ dri_util.c \ xmlconfig.c -mesa_dri_common_SOURCES := \ - $(mesa_dri_common_gallium_SOURCES) - # Paths are relative to MESA_TOP. mesa_dri_common_INCLUDES := \ include \ @@ -14,3 +11,6 @@ mesa_dri_common_INCLUDES := \ src/mapi \ src/mesa \ src/mesa/drivers/dri/common + +test_stubs_FILES := \ + dri_test.c diff --git a/mesalib/src/mesa/drivers/dri/common/SConscript b/mesalib/src/mesa/drivers/dri/common/SConscript new file mode 100644 index 000000000..8b15532e3 --- /dev/null +++ b/mesalib/src/mesa/drivers/dri/common/SConscript @@ -0,0 +1,83 @@ +################################### +# SConcscript file for dri targets + +Import('*') + +drienv = env.Clone() + +drienv.Replace(CPPPATH = [ + '#src/mesa/drivers/dri/common', + xmlpool_options.dir.dir, # Dir to generated xmlpool/options.h + '#include', + '#include/GL/internal', + '#src/mapi', + '#src/gallium/include', + '#src/gallium/auxiliary', + '#src/gallium/drivers', + '#src/gallium/winsys', + '#src/mesa', + '#src/mesa/main', + '#src/mesa/glapi', + '#src/mesa/math', + '#src/mesa/transform', + '#src/mesa/shader', + '#src/mesa/swrast', + '#src/mesa/swrast_setup', + '#src/egl/main', + '#src/egl/drivers/dri', +]) + +driswenv = drienv.Clone() +driswenv.Append(CPPDEFINES = [ + '__NOT_HAVE_DRM_H', +]) + +drienv.PkgUseModules('DRM') + +dri_common_utils = drienv.SharedObject( + target = 'utils.o', + source = '#src/mesa/drivers/dri/common/utils.c' +) + +dri_common_xmlconfig = drienv.SharedObject( + target = 'xmlconfig.o', + source = '#src/mesa/drivers/dri/common/xmlconfig.c' +) + +dri_common_dri_util = drienv.SharedObject( + target = 'dri_util.o', + source = '#src/mesa/drivers/dri/common/dri_util.c' +) + +dri_common_drisw_util = driswenv.SharedObject( + target = 'drisw_util.o', + source = '#src/mesa/drivers/dri/common/dri_util.c' +) + + +COMMON_DRI_SW_OBJECTS = [ + dri_common_utils, + dri_common_xmlconfig, + dri_common_drisw_util, +] + +COMMON_DRI_DRM_OBJECTS = [ + dri_common_utils, + dri_common_xmlconfig, + dri_common_dri_util, +] + +drienv.AppendUnique(LIBS = [ + 'expat', +]) + +driswenv.AppendUnique(LIBS = [ + 'expat', +]) + +Export([ + 'drienv', + 'driswenv', + 'COMMON_DRI_SW_OBJECTS', + 'COMMON_DRI_DRM_OBJECTS', +]) diff --git a/mesalib/src/mesa/main/api_arrayelt.c b/mesalib/src/mesa/main/api_arrayelt.c index 6822465e8..c9d4d038f 100644 --- a/mesalib/src/mesa/main/api_arrayelt.c +++ b/mesalib/src/mesa/main/api_arrayelt.c @@ -1469,6 +1469,18 @@ check_vbo(AEcontext *actx, struct gl_buffer_object *vbo) } +static inline void +update_derived_client_arrays(struct gl_context *ctx) +{ + struct gl_array_object *arrayObj = ctx->Array.ArrayObj; + + if (arrayObj->NewArrays) { + _mesa_update_array_object_client_arrays(ctx, arrayObj); + arrayObj->NewArrays = 0; + } +} + + /** * Make a list of per-vertex functions to call for each glArrayElement call. * These functions access the array data (i.e. glVertex, glColor, glNormal, @@ -1486,12 +1498,6 @@ _ae_update_state(struct gl_context *ctx) actx->nr_vbos = 0; - if (arrayObj->NewArrays) { - /* update the derived client arrays */ - _mesa_update_array_object_client_arrays(ctx, arrayObj); - arrayObj->NewArrays = 0; - } - /* conventional vertex arrays */ if (arrayObj->_VertexAttrib[VERT_ATTRIB_COLOR_INDEX].Enabled) { aa->array = &arrayObj->_VertexAttrib[VERT_ATTRIB_COLOR_INDEX]; @@ -1618,6 +1624,8 @@ _ae_map_vbos(struct gl_context *ctx) if (actx->mapped_vbos) return; + update_derived_client_arrays(ctx); + if (actx->NewState) _ae_update_state(ctx); @@ -1669,6 +1677,8 @@ _ae_ArrayElement(GLint elt) const struct _glapi_table * const disp = GET_DISPATCH(); GLboolean do_map; + update_derived_client_arrays(ctx); + /* If PrimitiveRestart is enabled and the index is the RestartIndex * then we call PrimitiveRestartNV and return. */ diff --git a/mesalib/src/mesa/main/arbprogram.c b/mesalib/src/mesa/main/arbprogram.c index 51a299370..8bd3f0bd0 100644 --- a/mesalib/src/mesa/main/arbprogram.c +++ b/mesalib/src/mesa/main/arbprogram.c @@ -265,6 +265,12 @@ get_local_param_pointer(struct gl_context *ctx, const char *func, return GL_FALSE; } + if (!prog->LocalParams) { + prog->LocalParams = calloc(maxParams, sizeof(float[4])); + if (!prog->LocalParams) + return GL_FALSE; + } + *param = prog->LocalParams[index]; return GL_TRUE; } diff --git a/mesalib/src/mesa/main/context.c b/mesalib/src/mesa/main/context.c index d005d2370..8cbc9352a 100644 --- a/mesalib/src/mesa/main/context.c +++ b/mesalib/src/mesa/main/context.c @@ -494,7 +494,7 @@ init_program_limits(struct gl_context *ctx, GLenum type, prog->MaxParameters = MAX_VERTEX_PROGRAM_PARAMS; prog->MaxAttribs = MAX_VERTEX_GENERIC_ATTRIBS; prog->MaxAddressRegs = MAX_VERTEX_PROGRAM_ADDRESS_REGS; - prog->MaxUniformComponents = MAX_GEOMETRY_UNIFORM_COMPONENTS; + prog->MaxUniformComponents = 4 * MAX_UNIFORMS; prog->MaxInputComponents = 16 * 4; /* old limit not to break tnl and swrast */ prog->MaxOutputComponents = 16 * 4; /* old limit not to break tnl and swrast */ break; diff --git a/mesalib/src/mesa/main/mtypes.h b/mesalib/src/mesa/main/mtypes.h index 41ffdb765..8801d6f61 100644 --- a/mesalib/src/mesa/main/mtypes.h +++ b/mesalib/src/mesa/main/mtypes.h @@ -1846,9 +1846,19 @@ struct gl_transform_feedback_state */ struct gl_perf_monitor_object { + GLuint Name; + + /** True if the monitor is currently active (Begin called but not End). */ GLboolean Active; /** + * True if the monitor has ended. + * + * This is distinct from !Active because it may never have began. + */ + GLboolean Ended; + + /** * A list of groups with currently active counters. * * ActiveGroups[g] == n if there are n counters active from group 'g'. @@ -1930,10 +1940,9 @@ struct gl_perf_monitor_state * NOTE: first four tokens must fit into 2 bits (see t_vb_arbprogram.c) * All values should fit in a 4-bit field. * - * NOTE: PROGRAM_ENV_PARAM, PROGRAM_STATE_VAR, - * PROGRAM_CONSTANT, and PROGRAM_UNIFORM can all be considered to - * be "uniform" variables since they can only be set outside glBegin/End. - * They're also all stored in the same Parameters array. + * NOTE: PROGRAM_STATE_VAR, PROGRAM_CONSTANT, and PROGRAM_UNIFORM can all be + * considered to be "uniform" variables since they can only be set outside + * glBegin/End. They're also all stored in the same Parameters array. */ typedef enum { @@ -1941,8 +1950,6 @@ typedef enum PROGRAM_ARRAY, /**< Arrays & Matrixes */ PROGRAM_INPUT, /**< machine->Inputs[] */ PROGRAM_OUTPUT, /**< machine->Outputs[] */ - PROGRAM_LOCAL_PARAM, /**< gl_program->LocalParams[] */ - PROGRAM_ENV_PARAM, /**< gl_program->Parameters[] */ PROGRAM_STATE_VAR, /**< gl_program->Parameters[] */ PROGRAM_CONSTANT, /**< gl_program->Parameters[] */ PROGRAM_UNIFORM, /**< gl_program->Parameters[] */ @@ -2038,8 +2045,15 @@ struct gl_program /** Named parameters, constants, etc. from program text */ struct gl_program_parameter_list *Parameters; - /** Numbered local parameters */ - GLfloat LocalParams[MAX_PROGRAM_LOCAL_PARAMS][4]; + + /** + * Local parameters used by the program. + * + * It's dynamically allocated because it is rarely used (just + * assembly-style programs), and MAX_PROGRAM_LOCAL_PARAMS entries once it's + * allocated. + */ + GLfloat (*LocalParams)[4]; /** Map from sampler unit to texture unit (set by glUniform1i()) */ GLubyte SamplerUnits[MAX_SAMPLERS]; diff --git a/mesalib/src/mesa/main/performance_monitor.c b/mesalib/src/mesa/main/performance_monitor.c index 17cae5183..6491b4200 100644 --- a/mesalib/src/mesa/main/performance_monitor.c +++ b/mesalib/src/mesa/main/performance_monitor.c @@ -62,6 +62,10 @@ new_performance_monitor(struct gl_context *ctx, GLuint index) if (m == NULL) return NULL; + m->Name = index; + + m->Active = false; + m->ActiveGroups = rzalloc_array(NULL, unsigned, ctx->PerfMonitor.NumGroups); @@ -355,8 +359,10 @@ _mesa_DeletePerfMonitorsAMD(GLsizei n, GLuint *monitors) if (m) { /* Give the driver a chance to stop the monitor if it's active. */ - if (m->Active) + if (m->Active) { ctx->Driver.ResetPerfMonitor(ctx, m); + m->Ended = false; + } _mesa_HashRemove(ctx->PerfMonitor.Monitors, monitors[i]); ralloc_free(m->ActiveGroups); @@ -474,6 +480,7 @@ _mesa_BeginPerfMonitorAMD(GLuint monitor) */ if (ctx->Driver.BeginPerfMonitor(ctx, m)) { m->Active = true; + m->Ended = false; } else { _mesa_error(ctx, GL_INVALID_OPERATION, "glBeginPerfMonitor(driver unable to begin monitoring)"); @@ -503,6 +510,7 @@ _mesa_EndPerfMonitorAMD(GLuint monitor) ctx->Driver.EndPerfMonitor(ctx, m); m->Active = false; + m->Ended = true; } /** @@ -560,8 +568,12 @@ _mesa_GetPerfMonitorCounterDataAMD(GLuint monitor, GLenum pname, return; } + /* If the monitor has never ended, there is no result. */ + bool result_available = m->Ended && + ctx->Driver.IsPerfMonitorResultAvailable(ctx, m); + /* AMD appears to return 0 for all queries unless a result is available. */ - if (!ctx->Driver.IsPerfMonitorResultAvailable(ctx, m)) { + if (!result_available) { *data = 0; if (bytesWritten != NULL) *bytesWritten = sizeof(GLuint); diff --git a/mesalib/src/mesa/main/texstorage.c b/mesalib/src/mesa/main/texstorage.c index 7bd8652b5..84b8f8224 100644 --- a/mesalib/src/mesa/main/texstorage.c +++ b/mesalib/src/mesa/main/texstorage.c @@ -365,6 +365,13 @@ texstorage(GLuint dims, GLenum target, GLsizei levels, GLenum internalformat, GET_CURRENT_CONTEXT(ctx); + if (MESA_VERBOSE & (VERBOSE_API|VERBOSE_TEXTURE)) + _mesa_debug(ctx, "glTexStorage%uD %s %d %s %d %d %d\n", + dims, + _mesa_lookup_enum_by_nr(target), levels, + _mesa_lookup_enum_by_nr(internalformat), + width, height, depth); + if (tex_storage_error_check(ctx, dims, target, levels, internalformat, width, height, depth)) { return; /* error was recorded */ diff --git a/mesalib/src/mesa/main/varray.h b/mesalib/src/mesa/main/varray.h index 3b9f39a61..bc820ed23 100644 --- a/mesalib/src/mesa/main/varray.h +++ b/mesalib/src/mesa/main/varray.h @@ -110,12 +110,6 @@ extern void GLAPIENTRY _mesa_VertexPointer(GLint size, GLenum type, GLsizei stride, const GLvoid *ptr); -extern void GLAPIENTRY -_mesa_UnlockArraysEXT( void ); - -extern void GLAPIENTRY -_mesa_LockArraysEXT(GLint first, GLsizei count); - extern void GLAPIENTRY _mesa_NormalPointer(GLenum type, GLsizei stride, const GLvoid *ptr); diff --git a/mesalib/src/mesa/program/Android.mk b/mesalib/src/mesa/program/Android.mk index 29a1b6a63..e85afe672 100644 --- a/mesalib/src/mesa/program/Android.mk +++ b/mesalib/src/mesa/program/Android.mk @@ -47,8 +47,6 @@ LOCAL_MODULE_CLASS := STATIC_LIBRARIES intermediates := $(call local-intermediates-dir) -MESA_ENABLED_APIS := ES1 ES2 - # TODO(chadv): In Makefile.sources, move these vars to a different list so we can # remove this kludge. generated_sources_basenames := \ diff --git a/mesalib/src/mesa/program/prog_execute.c b/mesalib/src/mesa/program/prog_execute.c index 560332a6e..115525eba 100644 --- a/mesalib/src/mesa/program/prog_execute.c +++ b/mesalib/src/mesa/program/prog_execute.c @@ -118,16 +118,6 @@ get_src_register_pointer(const struct prog_src_register *source, return ZeroVec; return machine->Outputs[reg]; - case PROGRAM_LOCAL_PARAM: - if (reg >= MAX_PROGRAM_LOCAL_PARAMS) - return ZeroVec; - return machine->CurProgram->LocalParams[reg]; - - case PROGRAM_ENV_PARAM: - if (reg >= MAX_PROGRAM_ENV_PARAMS) - return ZeroVec; - return machine->EnvParams[reg]; - case PROGRAM_STATE_VAR: /* Fallthrough */ case PROGRAM_CONSTANT: diff --git a/mesalib/src/mesa/program/prog_print.c b/mesalib/src/mesa/program/prog_print.c index fa9063f5b..fa120cc5e 100644 --- a/mesalib/src/mesa/program/prog_print.c +++ b/mesalib/src/mesa/program/prog_print.c @@ -50,10 +50,6 @@ _mesa_register_file_name(gl_register_file f) switch (f) { case PROGRAM_TEMPORARY: return "TEMP"; - case PROGRAM_LOCAL_PARAM: - return "LOCAL"; - case PROGRAM_ENV_PARAM: - return "ENV"; case PROGRAM_STATE_VAR: return "STATE"; case PROGRAM_INPUT: @@ -382,12 +378,6 @@ reg_string(gl_register_file f, GLint index, gl_prog_print_mode mode, case PROGRAM_TEMPORARY: sprintf(str, "temp%d", index); break; - case PROGRAM_ENV_PARAM: - sprintf(str, "program.env[%s%d]", addr, index); - break; - case PROGRAM_LOCAL_PARAM: - sprintf(str, "program.local[%s%d]", addr, index); - break; case PROGRAM_CONSTANT: /* extension */ sprintf(str, "constant[%s%d]", addr, index); break; diff --git a/mesalib/src/mesa/program/program.c b/mesalib/src/mesa/program/program.c index a102ec17a..01f8c6f11 100644 --- a/mesalib/src/mesa/program/program.c +++ b/mesalib/src/mesa/program/program.c @@ -349,6 +349,7 @@ _mesa_delete_program(struct gl_context *ctx, struct gl_program *prog) return; free(prog->String); + free(prog->LocalParams); if (prog->Instructions) { _mesa_free_instructions(prog->Instructions, prog->NumInstructions); @@ -477,7 +478,16 @@ _mesa_clone_program(struct gl_context *ctx, const struct gl_program *prog) if (prog->Parameters) clone->Parameters = _mesa_clone_parameter_list(prog->Parameters); - memcpy(clone->LocalParams, prog->LocalParams, sizeof(clone->LocalParams)); + if (prog->LocalParams) { + clone->LocalParams = malloc(MAX_PROGRAM_LOCAL_PARAMS * + sizeof(float[4])); + if (!clone->LocalParams) { + _mesa_reference_program(ctx, &clone, NULL); + return NULL; + } + memcpy(clone->LocalParams, prog->LocalParams, + MAX_PROGRAM_LOCAL_PARAMS * sizeof(float[4])); + } clone->IndirectRegisterFiles = prog->IndirectRegisterFiles; clone->NumInstructions = prog->NumInstructions; clone->NumTemporaries = prog->NumTemporaries; @@ -909,12 +919,6 @@ _mesa_valid_register_index(const struct gl_context *ctx, case PROGRAM_TEMPORARY: return index >= 0 && index < (GLint) c->MaxTemps; - case PROGRAM_ENV_PARAM: - return index >= 0 && index < (GLint) c->MaxEnvParams; - - case PROGRAM_LOCAL_PARAM: - return index >= 0 && index < (GLint) c->MaxLocalParams; - case PROGRAM_UNIFORM: case PROGRAM_STATE_VAR: /* aka constant buffer */ diff --git a/mesalib/src/mesa/program/program_parse.y b/mesalib/src/mesa/program/program_parse.y index a76db4e86..03c0a3dba 100644 --- a/mesalib/src/mesa/program/program_parse.y +++ b/mesalib/src/mesa/program/program_parse.y @@ -25,6 +25,7 @@ #include <stdlib.h> #include <string.h> +#include "main/macros.h" #include "main/mtypes.h" #include "main/imports.h" #include "program/program.h" @@ -2559,6 +2560,12 @@ initialize_symbol_from_param(struct gl_program *prog, param_var->type = at_param; param_var->param_binding_type = PROGRAM_STATE_VAR; + /* Dynamically allocate LocalParams, since it's a large array to have + * statically in every gl_program otherwise. + */ + if (state_tokens[1] == STATE_LOCAL && !prog->LocalParams) + prog->LocalParams = calloc(MAX_PROGRAM_LOCAL_PARAMS, sizeof(float[4])); + /* If we are adding a STATE_ENV or STATE_LOCAL that has multiple elements, * we need to unroll it and call add_state_reference() for each row */ diff --git a/mesalib/src/mesa/program/program_parser.h b/mesalib/src/mesa/program/program_parser.h index ca36bb6dc..04c64f446 100644 --- a/mesalib/src/mesa/program/program_parser.h +++ b/mesalib/src/mesa/program/program_parser.h @@ -44,7 +44,7 @@ struct asm_symbol { unsigned output_binding; /**< Output / result register number. */ /** - * One of PROGRAM_STATE_VAR, PROGRAM_LOCAL_PARAM, or PROGRAM_ENV_PARAM. + * One of PROGRAM_STATE_VAR or PROGRAM_CONSTANT. */ unsigned param_binding_type; diff --git a/mesalib/src/mesa/state_tracker/st_glsl_to_tgsi.cpp b/mesalib/src/mesa/state_tracker/st_glsl_to_tgsi.cpp index 0eaf7467b..6319079d5 100644 --- a/mesalib/src/mesa/state_tracker/st_glsl_to_tgsi.cpp +++ b/mesalib/src/mesa/state_tracker/st_glsl_to_tgsi.cpp @@ -70,9 +70,7 @@ extern "C" { } #define PROGRAM_IMMEDIATE PROGRAM_FILE_MAX -#define PROGRAM_ANY_CONST ((1 << PROGRAM_LOCAL_PARAM) | \ - (1 << PROGRAM_ENV_PARAM) | \ - (1 << PROGRAM_STATE_VAR) | \ +#define PROGRAM_ANY_CONST ((1 << PROGRAM_STATE_VAR) | \ (1 << PROGRAM_CONSTANT) | \ (1 << PROGRAM_UNIFORM)) @@ -565,8 +563,6 @@ glsl_to_tgsi_visitor::emit(ir_instruction *ir, unsigned op, /* Update indirect addressing status used by TGSI */ if (dst.reladdr) { switch(dst.file) { - case PROGRAM_LOCAL_PARAM: - case PROGRAM_ENV_PARAM: case PROGRAM_STATE_VAR: case PROGRAM_CONSTANT: case PROGRAM_UNIFORM: @@ -583,8 +579,6 @@ glsl_to_tgsi_visitor::emit(ir_instruction *ir, unsigned op, for (i=0; i<3; i++) { if(inst->src[i].reladdr) { switch(inst->src[i].file) { - case PROGRAM_LOCAL_PARAM: - case PROGRAM_ENV_PARAM: case PROGRAM_STATE_VAR: case PROGRAM_CONSTANT: case PROGRAM_UNIFORM: @@ -4311,8 +4305,6 @@ src_register(struct st_translate *t, case PROGRAM_ARRAY: return ureg_src(dst_register(t, file, index)); - case PROGRAM_ENV_PARAM: - case PROGRAM_LOCAL_PARAM: case PROGRAM_UNIFORM: assert(index >= 0); return t->constants[index]; @@ -4962,8 +4954,6 @@ st_translate_program( for (i = 0; i < proginfo->Parameters->NumParameters; i++) { switch (proginfo->Parameters->Parameters[i].Type) { - case PROGRAM_ENV_PARAM: - case PROGRAM_LOCAL_PARAM: case PROGRAM_STATE_VAR: case PROGRAM_UNIFORM: t->constants[i] = ureg_DECL_constant(ureg, i); diff --git a/mesalib/src/mesa/state_tracker/st_mesa_to_tgsi.c b/mesalib/src/mesa/state_tracker/st_mesa_to_tgsi.c index 1bbeced34..921b0f9b8 100644 --- a/mesalib/src/mesa/state_tracker/st_mesa_to_tgsi.c +++ b/mesalib/src/mesa/state_tracker/st_mesa_to_tgsi.c @@ -46,9 +46,7 @@ #include "util/u_memory.h" -#define PROGRAM_ANY_CONST ((1 << PROGRAM_LOCAL_PARAM) | \ - (1 << PROGRAM_ENV_PARAM) | \ - (1 << PROGRAM_STATE_VAR) | \ +#define PROGRAM_ANY_CONST ((1 << PROGRAM_STATE_VAR) | \ (1 << PROGRAM_CONSTANT) | \ (1 << PROGRAM_UNIFORM)) @@ -214,8 +212,6 @@ src_register( struct st_translate *t, t->temps[index] = ureg_DECL_temporary( t->ureg ); return ureg_src(t->temps[index]); - case PROGRAM_ENV_PARAM: - case PROGRAM_LOCAL_PARAM: case PROGRAM_UNIFORM: assert(index >= 0); return t->constants[index]; @@ -1195,8 +1191,6 @@ st_translate_mesa_program( for (i = 0; i < program->Parameters->NumParameters; i++) { switch (program->Parameters->Parameters[i].Type) { - case PROGRAM_ENV_PARAM: - case PROGRAM_LOCAL_PARAM: case PROGRAM_STATE_VAR: case PROGRAM_UNIFORM: t->constants[i] = ureg_DECL_constant( ureg, i ); |