diff options
Diffstat (limited to 'mesalib/src')
46 files changed, 819 insertions, 229 deletions
diff --git a/mesalib/src/glsl/Makefile.sources b/mesalib/src/glsl/Makefile.sources index f2743f750..765f06a27 100644 --- a/mesalib/src/glsl/Makefile.sources +++ b/mesalib/src/glsl/Makefile.sources @@ -66,6 +66,7 @@ LIBGLSL_CXX_FILES = \ $(GLSL_SRCDIR)/lower_vec_index_to_swizzle.cpp \ $(GLSL_SRCDIR)/lower_vector.cpp \ $(GLSL_SRCDIR)/lower_output_reads.cpp \ + $(GLSL_SRCDIR)/lower_ubo_reference.cpp \ $(GLSL_SRCDIR)/opt_algebraic.cpp \ $(GLSL_SRCDIR)/opt_array_splitting.cpp \ $(GLSL_SRCDIR)/opt_constant_folding.cpp \ diff --git a/mesalib/src/glsl/README b/mesalib/src/glsl/README index dd80a53d4..0a0afccdc 100644 --- a/mesalib/src/glsl/README +++ b/mesalib/src/glsl/README @@ -177,7 +177,6 @@ ir_unop_fract was added. The following areas need updating to add a new expression type: ir.h (new enum) -ir.cpp:get_num_operands() (used for ir_reader) ir.cpp:operator_strs (used for ir_reader) ir_constant_expression.cpp (you probably want to be able to constant fold) ir_validate.cpp (check users have the right types) diff --git a/mesalib/src/glsl/ast_to_hir.cpp b/mesalib/src/glsl/ast_to_hir.cpp index 1c54991cf..02fe66b60 100644 --- a/mesalib/src/glsl/ast_to_hir.cpp +++ b/mesalib/src/glsl/ast_to_hir.cpp @@ -4054,11 +4054,15 @@ ast_uniform_block::hir(exec_list *instructions, ubo_var->Type = var->type; ubo_var->Buffer = ubo - state->uniform_blocks; ubo_var->Offset = 0; /* Assigned at link time. */ - ubo_var->RowMajor = block_row_major; - if (decl_list->type->qualifier.flags.q.row_major) - ubo_var->RowMajor = true; - else if (decl_list->type->qualifier.flags.q.column_major) - ubo_var->RowMajor = false; + + if (var->type->is_matrix() || + (var->type->is_array() && var->type->fields.array->is_matrix())) { + ubo_var->RowMajor = block_row_major; + if (decl_list->type->qualifier.flags.q.row_major) + ubo_var->RowMajor = true; + else if (decl_list->type->qualifier.flags.q.column_major) + ubo_var->RowMajor = false; + } /* From the GL_ARB_uniform_buffer_object spec: * diff --git a/mesalib/src/glsl/glsl_parser.yy b/mesalib/src/glsl/glsl_parser.yy index 04c64f096..ee6a67288 100644 --- a/mesalib/src/glsl/glsl_parser.yy +++ b/mesalib/src/glsl/glsl_parser.yy @@ -1929,6 +1929,16 @@ uniform_block: void *ctx = state; $$ = new(ctx) ast_uniform_block(*state->default_uniform_qualifier, $2, $4); + + if (!state->ARB_uniform_buffer_object_enable) { + _mesa_glsl_error(& @1, state, + "#version 140 / GL_ARB_uniform_buffer_object " + "required for defining uniform blocks\n"); + } else if (state->ARB_uniform_buffer_object_warn) { + _mesa_glsl_warning(& @1, state, + "#version 140 / GL_ARB_uniform_buffer_object " + "required for defining uniform blocks\n"); + } } | layout_qualifier UNIFORM NEW_IDENTIFIER '{' member_list '}' ';' { @@ -1939,6 +1949,16 @@ uniform_block: YYERROR; } $$ = new(ctx) ast_uniform_block(qual, $3, $5); + + if (!state->ARB_uniform_buffer_object_enable) { + _mesa_glsl_error(& @1, state, + "#version 140 / GL_ARB_uniform_buffer_object " + "required for defining uniform blocks\n"); + } else if (state->ARB_uniform_buffer_object_warn) { + _mesa_glsl_warning(& @1, state, + "#version 140 / GL_ARB_uniform_buffer_object " + "required for defining uniform blocks\n"); + } } ; diff --git a/mesalib/src/glsl/glsl_types.cpp b/mesalib/src/glsl/glsl_types.cpp index 3d7866058..2aa51f0b3 100644 --- a/mesalib/src/glsl/glsl_types.cpp +++ b/mesalib/src/glsl/glsl_types.cpp @@ -694,14 +694,19 @@ glsl_type::std140_base_alignment(bool row_major) const * row vectors with <C> components each, according to rule (4). */ if (this->is_matrix()) { - const struct glsl_type *vec_type; + const struct glsl_type *vec_type, *array_type; + int c = this->matrix_columns; + int r = this->vector_elements; + if (row_major) { - vec_type = get_instance(GLSL_TYPE_FLOAT, this->vector_elements, 1); + vec_type = get_instance(GLSL_TYPE_FLOAT, c, 1); + array_type = glsl_type::get_array_instance(vec_type, r); } else { - vec_type = get_instance(GLSL_TYPE_FLOAT, this->matrix_columns, 1); + vec_type = get_instance(GLSL_TYPE_FLOAT, r, 1); + array_type = glsl_type::get_array_instance(vec_type, c); } - return vec_type->std140_base_alignment(false); + return array_type->std140_base_alignment(false); } /* (9) If the member is a structure, the base alignment of the diff --git a/mesalib/src/glsl/ir.cpp b/mesalib/src/glsl/ir.cpp index b0e38d820..f59cdd29a 100644 --- a/mesalib/src/glsl/ir.cpp +++ b/mesalib/src/glsl/ir.cpp @@ -480,6 +480,7 @@ static const char *const operator_strs[] = { "min", "max", "pow", + "ubo_load", "vector", }; diff --git a/mesalib/src/glsl/ir.h b/mesalib/src/glsl/ir.h index f019837d5..89c516c87 100644 --- a/mesalib/src/glsl/ir.h +++ b/mesalib/src/glsl/ir.h @@ -1018,9 +1018,17 @@ enum ir_expression_operation { ir_binop_pow, /** + * Load a value the size of a given GLSL type from a uniform block. + * + * operand0 is the ir_constant uniform block index in the linked shader. + * operand1 is a byte offset within the uniform block. + */ + ir_binop_ubo_load, + + /** * A sentinel marking the last of the binary operations. */ - ir_last_binop = ir_binop_pow, + ir_last_binop = ir_binop_ubo_load, ir_quadop_vector, diff --git a/mesalib/src/glsl/ir_optimization.h b/mesalib/src/glsl/ir_optimization.h index c435d7717..2220d511e 100644 --- a/mesalib/src/glsl/ir_optimization.h +++ b/mesalib/src/glsl/ir_optimization.h @@ -74,6 +74,7 @@ bool lower_variable_index_to_cond_assign(exec_list *instructions, bool lower_quadop_vector(exec_list *instructions, bool dont_lower_swz); bool lower_clip_distance(exec_list *instructions); void lower_output_reads(exec_list *instructions); +void lower_ubo_reference(struct gl_shader *shader, exec_list *instructions); bool optimize_redundant_jumps(exec_list *instructions); bool optimize_split_arrays(exec_list *instructions, bool linked); diff --git a/mesalib/src/glsl/ir_rvalue_visitor.cpp b/mesalib/src/glsl/ir_rvalue_visitor.cpp index 193bcd2d7..b34a419e8 100644 --- a/mesalib/src/glsl/ir_rvalue_visitor.cpp +++ b/mesalib/src/glsl/ir_rvalue_visitor.cpp @@ -36,7 +36,7 @@ #include "glsl_types.h" ir_visitor_status -ir_rvalue_visitor::visit_leave(ir_expression *ir) +ir_rvalue_base_visitor::rvalue_visit(ir_expression *ir) { unsigned int operand; @@ -48,7 +48,7 @@ ir_rvalue_visitor::visit_leave(ir_expression *ir) } ir_visitor_status -ir_rvalue_visitor::visit_leave(ir_texture *ir) +ir_rvalue_base_visitor::rvalue_visit(ir_texture *ir) { handle_rvalue(&ir->coordinate); handle_rvalue(&ir->projector); @@ -76,14 +76,14 @@ ir_rvalue_visitor::visit_leave(ir_texture *ir) } ir_visitor_status -ir_rvalue_visitor::visit_leave(ir_swizzle *ir) +ir_rvalue_base_visitor::rvalue_visit(ir_swizzle *ir) { handle_rvalue(&ir->val); return visit_continue; } ir_visitor_status -ir_rvalue_visitor::visit_leave(ir_dereference_array *ir) +ir_rvalue_base_visitor::rvalue_visit(ir_dereference_array *ir) { /* The array index is not the target of the assignment, so clear the * 'in_assignee' flag. Restore it after returning from the array index. @@ -98,14 +98,14 @@ ir_rvalue_visitor::visit_leave(ir_dereference_array *ir) } ir_visitor_status -ir_rvalue_visitor::visit_leave(ir_dereference_record *ir) +ir_rvalue_base_visitor::rvalue_visit(ir_dereference_record *ir) { handle_rvalue(&ir->record); return visit_continue; } ir_visitor_status -ir_rvalue_visitor::visit_leave(ir_assignment *ir) +ir_rvalue_base_visitor::rvalue_visit(ir_assignment *ir) { handle_rvalue(&ir->rhs); handle_rvalue(&ir->condition); @@ -114,7 +114,7 @@ ir_rvalue_visitor::visit_leave(ir_assignment *ir) } ir_visitor_status -ir_rvalue_visitor::visit_leave(ir_call *ir) +ir_rvalue_base_visitor::rvalue_visit(ir_call *ir) { foreach_iter(exec_list_iterator, iter, *ir) { ir_rvalue *param = (ir_rvalue *)iter.get(); @@ -129,15 +129,124 @@ ir_rvalue_visitor::visit_leave(ir_call *ir) } ir_visitor_status -ir_rvalue_visitor::visit_leave(ir_return *ir) +ir_rvalue_base_visitor::rvalue_visit(ir_return *ir) { handle_rvalue(&ir->value);; return visit_continue; } ir_visitor_status -ir_rvalue_visitor::visit_leave(ir_if *ir) +ir_rvalue_base_visitor::rvalue_visit(ir_if *ir) { handle_rvalue(&ir->condition); return visit_continue; } + + +ir_visitor_status +ir_rvalue_visitor::visit_leave(ir_expression *ir) +{ + return rvalue_visit(ir); +} + +ir_visitor_status +ir_rvalue_visitor::visit_leave(ir_texture *ir) +{ + return rvalue_visit(ir); +} + +ir_visitor_status +ir_rvalue_visitor::visit_leave(ir_swizzle *ir) +{ + return rvalue_visit(ir); +} + +ir_visitor_status +ir_rvalue_visitor::visit_leave(ir_dereference_array *ir) +{ + return rvalue_visit(ir); +} + +ir_visitor_status +ir_rvalue_visitor::visit_leave(ir_dereference_record *ir) +{ + return rvalue_visit(ir); +} + +ir_visitor_status +ir_rvalue_visitor::visit_leave(ir_assignment *ir) +{ + return rvalue_visit(ir); +} + +ir_visitor_status +ir_rvalue_visitor::visit_leave(ir_call *ir) +{ + return rvalue_visit(ir); +} + +ir_visitor_status +ir_rvalue_visitor::visit_leave(ir_return *ir) +{ + return rvalue_visit(ir); +} + +ir_visitor_status +ir_rvalue_visitor::visit_leave(ir_if *ir) +{ + return rvalue_visit(ir); +} + +ir_visitor_status +ir_rvalue_enter_visitor::visit_enter(ir_expression *ir) +{ + return rvalue_visit(ir); +} + +ir_visitor_status +ir_rvalue_enter_visitor::visit_enter(ir_texture *ir) +{ + return rvalue_visit(ir); +} + +ir_visitor_status +ir_rvalue_enter_visitor::visit_enter(ir_swizzle *ir) +{ + return rvalue_visit(ir); +} + +ir_visitor_status +ir_rvalue_enter_visitor::visit_enter(ir_dereference_array *ir) +{ + return rvalue_visit(ir); +} + +ir_visitor_status +ir_rvalue_enter_visitor::visit_enter(ir_dereference_record *ir) +{ + return rvalue_visit(ir); +} + +ir_visitor_status +ir_rvalue_enter_visitor::visit_enter(ir_assignment *ir) +{ + return rvalue_visit(ir); +} + +ir_visitor_status +ir_rvalue_enter_visitor::visit_enter(ir_call *ir) +{ + return rvalue_visit(ir); +} + +ir_visitor_status +ir_rvalue_enter_visitor::visit_enter(ir_return *ir) +{ + return rvalue_visit(ir); +} + +ir_visitor_status +ir_rvalue_enter_visitor::visit_enter(ir_if *ir) +{ + return rvalue_visit(ir); +} diff --git a/mesalib/src/glsl/ir_rvalue_visitor.h b/mesalib/src/glsl/ir_rvalue_visitor.h index 31a56beb9..2179fa5a8 100644 --- a/mesalib/src/glsl/ir_rvalue_visitor.h +++ b/mesalib/src/glsl/ir_rvalue_visitor.h @@ -30,7 +30,22 @@ * a pointer to each rvalue in the tree. */ -class ir_rvalue_visitor : public ir_hierarchical_visitor { +class ir_rvalue_base_visitor : public ir_hierarchical_visitor { +public: + ir_visitor_status rvalue_visit(ir_assignment *); + ir_visitor_status rvalue_visit(ir_call *); + ir_visitor_status rvalue_visit(ir_dereference_array *); + ir_visitor_status rvalue_visit(ir_dereference_record *); + ir_visitor_status rvalue_visit(ir_expression *); + ir_visitor_status rvalue_visit(ir_if *); + ir_visitor_status rvalue_visit(ir_return *); + ir_visitor_status rvalue_visit(ir_swizzle *); + ir_visitor_status rvalue_visit(ir_texture *); + + virtual void handle_rvalue(ir_rvalue **rvalue) = 0; +}; + +class ir_rvalue_visitor : public ir_rvalue_base_visitor { public: virtual ir_visitor_status visit_leave(ir_assignment *); @@ -42,6 +57,18 @@ public: virtual ir_visitor_status visit_leave(ir_return *); virtual ir_visitor_status visit_leave(ir_swizzle *); virtual ir_visitor_status visit_leave(ir_texture *); +}; - virtual void handle_rvalue(ir_rvalue **rvalue) = 0; +class ir_rvalue_enter_visitor : public ir_rvalue_base_visitor { +public: + + virtual ir_visitor_status visit_enter(ir_assignment *); + virtual ir_visitor_status visit_enter(ir_call *); + virtual ir_visitor_status visit_enter(ir_dereference_array *); + virtual ir_visitor_status visit_enter(ir_dereference_record *); + virtual ir_visitor_status visit_enter(ir_expression *); + virtual ir_visitor_status visit_enter(ir_if *); + virtual ir_visitor_status visit_enter(ir_return *); + virtual ir_visitor_status visit_enter(ir_swizzle *); + virtual ir_visitor_status visit_enter(ir_texture *); }; diff --git a/mesalib/src/glsl/ir_validate.cpp b/mesalib/src/glsl/ir_validate.cpp index 191d39831..af0b5768a 100644 --- a/mesalib/src/glsl/ir_validate.cpp +++ b/mesalib/src/glsl/ir_validate.cpp @@ -423,6 +423,13 @@ ir_validate::visit_leave(ir_expression *ir) assert(ir->operands[0]->type == ir->operands[1]->type); break; + case ir_binop_ubo_load: + assert(ir->operands[0]->as_constant()); + assert(ir->operands[0]->type == glsl_type::uint_type); + + assert(ir->operands[1]->type == glsl_type::uint_type); + break; + case ir_quadop_vector: /* The vector operator collects some number of scalars and generates a * vector from them. diff --git a/mesalib/src/glsl/link_uniforms.cpp b/mesalib/src/glsl/link_uniforms.cpp index 1baa46c5d..25dc1d7dc 100644 --- a/mesalib/src/glsl/link_uniforms.cpp +++ b/mesalib/src/glsl/link_uniforms.cpp @@ -224,14 +224,24 @@ public: } void set_and_process(struct gl_shader_program *prog, + struct gl_shader *shader, ir_variable *var) { ubo_var = NULL; if (var->uniform_block != -1) { struct gl_uniform_block *block = - &prog->UniformBlocks[var->uniform_block]; + &shader->UniformBlocks[var->uniform_block]; + + ubo_block_index = -1; + for (unsigned i = 0; i < prog->NumUniformBlocks; i++) { + if (!strcmp(prog->UniformBlocks[i].Name, + shader->UniformBlocks[var->uniform_block].Name)) { + ubo_block_index = i; + break; + } + } + assert(ubo_block_index != -1); - ubo_block_index = var->uniform_block; ubo_var_index = var->location; ubo_var = &block->Uniforms[var->location]; ubo_byte_offset = ubo_var->Offset; @@ -490,7 +500,19 @@ link_assign_uniform_block_offsets(struct gl_shader *shader) ubo_var->Offset = offset; offset += size; } - block->UniformBufferSize = offset; + + /* From the GL_ARB_uniform_buffer_object spec: + * + * "For uniform blocks laid out according to [std140] rules, + * the minimum buffer object size returned by the + * UNIFORM_BLOCK_DATA_SIZE query is derived by taking the + * offset of the last basic machine unit consumed by the + * last uniform of the uniform block (including any + * end-of-array or end-of-structure padding), adding one, + * and rounding up to the next multiple of the base + * alignment required for a vec4." + */ + block->UniformBufferSize = align(offset, 16); } } @@ -598,7 +620,7 @@ link_assign_uniform_locations(struct gl_shader_program *prog) if (strncmp("gl_", var->name, 3) == 0) continue; - parcel.set_and_process(prog, var); + parcel.set_and_process(prog, prog->_LinkedShaders[i], var); } prog->_LinkedShaders[i]->active_samplers = parcel.shader_samplers_used; diff --git a/mesalib/src/glsl/lower_ubo_reference.cpp b/mesalib/src/glsl/lower_ubo_reference.cpp new file mode 100644 index 000000000..e8d2c4742 --- /dev/null +++ b/mesalib/src/glsl/lower_ubo_reference.cpp @@ -0,0 +1,313 @@ +/* + * Copyright © 2012 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. + */ + +/** + * \file lower_ubo_reference.cpp + * + * IR lower pass to replace dereferences of variables in a uniform + * buffer object with usage of ir_binop_ubo_load expressions, each of + * which can read data up to the size of a vec4. + * + * This relieves drivers of the responsibility to deal with tricky UBO + * layout issues like std140 structures and row_major matrices on + * their own. + */ + +#include "ir.h" +#include "ir_builder.h" +#include "ir_rvalue_visitor.h" +#include "main/macros.h" + +using namespace ir_builder; + +namespace { +class lower_ubo_reference_visitor : public ir_rvalue_enter_visitor { +public: + lower_ubo_reference_visitor(struct gl_shader *shader) + : shader(shader) + { + } + + void handle_rvalue(ir_rvalue **rvalue); + void emit_ubo_loads(ir_dereference *deref, ir_variable *base_offset, + unsigned int deref_offset); + ir_expression *ubo_load(const struct glsl_type *type, + ir_rvalue *offset); + + void *mem_ctx; + struct gl_shader *shader; + struct gl_uniform_buffer_variable *ubo_var; + unsigned uniform_block; + bool progress; +}; + +static inline unsigned int +align(unsigned int a, unsigned int align) +{ + return (a + align - 1) / align * align; +} + +void +lower_ubo_reference_visitor::handle_rvalue(ir_rvalue **rvalue) +{ + if (!*rvalue) + return; + + ir_dereference *deref = (*rvalue)->as_dereference(); + if (!deref) + return; + + ir_variable *var = deref->variable_referenced(); + if (!var || var->uniform_block == -1) + return; + + mem_ctx = ralloc_parent(*rvalue); + uniform_block = var->uniform_block; + struct gl_uniform_block *block = &shader->UniformBlocks[uniform_block]; + this->ubo_var = &block->Uniforms[var->location]; + ir_rvalue *offset = new(mem_ctx) ir_constant(0u); + unsigned const_offset = 0; + bool row_major = ubo_var->RowMajor; + + /* Calculate the offset to the start of the region of the UBO + * dereferenced by *rvalue. This may be a variable offset if an + * array dereference has a variable index. + */ + while (deref) { + switch (deref->ir_type) { + case ir_type_dereference_variable: { + const_offset += ubo_var->Offset; + deref = NULL; + break; + } + + case ir_type_dereference_array: { + ir_dereference_array *deref_array = (ir_dereference_array *)deref; + unsigned array_stride; + if (deref_array->array->type->is_matrix() && row_major) { + /* When loading a vector out of a row major matrix, the + * step between the columns (vectors) is the size of a + * float, while the step between the rows (elements of a + * vector) is handled below in emit_ubo_loads. + */ + array_stride = 4; + } else { + array_stride = deref_array->type->std140_size(row_major); + array_stride = align(array_stride, 16); + } + + ir_constant *const_index = deref_array->array_index->as_constant(); + if (const_index) { + const_offset += array_stride * const_index->value.i[0]; + } else { + offset = add(offset, + mul(deref_array->array_index, + new(mem_ctx) ir_constant(array_stride))); + } + deref = deref_array->array->as_dereference(); + break; + } + + case ir_type_dereference_record: { + ir_dereference_record *deref_record = (ir_dereference_record *)deref; + const glsl_type *struct_type = deref_record->record->type; + unsigned intra_struct_offset = 0; + + unsigned max_field_align = 16; + for (unsigned int i = 0; i < struct_type->length; i++) { + const glsl_type *type = struct_type->fields.structure[i].type; + unsigned field_align = type->std140_base_alignment(row_major); + max_field_align = MAX2(field_align, max_field_align); + intra_struct_offset = align(intra_struct_offset, field_align); + + if (strcmp(struct_type->fields.structure[i].name, + deref_record->field) == 0) + break; + intra_struct_offset += type->std140_size(row_major); + } + + const_offset = align(const_offset, max_field_align); + const_offset += intra_struct_offset; + + deref = deref_record->record->as_dereference(); + break; + } + default: + assert(!"not reached"); + deref = NULL; + break; + } + } + + /* Now that we've calculated the offset to the start of the + * dereference, walk over the type and emit loads into a temporary. + */ + const glsl_type *type = (*rvalue)->type; + ir_variable *load_var = new(mem_ctx) ir_variable(type, + "ubo_load_temp", + ir_var_temporary); + base_ir->insert_before(load_var); + + ir_variable *load_offset = new(mem_ctx) ir_variable(glsl_type::uint_type, + "ubo_load_temp_offset", + ir_var_temporary); + base_ir->insert_before(load_offset); + base_ir->insert_before(assign(load_offset, offset)); + + deref = new(mem_ctx) ir_dereference_variable(load_var); + emit_ubo_loads(deref, load_offset, const_offset); + *rvalue = deref; + + progress = true; +} + +ir_expression * +lower_ubo_reference_visitor::ubo_load(const glsl_type *type, + ir_rvalue *offset) +{ + return new(mem_ctx) + ir_expression(ir_binop_ubo_load, + type, + new(mem_ctx) ir_constant(this->uniform_block), + offset); + +} + +/** + * Takes LHS and emits a series of assignments into its components + * from the UBO variable at variable_offset + deref_offset. + * + * Recursively calls itself to break the deref down to the point that + * the ir_binop_ubo_load expressions generated are contiguous scalars + * or vectors. + */ +void +lower_ubo_reference_visitor::emit_ubo_loads(ir_dereference *deref, + ir_variable *base_offset, + unsigned int deref_offset) +{ + if (deref->type->is_record()) { + unsigned int field_offset = 0; + + for (unsigned i = 0; i < deref->type->length; i++) { + const struct glsl_struct_field *field = + &deref->type->fields.structure[i]; + ir_dereference *field_deref = + new(mem_ctx) ir_dereference_record(deref->clone(mem_ctx, NULL), + field->name); + + field_offset = + align(field_offset, + field->type->std140_base_alignment(ubo_var->RowMajor)); + + emit_ubo_loads(field_deref, base_offset, deref_offset + field_offset); + + field_offset += field->type->std140_size(ubo_var->RowMajor); + } + return; + } + + if (deref->type->is_array()) { + unsigned array_stride = + align(deref->type->fields.array->std140_size(ubo_var->RowMajor), 16); + + for (unsigned i = 0; i < deref->type->length; i++) { + ir_constant *element = new(mem_ctx) ir_constant(i); + ir_dereference *element_deref = + new(mem_ctx) ir_dereference_array(deref->clone(mem_ctx, NULL), + element); + emit_ubo_loads(element_deref, base_offset, + deref_offset + i * array_stride); + } + return; + } + + if (deref->type->is_matrix()) { + for (unsigned i = 0; i < deref->type->matrix_columns; i++) { + ir_constant *col = new(mem_ctx) ir_constant(i); + ir_dereference *col_deref = + new(mem_ctx) ir_dereference_array(deref->clone(mem_ctx, NULL), + col); + + /* std140 always rounds the stride of arrays (and matrices) + * to a vec4, so matrices are always 16 between columns/rows. + */ + emit_ubo_loads(col_deref, base_offset, deref_offset + i * 16); + } + return; + } + + assert(deref->type->is_scalar() || + deref->type->is_vector()); + + if (!ubo_var->RowMajor) { + ir_rvalue *offset = add(base_offset, + new(mem_ctx) ir_constant(deref_offset)); + base_ir->insert_before(assign(deref->clone(mem_ctx, NULL), + ubo_load(deref->type, offset))); + } else { + /* We're dereffing a column out of a row-major matrix, so we + * gather the vector from each stored row. + */ + assert(deref->type->base_type == GLSL_TYPE_FLOAT); + /* Matrices, row_major or not, are stored as if they were + * arrays of vectors of the appropriate size in std140. + * Arrays have their strides rounded up to a vec4, so the + * matrix stride is always 16. + */ + unsigned matrix_stride = 16; + + for (unsigned i = 0; i < deref->type->vector_elements; i++) { + ir_rvalue *chan = new(mem_ctx) ir_constant((int)i); + ir_dereference *deref_chan = + new(mem_ctx) ir_dereference_array(deref->clone(mem_ctx, NULL), + chan); + + ir_rvalue *chan_offset = + add(base_offset, + new(mem_ctx) ir_constant(deref_offset + i * matrix_stride)); + + base_ir->insert_before(assign(deref_chan, + ubo_load(glsl_type::float_type, + chan_offset))); + } + } +} + +} /* unnamed namespace */ + +void +lower_ubo_reference(struct gl_shader *shader, exec_list *instructions) +{ + lower_ubo_reference_visitor v(shader); + + /* Loop over the instructions lowering references, because we take + * a deref of a UBO array using a UBO dereference as the index will + * produce a collection of instructions all of which have cloned + * UBO dereferences for that array index. + */ + do { + v.progress = false; + visit_list_elements(&v, instructions); + } while (v.progress); +} diff --git a/mesalib/src/mapi/glapi/gen/glX_proto_send.py b/mesalib/src/mapi/glapi/gen/glX_proto_send.py index bec022218..ca3a79056 100644 --- a/mesalib/src/mapi/glapi/gen/glX_proto_send.py +++ b/mesalib/src/mapi/glapi/gen/glX_proto_send.py @@ -423,7 +423,10 @@ __indirect_get_proc_address(const char *name) print '' print '#if defined(GLX_DIRECT_RENDERING) && !defined(GLX_USE_APPLEGL)' print ' if (gc->isDirect) {' - print ' %sGET_DISPATCH()->%s(%s);' % (ret_string, func.name, func.get_called_parameter_string()) + print ' const _glapi_proc *const table = GET_DISPATCH();' + print ' PFNGL%sPROC p =' % (name.upper()) + print ' (PFNGL%sPROC) table[%d];' % (name.upper(), func.offset) + print ' %sp(%s);' % (ret_string, func.get_called_parameter_string()) print ' } else' print '#endif' print ' {' @@ -928,6 +931,7 @@ class PrintGlxProtoInit_c(gl_XML.gl_print_base): #include "indirect_init.h" #include "indirect.h" #include "glapi.h" +#include <assert.h> /** @@ -945,26 +949,24 @@ static int NoOp(void) */ struct _glapi_table * __glXNewIndirectAPI( void ) { - struct _glapi_table *glAPI; - GLuint entries; + _glapi_proc *table; + unsigned entries; + unsigned i; + int o; entries = _glapi_get_dispatch_table_size(); - glAPI = (struct _glapi_table *) Xmalloc(entries * sizeof(void *)); + table = (_glapi_proc *) Xmalloc(entries * sizeof(_glapi_proc)); /* first, set all entries to point to no-op functions */ - { - int i; - void **dispatch = (void **) glAPI; - for (i = 0; i < entries; i++) { - dispatch[i] = (void *) NoOp; - } + for (i = 0; i < entries; i++) { + table[i] = (_glapi_proc) NoOp; } /* now, initialize the entries we understand */""" def printRealFooter(self): print """ - return glAPI; + return (struct _glapi_table *) table; } """ return @@ -973,14 +975,22 @@ struct _glapi_table * __glXNewIndirectAPI( void ) def printBody(self, api): for [name, number] in api.categoryIterate(): if number != None: - preamble = '\n /* %3u. %s */\n\n' % (int(number), name) + preamble = '\n /* %3u. %s */\n' % (int(number), name) else: - preamble = '\n /* %s */\n\n' % (name) + preamble = '\n /* %s */\n' % (name) for func in api.functionIterateByCategory(name): if func.client_supported_for_indirect(): - print '%s glAPI->%s = __indirect_gl%s;' % (preamble, func.name, func.name) - preamble = '' + if preamble: + print preamble + preamble = None + + if func.is_abi(): + print ' table[{offset}] = (_glapi_proc) __indirect_gl{name};'.format(name = func.name, offset = func.offset) + else: + print ' o = _glapi_get_proc_offset("gl{0}");'.format(func.name) + print ' assert(o > 0);' + print ' table[o] = (_glapi_proc) __indirect_gl{0};'.format(func.name) return diff --git a/mesalib/src/mapi/glapi/gen/gl_table.py b/mesalib/src/mapi/glapi/gen/gl_table.py index 7f3b91513..a0ae4c39a 100644 --- a/mesalib/src/mapi/glapi/gen/gl_table.py +++ b/mesalib/src/mapi/glapi/gen/gl_table.py @@ -39,14 +39,20 @@ class PrintGlTable(gl_XML.gl_print_base): self.license = license.bsd_license_template % ( \ """Copyright (C) 1999-2003 Brian Paul All Rights Reserved. (C) Copyright IBM Corporation 2004""", "BRIAN PAUL, IBM") + self.ifdef_emitted = False; return def printBody(self, api): for f in api.functionIterateByOffset(): + if not f.is_abi() and not self.ifdef_emitted: + print '#if !defined HAVE_SHARED_GLAPI' + self.ifdef_emitted = True arg_string = f.get_parameter_string() print ' %s (GLAPIENTRYP %s)(%s); /* %d */' % (f.return_type, f.name, arg_string, f.offset) + print '#endif /* !defined HAVE_SHARED_GLAPI */' + def printRealHeader(self): print '#ifndef GLAPIENTRYP' diff --git a/mesalib/src/mesa/drivers/common/meta.c b/mesalib/src/mesa/drivers/common/meta.c index af89d8180..d36b1a3b8 100644 --- a/mesalib/src/mesa/drivers/common/meta.c +++ b/mesalib/src/mesa/drivers/common/meta.c @@ -70,6 +70,7 @@ #include "main/uniforms.h" #include "main/varray.h" #include "main/viewport.h" +#include "main/samplerobj.h" #include "program/program.h" #include "swrast/swrast.h" #include "drivers/common/meta.h" @@ -278,6 +279,7 @@ struct gen_mipmap_state GLuint ArrayObj; GLuint VBO; GLuint FBO; + GLuint Sampler; }; @@ -2925,14 +2927,8 @@ _mesa_meta_GenerateMipmap(struct gl_context *ctx, GLenum target, struct vertex verts[4]; const GLuint baseLevel = texObj->BaseLevel; const GLuint maxLevel = texObj->MaxLevel; - const GLenum minFilterSave = texObj->Sampler.MinFilter; - const GLenum magFilterSave = texObj->Sampler.MagFilter; const GLint maxLevelSave = texObj->MaxLevel; const GLboolean genMipmapSave = texObj->GenerateMipmap; - const GLenum wrapSSave = texObj->Sampler.WrapS; - const GLenum wrapTSave = texObj->Sampler.WrapT; - const GLenum wrapRSave = texObj->Sampler.WrapR; - const GLenum srgbDecodeSave = texObj->Sampler.sRGBDecode; const GLenum srgbBufferSave = ctx->Color.sRGBEnabled; const GLuint fboSave = ctx->DrawBuffer->Name; const GLuint original_active_unit = ctx->Texture.CurrentUnit; @@ -2940,6 +2936,7 @@ _mesa_meta_GenerateMipmap(struct gl_context *ctx, GLenum target, GLuint dstLevel; const GLuint border = 0; const GLint slice = 0; + GLuint samplerSave; if (_mesa_meta_check_generate_mipmap_fallback(ctx, target, texObj)) { _mesa_generate_mipmap(ctx, target, texObj); @@ -2957,6 +2954,9 @@ _mesa_meta_GenerateMipmap(struct gl_context *ctx, GLenum target, _mesa_meta_begin(ctx, MESA_META_ALL); + samplerSave = ctx->Texture.Unit[ctx->Texture.CurrentUnit].Sampler ? + ctx->Texture.Unit[ctx->Texture.CurrentUnit].Sampler->Name : 0; + if (original_active_unit != 0) _mesa_BindTexture(target, texObj->Name); @@ -2987,20 +2987,29 @@ _mesa_meta_GenerateMipmap(struct gl_context *ctx, GLenum target, if (!mipmap->FBO) { _mesa_GenFramebuffersEXT(1, &mipmap->FBO); } + + if (!mipmap->Sampler) { + _mesa_GenSamplers(1, &mipmap->Sampler); + _mesa_BindSampler(ctx->Texture.CurrentUnit, mipmap->Sampler); + _mesa_SamplerParameteri(mipmap->Sampler, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR); + _mesa_SamplerParameteri(mipmap->Sampler, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + _mesa_SamplerParameteri(mipmap->Sampler, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); + _mesa_SamplerParameteri(mipmap->Sampler, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); + _mesa_SamplerParameteri(mipmap->Sampler, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE); + /* We don't want to encode or decode sRGB values; treat them as linear */ + if (ctx->Extensions.EXT_texture_sRGB_decode) { + _mesa_SamplerParameteri(mipmap->Sampler, GL_TEXTURE_SRGB_DECODE_EXT, + GL_SKIP_DECODE_EXT); + } + + } else { + _mesa_BindSampler(ctx->Texture.CurrentUnit, mipmap->Sampler); + } + _mesa_BindFramebufferEXT(GL_FRAMEBUFFER_EXT, mipmap->FBO); - _mesa_TexParameteri(target, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR); - _mesa_TexParameteri(target, GL_TEXTURE_MAG_FILTER, GL_LINEAR); _mesa_TexParameteri(target, GL_GENERATE_MIPMAP, GL_FALSE); - _mesa_TexParameteri(target, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); - _mesa_TexParameteri(target, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); - _mesa_TexParameteri(target, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE); - /* We don't want to encode or decode sRGB values; treat them as linear */ - if (ctx->Extensions.EXT_texture_sRGB_decode) { - _mesa_TexParameteri(target, GL_TEXTURE_SRGB_DECODE_EXT, - GL_SKIP_DECODE_EXT); - } if (ctx->Extensions.EXT_framebuffer_sRGB) { _mesa_set_enable(ctx, GL_FRAMEBUFFER_SRGB_EXT, GL_FALSE); } @@ -3127,25 +3136,18 @@ _mesa_meta_GenerateMipmap(struct gl_context *ctx, GLenum target, _mesa_DrawArrays(GL_TRIANGLE_FAN, 0, 4); } - if (ctx->Extensions.EXT_texture_sRGB_decode) { - _mesa_TexParameteri(target, GL_TEXTURE_SRGB_DECODE_EXT, - srgbDecodeSave); - } if (ctx->Extensions.EXT_framebuffer_sRGB && srgbBufferSave) { _mesa_set_enable(ctx, GL_FRAMEBUFFER_SRGB_EXT, GL_TRUE); } _mesa_lock_texture(ctx, texObj); /* relock */ + _mesa_BindSampler(ctx->Texture.CurrentUnit, samplerSave); + _mesa_meta_end(ctx); - _mesa_TexParameteri(target, GL_TEXTURE_MIN_FILTER, minFilterSave); - _mesa_TexParameteri(target, GL_TEXTURE_MAG_FILTER, magFilterSave); _mesa_TexParameteri(target, GL_TEXTURE_MAX_LEVEL, maxLevelSave); _mesa_TexParameteri(target, GL_GENERATE_MIPMAP, genMipmapSave); - _mesa_TexParameteri(target, GL_TEXTURE_WRAP_S, wrapSSave); - _mesa_TexParameteri(target, GL_TEXTURE_WRAP_T, wrapTSave); - _mesa_TexParameteri(target, GL_TEXTURE_WRAP_R, wrapRSave); _mesa_BindFramebufferEXT(GL_FRAMEBUFFER_EXT, fboSave); } @@ -3408,8 +3410,10 @@ decompress_texture_image(struct gl_context *ctx, const GLint maxLevelSave = texObj->MaxLevel; /* restrict sampling to the texture level of interest */ - _mesa_TexParameteri(target, GL_TEXTURE_BASE_LEVEL, texImage->Level); - _mesa_TexParameteri(target, GL_TEXTURE_MAX_LEVEL, texImage->Level); + if (target != GL_TEXTURE_RECTANGLE_ARB) { + _mesa_TexParameteri(target, GL_TEXTURE_BASE_LEVEL, texImage->Level); + _mesa_TexParameteri(target, GL_TEXTURE_MAX_LEVEL, texImage->Level); + } /* No sRGB decode or encode.*/ if (ctx->Extensions.EXT_framebuffer_sRGB) { diff --git a/mesalib/src/mesa/drivers/dri/common/utils.c b/mesalib/src/mesa/drivers/dri/common/utils.c index 328f56b50..6d8cb4e29 100644 --- a/mesalib/src/mesa/drivers/dri/common/utils.c +++ b/mesalib/src/mesa/drivers/dri/common/utils.c @@ -409,6 +409,11 @@ __DRIconfig **driConcatConfigs(__DRIconfig **a, __DRIconfig **all; int i, j, index; + if (a == NULL || a[0] == NULL) + return b; + else if (b == NULL || b[0] == NULL) + return a; + i = 0; while (a[i] != NULL) i++; diff --git a/mesalib/src/mesa/drivers/dri/swrast/swrast.c b/mesalib/src/mesa/drivers/dri/swrast/swrast.c index 22d71bf10..ca6bda027 100644 --- a/mesalib/src/mesa/drivers/dri/swrast/swrast.c +++ b/mesalib/src/mesa/drivers/dri/swrast/swrast.c @@ -771,6 +771,8 @@ dri_create_context(gl_api api, _mesa_enable_sw_extensions(mesaCtx); switch (api) { + case API_OPENGL_CORE: + /* XXX fix me, fall-through for now */ case API_OPENGL: _mesa_enable_1_3_extensions(mesaCtx); _mesa_enable_1_4_extensions(mesaCtx); diff --git a/mesalib/src/mesa/main/attrib.c b/mesalib/src/mesa/main/attrib.c index 8bc7c348f..9cab35b0c 100644 --- a/mesalib/src/mesa/main/attrib.c +++ b/mesalib/src/mesa/main/attrib.c @@ -135,6 +135,9 @@ struct gl_enable_attrib /* GL_ARB_point_sprite / GL_NV_point_sprite */ GLboolean PointSprite; GLboolean FragmentShaderATI; + + /* GL_ARB_framebuffer_sRGB / GL_EXT_framebuffer_sRGB */ + GLboolean sRGBEnabled; }; @@ -322,6 +325,9 @@ _mesa_PushAttrib(GLbitfield mask) attr->VertexProgramPointSize = ctx->VertexProgram.PointSizeEnabled; attr->VertexProgramTwoSide = ctx->VertexProgram.TwoSideEnabled; save_attrib_data(&head, GL_ENABLE_BIT, attr); + + /* GL_ARB_framebuffer_sRGB / GL_EXT_framebuffer_sRGB */ + attr->sRGBEnabled = ctx->Color.sRGBEnabled; } if (mask & GL_EVAL_BIT) { @@ -617,6 +623,10 @@ pop_enable_group(struct gl_context *ctx, const struct gl_enable_attrib *enable) enable->VertexProgramTwoSide, GL_VERTEX_PROGRAM_TWO_SIDE_ARB); + /* GL_ARB_framebuffer_sRGB / GL_EXT_framebuffer_sRGB */ + TEST_AND_UPDATE(ctx->Color.sRGBEnabled, enable->sRGBEnabled, + GL_FRAMEBUFFER_SRGB); + /* texture unit enables */ for (i = 0; i < ctx->Const.MaxTextureUnits; i++) { const GLbitfield enabled = enable->Texture[i]; @@ -981,6 +991,9 @@ _mesa_PopAttrib(void) _mesa_set_enable(ctx, GL_DITHER, color->DitherFlag); _mesa_ClampColorARB(GL_CLAMP_FRAGMENT_COLOR_ARB, color->ClampFragmentColor); _mesa_ClampColorARB(GL_CLAMP_READ_COLOR_ARB, color->ClampReadColor); + + /* GL_ARB_framebuffer_sRGB / GL_EXT_framebuffer_sRGB */ + _mesa_set_enable(ctx, GL_FRAMEBUFFER_SRGB, color->sRGBEnabled); } break; case GL_CURRENT_BIT: diff --git a/mesalib/src/mesa/main/bufferobj.c b/mesalib/src/mesa/main/bufferobj.c index 48edd89c9..22d7927bb 100644 --- a/mesalib/src/mesa/main/bufferobj.c +++ b/mesalib/src/mesa/main/bufferobj.c @@ -656,6 +656,28 @@ _mesa_free_buffer_objects( struct gl_context *ctx ) ctx->UniformBufferBindings = NULL; } +static void +handle_bind_buffer_gen(struct gl_context *ctx, + GLenum target, + GLuint buffer, + struct gl_buffer_object **buf_handle) +{ + struct gl_buffer_object *buf = *buf_handle; + + if (!buf || buf == &DummyBufferObject) { + /* If this is a new buffer object id, or one which was generated but + * never used before, allocate a buffer object now. + */ + ASSERT(ctx->Driver.NewBufferObject); + buf = ctx->Driver.NewBufferObject(ctx, buffer, target); + if (!buf) { + _mesa_error(ctx, GL_OUT_OF_MEMORY, "glBindBufferARB"); + return; + } + _mesa_HashInsert(ctx->Shared->BufferObjects, buffer, buf); + *buf_handle = buf; + } +} /** * Bind the specified target to buffer for the specified context. @@ -691,18 +713,7 @@ bind_buffer_object(struct gl_context *ctx, GLenum target, GLuint buffer) else { /* non-default buffer object */ newBufObj = _mesa_lookup_bufferobj(ctx, buffer); - if (!newBufObj || newBufObj == &DummyBufferObject) { - /* If this is a new buffer object id, or one which was generated but - * never used before, allocate a buffer object now. - */ - ASSERT(ctx->Driver.NewBufferObject); - newBufObj = ctx->Driver.NewBufferObject(ctx, buffer, target); - if (!newBufObj) { - _mesa_error(ctx, GL_OUT_OF_MEMORY, "glBindBufferARB"); - return; - } - _mesa_HashInsert(ctx->Shared->BufferObjects, buffer, newBufObj); - } + handle_bind_buffer_gen(ctx, target, buffer, &newBufObj); } /* bind new buffer */ @@ -875,6 +886,13 @@ _mesa_DeleteBuffersARB(GLsizei n, const GLuint *ids) } } + /* unbind UBO binding points */ + for (j = 0; j < ctx->Const.MaxUniformBufferBindings; j++) { + if (ctx->UniformBufferBindings[j].BufferObject == bufObj) { + _mesa_BindBufferBase( GL_UNIFORM_BUFFER, j, 0 ); + } + } + if (ctx->UniformBuffer == bufObj) { _mesa_BindBufferARB( GL_UNIFORM_BUFFER, 0 ); } @@ -2089,6 +2107,7 @@ _mesa_BindBufferRange(GLenum target, GLuint index, } else { bufObj = _mesa_lookup_bufferobj(ctx, buffer); } + handle_bind_buffer_gen(ctx, target, buffer, &bufObj); if (!bufObj) { _mesa_error(ctx, GL_INVALID_OPERATION, @@ -2134,6 +2153,7 @@ _mesa_BindBufferBase(GLenum target, GLuint index, GLuint buffer) } else { bufObj = _mesa_lookup_bufferobj(ctx, buffer); } + handle_bind_buffer_gen(ctx, target, buffer, &bufObj); if (!bufObj) { _mesa_error(ctx, GL_INVALID_OPERATION, diff --git a/mesalib/src/mesa/main/condrender.c b/mesalib/src/mesa/main/condrender.c index 57f371521..bfd2b0818 100644 --- a/mesalib/src/mesa/main/condrender.c +++ b/mesalib/src/mesa/main/condrender.c @@ -139,6 +139,8 @@ _mesa_check_conditional_render(struct gl_context *ctx) case GL_QUERY_BY_REGION_NO_WAIT: /* fall-through */ case GL_QUERY_NO_WAIT: + if (!q->Ready) + ctx->Driver.CheckQuery(ctx, q); return q->Ready ? (q->Result > 0) : GL_TRUE; default: _mesa_problem(ctx, "Bad cond render mode %s in " diff --git a/mesalib/src/mesa/main/context.c b/mesalib/src/mesa/main/context.c index 7616eb78b..b78bceeb9 100644 --- a/mesalib/src/mesa/main/context.c +++ b/mesalib/src/mesa/main/context.c @@ -476,7 +476,8 @@ _mesa_init_current(struct gl_context *ctx) * Important: drivers should override these with actual limits. */ static void -init_program_limits(GLenum type, struct gl_program_constants *prog) +init_program_limits(struct gl_context *ctx, GLenum type, + struct gl_program_constants *prog) { prog->MaxInstructions = MAX_PROGRAM_INSTRUCTIONS; prog->MaxAluInstructions = MAX_PROGRAM_INSTRUCTIONS; @@ -542,7 +543,9 @@ init_program_limits(GLenum type, struct gl_program_constants *prog) prog->LowInt = prog->HighInt = prog->MediumInt; prog->MaxUniformBlocks = 12; - prog->MaxCombinedUniformComponents = prog->MaxUniformComponents; + prog->MaxCombinedUniformComponents = (prog->MaxUniformComponents + + ctx->Const.MaxUniformBlockSize / 4 * + prog->MaxUniformBlocks); } @@ -589,14 +592,21 @@ _mesa_init_constants(struct gl_context *ctx) ctx->Const.MaxSpotExponent = 128.0; ctx->Const.MaxViewportWidth = MAX_VIEWPORT_WIDTH; ctx->Const.MaxViewportHeight = MAX_VIEWPORT_HEIGHT; + + /** GL_ARB_uniform_buffer_object */ + ctx->Const.MaxCombinedUniformBlocks = 36; + ctx->Const.MaxUniformBufferBindings = 36; + ctx->Const.MaxUniformBlockSize = 16384; + ctx->Const.UniformBufferOffsetAlignment = 1; + #if FEATURE_ARB_vertex_program - init_program_limits(GL_VERTEX_PROGRAM_ARB, &ctx->Const.VertexProgram); + init_program_limits(ctx, GL_VERTEX_PROGRAM_ARB, &ctx->Const.VertexProgram); #endif #if FEATURE_ARB_fragment_program - init_program_limits(GL_FRAGMENT_PROGRAM_ARB, &ctx->Const.FragmentProgram); + init_program_limits(ctx, GL_FRAGMENT_PROGRAM_ARB, &ctx->Const.FragmentProgram); #endif #if FEATURE_ARB_geometry_shader4 - init_program_limits(MESA_GEOMETRY_PROGRAM, &ctx->Const.GeometryProgram); + init_program_limits(ctx, MESA_GEOMETRY_PROGRAM, &ctx->Const.GeometryProgram); #endif ctx->Const.MaxProgramMatrices = MAX_PROGRAM_MATRICES; ctx->Const.MaxProgramMatrixStackDepth = MAX_PROGRAM_MATRIX_STACK_DEPTH; @@ -655,12 +665,6 @@ _mesa_init_constants(struct gl_context *ctx) ctx->Const.MaxTransformFeedbackInterleavedComponents = 4 * MAX_FEEDBACK_ATTRIBS; ctx->Const.MaxVertexStreams = 1; - /** GL_ARB_uniform_buffer_object */ - ctx->Const.MaxCombinedUniformBlocks = 36; - ctx->Const.MaxUniformBufferBindings = 36; - ctx->Const.MaxUniformBlockSize = 16384; - ctx->Const.UniformBufferOffsetAlignment = 1; - /* GL 3.2: hard-coded for now: */ ctx->Const.ProfileMask = GL_CONTEXT_COMPATIBILITY_PROFILE_BIT; diff --git a/mesalib/src/mesa/main/dd.h b/mesalib/src/mesa/main/dd.h index e60d019bb..226897b19 100644 --- a/mesalib/src/mesa/main/dd.h +++ b/mesalib/src/mesa/main/dd.h @@ -208,8 +208,6 @@ struct dd_function_table { */ void (*TexImage)(struct gl_context *ctx, GLuint dims, struct gl_texture_image *texImage, - GLint internalFormat, - GLint width, GLint height, GLint depth, GLint border, GLenum format, GLenum type, const GLvoid *pixels, const struct gl_pixelstore_attrib *packing); @@ -273,9 +271,6 @@ struct dd_function_table { */ void (*CompressedTexImage)(struct gl_context *ctx, GLuint dims, struct gl_texture_image *texImage, - GLint internalFormat, - GLsizei width, GLsizei height, GLsizei depth, - GLint border, GLsizei imageSize, const GLvoid *data); /** @@ -329,9 +324,7 @@ struct dd_function_table { /** Called to allocate memory for a single texture image */ GLboolean (*AllocTextureImageBuffer)(struct gl_context *ctx, - struct gl_texture_image *texImage, - gl_format format, GLsizei width, - GLsizei height, GLsizei depth); + struct gl_texture_image *texImage); /** Free the memory for a single texture image */ void (*FreeTextureImageBuffer)(struct gl_context *ctx, diff --git a/mesalib/src/mesa/main/dlist.c b/mesalib/src/mesa/main/dlist.c index 510fd1e18..5a813e98a 100644 --- a/mesalib/src/mesa/main/dlist.c +++ b/mesalib/src/mesa/main/dlist.c @@ -482,6 +482,9 @@ typedef enum OPCODE_DRAW_TRANSFORM_FEEDBACK_INSTANCED, OPCODE_DRAW_TRANSFORM_FEEDBACK_STREAM_INSTANCED, + /* ARB_uniform_buffer_object */ + OPCODE_UNIFORM_BLOCK_BINDING, + /* The following three are meta instructions */ OPCODE_ERROR, /* raise compiled-in error */ OPCODE_CONTINUE, @@ -7582,6 +7585,23 @@ save_EndConditionalRender(void) } } +static void GLAPIENTRY +save_UniformBlockBinding(GLuint prog, GLuint index, GLuint binding) +{ + GET_CURRENT_CONTEXT(ctx); + Node *n; + ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx); + n = alloc_instruction(ctx, OPCODE_UNIFORM_BLOCK_BINDING, 3); + if (n) { + n[1].ui = prog; + n[2].ui = index; + n[3].ui = binding; + } + if (ctx->ExecuteFlag) { + CALL_UniformBlockBinding(ctx->Exec, (prog, index, binding)); + } +} + /** * Save an error-generating command into display list. @@ -8877,6 +8897,10 @@ execute_list(struct gl_context *ctx, GLuint list) CALL_EndConditionalRenderNV(ctx->Exec, ()); break; + case OPCODE_UNIFORM_BLOCK_BINDING: + CALL_UniformBlockBinding(ctx->Exec, (n[1].ui, n[2].ui, n[3].ui)); + break; + case OPCODE_CONTINUE: n = (Node *) n[1].next; break; @@ -10632,6 +10656,9 @@ _mesa_create_save_table(void) /* GL_ARB_debug_output (no dlist support) */ _mesa_init_errors_dispatch(table); + /* GL_ARB_uniform_buffer_object */ + SET_UniformBlockBinding(table, save_UniformBlockBinding); + /* GL_NV_primitive_restart */ SET_PrimitiveRestartIndexNV(table, _mesa_PrimitiveRestartIndex); diff --git a/mesalib/src/mesa/main/enable.c b/mesalib/src/mesa/main/enable.c index c811f2a9c..f8110578a 100644 --- a/mesalib/src/mesa/main/enable.c +++ b/mesalib/src/mesa/main/enable.c @@ -902,7 +902,7 @@ _mesa_set_enable(struct gl_context *ctx, GLenum cap, GLboolean state) * GL_PRIMITIVE_RESTART_NV (which is client state). */ case GL_PRIMITIVE_RESTART: - if (ctx->VersionMajor * 10 + ctx->VersionMinor < 31) { + if (ctx->Version < 31) { goto invalid_enum_error; } if (ctx->Array.PrimitiveRestart != state) { @@ -1419,7 +1419,7 @@ _mesa_IsEnabled( GLenum cap ) /* GL 3.1 primitive restart */ case GL_PRIMITIVE_RESTART: - if (ctx->VersionMajor * 10 + ctx->VersionMinor < 31) { + if (ctx->Version < 31) { goto invalid_enum_error; } return ctx->Array.PrimitiveRestart; diff --git a/mesalib/src/mesa/main/fbobject.c b/mesalib/src/mesa/main/fbobject.c index eb03b0918..d558d7f87 100644 --- a/mesalib/src/mesa/main/fbobject.c +++ b/mesalib/src/mesa/main/fbobject.c @@ -1226,7 +1226,7 @@ _mesa_base_fbo_format(struct gl_context *ctx, GLenum internalFormat) case GL_RGBA8I_EXT: case GL_RGBA16I_EXT: case GL_RGBA32I_EXT: - return ctx->VersionMajor >= 3 || + return ctx->Version >= 30 || ctx->Extensions.EXT_texture_integer ? GL_RGBA : 0; case GL_RGB8UI_EXT: @@ -1235,7 +1235,7 @@ _mesa_base_fbo_format(struct gl_context *ctx, GLenum internalFormat) case GL_RGB8I_EXT: case GL_RGB16I_EXT: case GL_RGB32I_EXT: - return ctx->VersionMajor >= 3 || + return ctx->Version >= 30 || ctx->Extensions.EXT_texture_integer ? GL_RGB : 0; case GL_R8UI: @@ -1244,7 +1244,7 @@ _mesa_base_fbo_format(struct gl_context *ctx, GLenum internalFormat) case GL_R16I: case GL_R32UI: case GL_R32I: - return ctx->VersionMajor >= 3 || + return ctx->Version >= 30 || (ctx->Extensions.ARB_texture_rg && ctx->Extensions.EXT_texture_integer) ? GL_RED : 0; @@ -1254,7 +1254,7 @@ _mesa_base_fbo_format(struct gl_context *ctx, GLenum internalFormat) case GL_RG16I: case GL_RG32UI: case GL_RG32I: - return ctx->VersionMajor >= 3 || + return ctx->Version >= 30 || (ctx->Extensions.ARB_texture_rg && ctx->Extensions.EXT_texture_integer) ? GL_RG : 0; diff --git a/mesalib/src/mesa/main/get.c b/mesalib/src/mesa/main/get.c index 16ad2c430..332dfaf7f 100644 --- a/mesalib/src/mesa/main/get.c +++ b/mesalib/src/mesa/main/get.c @@ -1303,8 +1303,8 @@ static const struct value_desc values[] = { /* GL 3.0 */ { GL_NUM_EXTENSIONS, LOC_CUSTOM, TYPE_INT, 0, extra_version_30 }, - { GL_MAJOR_VERSION, CONTEXT_INT(VersionMajor), extra_version_30 }, - { GL_MINOR_VERSION, CONTEXT_INT(VersionMinor), extra_version_30 }, + { GL_MAJOR_VERSION, LOC_CUSTOM, TYPE_INT, 0, extra_version_30 }, + { GL_MINOR_VERSION, LOC_CUSTOM, TYPE_INT, 0, extra_version_30 }, { GL_CONTEXT_FLAGS, CONTEXT_INT(Const.ContextFlags), extra_version_30 }, /* GL3.0 / GL_EXT_framebuffer_sRGB */ @@ -1486,6 +1486,13 @@ find_custom_value(struct gl_context *ctx, const struct value_desc *d, union valu GLuint unit, *p; switch (d->pname) { + case GL_MAJOR_VERSION: + v->value_int = ctx->Version / 10; + break; + case GL_MINOR_VERSION: + v->value_int = ctx->Version % 10; + break; + case GL_TEXTURE_1D: case GL_TEXTURE_2D: case GL_TEXTURE_3D: @@ -1848,7 +1855,7 @@ find_custom_value(struct gl_context *ctx, const struct value_desc *d, union valu static GLboolean check_extra(struct gl_context *ctx, const char *func, const struct value_desc *d) { - const GLuint version = ctx->VersionMajor * 10 + ctx->VersionMinor; + const GLuint version = ctx->Version; int total, enabled; const int *e; diff --git a/mesalib/src/mesa/main/glformats.c b/mesalib/src/mesa/main/glformats.c index 4fe0ae078..daf1b7667 100644 --- a/mesalib/src/mesa/main/glformats.c +++ b/mesalib/src/mesa/main/glformats.c @@ -1237,7 +1237,7 @@ _mesa_error_check_format_and_type(const struct gl_context *ctx, case GL_UNSIGNED_SHORT: case GL_INT: case GL_UNSIGNED_INT: - return (ctx->VersionMajor >= 3 || + return (ctx->Version >= 30 || ctx->Extensions.EXT_texture_integer) ? GL_NO_ERROR : GL_INVALID_ENUM; default: @@ -1252,7 +1252,7 @@ _mesa_error_check_format_and_type(const struct gl_context *ctx, case GL_UNSIGNED_SHORT: case GL_INT: case GL_UNSIGNED_INT: - return (ctx->VersionMajor >= 3 || + return (ctx->Version >= 30 || ctx->Extensions.EXT_texture_integer) ? GL_NO_ERROR : GL_INVALID_ENUM; case GL_UNSIGNED_BYTE_3_3_2: @@ -1274,7 +1274,7 @@ _mesa_error_check_format_and_type(const struct gl_context *ctx, case GL_INT: case GL_UNSIGNED_INT: /* NOTE: no packed formats w/ BGR format */ - return (ctx->VersionMajor >= 3 || + return (ctx->Version >= 30 || ctx->Extensions.EXT_texture_integer) ? GL_NO_ERROR : GL_INVALID_ENUM; default: @@ -1290,7 +1290,7 @@ _mesa_error_check_format_and_type(const struct gl_context *ctx, case GL_UNSIGNED_SHORT: case GL_INT: case GL_UNSIGNED_INT: - return (ctx->VersionMajor >= 3 || + return (ctx->Version >= 30 || ctx->Extensions.EXT_texture_integer) ? GL_NO_ERROR : GL_INVALID_ENUM; case GL_UNSIGNED_SHORT_4_4_4_4: diff --git a/mesalib/src/mesa/main/mipmap.c b/mesalib/src/mesa/main/mipmap.c index 9f531ae20..00d3e8f9e 100644 --- a/mesalib/src/mesa/main/mipmap.c +++ b/mesalib/src/mesa/main/mipmap.c @@ -1865,8 +1865,7 @@ _mesa_prepare_mipmap_level(struct gl_context *ctx, width, height, depth, border, intFormat, format); - ctx->Driver.AllocTextureImageBuffer(ctx, dstImage, - format, width, height, depth); + ctx->Driver.AllocTextureImageBuffer(ctx, dstImage); /* in case the mipmap level is part of an FBO: */ _mesa_update_fbo_texture(ctx, texObj, face, level); diff --git a/mesalib/src/mesa/main/mtypes.h b/mesalib/src/mesa/main/mtypes.h index e8adac99d..8fcb6b456 100644 --- a/mesalib/src/mesa/main/mtypes.h +++ b/mesalib/src/mesa/main/mtypes.h @@ -3424,8 +3424,8 @@ struct gl_context /** Extension information */ struct gl_extensions Extensions; - /** Version info */ - GLuint VersionMajor, VersionMinor; + /** GL version integer, for example 31 for GL 3.1, or 20 for GLES 2.0. */ + GLuint Version; char *VersionString; /** \name State attribute stack (for glPush/PopAttrib) */ diff --git a/mesalib/src/mesa/main/samplerobj.h b/mesalib/src/mesa/main/samplerobj.h index 2b0cd7946..e70ee4881 100644 --- a/mesalib/src/mesa/main/samplerobj.h +++ b/mesalib/src/mesa/main/samplerobj.h @@ -33,8 +33,10 @@ _mesa_get_samplerobj(struct gl_context *ctx, GLuint unit) { if (ctx->Texture.Unit[unit].Sampler) return ctx->Texture.Unit[unit].Sampler; - else + else if (ctx->Texture.Unit[unit]._Current) return &ctx->Texture.Unit[unit]._Current->Sampler; + else + return NULL; } diff --git a/mesalib/src/mesa/main/texformat.c b/mesalib/src/mesa/main/texformat.c index d360f0e22..275e69e31 100644 --- a/mesalib/src/mesa/main/texformat.c +++ b/mesalib/src/mesa/main/texformat.c @@ -719,7 +719,7 @@ _mesa_choose_tex_format( struct gl_context *ctx, GLint internalFormat, } } - if (ctx->VersionMajor >= 3 || + if (ctx->Version >= 30 || ctx->Extensions.EXT_texture_integer) { switch (internalFormat) { case GL_RGB8UI_EXT: @@ -838,7 +838,7 @@ _mesa_choose_tex_format( struct gl_context *ctx, GLint internalFormat, } } - if (ctx->VersionMajor >= 3 || + if (ctx->Version >= 30 || (ctx->Extensions.ARB_texture_rg && ctx->Extensions.EXT_texture_integer)) { switch (internalFormat) { diff --git a/mesalib/src/mesa/main/teximage.c b/mesalib/src/mesa/main/teximage.c index d2746c6f3..569adc16a 100644 --- a/mesalib/src/mesa/main/teximage.c +++ b/mesalib/src/mesa/main/teximage.c @@ -332,7 +332,7 @@ _mesa_base_tex_format( struct gl_context *ctx, GLint internalFormat ) } #endif /* FEATURE_EXT_texture_sRGB */ - if (ctx->VersionMajor >= 3 || + if (ctx->Version >= 30 || ctx->Extensions.EXT_texture_integer) { switch (internalFormat) { case GL_RGBA8UI_EXT: @@ -406,7 +406,7 @@ _mesa_base_tex_format( struct gl_context *ctx, GLint internalFormat ) case GL_R16UI: case GL_R32I: case GL_R32UI: - if (ctx->VersionMajor < 3 && !ctx->Extensions.EXT_texture_integer) + if (ctx->Version < 30 && !ctx->Extensions.EXT_texture_integer) break; /* FALLTHROUGH */ case GL_R8: @@ -431,7 +431,7 @@ _mesa_base_tex_format( struct gl_context *ctx, GLint internalFormat ) case GL_RG16UI: case GL_RG32I: case GL_RG32UI: - if (ctx->VersionMajor < 3 && !ctx->Extensions.EXT_texture_integer) + if (ctx->Version < 30 && !ctx->Extensions.EXT_texture_integer) break; /* FALLTHROUGH */ case GL_RG: @@ -1732,7 +1732,7 @@ texture_error_check( struct gl_context *ctx, target != GL_TEXTURE_RECTANGLE_ARB && target != GL_PROXY_TEXTURE_RECTANGLE_ARB && !((_mesa_is_cube_face(target) || target == GL_PROXY_TEXTURE_CUBE_MAP) && - (ctx->VersionMajor >= 3 || ctx->Extensions.EXT_gpu_shader4))) { + (ctx->Version >= 30 || ctx->Extensions.EXT_gpu_shader4))) { if (!isProxy) _mesa_error(ctx, GL_INVALID_ENUM, "glTexImage(target/internalFormat)"); @@ -1764,7 +1764,7 @@ texture_error_check( struct gl_context *ctx, } /* additional checks for integer textures */ - if ((ctx->VersionMajor >= 3 || ctx->Extensions.EXT_texture_integer) && + if ((ctx->Version >= 30 || ctx->Extensions.EXT_texture_integer) && (_mesa_is_enum_format_integer(format) != _mesa_is_enum_format_integer(internalFormat))) { if (!isProxy) { @@ -1937,7 +1937,7 @@ subtexture_error_check2( struct gl_context *ctx, GLuint dimensions, } } - if (ctx->VersionMajor >= 3 || ctx->Extensions.EXT_texture_integer) { + if (ctx->Version >= 30 || ctx->Extensions.EXT_texture_integer) { /* both source and dest must be integer-valued, or neither */ if (_mesa_is_format_integer_color(destTex->TexFormat) != _mesa_is_enum_format_integer(format)) { @@ -2616,8 +2616,7 @@ teximage(struct gl_context *ctx, GLuint dims, border, internalFormat, texFormat); /* Give the texture to the driver. <pixels> may be null. */ - ctx->Driver.TexImage(ctx, dims, texImage, internalFormat, - width, height, depth, border, format, + ctx->Driver.TexImage(ctx, dims, texImage, format, type, pixels, unpack); check_gen_mipmap(ctx, target, texObj, level); @@ -2945,8 +2944,8 @@ copyteximage(struct gl_context *ctx, GLuint dims, border, internalFormat, texFormat); /* Allocate texture memory (no pixel data yet) */ - ctx->Driver.TexImage(ctx, dims, texImage, internalFormat, - width, height, 1, border, GL_NONE, GL_NONE, + ctx->Driver.TexImage(ctx, dims, texImage, + GL_NONE, GL_NONE, NULL, &ctx->Unpack); if (_mesa_clip_copytexsubimage(ctx, &dstX, &dstY, &srcX, &srcY, @@ -3551,10 +3550,8 @@ compressedteximage(struct gl_context *ctx, GLuint dims, width, height, depth, border, internalFormat, texFormat); - ctx->Driver.CompressedTexImage(ctx, dims, texImage, - internalFormat, - width, height, depth, - border, imageSize, data); + ctx->Driver.CompressedTexImage(ctx, dims, texImage, imageSize, + data); check_gen_mipmap(ctx, target, texObj, level); @@ -3860,8 +3857,7 @@ validate_texbuffer_format(const struct gl_context *ctx, GLenum internalFormat) * any mention of R/RG formats, but they appear in the GL 3.1 core * specification. */ - if (ctx->VersionMajor < 3 || - (ctx->VersionMajor == 3 && ctx->VersionMinor == 0)) { + if (ctx->Version <= 30) { GLenum base_format = _mesa_get_format_base_format(format); if (base_format == GL_R || base_format == GL_RG) diff --git a/mesalib/src/mesa/main/texobj.c b/mesalib/src/mesa/main/texobj.c index 529a6d449..f70da4fbc 100644 --- a/mesalib/src/mesa/main/texobj.c +++ b/mesalib/src/mesa/main/texobj.c @@ -807,8 +807,7 @@ _mesa_get_fallback_texture(struct gl_context *ctx, gl_texture_index tex) 0, /* border */ GL_RGBA, texFormat); - ctx->Driver.TexImage(ctx, dims, texImage, GL_RGBA, - width, height, depth, 0, + ctx->Driver.TexImage(ctx, dims, texImage, GL_RGBA, GL_UNSIGNED_BYTE, texel, &ctx->DefaultPacking); } diff --git a/mesalib/src/mesa/main/texparam.c b/mesalib/src/mesa/main/texparam.c index 9213499a4..9e7c3e457 100644 --- a/mesalib/src/mesa/main/texparam.c +++ b/mesalib/src/mesa/main/texparam.c @@ -1016,7 +1016,7 @@ _mesa_GetTexLevelParameteriv( GLenum target, GLint level, *params = _mesa_get_format_bits(texFormat, pname); break; case GL_TEXTURE_SHARED_SIZE: - if (ctx->VersionMajor < 3 && + if (ctx->Version < 30 && !ctx->Extensions.EXT_texture_shared_exponent) goto invalid_pname; *params = texFormat == MESA_FORMAT_RGB9_E5_FLOAT ? 5 : 0; diff --git a/mesalib/src/mesa/main/texstore.c b/mesalib/src/mesa/main/texstore.c index ab9fdf26d..544c08d73 100644 --- a/mesalib/src/mesa/main/texstore.c +++ b/mesalib/src/mesa/main/texstore.c @@ -4336,25 +4336,22 @@ void _mesa_store_teximage(struct gl_context *ctx, GLuint dims, struct gl_texture_image *texImage, - GLint internalFormat, - GLint width, GLint height, GLint depth, GLint border, GLenum format, GLenum type, const GLvoid *pixels, const struct gl_pixelstore_attrib *packing) { assert(dims == 1 || dims == 2 || dims == 3); - if (width == 0 || height == 0 || depth == 0) + if (texImage->Width == 0 || texImage->Height == 0 || texImage->Depth == 0) return; /* allocate storage for texture data */ - if (!ctx->Driver.AllocTextureImageBuffer(ctx, texImage, texImage->TexFormat, - width, height, depth)) { + if (!ctx->Driver.AllocTextureImageBuffer(ctx, texImage)) { _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexImage%uD", dims); return; } store_texsubimage(ctx, texImage, - 0, 0, 0, width, height, depth, + 0, 0, 0, texImage->Width, texImage->Height, texImage->Depth, format, type, pixels, packing, "glTexImage"); } @@ -4382,9 +4379,6 @@ _mesa_store_texsubimage(struct gl_context *ctx, GLuint dims, void _mesa_store_compressed_teximage(struct gl_context *ctx, GLuint dims, struct gl_texture_image *texImage, - GLint internalFormat, - GLint width, GLint height, GLint depth, - GLint border, GLsizei imageSize, const GLvoid *data) { /* only 2D compressed images are supported at this time */ @@ -4403,15 +4397,14 @@ _mesa_store_compressed_teximage(struct gl_context *ctx, GLuint dims, ASSERT(texImage->Depth == 1); /* allocate storage for texture data */ - if (!ctx->Driver.AllocTextureImageBuffer(ctx, texImage, texImage->TexFormat, - width, height, 1)) { + if (!ctx->Driver.AllocTextureImageBuffer(ctx, texImage)) { _mesa_error(ctx, GL_OUT_OF_MEMORY, "glCompressedTexImage2D"); return; } _mesa_store_compressed_texsubimage(ctx, dims, texImage, 0, 0, 0, - width, height, depth, + texImage->Width, texImage->Height, texImage->Depth, texImage->TexFormat, imageSize, data); } diff --git a/mesalib/src/mesa/main/texstore.h b/mesalib/src/mesa/main/texstore.h index 5a1c01423..7af532d65 100644 --- a/mesalib/src/mesa/main/texstore.h +++ b/mesalib/src/mesa/main/texstore.h @@ -93,8 +93,6 @@ extern void _mesa_store_teximage(struct gl_context *ctx, GLuint dims, struct gl_texture_image *texImage, - GLint internalFormat, - GLint width, GLint height, GLint depth, GLint border, GLenum format, GLenum type, const GLvoid *pixels, const struct gl_pixelstore_attrib *packing); @@ -111,9 +109,6 @@ _mesa_store_texsubimage(struct gl_context *ctx, GLuint dims, extern void _mesa_store_compressed_teximage(struct gl_context *ctx, GLuint dims, struct gl_texture_image *texImage, - GLint internalFormat, - GLint width, GLint height, GLint depth, - GLint border, GLsizei imageSize, const GLvoid *data); diff --git a/mesalib/src/mesa/main/varray.c b/mesalib/src/mesa/main/varray.c index 7ec7cfee6..327fabbc1 100644 --- a/mesalib/src/mesa/main/varray.c +++ b/mesalib/src/mesa/main/varray.c @@ -568,7 +568,7 @@ get_vertex_array_attrib(struct gl_context *ctx, GLuint index, GLenum pname, case GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING_ARB: return array->BufferObj->Name; case GL_VERTEX_ATTRIB_ARRAY_INTEGER: - if (ctx->VersionMajor >= 3 || ctx->Extensions.EXT_gpu_shader4) { + if (ctx->Version >= 30 || ctx->Extensions.EXT_gpu_shader4) { return array->Integer; } goto error; @@ -1092,8 +1092,7 @@ _mesa_PrimitiveRestartIndex(GLuint index) { GET_CURRENT_CONTEXT(ctx); - if (!ctx->Extensions.NV_primitive_restart && - ctx->VersionMajor * 10 + ctx->VersionMinor < 31) { + if (!ctx->Extensions.NV_primitive_restart && ctx->Version < 31) { _mesa_error(ctx, GL_INVALID_OPERATION, "glPrimitiveRestartIndexNV()"); return; } diff --git a/mesalib/src/mesa/main/version.c b/mesalib/src/mesa/main/version.c index 85e623142..59c81aedc 100644 --- a/mesalib/src/mesa/main/version.c +++ b/mesalib/src/mesa/main/version.c @@ -33,22 +33,25 @@ * are point-separated version numbers, such as "3.0". */ static void -override_version(struct gl_context *ctx, GLuint *major, GLuint *minor) +override_version(struct gl_context *ctx) { const char *env_var = "MESA_GL_VERSION_OVERRIDE"; const char *version; int n; + int major, minor; version = getenv(env_var); if (!version) { return; } - n = sscanf(version, "%u.%u", major, minor); + n = sscanf(version, "%u.%u", &major, &minor); if (n != 2) { fprintf(stderr, "error: invalid value for %s: %s\n", env_var, version); return; } + + ctx->Version = major * 10 + minor; } /** @@ -218,10 +221,9 @@ compute_version(struct gl_context *ctx) minor = 2; } - ctx->VersionMajor = major; - ctx->VersionMinor = minor; + ctx->Version = major * 10 + minor; - override_version(ctx, &ctx->VersionMajor, &ctx->VersionMinor); + override_version(ctx); ctx->VersionString = (char *) malloc(max); if (ctx->VersionString) { @@ -231,7 +233,7 @@ compute_version(struct gl_context *ctx) " (" MESA_GIT_SHA1 ")" #endif , - ctx->VersionMajor, ctx->VersionMinor); + ctx->Version / 10, ctx->Version % 10); } } @@ -248,11 +250,9 @@ compute_version_es1(struct gl_context *ctx) ctx->Extensions.EXT_point_parameters); if (ver_1_1) { - ctx->VersionMajor = 1; - ctx->VersionMinor = 1; + ctx->Version = 11; } else if (ver_1_0) { - ctx->VersionMajor = 1; - ctx->VersionMinor = 0; + ctx->Version = 10; } else { _mesa_problem(ctx, "Incomplete OpenGL ES 1.0 support."); } @@ -265,7 +265,7 @@ compute_version_es1(struct gl_context *ctx) " (" MESA_GIT_SHA1 ")" #endif , - ctx->VersionMinor); + ctx->Version % 10); } } @@ -285,8 +285,7 @@ compute_version_es2(struct gl_context *ctx) ctx->Extensions.ARB_texture_non_power_of_two && ctx->Extensions.EXT_blend_equation_separate); if (ver_2_0) { - ctx->VersionMajor = 2; - ctx->VersionMinor = 0; + ctx->Version = 20; } else { _mesa_problem(ctx, "Incomplete OpenGL ES 2.0 support."); } @@ -303,14 +302,14 @@ compute_version_es2(struct gl_context *ctx) } /** - * Set the context's VersionMajor, VersionMinor, VersionString fields. + * Set the context's Version and VersionString fields. * This should only be called once as part of context initialization * or to perform version check for GLX_ARB_create_context_profile. */ void _mesa_compute_version(struct gl_context *ctx) { - if (ctx->VersionMajor) + if (ctx->Version) return; switch (ctx->API) { diff --git a/mesalib/src/mesa/program/ir_to_mesa.cpp b/mesalib/src/mesa/program/ir_to_mesa.cpp index 255a8a76a..d675da269 100644 --- a/mesalib/src/mesa/program/ir_to_mesa.cpp +++ b/mesalib/src/mesa/program/ir_to_mesa.cpp @@ -1456,6 +1456,10 @@ ir_to_mesa_visitor::visit(ir_expression *ir) emit(ir, OPCODE_MOV, result_dst, op[0]); break; + case ir_binop_ubo_load: + assert(!"not supported"); + break; + case ir_quadop_vector: /* This operation should have already been handled. */ @@ -2455,7 +2459,7 @@ _mesa_generate_parameters_list_for_uniforms(struct gl_shader_program ir_variable *var = ((ir_instruction *) node)->as_variable(); if ((var == NULL) || (var->mode != ir_var_uniform) - || (strncmp(var->name, "gl_", 3) == 0)) + || var->uniform_block != -1 || (strncmp(var->name, "gl_", 3) == 0)) continue; add.process(var); diff --git a/mesalib/src/mesa/state_tracker/st_cb_fbo.c b/mesalib/src/mesa/state_tracker/st_cb_fbo.c index 7eef5c659..40e3677f6 100644 --- a/mesalib/src/mesa/state_tracker/st_cb_fbo.c +++ b/mesalib/src/mesa/state_tracker/st_cb_fbo.c @@ -458,6 +458,12 @@ st_render_texture(struct gl_context *ctx, * passed to the pipe as a (color/depth) render target. */ st_invalidate_state(ctx, _NEW_BUFFERS); + + + /* Need to trigger a call to update_framebuffer() since we just + * attached a new renderbuffer. + */ + ctx->NewState |= _NEW_BUFFERS; } diff --git a/mesalib/src/mesa/state_tracker/st_cb_texture.c b/mesalib/src/mesa/state_tracker/st_cb_texture.c index a7f57b96f..a7c732bd7 100644 --- a/mesalib/src/mesa/state_tracker/st_cb_texture.c +++ b/mesalib/src/mesa/state_tracker/st_cb_texture.c @@ -415,20 +415,18 @@ guess_and_alloc_texture(struct st_context *st, */ static GLboolean st_AllocTextureImageBuffer(struct gl_context *ctx, - struct gl_texture_image *texImage, - gl_format format, GLsizei width, - GLsizei height, GLsizei depth) + struct gl_texture_image *texImage) { struct st_context *st = st_context(ctx); struct st_texture_image *stImage = st_texture_image(texImage); struct st_texture_object *stObj = st_texture_object(texImage->TexObject); const GLuint level = texImage->Level; + GLuint width = texImage->Width; + GLuint height = texImage->Height; + GLuint depth = texImage->Depth; DBG("%s\n", __FUNCTION__); - assert(width > 0); - assert(height > 0); - assert(depth > 0); assert(!stImage->TexData); assert(!stImage->pt); /* xxx this might be wrong */ @@ -500,8 +498,6 @@ st_AllocTextureImageBuffer(struct gl_context *ctx, */ static void prep_teximage(struct gl_context *ctx, struct gl_texture_image *texImage, - GLint internalFormat, - GLint width, GLint height, GLint depth, GLint border, GLenum format, GLenum type) { struct gl_texture_object *texObj = texImage->TexObject; @@ -518,11 +514,13 @@ prep_teximage(struct gl_context *ctx, struct gl_texture_image *texImage, /* oops, need to init this image again */ texFormat = _mesa_choose_texture_format(ctx, texObj, target, level, - internalFormat, format, type); + texImage->InternalFormat, format, + type); _mesa_init_teximage_fields(ctx, texImage, - width, height, depth, border, - internalFormat, texFormat); + texImage->Width, texImage->Height, + texImage->Depth, texImage->Border, + texImage->InternalFormat, texFormat); stObj->surface_based = GL_FALSE; } @@ -532,29 +530,21 @@ prep_teximage(struct gl_context *ctx, struct gl_texture_image *texImage, static void st_TexImage(struct gl_context * ctx, GLuint dims, struct gl_texture_image *texImage, - GLint internalFormat, - GLint width, GLint height, GLint depth, GLint border, GLenum format, GLenum type, const void *pixels, const struct gl_pixelstore_attrib *unpack) { - prep_teximage(ctx, texImage, internalFormat, width, height, depth, border, - format, type); - _mesa_store_teximage(ctx, dims, texImage, internalFormat, width, height, depth, - border, format, type, pixels, unpack); + prep_teximage(ctx, texImage, format, type); + _mesa_store_teximage(ctx, dims, texImage, format, type, pixels, unpack); } static void st_CompressedTexImage(struct gl_context *ctx, GLuint dims, struct gl_texture_image *texImage, - GLint internalFormat, - GLint width, GLint height, GLint border, GLint depth, GLsizei imageSize, const GLvoid *data) { - prep_teximage(ctx, texImage, internalFormat, width, height, depth, border, - GL_NONE, GL_NONE); - _mesa_store_compressed_teximage(ctx, dims, texImage, internalFormat, width, - height, depth, border, imageSize, data); + prep_teximage(ctx, texImage, GL_NONE, GL_NONE); + _mesa_store_compressed_teximage(ctx, dims, texImage, imageSize, data); } @@ -1004,14 +994,22 @@ st_CopyTexSubImage(struct gl_context *ctx, GLuint dims, !do_flip) { /* use surface_copy() / blit */ struct pipe_box src_box; + unsigned dstLevel; + u_box_2d_zslice(srcX, srcY, strb->surface->u.tex.first_layer, width, height, &src_box); + /* If stImage->pt is an independent image (not a pointer into a full + * mipmap) stImage->pt.last_level will be zero and we need to use that + * as the dest level. + */ + dstLevel = MIN2(stImage->base.Level, stImage->pt->last_level); + /* for resource_copy_region(), y=0=top, always */ pipe->resource_copy_region(pipe, /* dest */ stImage->pt, - stImage->base.Level, + dstLevel, destX, destY, destZ + stImage->base.Face, /* src */ strb->texture, 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 66627acb6..39717b6fd 100644 --- a/mesalib/src/mesa/state_tracker/st_glsl_to_tgsi.cpp +++ b/mesalib/src/mesa/state_tracker/st_glsl_to_tgsi.cpp @@ -1867,6 +1867,10 @@ glsl_to_tgsi_visitor::visit(ir_expression *ir) assert(!"GLSL 1.30 features unsupported"); break; + case ir_binop_ubo_load: + assert(!"not yet supported"); + break; + case ir_quadop_vector: /* This operation should have already been handled. */ @@ -4174,6 +4178,7 @@ translate_tex_offset(struct st_translate *t, offset.SwizzleX = in_offset->SwizzleX; offset.SwizzleY = in_offset->SwizzleY; offset.SwizzleZ = in_offset->SwizzleZ; + offset.Padding = 0; return offset; } diff --git a/mesalib/src/mesa/state_tracker/st_manager.c b/mesalib/src/mesa/state_tracker/st_manager.c index 875e0c44a..5142eb2dd 100644 --- a/mesalib/src/mesa/state_tracker/st_manager.c +++ b/mesalib/src/mesa/state_tracker/st_manager.c @@ -652,8 +652,7 @@ st_api_create_context(struct st_api *stapi, struct st_manager *smapi, * yet enforce the added restrictions of a forward-looking context, so * fail that too. */ - if (st->ctx->VersionMajor * 10 + st->ctx->VersionMinor < - attribs->major * 10 + attribs->minor + if (st->ctx->Version < attribs->major * 10 + attribs->minor || (attribs->flags & ~ST_CONTEXT_FLAG_DEBUG) != 0) { *error = ST_CONTEXT_ERROR_BAD_VERSION; st_destroy_context(st); diff --git a/mesalib/src/mesa/swrast/s_texture.c b/mesalib/src/mesa/swrast/s_texture.c index 9718367a8..8df4b8439 100644 --- a/mesalib/src/mesa/swrast/s_texture.c +++ b/mesalib/src/mesa/swrast/s_texture.c @@ -63,40 +63,34 @@ _swrast_delete_texture_image(struct gl_context *ctx, */ GLboolean _swrast_alloc_texture_image_buffer(struct gl_context *ctx, - struct gl_texture_image *texImage, - gl_format format, GLsizei width, - GLsizei height, GLsizei depth) + struct gl_texture_image *texImage) { struct swrast_texture_image *swImg = swrast_texture_image(texImage); - GLuint bytes = _mesa_format_image_size(format, width, height, depth); + GLuint bytes = _mesa_format_image_size(texImage->TexFormat, texImage->Width, + texImage->Height, texImage->Depth); GLuint i; - /* This _should_ be true (revisit if these ever fail) */ - assert(texImage->Width == width); - assert(texImage->Height == height); - assert(texImage->Depth == depth); - assert(!swImg->Buffer); swImg->Buffer = _mesa_align_malloc(bytes, 512); if (!swImg->Buffer) return GL_FALSE; /* RowStride and ImageOffsets[] describe how to address texels in 'Data' */ - swImg->RowStride = width; + swImg->RowStride = texImage->Width; /* Allocate the ImageOffsets array and initialize to typical values. * We allocate the array for 1D/2D textures too in order to avoid special- * case code in the texstore routines. */ - swImg->ImageOffsets = (GLuint *) malloc(depth * sizeof(GLuint)); + swImg->ImageOffsets = (GLuint *) malloc(texImage->Depth * sizeof(GLuint)); if (!swImg->ImageOffsets) return GL_FALSE; - for (i = 0; i < depth; i++) { - swImg->ImageOffsets[i] = i * width * height; + for (i = 0; i < texImage->Depth; i++) { + swImg->ImageOffsets[i] = i * texImage->Width * texImage->Height; } - _swrast_init_texture_image(texImage, width, height, depth); + _swrast_init_texture_image(texImage); return GL_TRUE; } @@ -110,14 +104,13 @@ _swrast_alloc_texture_image_buffer(struct gl_context *ctx, * Returns GL_TRUE on success, GL_FALSE on memory allocation failure. */ void -_swrast_init_texture_image(struct gl_texture_image *texImage, GLsizei width, - GLsizei height, GLsizei depth) +_swrast_init_texture_image(struct gl_texture_image *texImage) { struct swrast_texture_image *swImg = swrast_texture_image(texImage); - if ((width == 1 || _mesa_is_pow_two(texImage->Width2)) && - (height == 1 || _mesa_is_pow_two(texImage->Height2)) && - (depth == 1 || _mesa_is_pow_two(texImage->Depth2))) + if ((texImage->Width == 1 || _mesa_is_pow_two(texImage->Width2)) && + (texImage->Height == 1 || _mesa_is_pow_two(texImage->Height2)) && + (texImage->Depth == 1 || _mesa_is_pow_two(texImage->Depth2))) swImg->_IsPowerOfTwo = GL_TRUE; else swImg->_IsPowerOfTwo = GL_FALSE; @@ -348,11 +341,7 @@ _swrast_AllocTextureStorage(struct gl_context *ctx, for (face = 0; face < numFaces; face++) { for (level = 0; level < levels; level++) { struct gl_texture_image *texImage = texObj->Image[face][level]; - if (!_swrast_alloc_texture_image_buffer(ctx, texImage, - texImage->TexFormat, - texImage->Width, - texImage->Height, - texImage->Depth)) { + if (!_swrast_alloc_texture_image_buffer(ctx, texImage)) { return GL_FALSE; } } diff --git a/mesalib/src/mesa/swrast/swrast.h b/mesalib/src/mesa/swrast/swrast.h index a299e6fda..97cc5ee63 100644 --- a/mesalib/src/mesa/swrast/swrast.h +++ b/mesalib/src/mesa/swrast/swrast.h @@ -215,13 +215,10 @@ _swrast_delete_texture_image(struct gl_context *ctx, extern GLboolean _swrast_alloc_texture_image_buffer(struct gl_context *ctx, - struct gl_texture_image *texImage, - gl_format format, GLsizei width, - GLsizei height, GLsizei depth); + struct gl_texture_image *texImage); extern void -_swrast_init_texture_image(struct gl_texture_image *texImage, GLsizei width, - GLsizei height, GLsizei depth); +_swrast_init_texture_image(struct gl_texture_image *texImage); extern void _swrast_free_texture_image_buffer(struct gl_context *ctx, |