aboutsummaryrefslogtreecommitdiff
path: root/mesalib
diff options
context:
space:
mode:
authormarha <marha@users.sourceforge.net>2014-01-15 21:23:25 +0100
committermarha <marha@users.sourceforge.net>2014-01-15 21:23:25 +0100
commit1b0fcca503ae9cf2d462b60770f96c794dfbb27a (patch)
treed08c81de02b94da202195d84c99e192bc24ae69e /mesalib
parentaaeb8bf497c82efabc4f9b27c319042c0e72d816 (diff)
downloadvcxsrv-1b0fcca503ae9cf2d462b60770f96c794dfbb27a.tar.gz
vcxsrv-1b0fcca503ae9cf2d462b60770f96c794dfbb27a.tar.bz2
vcxsrv-1b0fcca503ae9cf2d462b60770f96c794dfbb27a.zip
mesa xkeyboard-config xserver git update 15 jan 2014
xserver commit 2d2d49dab5c5718989de97d7227aac793479745e xkeyboard-config commit 78af7aa79c6552924295644b911e45d07a0fcdad mesa commit a05c596a00916ce6a9c9d35ff36cd1e401fddd43
Diffstat (limited to 'mesalib')
-rw-r--r--mesalib/configure.ac6
-rw-r--r--mesalib/docs/GL3.txt2
-rw-r--r--mesalib/src/gallium/auxiliary/util/u_clear.h5
-rw-r--r--mesalib/src/gallium/auxiliary/util/u_framebuffer.c24
-rw-r--r--mesalib/src/gallium/auxiliary/util/u_framebuffer.h4
-rw-r--r--mesalib/src/glsl/ast_function.cpp16
-rw-r--r--mesalib/src/glsl/ast_to_hir.cpp4
-rw-r--r--mesalib/src/glsl/builtin_functions.cpp4
-rw-r--r--mesalib/src/glsl/ir.cpp20
-rw-r--r--mesalib/src/glsl/ir.h24
-rw-r--r--mesalib/src/glsl/ir_basic_block.cpp10
-rw-r--r--mesalib/src/glsl/ir_clone.cpp16
-rw-r--r--mesalib/src/glsl/ir_expression_flattening.cpp4
-rw-r--r--mesalib/src/glsl/ir_function.cpp10
-rw-r--r--mesalib/src/glsl/ir_print_visitor.cpp34
-rw-r--r--mesalib/src/glsl/ir_reader.cpp42
-rw-r--r--mesalib/src/glsl/ir_rvalue_visitor.cpp4
-rw-r--r--mesalib/src/glsl/ir_validate.cpp4
-rw-r--r--mesalib/src/glsl/linker.cpp18
-rw-r--r--mesalib/src/glsl/list.h80
-rw-r--r--mesalib/src/glsl/lower_if_to_cond_assign.cpp8
-rw-r--r--mesalib/src/glsl/lower_vec_index_to_cond_assign.cpp4
-rw-r--r--mesalib/src/glsl/lower_vec_index_to_swizzle.cpp4
-rw-r--r--mesalib/src/glsl/opt_array_splitting.cpp16
-rw-r--r--mesalib/src/glsl/opt_constant_folding.cpp9
-rw-r--r--mesalib/src/glsl/opt_constant_propagation.cpp33
-rw-r--r--mesalib/src/glsl/opt_constant_variable.cpp18
-rw-r--r--mesalib/src/glsl/opt_copy_propagation.cpp29
-rw-r--r--mesalib/src/glsl/opt_copy_propagation_elements.cpp17
-rw-r--r--mesalib/src/glsl/opt_dead_code.cpp9
-rw-r--r--mesalib/src/glsl/opt_dead_code_local.cpp20
-rw-r--r--mesalib/src/glsl/opt_dead_functions.cpp12
-rw-r--r--mesalib/src/glsl/opt_function_inlining.cpp45
-rw-r--r--mesalib/src/glsl/opt_if_simplification.cpp8
-rw-r--r--mesalib/src/glsl/opt_structure_splitting.cpp16
-rw-r--r--mesalib/src/glsl/opt_tree_grafting.cpp10
-rw-r--r--mesalib/src/glsl/s_expression.cpp8
-rw-r--r--mesalib/src/mapi/glapi/gen/ARB_shader_image_load_store.xml89
-rw-r--r--mesalib/src/mapi/glapi/gen/Makefile.am1
-rw-r--r--mesalib/src/mapi/glapi/gen/gl_API.xml2
-rw-r--r--mesalib/src/mapi/glapi/gen/gl_genexec.py1
-rw-r--r--mesalib/src/mesa/Makefile.am12
-rw-r--r--mesalib/src/mesa/Makefile.sources1
-rw-r--r--mesalib/src/mesa/SConscript1
-rw-r--r--mesalib/src/mesa/drivers/common/driverfuncs.c3
-rw-r--r--mesalib/src/mesa/drivers/dri/common/utils.c1
-rw-r--r--mesalib/src/mesa/drivers/dri/swrast/swrast.c6
-rw-r--r--mesalib/src/mesa/drivers/windows/gdi/wmesa.c4
-rw-r--r--mesalib/src/mesa/main/clear.c8
-rw-r--r--mesalib/src/mesa/main/condrender.c41
-rw-r--r--mesalib/src/mesa/main/config.h3
-rw-r--r--mesalib/src/mesa/main/dd.h20
-rw-r--r--mesalib/src/mesa/main/extensions.c1
-rw-r--r--mesalib/src/mesa/main/format_pack.c57
-rw-r--r--mesalib/src/mesa/main/format_unpack.c61
-rw-r--r--mesalib/src/mesa/main/formats.c54
-rw-r--r--mesalib/src/mesa/main/formats.h5
-rw-r--r--mesalib/src/mesa/main/get.c70
-rw-r--r--mesalib/src/mesa/main/get_hash_params.py9
-rw-r--r--mesalib/src/mesa/main/mtypes.h104
-rw-r--r--mesalib/src/mesa/main/scissor.c2
-rw-r--r--mesalib/src/mesa/main/shaderimage.c488
-rw-r--r--mesalib/src/mesa/main/shaderimage.h51
-rw-r--r--mesalib/src/mesa/main/texcompress.c37
-rw-r--r--mesalib/src/mesa/main/teximage.c87
-rw-r--r--mesalib/src/mesa/main/teximage.h6
-rw-r--r--mesalib/src/mesa/main/texobj.c26
-rw-r--r--mesalib/src/mesa/main/texparam.c6
-rw-r--r--mesalib/src/mesa/main/texstate.c3
-rw-r--r--mesalib/src/mesa/main/texstore.c107
-rw-r--r--mesalib/src/mesa/main/viewport.c4
-rw-r--r--mesalib/src/mesa/program/ir_to_mesa.cpp26
-rw-r--r--mesalib/src/mesa/state_tracker/st_atom_framebuffer.c14
-rw-r--r--mesalib/src/mesa/state_tracker/st_atom_msaa.c8
-rw-r--r--mesalib/src/mesa/state_tracker/st_cb_blit.c32
-rw-r--r--mesalib/src/mesa/state_tracker/st_cb_clear.c40
-rw-r--r--mesalib/src/mesa/state_tracker/st_cb_fbo.c5
-rw-r--r--mesalib/src/mesa/state_tracker/st_cb_viewport.c3
-rw-r--r--mesalib/src/mesa/state_tracker/st_glsl_to_tgsi.cpp115
-rw-r--r--mesalib/src/mesa/swrast/s_texfetch.c18
80 files changed, 1745 insertions, 484 deletions
diff --git a/mesalib/configure.ac b/mesalib/configure.ac
index 4b55140d2..4da6c51d3 100644
--- a/mesalib/configure.ac
+++ b/mesalib/configure.ac
@@ -583,7 +583,7 @@ AC_ARG_ENABLE([xvmc],
[AS_HELP_STRING([--enable-xvmc],
[enable xvmc library @<:@default=auto@:>@])],
[enable_xvmc="$enableval"],
- [enable_xvmc=auto])
+ [enable_xvmc=no])
AC_ARG_ENABLE([vdpau],
[AS_HELP_STRING([--enable-vdpau],
[enable vdpau library @<:@default=auto@:>@])],
@@ -1567,9 +1567,9 @@ if test "x$enable_gallium_llvm" = xauto; then
fi
if test "x$enable_gallium_llvm" = xyes; then
if test "x$llvm_prefix" != x; then
- AC_PATH_PROG([LLVM_CONFIG], [llvm-config], [no], ["$llvm_prefix/bin"])
+ AC_PATH_TOOL([LLVM_CONFIG], [llvm-config], [no], ["$llvm_prefix/bin"])
else
- AC_PATH_PROG([LLVM_CONFIG], [llvm-config], [no])
+ AC_PATH_TOOL([LLVM_CONFIG], [llvm-config], [no])
fi
if test "x$LLVM_CONFIG" != xno; then
diff --git a/mesalib/docs/GL3.txt b/mesalib/docs/GL3.txt
index f98a54a78..0672ec708 100644
--- a/mesalib/docs/GL3.txt
+++ b/mesalib/docs/GL3.txt
@@ -132,7 +132,7 @@ GL 4.2:
GL_ARB_texture_storage DONE (all drivers)
GL_ARB_transform_feedback_instanced DONE (i965, r600, radeonsi)
GL_ARB_base_instance DONE (i965, nv50, nvc0, r600, radeonsi)
- GL_ARB_shader_image_load_store not started
+ GL_ARB_shader_image_load_store in progress (curro)
GL_ARB_conservative_depth DONE (all drivers that support GLSL 1.30)
GL_ARB_shading_language_420pack DONE (all drivers that support GLSL 1.30)
GL_ARB_internalformat_query DONE (i965, r300, r600, radeonsi)
diff --git a/mesalib/src/gallium/auxiliary/util/u_clear.h b/mesalib/src/gallium/auxiliary/util/u_clear.h
index 75047c16b..bd8efdb4a 100644
--- a/mesalib/src/gallium/auxiliary/util/u_clear.h
+++ b/mesalib/src/gallium/auxiliary/util/u_clear.h
@@ -47,7 +47,10 @@ util_clear(struct pipe_context *pipe,
for (i = 0; i < framebuffer->nr_cbufs; i++) {
if (buffers & (PIPE_CLEAR_COLOR0 << i)) {
struct pipe_surface *ps = framebuffer->cbufs[i];
- pipe->clear_render_target(pipe, ps, color, 0, 0, ps->width, ps->height);
+
+ if (ps) {
+ pipe->clear_render_target(pipe, ps, color, 0, 0, ps->width, ps->height);
+ }
}
}
diff --git a/mesalib/src/gallium/auxiliary/util/u_framebuffer.c b/mesalib/src/gallium/auxiliary/util/u_framebuffer.c
index 683967237..2e0ef749e 100644
--- a/mesalib/src/gallium/auxiliary/util/u_framebuffer.c
+++ b/mesalib/src/gallium/auxiliary/util/u_framebuffer.c
@@ -127,6 +127,9 @@ util_framebuffer_min_size(const struct pipe_framebuffer_state *fb,
unsigned i;
for (i = 0; i < fb->nr_cbufs; i++) {
+ if (!fb->cbufs[i])
+ continue;
+
w = MIN2(w, fb->cbufs[i]->width);
h = MIN2(h, fb->cbufs[i]->height);
}
@@ -171,3 +174,24 @@ util_framebuffer_get_num_layers(const struct pipe_framebuffer_state *fb)
}
return num_layers;
}
+
+
+/**
+ * Return the number of MSAA samples.
+ */
+unsigned
+util_framebuffer_get_num_samples(const struct pipe_framebuffer_state *fb)
+{
+ unsigned i;
+
+ for (i = 0; i < fb->nr_cbufs; i++) {
+ if (fb->cbufs[i]) {
+ return MAX2(1, fb->cbufs[i]->texture->nr_samples);
+ }
+ }
+ if (fb->zsbuf) {
+ return MAX2(1, fb->zsbuf->texture->nr_samples);
+ }
+
+ return 1;
+}
diff --git a/mesalib/src/gallium/auxiliary/util/u_framebuffer.h b/mesalib/src/gallium/auxiliary/util/u_framebuffer.h
index 0e6c98363..c73942c9c 100644
--- a/mesalib/src/gallium/auxiliary/util/u_framebuffer.h
+++ b/mesalib/src/gallium/auxiliary/util/u_framebuffer.h
@@ -60,6 +60,10 @@ extern unsigned
util_framebuffer_get_num_layers(const struct pipe_framebuffer_state *fb);
+extern unsigned
+util_framebuffer_get_num_samples(const struct pipe_framebuffer_state *fb);
+
+
#ifdef __cplusplus
}
#endif
diff --git a/mesalib/src/glsl/ast_function.cpp b/mesalib/src/glsl/ast_function.cpp
index e4c0fd1c4..2d05d0723 100644
--- a/mesalib/src/glsl/ast_function.cpp
+++ b/mesalib/src/glsl/ast_function.cpp
@@ -293,15 +293,10 @@ generate_call(exec_list *instructions, ir_function_signature *sig,
* call takes place. Since we haven't emitted the call yet, we'll place
* the post-call conversions in a temporary exec_list, and emit them later.
*/
- exec_list_iterator actual_iter = actual_parameters->iterator();
- exec_list_iterator formal_iter = sig->parameters.iterator();
-
- while (actual_iter.has_next()) {
- ir_rvalue *actual = (ir_rvalue *) actual_iter.get();
- ir_variable *formal = (ir_variable *) formal_iter.get();
-
- assert(actual != NULL);
- assert(formal != NULL);
+ foreach_two_lists(formal_node, &sig->parameters,
+ actual_node, actual_parameters) {
+ ir_rvalue *actual = (ir_rvalue *) actual_node;
+ ir_variable *formal = (ir_variable *) formal_node;
if (formal->type->is_numeric() || formal->type->is_boolean()) {
switch (formal->data.mode) {
@@ -323,9 +318,6 @@ generate_call(exec_list *instructions, ir_function_signature *sig,
break;
}
}
-
- actual_iter.next();
- formal_iter.next();
}
/* If the function call is a constant expression, don't generate any
diff --git a/mesalib/src/glsl/ast_to_hir.cpp b/mesalib/src/glsl/ast_to_hir.cpp
index ef8e699e0..4cc8eb18d 100644
--- a/mesalib/src/glsl/ast_to_hir.cpp
+++ b/mesalib/src/glsl/ast_to_hir.cpp
@@ -3818,8 +3818,8 @@ ast_function_definition::hir(exec_list *instructions,
* Add these to the symbol table.
*/
state->symbols->push_scope();
- foreach_iter(exec_list_iterator, iter, signature->parameters) {
- ir_variable *const var = ((ir_instruction *) iter.get())->as_variable();
+ foreach_list(n, &signature->parameters) {
+ ir_variable *const var = ((ir_instruction *) n)->as_variable();
assert(var != NULL);
diff --git a/mesalib/src/glsl/builtin_functions.cpp b/mesalib/src/glsl/builtin_functions.cpp
index 038e47363..662ff4cea 100644
--- a/mesalib/src/glsl/builtin_functions.cpp
+++ b/mesalib/src/glsl/builtin_functions.cpp
@@ -2398,8 +2398,8 @@ builtin_builder::call(ir_function *f, ir_variable *ret, exec_list params)
{
exec_list actual_params;
- foreach_iter(exec_list_iterator, it, params) {
- ir_variable *var = ((ir_instruction *)it.get())->as_variable();
+ foreach_list(node, &params) {
+ ir_variable *var = (ir_variable *) node;
actual_params.push_tail(var_ref(var));
}
diff --git a/mesalib/src/glsl/ir.cpp b/mesalib/src/glsl/ir.cpp
index ba6903d8a..1a36bd631 100644
--- a/mesalib/src/glsl/ir.cpp
+++ b/mesalib/src/glsl/ir.cpp
@@ -1649,13 +1649,10 @@ modes_match(unsigned a, unsigned b)
const char *
ir_function_signature::qualifiers_match(exec_list *params)
{
- exec_list_iterator iter_a = parameters.iterator();
- exec_list_iterator iter_b = params->iterator();
-
/* check that the qualifiers match. */
- while (iter_a.has_next()) {
- ir_variable *a = (ir_variable *)iter_a.get();
- ir_variable *b = (ir_variable *)iter_b.get();
+ foreach_two_lists(a_node, &this->parameters, b_node, params) {
+ ir_variable *a = (ir_variable *) a_node;
+ ir_variable *b = (ir_variable *) b_node;
if (a->data.read_only != b->data.read_only ||
!modes_match(a->data.mode, b->data.mode) ||
@@ -1666,9 +1663,6 @@ ir_function_signature::qualifiers_match(exec_list *params)
/* parameter a's qualifiers don't match */
return a->name;
}
-
- iter_a.next();
- iter_b.next();
}
return NULL;
}
@@ -1717,8 +1711,8 @@ ir_rvalue::error_value(void *mem_ctx)
void
visit_exec_list(exec_list *list, ir_visitor *visitor)
{
- foreach_iter(exec_list_iterator, iter, *list) {
- ((ir_instruction *)iter.get())->accept(visitor);
+ foreach_list_safe(n, list) {
+ ((ir_instruction *) n)->accept(visitor);
}
}
@@ -1739,8 +1733,8 @@ steal_memory(ir_instruction *ir, void *new_ctx)
*/
if (constant != NULL) {
if (constant->type->is_record()) {
- foreach_iter(exec_list_iterator, iter, constant->components) {
- ir_constant *field = (ir_constant *)iter.get();
+ foreach_list(n, &constant->components) {
+ ir_constant *field = (ir_constant *) n;
steal_memory(field, ir);
}
} else if (constant->type->is_array()) {
diff --git a/mesalib/src/glsl/ir.h b/mesalib/src/glsl/ir.h
index aff679826..2ae8513a6 100644
--- a/mesalib/src/glsl/ir.h
+++ b/mesalib/src/glsl/ir.h
@@ -914,14 +914,6 @@ public:
}
/**
- * Get an iterator for the set of function signatures
- */
- exec_list_iterator iterator()
- {
- return signatures.iterator();
- }
-
- /**
* Find a signature that matches a set of actual parameters, taking implicit
* conversions into account. Also flags whether the match was exact.
*/
@@ -1018,14 +1010,6 @@ public:
return this;
}
- /**
- * Get an iterator for the instructions of the loop body
- */
- exec_list_iterator iterator()
- {
- return body_instructions.iterator();
- }
-
/** List of ir_instruction that make up the body of the loop. */
exec_list body_instructions;
};
@@ -1521,14 +1505,6 @@ public:
virtual ir_visitor_status accept(ir_hierarchical_visitor *);
/**
- * Get an iterator for the set of acutal parameters
- */
- exec_list_iterator iterator()
- {
- return actual_parameters.iterator();
- }
-
- /**
* Get the name of the function being called.
*/
const char *callee_name() const
diff --git a/mesalib/src/glsl/ir_basic_block.cpp b/mesalib/src/glsl/ir_basic_block.cpp
index 2cbc682d4..426fda2f2 100644
--- a/mesalib/src/glsl/ir_basic_block.cpp
+++ b/mesalib/src/glsl/ir_basic_block.cpp
@@ -58,8 +58,8 @@ void call_for_basic_blocks(exec_list *instructions,
ir_instruction *leader = NULL;
ir_instruction *last = NULL;
- foreach_iter(exec_list_iterator, iter, *instructions) {
- ir_instruction *ir = (ir_instruction *)iter.get();
+ foreach_list(n, instructions) {
+ ir_instruction *ir = (ir_instruction *) n;
ir_if *ir_if;
ir_loop *ir_loop;
ir_function *ir_function;
@@ -90,10 +90,8 @@ void call_for_basic_blocks(exec_list *instructions,
* and the body of main(). Perhaps those instructions ought
* to live inside of main().
*/
- foreach_iter(exec_list_iterator, fun_iter, *ir_function) {
- ir_function_signature *ir_sig;
-
- ir_sig = (ir_function_signature *)fun_iter.get();
+ foreach_list(func_node, &ir_function->signatures) {
+ ir_function_signature *ir_sig = (ir_function_signature *) func_node;
call_for_basic_blocks(&ir_sig->body, callback, data);
}
diff --git a/mesalib/src/glsl/ir_clone.cpp b/mesalib/src/glsl/ir_clone.cpp
index 4e5cf68ca..cb732a51a 100644
--- a/mesalib/src/glsl/ir_clone.cpp
+++ b/mesalib/src/glsl/ir_clone.cpp
@@ -123,13 +123,13 @@ ir_if::clone(void *mem_ctx, struct hash_table *ht) const
{
ir_if *new_if = new(mem_ctx) ir_if(this->condition->clone(mem_ctx, ht));
- foreach_iter(exec_list_iterator, iter, this->then_instructions) {
- ir_instruction *ir = (ir_instruction *)iter.get();
+ foreach_list(n, &this->then_instructions) {
+ ir_instruction *ir = (ir_instruction *) n;
new_if->then_instructions.push_tail(ir->clone(mem_ctx, ht));
}
- foreach_iter(exec_list_iterator, iter, this->else_instructions) {
- ir_instruction *ir = (ir_instruction *)iter.get();
+ foreach_list(n, &this->else_instructions) {
+ ir_instruction *ir = (ir_instruction *) n;
new_if->else_instructions.push_tail(ir->clone(mem_ctx, ht));
}
@@ -141,8 +141,8 @@ ir_loop::clone(void *mem_ctx, struct hash_table *ht) const
{
ir_loop *new_loop = new(mem_ctx) ir_loop();
- foreach_iter(exec_list_iterator, iter, this->body_instructions) {
- ir_instruction *ir = (ir_instruction *)iter.get();
+ foreach_list(n, &this->body_instructions) {
+ ir_instruction *ir = (ir_instruction *) n;
new_loop->body_instructions.push_tail(ir->clone(mem_ctx, ht));
}
@@ -158,8 +158,8 @@ ir_call::clone(void *mem_ctx, struct hash_table *ht) const
exec_list new_parameters;
- foreach_iter(exec_list_iterator, iter, this->actual_parameters) {
- ir_instruction *ir = (ir_instruction *)iter.get();
+ foreach_list(n, &this->actual_parameters) {
+ ir_instruction *ir = (ir_instruction *) n;
new_parameters.push_tail(ir->clone(mem_ctx, ht));
}
diff --git a/mesalib/src/glsl/ir_expression_flattening.cpp b/mesalib/src/glsl/ir_expression_flattening.cpp
index b44e68ca3..c1cadb122 100644
--- a/mesalib/src/glsl/ir_expression_flattening.cpp
+++ b/mesalib/src/glsl/ir_expression_flattening.cpp
@@ -59,8 +59,8 @@ do_expression_flattening(exec_list *instructions,
{
ir_expression_flattening_visitor v(predicate);
- foreach_iter(exec_list_iterator, iter, *instructions) {
- ir_instruction *ir = (ir_instruction *)iter.get();
+ foreach_list(n, instructions) {
+ ir_instruction *ir = (ir_instruction *) n;
ir->accept(&v);
}
diff --git a/mesalib/src/glsl/ir_function.cpp b/mesalib/src/glsl/ir_function.cpp
index bd5318d23..40cf5894a 100644
--- a/mesalib/src/glsl/ir_function.cpp
+++ b/mesalib/src/glsl/ir_function.cpp
@@ -141,9 +141,8 @@ ir_function::matching_signature(_mesa_glsl_parse_state *state,
* multiple ways to apply these conversions to the actual arguments of a
* call such that the call can be made to match multiple signatures."
*/
- foreach_iter(exec_list_iterator, iter, signatures) {
- ir_function_signature *const sig =
- (ir_function_signature *) iter.get();
+ foreach_list(n, &this->signatures) {
+ ir_function_signature *const sig = (ir_function_signature *) n;
/* Skip over any built-ins that aren't available in this shader. */
if (sig->is_builtin() && !sig->is_builtin_available(state))
@@ -212,9 +211,8 @@ ir_function_signature *
ir_function::exact_matching_signature(_mesa_glsl_parse_state *state,
const exec_list *actual_parameters)
{
- foreach_iter(exec_list_iterator, iter, signatures) {
- ir_function_signature *const sig =
- (ir_function_signature *) iter.get();
+ foreach_list(n, &this->signatures) {
+ ir_function_signature *const sig = (ir_function_signature *) n;
/* Skip over any built-ins that aren't available in this shader. */
if (sig->is_builtin() && !sig->is_builtin_available(state))
diff --git a/mesalib/src/glsl/ir_print_visitor.cpp b/mesalib/src/glsl/ir_print_visitor.cpp
index 01c5f7f1c..935782184 100644
--- a/mesalib/src/glsl/ir_print_visitor.cpp
+++ b/mesalib/src/glsl/ir_print_visitor.cpp
@@ -61,8 +61,8 @@ _mesa_print_ir(exec_list *instructions,
}
printf("(\n");
- foreach_iter(exec_list_iterator, iter, *instructions) {
- ir_instruction *ir = (ir_instruction *)iter.get();
+ foreach_list(n, instructions) {
+ ir_instruction *ir = (ir_instruction *) n;
ir->print();
if (ir->ir_type != ir_type_function)
printf("\n");
@@ -179,8 +179,8 @@ void ir_print_visitor::visit(ir_function_signature *ir)
printf("(parameters\n");
indentation++;
- foreach_iter(exec_list_iterator, iter, ir->parameters) {
- ir_variable *const inst = (ir_variable *) iter.get();
+ foreach_list(n, &ir->parameters) {
+ ir_variable *const inst = (ir_variable *) n;
indent();
inst->accept(this);
@@ -196,8 +196,8 @@ void ir_print_visitor::visit(ir_function_signature *ir)
printf("(\n");
indentation++;
- foreach_iter(exec_list_iterator, iter, ir->body) {
- ir_instruction *const inst = (ir_instruction *) iter.get();
+ foreach_list(n, &ir->body) {
+ ir_instruction *const inst = (ir_instruction *) n;
indent();
inst->accept(this);
@@ -215,8 +215,8 @@ void ir_print_visitor::visit(ir_function *ir)
{
printf("(function %s\n", ir->name);
indentation++;
- foreach_iter(exec_list_iterator, iter, *ir) {
- ir_function_signature *const sig = (ir_function_signature *) iter.get();
+ foreach_list(n, &ir->signatures) {
+ ir_function_signature *const sig = (ir_function_signature *) n;
indent();
sig->accept(this);
printf("\n");
@@ -440,10 +440,10 @@ ir_print_visitor::visit(ir_call *ir)
if (ir->return_deref)
ir->return_deref->accept(this);
printf(" (");
- foreach_iter(exec_list_iterator, iter, *ir) {
- ir_instruction *const inst = (ir_instruction *) iter.get();
+ foreach_list(n, &ir->actual_parameters) {
+ ir_rvalue *const param = (ir_rvalue *) n;
- inst->accept(this);
+ param->accept(this);
}
printf("))\n");
}
@@ -487,8 +487,8 @@ ir_print_visitor::visit(ir_if *ir)
printf("(\n");
indentation++;
- foreach_iter(exec_list_iterator, iter, ir->then_instructions) {
- ir_instruction *const inst = (ir_instruction *) iter.get();
+ foreach_list(n, &ir->then_instructions) {
+ ir_instruction *const inst = (ir_instruction *) n;
indent();
inst->accept(this);
@@ -504,8 +504,8 @@ ir_print_visitor::visit(ir_if *ir)
printf("(\n");
indentation++;
- foreach_iter(exec_list_iterator, iter, ir->else_instructions) {
- ir_instruction *const inst = (ir_instruction *) iter.get();
+ foreach_list(n, &ir->else_instructions) {
+ ir_instruction *const inst = (ir_instruction *) n;
indent();
inst->accept(this);
@@ -526,8 +526,8 @@ ir_print_visitor::visit(ir_loop *ir)
printf("(loop (\n");
indentation++;
- foreach_iter(exec_list_iterator, iter, ir->body_instructions) {
- ir_instruction *const inst = (ir_instruction *) iter.get();
+ foreach_list(n, &ir->body_instructions) {
+ ir_instruction *const inst = (ir_instruction *) n;
indent();
inst->accept(this);
diff --git a/mesalib/src/glsl/ir_reader.cpp b/mesalib/src/glsl/ir_reader.cpp
index 7970112ec..28923f3b8 100644
--- a/mesalib/src/glsl/ir_reader.cpp
+++ b/mesalib/src/glsl/ir_reader.cpp
@@ -170,8 +170,8 @@ ir_reader::scan_for_prototypes(exec_list *instructions, s_expression *expr)
return;
}
- foreach_iter(exec_list_iterator, it, list->subexpressions) {
- s_list *sub = SX_AS_LIST(it.get());
+ foreach_list(n, &list->subexpressions) {
+ s_list *sub = SX_AS_LIST(n);
if (sub == NULL)
continue; // not a (function ...); ignore it.
@@ -205,11 +205,12 @@ ir_reader::read_function(s_expression *expr, bool skip_body)
assert(added);
}
- exec_list_iterator it = ((s_list *) expr)->subexpressions.iterator();
- it.next(); // skip "function" tag
- it.next(); // skip function name
- for (/* nothing */; it.has_next(); it.next()) {
- s_expression *s_sig = (s_expression *) it.get();
+ /* Skip over "function" tag and function name (which are guaranteed to be
+ * present by the above PARTIAL_MATCH call).
+ */
+ exec_node *node = ((s_list *) expr)->subexpressions.head->next->next;
+ for (/* nothing */; !node->is_tail_sentinel(); node = node->next) {
+ s_expression *s_sig = (s_expression *) node;
read_function_sig(f, s_sig, skip_body);
}
return added ? f : NULL;
@@ -249,9 +250,10 @@ ir_reader::read_function_sig(ir_function *f, s_expression *expr, bool skip_body)
exec_list hir_parameters;
state->symbols->push_scope();
- exec_list_iterator it = paramlist->subexpressions.iterator();
- for (it.next() /* skip "parameters" */; it.has_next(); it.next()) {
- ir_variable *var = read_declaration((s_expression *) it.get());
+ /* Skip over the "parameters" tag. */
+ exec_node *node = paramlist->subexpressions.head->next;
+ for (/* nothing */; !node->is_tail_sentinel(); node = node->next) {
+ ir_variable *var = read_declaration((s_expression *) node);
if (var == NULL)
return;
@@ -315,8 +317,8 @@ ir_reader::read_instructions(exec_list *instructions, s_expression *expr,
return;
}
- foreach_iter(exec_list_iterator, it, list->subexpressions) {
- s_expression *sub = (s_expression*) it.get();
+ foreach_list(n, &list->subexpressions) {
+ s_expression *sub = (s_expression *) n;
ir_instruction *ir = read_instruction(sub, loop_ctx);
if (ir != NULL) {
/* Global variable declarations should be moved to the top, before
@@ -403,8 +405,8 @@ ir_reader::read_declaration(s_expression *expr)
ir_variable *var = new(mem_ctx) ir_variable(type, s_name->value(),
ir_var_auto);
- foreach_iter(exec_list_iterator, it, s_quals->subexpressions) {
- s_symbol *qualifier = SX_AS_SYMBOL(it.get());
+ foreach_list(n, &s_quals->subexpressions) {
+ s_symbol *qualifier = SX_AS_SYMBOL(n);
if (qualifier == NULL) {
ir_read_error(expr, "qualifier list must contain only symbols");
return NULL;
@@ -656,8 +658,8 @@ ir_reader::read_call(s_expression *expr)
exec_list parameters;
- foreach_iter(exec_list_iterator, it, params->subexpressions) {
- s_expression *expr = (s_expression*) it.get();
+ foreach_list(n, &params->subexpressions) {
+ s_expression *expr = (s_expression *) n;
ir_rvalue *param = read_rvalue(expr);
if (param == NULL) {
ir_read_error(expr, "when reading parameter to function call");
@@ -796,8 +798,8 @@ ir_reader::read_constant(s_expression *expr)
if (type->is_array()) {
unsigned elements_supplied = 0;
exec_list elements;
- foreach_iter(exec_list_iterator, it, values->subexpressions) {
- s_expression *elt = (s_expression *) it.get();
+ foreach_list(n, &values->subexpressions) {
+ s_expression *elt = (s_expression *) n;
ir_constant *ir_elt = read_constant(elt);
if (ir_elt == NULL)
return NULL;
@@ -817,13 +819,13 @@ ir_reader::read_constant(s_expression *expr)
// Read in list of values (at most 16).
unsigned k = 0;
- foreach_iter(exec_list_iterator, it, values->subexpressions) {
+ foreach_list(n, &values->subexpressions) {
if (k >= 16) {
ir_read_error(values, "expected at most 16 numbers");
return NULL;
}
- s_expression *expr = (s_expression*) it.get();
+ s_expression *expr = (s_expression *) n;
if (type->base_type == GLSL_TYPE_FLOAT) {
s_number *value = SX_AS_NUMBER(expr);
diff --git a/mesalib/src/glsl/ir_rvalue_visitor.cpp b/mesalib/src/glsl/ir_rvalue_visitor.cpp
index 9d8ccd94a..fcbe9448d 100644
--- a/mesalib/src/glsl/ir_rvalue_visitor.cpp
+++ b/mesalib/src/glsl/ir_rvalue_visitor.cpp
@@ -123,8 +123,8 @@ ir_rvalue_base_visitor::rvalue_visit(ir_assignment *ir)
ir_visitor_status
ir_rvalue_base_visitor::rvalue_visit(ir_call *ir)
{
- foreach_iter(exec_list_iterator, iter, *ir) {
- ir_rvalue *param = (ir_rvalue *)iter.get();
+ foreach_list_safe(n, &ir->actual_parameters) {
+ ir_rvalue *param = (ir_rvalue *) n;
ir_rvalue *new_param = param;
handle_rvalue(&new_param);
diff --git a/mesalib/src/glsl/ir_validate.cpp b/mesalib/src/glsl/ir_validate.cpp
index 4bbb3ce65..527acea4c 100644
--- a/mesalib/src/glsl/ir_validate.cpp
+++ b/mesalib/src/glsl/ir_validate.cpp
@@ -813,8 +813,8 @@ validate_ir_tree(exec_list *instructions)
v.run(instructions);
- foreach_iter(exec_list_iterator, iter, *instructions) {
- ir_instruction *ir = (ir_instruction *)iter.get();
+ foreach_list(n, instructions) {
+ ir_instruction *ir = (ir_instruction *) n;
visit_tree(ir, check_node_type, NULL);
}
diff --git a/mesalib/src/glsl/linker.cpp b/mesalib/src/glsl/linker.cpp
index e820f0f9f..85a4d3883 100644
--- a/mesalib/src/glsl/linker.cpp
+++ b/mesalib/src/glsl/linker.cpp
@@ -109,10 +109,10 @@ public:
virtual ir_visitor_status visit_enter(ir_call *ir)
{
- exec_list_iterator sig_iter = ir->callee->parameters.iterator();
- foreach_iter(exec_list_iterator, iter, *ir) {
- ir_rvalue *param_rval = (ir_rvalue *)iter.get();
- ir_variable *sig_param = (ir_variable *)sig_iter.get();
+ foreach_two_lists(formal_node, &ir->callee->parameters,
+ actual_node, &ir->actual_parameters) {
+ ir_rvalue *param_rval = (ir_rvalue *) actual_node;
+ ir_variable *sig_param = (ir_variable *) formal_node;
if (sig_param->data.mode == ir_var_function_out ||
sig_param->data.mode == ir_var_function_inout) {
@@ -122,7 +122,6 @@ public:
return visit_stop;
}
}
- sig_iter.next();
}
if (ir->return_deref != NULL) {
@@ -1338,9 +1337,8 @@ link_intrastage_shaders(void *mem_ctx,
if (other == NULL)
continue;
- foreach_iter (exec_list_iterator, iter, *f) {
- ir_function_signature *sig =
- (ir_function_signature *) iter.get();
+ foreach_list(n, &f->signatures) {
+ ir_function_signature *sig = (ir_function_signature *) n;
if (!sig->is_defined || sig->is_builtin())
continue;
@@ -1453,8 +1451,8 @@ link_intrastage_shaders(void *mem_ctx,
if (linked->Stage == MESA_SHADER_GEOMETRY) {
unsigned num_vertices = vertices_per_prim(prog->Geom.InputType);
geom_array_resize_visitor input_resize_visitor(num_vertices, prog);
- foreach_iter(exec_list_iterator, iter, *linked->ir) {
- ir_instruction *ir = (ir_instruction *)iter.get();
+ foreach_list(n, linked->ir) {
+ ir_instruction *ir = (ir_instruction *) n;
ir->accept(&input_resize_visitor);
}
}
diff --git a/mesalib/src/glsl/list.h b/mesalib/src/glsl/list.h
index 5ac17cb37..694b686b0 100644
--- a/mesalib/src/glsl/list.h
+++ b/mesalib/src/glsl/list.h
@@ -206,62 +206,8 @@ struct exec_node {
#ifdef __cplusplus
struct exec_node;
-
-class iterator {
-public:
- void next()
- {
- }
-
- void *get()
- {
- return NULL;
- }
-
- bool has_next() const
- {
- return false;
- }
-};
-
-class exec_list_iterator : public iterator {
-public:
- exec_list_iterator(exec_node *n) : node(n), _next(n->next)
- {
- /* empty */
- }
-
- void next()
- {
- node = _next;
- _next = node->next;
- }
-
- void remove()
- {
- node->remove();
- }
-
- exec_node *get()
- {
- return node;
- }
-
- bool has_next() const
- {
- return _next != NULL;
- }
-
-private:
- exec_node *node;
- exec_node *_next;
-};
-
-#define foreach_iter(iter_type, iter, container) \
- for (iter_type iter = (container) . iterator(); iter.has_next(); iter.next())
#endif
-
struct exec_list {
struct exec_node *head;
struct exec_node *tail;
@@ -404,16 +350,6 @@ struct exec_list {
*/
source->make_empty();
}
-
- exec_list_iterator iterator()
- {
- return exec_list_iterator(head);
- }
-
- exec_list_iterator iterator() const
- {
- return exec_list_iterator((exec_node *) head);
- }
#endif
};
@@ -447,6 +383,22 @@ inline void exec_node::insert_before(exec_list *before)
; (__node)->next != NULL \
; (__node) = (__node)->next)
+/**
+ * Iterate through two lists at once. Stops at the end of the shorter list.
+ *
+ * This is safe against either current node being removed or replaced.
+ */
+#define foreach_two_lists(__node1, __list1, __node2, __list2) \
+ for (exec_node * __node1 = (__list1)->head, \
+ * __node2 = (__list2)->head, \
+ * __next1 = __node1->next, \
+ * __next2 = __node2->next \
+ ; __next1 != NULL && __next2 != NULL \
+ ; __node1 = __next1, \
+ __node2 = __next2, \
+ __next1 = __next1->next, \
+ __next2 = __next2->next)
+
#define foreach_list_const(__node, __list) \
for (const exec_node * __node = (__list)->head \
; (__node)->next != NULL \
diff --git a/mesalib/src/glsl/lower_if_to_cond_assign.cpp b/mesalib/src/glsl/lower_if_to_cond_assign.cpp
index 1e7ce51c7..f15b217e0 100644
--- a/mesalib/src/glsl/lower_if_to_cond_assign.cpp
+++ b/mesalib/src/glsl/lower_if_to_cond_assign.cpp
@@ -178,12 +178,12 @@ ir_if_to_cond_assign_visitor::visit_leave(ir_if *ir)
ir_assignment *assign;
/* Check that both blocks don't contain anything we can't support. */
- foreach_iter(exec_list_iterator, then_iter, ir->then_instructions) {
- ir_instruction *then_ir = (ir_instruction *)then_iter.get();
+ foreach_list(n, &ir->then_instructions) {
+ ir_instruction *then_ir = (ir_instruction *) n;
visit_tree(then_ir, check_control_flow, &found_control_flow);
}
- foreach_iter(exec_list_iterator, else_iter, ir->else_instructions) {
- ir_instruction *else_ir = (ir_instruction *)else_iter.get();
+ foreach_list(n, &ir->else_instructions) {
+ ir_instruction *else_ir = (ir_instruction *) n;
visit_tree(else_ir, check_control_flow, &found_control_flow);
}
if (found_control_flow)
diff --git a/mesalib/src/glsl/lower_vec_index_to_cond_assign.cpp b/mesalib/src/glsl/lower_vec_index_to_cond_assign.cpp
index 8080006c1..fe6a3f208 100644
--- a/mesalib/src/glsl/lower_vec_index_to_cond_assign.cpp
+++ b/mesalib/src/glsl/lower_vec_index_to_cond_assign.cpp
@@ -197,8 +197,8 @@ ir_vec_index_to_cond_assign_visitor::visit_leave(ir_assignment *ir)
ir_visitor_status
ir_vec_index_to_cond_assign_visitor::visit_enter(ir_call *ir)
{
- foreach_iter(exec_list_iterator, iter, *ir) {
- ir_rvalue *param = (ir_rvalue *)iter.get();
+ foreach_list_safe(n, &ir->actual_parameters) {
+ ir_rvalue *param = (ir_rvalue *) n;
ir_rvalue *new_param = convert_vector_extract_to_cond_assign(param);
if (new_param != param) {
diff --git a/mesalib/src/glsl/lower_vec_index_to_swizzle.cpp b/mesalib/src/glsl/lower_vec_index_to_swizzle.cpp
index 46985791e..b5bb00c30 100644
--- a/mesalib/src/glsl/lower_vec_index_to_swizzle.cpp
+++ b/mesalib/src/glsl/lower_vec_index_to_swizzle.cpp
@@ -131,8 +131,8 @@ ir_vec_index_to_swizzle_visitor::visit_enter(ir_assignment *ir)
ir_visitor_status
ir_vec_index_to_swizzle_visitor::visit_enter(ir_call *ir)
{
- foreach_iter(exec_list_iterator, iter, *ir) {
- ir_rvalue *param = (ir_rvalue *)iter.get();
+ foreach_list_safe(n, &ir->actual_parameters) {
+ ir_rvalue *param = (ir_rvalue *) n;
ir_rvalue *new_param = convert_vector_extract_to_swizzle(param);
if (new_param != param) {
diff --git a/mesalib/src/glsl/opt_array_splitting.cpp b/mesalib/src/glsl/opt_array_splitting.cpp
index e946e0ae5..f37d09022 100644
--- a/mesalib/src/glsl/opt_array_splitting.cpp
+++ b/mesalib/src/glsl/opt_array_splitting.cpp
@@ -135,8 +135,8 @@ ir_array_reference_visitor::get_variable_entry(ir_variable *var)
if (var->type->is_unsized_array())
return NULL;
- foreach_iter(exec_list_iterator, iter, this->variable_list) {
- variable_entry *entry = (variable_entry *)iter.get();
+ foreach_list(n, &this->variable_list) {
+ variable_entry *entry = (variable_entry *) n;
if (entry->var == var)
return entry;
}
@@ -224,8 +224,8 @@ ir_array_reference_visitor::get_split_list(exec_list *instructions,
}
/* Trim out variables we found that we can't split. */
- foreach_iter(exec_list_iterator, iter, variable_list) {
- variable_entry *entry = (variable_entry *)iter.get();
+ foreach_list_safe(n, &variable_list) {
+ variable_entry *entry = (variable_entry *) n;
if (debug) {
printf("array %s@%p: decl %d, split %d\n",
@@ -270,8 +270,8 @@ ir_array_splitting_visitor::get_splitting_entry(ir_variable *var)
{
assert(var);
- foreach_iter(exec_list_iterator, iter, *this->variable_list) {
- variable_entry *entry = (variable_entry *)iter.get();
+ foreach_list(n, this->variable_list) {
+ variable_entry *entry = (variable_entry *) n;
if (entry->var == var) {
return entry;
}
@@ -368,8 +368,8 @@ optimize_split_arrays(exec_list *instructions, bool linked)
/* Replace the decls of the arrays to be split with their split
* components.
*/
- foreach_iter(exec_list_iterator, iter, refs.variable_list) {
- variable_entry *entry = (variable_entry *)iter.get();
+ foreach_list(n, &refs.variable_list) {
+ variable_entry *entry = (variable_entry *) n;
const struct glsl_type *type = entry->var->type;
const struct glsl_type *subtype;
diff --git a/mesalib/src/glsl/opt_constant_folding.cpp b/mesalib/src/glsl/opt_constant_folding.cpp
index 08a47b96b..d0e575460 100644
--- a/mesalib/src/glsl/opt_constant_folding.cpp
+++ b/mesalib/src/glsl/opt_constant_folding.cpp
@@ -122,10 +122,10 @@ ir_visitor_status
ir_constant_folding_visitor::visit_enter(ir_call *ir)
{
/* Attempt to constant fold parameters */
- exec_list_iterator sig_iter = ir->callee->parameters.iterator();
- foreach_iter(exec_list_iterator, iter, *ir) {
- ir_rvalue *param_rval = (ir_rvalue *)iter.get();
- ir_variable *sig_param = (ir_variable *)sig_iter.get();
+ foreach_two_lists(formal_node, &ir->callee->parameters,
+ actual_node, &ir->actual_parameters) {
+ ir_rvalue *param_rval = (ir_rvalue *) actual_node;
+ ir_variable *sig_param = (ir_variable *) formal_node;
if (sig_param->data.mode == ir_var_function_in
|| sig_param->data.mode == ir_var_const_in) {
@@ -136,7 +136,6 @@ ir_constant_folding_visitor::visit_enter(ir_call *ir)
param_rval->replace_with(new_param);
}
}
- sig_iter.next();
}
/* Next, see if the call can be replaced with an assignment of a constant */
diff --git a/mesalib/src/glsl/opt_constant_propagation.cpp b/mesalib/src/glsl/opt_constant_propagation.cpp
index f1a6fbdaa..18f5da689 100644
--- a/mesalib/src/glsl/opt_constant_propagation.cpp
+++ b/mesalib/src/glsl/opt_constant_propagation.cpp
@@ -172,8 +172,8 @@ ir_constant_propagation_visitor::handle_rvalue(ir_rvalue **rvalue)
channel = i;
}
- foreach_iter(exec_list_iterator, iter, *this->acp) {
- acp_entry *entry = (acp_entry *)iter.get();
+ foreach_list(n, this->acp) {
+ acp_entry *entry = (acp_entry *) n;
if (entry->var == deref->var && entry->write_mask & (1 << channel)) {
found = entry;
break;
@@ -281,10 +281,10 @@ ir_visitor_status
ir_constant_propagation_visitor::visit_enter(ir_call *ir)
{
/* Do constant propagation on call parameters, but skip any out params */
- exec_list_iterator sig_param_iter = ir->callee->parameters.iterator();
- foreach_iter(exec_list_iterator, iter, ir->actual_parameters) {
- ir_variable *sig_param = (ir_variable *)sig_param_iter.get();
- ir_rvalue *param = (ir_rvalue *)iter.get();
+ foreach_two_lists(formal_node, &ir->callee->parameters,
+ actual_node, &ir->actual_parameters) {
+ ir_variable *sig_param = (ir_variable *) formal_node;
+ ir_rvalue *param = (ir_rvalue *) actual_node;
if (sig_param->data.mode != ir_var_function_out
&& sig_param->data.mode != ir_var_function_inout) {
ir_rvalue *new_param = param;
@@ -294,7 +294,6 @@ ir_constant_propagation_visitor::visit_enter(ir_call *ir)
else
param->accept(this);
}
- sig_param_iter.next();
}
/* Since we're unlinked, we don't (necssarily) know the side effects of
@@ -318,8 +317,8 @@ ir_constant_propagation_visitor::handle_if_block(exec_list *instructions)
this->killed_all = false;
/* Populate the initial acp with a constant of the original */
- foreach_iter(exec_list_iterator, iter, *orig_acp) {
- acp_entry *a = (acp_entry *)iter.get();
+ foreach_list(n, orig_acp) {
+ acp_entry *a = (acp_entry *) n;
this->acp->push_tail(new(this->mem_ctx) acp_entry(a));
}
@@ -334,8 +333,8 @@ ir_constant_propagation_visitor::handle_if_block(exec_list *instructions)
this->acp = orig_acp;
this->killed_all = this->killed_all || orig_killed_all;
- foreach_iter(exec_list_iterator, iter, *new_kills) {
- kill_entry *k = (kill_entry *)iter.get();
+ foreach_list(n, new_kills) {
+ kill_entry *k = (kill_entry *) n;
kill(k->var, k->write_mask);
}
}
@@ -379,8 +378,8 @@ ir_constant_propagation_visitor::visit_enter(ir_loop *ir)
this->acp = orig_acp;
this->killed_all = this->killed_all || orig_killed_all;
- foreach_iter(exec_list_iterator, iter, *new_kills) {
- kill_entry *k = (kill_entry *)iter.get();
+ foreach_list(n, new_kills) {
+ kill_entry *k = (kill_entry *) n;
kill(k->var, k->write_mask);
}
@@ -398,8 +397,8 @@ ir_constant_propagation_visitor::kill(ir_variable *var, unsigned write_mask)
return;
/* Remove any entries currently in the ACP for this kill. */
- foreach_iter(exec_list_iterator, iter, *this->acp) {
- acp_entry *entry = (acp_entry *)iter.get();
+ foreach_list_safe(n, this->acp) {
+ acp_entry *entry = (acp_entry *) n;
if (entry->var == var) {
entry->write_mask &= ~write_mask;
@@ -411,8 +410,8 @@ ir_constant_propagation_visitor::kill(ir_variable *var, unsigned write_mask)
/* Add this writemask of the variable to the list of killed
* variables in this block.
*/
- foreach_iter(exec_list_iterator, iter, *this->kills) {
- kill_entry *entry = (kill_entry *)iter.get();
+ foreach_list(n, this->kills) {
+ kill_entry *entry = (kill_entry *) n;
if (entry->var == var) {
entry->write_mask |= write_mask;
diff --git a/mesalib/src/glsl/opt_constant_variable.cpp b/mesalib/src/glsl/opt_constant_variable.cpp
index a026c51c3..961b8aa06 100644
--- a/mesalib/src/glsl/opt_constant_variable.cpp
+++ b/mesalib/src/glsl/opt_constant_variable.cpp
@@ -132,10 +132,10 @@ ir_visitor_status
ir_constant_variable_visitor::visit_enter(ir_call *ir)
{
/* Mark any out parameters as assigned to */
- exec_list_iterator sig_iter = ir->callee->parameters.iterator();
- foreach_iter(exec_list_iterator, iter, *ir) {
- ir_rvalue *param_rval = (ir_rvalue *)iter.get();
- ir_variable *param = (ir_variable *)sig_iter.get();
+ foreach_two_lists(formal_node, &ir->callee->parameters,
+ actual_node, &ir->actual_parameters) {
+ ir_rvalue *param_rval = (ir_rvalue *) actual_node;
+ ir_variable *param = (ir_variable *) formal_node;
if (param->data.mode == ir_var_function_out ||
param->data.mode == ir_var_function_inout) {
@@ -146,7 +146,6 @@ ir_constant_variable_visitor::visit_enter(ir_call *ir)
entry = get_assignment_entry(var, &this->list);
entry->assignment_count++;
}
- sig_iter.next();
}
/* Mark the return storage as having been assigned to */
@@ -194,13 +193,12 @@ do_constant_variable_unlinked(exec_list *instructions)
{
bool progress = false;
- foreach_iter(exec_list_iterator, iter, *instructions) {
- ir_instruction *ir = (ir_instruction *)iter.get();
+ foreach_list(n, instructions) {
+ ir_instruction *ir = (ir_instruction *) n;
ir_function *f = ir->as_function();
if (f) {
- foreach_iter(exec_list_iterator, sigiter, *f) {
- ir_function_signature *sig =
- (ir_function_signature *) sigiter.get();
+ foreach_list(signode, &f->signatures) {
+ ir_function_signature *sig = (ir_function_signature *) signode;
if (do_constant_variable(&sig->body))
progress = true;
}
diff --git a/mesalib/src/glsl/opt_copy_propagation.cpp b/mesalib/src/glsl/opt_copy_propagation.cpp
index db5dfc153..195cc8baa 100644
--- a/mesalib/src/glsl/opt_copy_propagation.cpp
+++ b/mesalib/src/glsl/opt_copy_propagation.cpp
@@ -167,8 +167,8 @@ ir_copy_propagation_visitor::visit(ir_dereference_variable *ir)
ir_variable *var = ir->var;
- foreach_iter(exec_list_iterator, iter, *this->acp) {
- acp_entry *entry = (acp_entry *)iter.get();
+ foreach_list(n, this->acp) {
+ acp_entry *entry = (acp_entry *) n;
if (var == entry->lhs) {
ir->var = entry->rhs;
@@ -185,15 +185,14 @@ ir_visitor_status
ir_copy_propagation_visitor::visit_enter(ir_call *ir)
{
/* Do copy propagation on call parameters, but skip any out params */
- exec_list_iterator sig_param_iter = ir->callee->parameters.iterator();
- foreach_iter(exec_list_iterator, iter, ir->actual_parameters) {
- ir_variable *sig_param = (ir_variable *)sig_param_iter.get();
- ir_instruction *ir = (ir_instruction *)iter.get();
+ foreach_two_lists(formal_node, &ir->callee->parameters,
+ actual_node, &ir->actual_parameters) {
+ ir_variable *sig_param = (ir_variable *) formal_node;
+ ir_rvalue *ir = (ir_rvalue *) actual_node;
if (sig_param->data.mode != ir_var_function_out
&& sig_param->data.mode != ir_var_function_inout) {
ir->accept(this);
}
- sig_param_iter.next();
}
/* Since we're unlinked, we don't (necessarily) know the side effects of
@@ -217,8 +216,8 @@ ir_copy_propagation_visitor::handle_if_block(exec_list *instructions)
this->killed_all = false;
/* Populate the initial acp with a copy of the original */
- foreach_iter(exec_list_iterator, iter, *orig_acp) {
- acp_entry *a = (acp_entry *)iter.get();
+ foreach_list(n, orig_acp) {
+ acp_entry *a = (acp_entry *) n;
this->acp->push_tail(new(this->mem_ctx) acp_entry(a->lhs, a->rhs));
}
@@ -233,8 +232,8 @@ ir_copy_propagation_visitor::handle_if_block(exec_list *instructions)
this->acp = orig_acp;
this->killed_all = this->killed_all || orig_killed_all;
- foreach_iter(exec_list_iterator, iter, *new_kills) {
- kill_entry *k = (kill_entry *)iter.get();
+ foreach_list(n, new_kills) {
+ kill_entry *k = (kill_entry *) n;
kill(k->var);
}
}
@@ -277,8 +276,8 @@ ir_copy_propagation_visitor::visit_enter(ir_loop *ir)
this->acp = orig_acp;
this->killed_all = this->killed_all || orig_killed_all;
- foreach_iter(exec_list_iterator, iter, *new_kills) {
- kill_entry *k = (kill_entry *)iter.get();
+ foreach_list(n, new_kills) {
+ kill_entry *k = (kill_entry *) n;
kill(k->var);
}
@@ -292,8 +291,8 @@ ir_copy_propagation_visitor::kill(ir_variable *var)
assert(var != NULL);
/* Remove any entries currently in the ACP for this kill. */
- foreach_iter(exec_list_iterator, iter, *acp) {
- acp_entry *entry = (acp_entry *)iter.get();
+ foreach_list_safe(n, acp) {
+ acp_entry *entry = (acp_entry *) n;
if (entry->lhs == var || entry->rhs == var) {
entry->remove();
diff --git a/mesalib/src/glsl/opt_copy_propagation_elements.cpp b/mesalib/src/glsl/opt_copy_propagation_elements.cpp
index ba8a0f532..cc53e0dd0 100644
--- a/mesalib/src/glsl/opt_copy_propagation_elements.cpp
+++ b/mesalib/src/glsl/opt_copy_propagation_elements.cpp
@@ -244,8 +244,8 @@ ir_copy_propagation_elements_visitor::handle_rvalue(ir_rvalue **ir)
/* Try to find ACP entries covering swizzle_chan[], hoping they're
* the same source variable.
*/
- foreach_iter(exec_list_iterator, iter, *this->acp) {
- acp_entry *entry = (acp_entry *)iter.get();
+ foreach_list(n, this->acp) {
+ acp_entry *entry = (acp_entry *) n;
if (var == entry->lhs) {
for (int c = 0; c < chans; c++) {
@@ -293,15 +293,14 @@ ir_visitor_status
ir_copy_propagation_elements_visitor::visit_enter(ir_call *ir)
{
/* Do copy propagation on call parameters, but skip any out params */
- exec_list_iterator sig_param_iter = ir->callee->parameters.iterator();
- foreach_iter(exec_list_iterator, iter, ir->actual_parameters) {
- ir_variable *sig_param = (ir_variable *)sig_param_iter.get();
- ir_instruction *ir = (ir_instruction *)iter.get();
+ foreach_two_lists(formal_node, &ir->callee->parameters,
+ actual_node, &ir->actual_parameters) {
+ ir_variable *sig_param = (ir_variable *) formal_node;
+ ir_rvalue *ir = (ir_rvalue *) actual_node;
if (sig_param->data.mode != ir_var_function_out
&& sig_param->data.mode != ir_var_function_inout) {
ir->accept(this);
}
- sig_param_iter.next();
}
/* Since we're unlinked, we don't (necessarily) know the side effects of
@@ -325,8 +324,8 @@ ir_copy_propagation_elements_visitor::handle_if_block(exec_list *instructions)
this->killed_all = false;
/* Populate the initial acp with a copy of the original */
- foreach_iter(exec_list_iterator, iter, *orig_acp) {
- acp_entry *a = (acp_entry *)iter.get();
+ foreach_list(n, orig_acp) {
+ acp_entry *a = (acp_entry *) n;
this->acp->push_tail(new(this->mem_ctx) acp_entry(a));
}
diff --git a/mesalib/src/glsl/opt_dead_code.cpp b/mesalib/src/glsl/opt_dead_code.cpp
index a8d8b4a39..af53d94fd 100644
--- a/mesalib/src/glsl/opt_dead_code.cpp
+++ b/mesalib/src/glsl/opt_dead_code.cpp
@@ -129,13 +129,12 @@ do_dead_code_unlinked(exec_list *instructions)
{
bool progress = false;
- foreach_iter(exec_list_iterator, iter, *instructions) {
- ir_instruction *ir = (ir_instruction *)iter.get();
+ foreach_list(n, instructions) {
+ ir_instruction *ir = (ir_instruction *) n;
ir_function *f = ir->as_function();
if (f) {
- foreach_iter(exec_list_iterator, sigiter, *f) {
- ir_function_signature *sig =
- (ir_function_signature *) sigiter.get();
+ foreach_list(signode, &f->signatures) {
+ ir_function_signature *sig = (ir_function_signature *) signode;
/* The setting of the uniform_locations_assigned flag here is
* irrelevent. If there is a uniform declaration encountered
* inside the body of the function, something has already gone
diff --git a/mesalib/src/glsl/opt_dead_code_local.cpp b/mesalib/src/glsl/opt_dead_code_local.cpp
index 43a01662a..e7d46edbe 100644
--- a/mesalib/src/glsl/opt_dead_code_local.cpp
+++ b/mesalib/src/glsl/opt_dead_code_local.cpp
@@ -70,8 +70,8 @@ public:
void kill_channels(ir_variable *const var, int used)
{
- foreach_iter(exec_list_iterator, iter, *this->assignments) {
- assignment_entry *entry = (assignment_entry *)iter.get();
+ foreach_list_safe(n, this->assignments) {
+ assignment_entry *entry = (assignment_entry *) n;
if (entry->lhs == var) {
if (var->type->is_scalar() || var->type->is_vector()) {
@@ -119,8 +119,8 @@ public:
/* For the purpose of dead code elimination, emitting a vertex counts as
* "reading" all of the currently assigned output variables.
*/
- foreach_iter(exec_list_iterator, iter, *this->assignments) {
- assignment_entry *entry = (assignment_entry *)iter.get();
+ foreach_list_safe(n, this->assignments) {
+ assignment_entry *entry = (assignment_entry *) n;
if (entry->lhs->data.mode == ir_var_shader_out) {
if (debug)
printf("kill %s\n", entry->lhs->name);
@@ -196,8 +196,8 @@ process_assignment(void *ctx, ir_assignment *ir, exec_list *assignments)
printf("looking for %s.0x%01x to remove\n", var->name,
ir->write_mask);
- foreach_iter(exec_list_iterator, iter, *assignments) {
- assignment_entry *entry = (assignment_entry *)iter.get();
+ foreach_list_safe(n, assignments) {
+ assignment_entry *entry = (assignment_entry *) n;
if (entry->lhs != var)
continue;
@@ -258,8 +258,8 @@ process_assignment(void *ctx, ir_assignment *ir, exec_list *assignments)
*/
if (debug)
printf("looking for %s to remove\n", var->name);
- foreach_iter(exec_list_iterator, iter, *assignments) {
- assignment_entry *entry = (assignment_entry *)iter.get();
+ foreach_list_safe(n, assignments) {
+ assignment_entry *entry = (assignment_entry *) n;
if (entry->lhs == var) {
if (debug)
@@ -280,8 +280,8 @@ process_assignment(void *ctx, ir_assignment *ir, exec_list *assignments)
printf("add %s\n", var->name);
printf("current entries\n");
- foreach_iter(exec_list_iterator, iter, *assignments) {
- assignment_entry *entry = (assignment_entry *)iter.get();
+ foreach_list(n, assignments) {
+ assignment_entry *entry = (assignment_entry *) n;
printf(" %s (0x%01x)\n", entry->lhs->name, entry->available);
}
diff --git a/mesalib/src/glsl/opt_dead_functions.cpp b/mesalib/src/glsl/opt_dead_functions.cpp
index cd3b2c12e..8bb278e45 100644
--- a/mesalib/src/glsl/opt_dead_functions.cpp
+++ b/mesalib/src/glsl/opt_dead_functions.cpp
@@ -74,8 +74,8 @@ public:
signature_entry *
ir_dead_functions_visitor::get_signature_entry(ir_function_signature *sig)
{
- foreach_iter(exec_list_iterator, iter, this->signature_list) {
- signature_entry *entry = (signature_entry *)iter.get();
+ foreach_list(n, &this->signature_list) {
+ signature_entry *entry = (signature_entry *) n;
if (entry->signature == sig)
return entry;
}
@@ -123,8 +123,8 @@ do_dead_functions(exec_list *instructions)
* the unused ones, and remove function definitions that have no more
* signatures.
*/
- foreach_iter(exec_list_iterator, iter, v.signature_list) {
- signature_entry *entry = (signature_entry *)iter.get();
+ foreach_list_safe(n, &v.signature_list) {
+ signature_entry *entry = (signature_entry *) n;
if (!entry->used) {
entry->signature->remove();
@@ -137,8 +137,8 @@ do_dead_functions(exec_list *instructions)
/* We don't just do this above when we nuked a signature because of
* const pointers.
*/
- foreach_iter(exec_list_iterator, iter, *instructions) {
- ir_instruction *ir = (ir_instruction *)iter.get();
+ foreach_list_safe(n, instructions) {
+ ir_instruction *ir = (ir_instruction *) n;
ir_function *func = ir->as_function();
if (func && func->signatures.is_empty()) {
diff --git a/mesalib/src/glsl/opt_function_inlining.cpp b/mesalib/src/glsl/opt_function_inlining.cpp
index c8f42a424..9649598dd 100644
--- a/mesalib/src/glsl/opt_function_inlining.cpp
+++ b/mesalib/src/glsl/opt_function_inlining.cpp
@@ -107,7 +107,7 @@ ir_call::generate_inline(ir_instruction *next_ir)
ht = hash_table_ctor(0, hash_table_pointer_hash, hash_table_pointer_compare);
num_parameters = 0;
- foreach_iter(exec_list_iterator, iter_sig, this->callee->parameters)
+ foreach_list(n, &this->callee->parameters)
num_parameters++;
parameters = new ir_variable *[num_parameters];
@@ -116,11 +116,10 @@ ir_call::generate_inline(ir_instruction *next_ir)
* and set up the mapping of real function body variables to ours.
*/
i = 0;
- exec_list_iterator sig_param_iter = this->callee->parameters.iterator();
- exec_list_iterator param_iter = this->actual_parameters.iterator();
- for (i = 0; i < num_parameters; i++) {
- ir_variable *sig_param = (ir_variable *) sig_param_iter.get();
- ir_rvalue *param = (ir_rvalue *) param_iter.get();
+ foreach_two_lists(formal_node, &this->callee->parameters,
+ actual_node, &this->actual_parameters) {
+ ir_variable *sig_param = (ir_variable *) formal_node;
+ ir_rvalue *param = (ir_rvalue *) actual_node;
/* Generate a new variable for the parameter. */
if (sig_param->type->contains_opaque()) {
@@ -154,15 +153,14 @@ ir_call::generate_inline(ir_instruction *next_ir)
next_ir->insert_before(assign);
}
- sig_param_iter.next();
- param_iter.next();
+ ++i;
}
exec_list new_instructions;
/* Generate the inlined body of the function to a new list */
- foreach_iter(exec_list_iterator, iter, callee->body) {
- ir_instruction *ir = (ir_instruction *)iter.get();
+ foreach_list(n, &callee->body) {
+ ir_instruction *ir = (ir_instruction *) n;
ir_instruction *new_ir = ir->clone(ctx, ht);
new_instructions.push_tail(new_ir);
@@ -172,11 +170,10 @@ ir_call::generate_inline(ir_instruction *next_ir)
/* If any opaque types were passed in, replace any deref of the
* opaque variable with a deref of the argument.
*/
- param_iter = this->actual_parameters.iterator();
- sig_param_iter = this->callee->parameters.iterator();
- for (i = 0; i < num_parameters; i++) {
- ir_instruction *const param = (ir_instruction *) param_iter.get();
- ir_variable *sig_param = (ir_variable *) sig_param_iter.get();
+ foreach_two_lists(formal_node, &this->callee->parameters,
+ actual_node, &this->actual_parameters) {
+ ir_rvalue *const param = (ir_rvalue *) actual_node;
+ ir_variable *sig_param = (ir_variable *) formal_node;
if (sig_param->type->contains_opaque()) {
ir_dereference *deref = param->as_dereference();
@@ -184,8 +181,6 @@ ir_call::generate_inline(ir_instruction *next_ir)
assert(deref);
do_variable_replacement(&new_instructions, sig_param, deref);
}
- param_iter.next();
- sig_param_iter.next();
}
/* Now push those new instructions in. */
@@ -195,11 +190,10 @@ ir_call::generate_inline(ir_instruction *next_ir)
* variables to our own.
*/
i = 0;
- param_iter = this->actual_parameters.iterator();
- sig_param_iter = this->callee->parameters.iterator();
- for (i = 0; i < num_parameters; i++) {
- ir_instruction *const param = (ir_instruction *) param_iter.get();
- const ir_variable *const sig_param = (ir_variable *) sig_param_iter.get();
+ foreach_two_lists(formal_node, &this->callee->parameters,
+ actual_node, &this->actual_parameters) {
+ ir_rvalue *const param = (ir_rvalue *) actual_node;
+ const ir_variable *const sig_param = (ir_variable *) formal_node;
/* Move our param variable into the actual param if it's an 'out' type. */
if (parameters[i] && (sig_param->data.mode == ir_var_function_out ||
@@ -212,8 +206,7 @@ ir_call::generate_inline(ir_instruction *next_ir)
next_ir->insert_before(assign);
}
- param_iter.next();
- sig_param_iter.next();
+ ++i;
}
delete [] parameters;
@@ -349,8 +342,8 @@ ir_variable_replacement_visitor::visit_leave(ir_dereference_record *ir)
ir_visitor_status
ir_variable_replacement_visitor::visit_leave(ir_call *ir)
{
- foreach_iter(exec_list_iterator, iter, *ir) {
- ir_rvalue *param = (ir_rvalue *)iter.get();
+ foreach_list_safe(n, &ir->actual_parameters) {
+ ir_rvalue *param = (ir_rvalue *) n;
ir_rvalue *new_param = param;
replace_rvalue(&new_param);
diff --git a/mesalib/src/glsl/opt_if_simplification.cpp b/mesalib/src/glsl/opt_if_simplification.cpp
index db59b131d..2bec8252e 100644
--- a/mesalib/src/glsl/opt_if_simplification.cpp
+++ b/mesalib/src/glsl/opt_if_simplification.cpp
@@ -90,13 +90,13 @@ ir_if_simplification_visitor::visit_leave(ir_if *ir)
* that matters out.
*/
if (condition_constant->value.b[0]) {
- foreach_iter(exec_list_iterator, then_iter, ir->then_instructions) {
- ir_instruction *then_ir = (ir_instruction *)then_iter.get();
+ foreach_list_safe(n, &ir->then_instructions) {
+ ir_instruction *then_ir = (ir_instruction *) n;
ir->insert_before(then_ir);
}
} else {
- foreach_iter(exec_list_iterator, else_iter, ir->else_instructions) {
- ir_instruction *else_ir = (ir_instruction *)else_iter.get();
+ foreach_list_safe(n, &ir->else_instructions) {
+ ir_instruction *else_ir = (ir_instruction *) n;
ir->insert_before(else_ir);
}
}
diff --git a/mesalib/src/glsl/opt_structure_splitting.cpp b/mesalib/src/glsl/opt_structure_splitting.cpp
index 414f0000d..1ec537b13 100644
--- a/mesalib/src/glsl/opt_structure_splitting.cpp
+++ b/mesalib/src/glsl/opt_structure_splitting.cpp
@@ -107,8 +107,8 @@ ir_structure_reference_visitor::get_variable_entry(ir_variable *var)
|| var->data.mode == ir_var_shader_in || var->data.mode == ir_var_shader_out)
return NULL;
- foreach_iter(exec_list_iterator, iter, this->variable_list) {
- variable_entry *entry = (variable_entry *)iter.get();
+ foreach_list(n, &this->variable_list) {
+ variable_entry *entry = (variable_entry *) n;
if (entry->var == var)
return entry;
}
@@ -209,8 +209,8 @@ ir_structure_splitting_visitor::get_splitting_entry(ir_variable *var)
if (!var->type->is_record())
return NULL;
- foreach_iter(exec_list_iterator, iter, *this->variable_list) {
- variable_entry *entry = (variable_entry *)iter.get();
+ foreach_list(n, this->variable_list) {
+ variable_entry *entry = (variable_entry *) n;
if (entry->var == var) {
return entry;
}
@@ -315,8 +315,8 @@ do_structure_splitting(exec_list *instructions)
visit_list_elements(&refs, instructions);
/* Trim out variables we can't split. */
- foreach_iter(exec_list_iterator, iter, refs.variable_list) {
- variable_entry *entry = (variable_entry *)iter.get();
+ foreach_list_safe(n, &refs.variable_list) {
+ variable_entry *entry = (variable_entry *) n;
if (debug) {
printf("structure %s@%p: decl %d, whole_access %d\n",
@@ -337,8 +337,8 @@ do_structure_splitting(exec_list *instructions)
/* Replace the decls of the structures to be split with their split
* components.
*/
- foreach_iter(exec_list_iterator, iter, refs.variable_list) {
- variable_entry *entry = (variable_entry *)iter.get();
+ foreach_list_safe(n, &refs.variable_list) {
+ variable_entry *entry = (variable_entry *) n;
const struct glsl_type *type = entry->var->type;
entry->mem_ctx = ralloc_parent(entry->var);
diff --git a/mesalib/src/glsl/opt_tree_grafting.cpp b/mesalib/src/glsl/opt_tree_grafting.cpp
index 6d75a1573..f3bd580af 100644
--- a/mesalib/src/glsl/opt_tree_grafting.cpp
+++ b/mesalib/src/glsl/opt_tree_grafting.cpp
@@ -204,11 +204,10 @@ ir_tree_grafting_visitor::visit_enter(ir_function_signature *ir)
ir_visitor_status
ir_tree_grafting_visitor::visit_enter(ir_call *ir)
{
- exec_list_iterator sig_iter = ir->callee->parameters.iterator();
- /* Reminder: iterating ir_call iterates its parameters. */
- foreach_iter(exec_list_iterator, iter, *ir) {
- ir_variable *sig_param = (ir_variable *)sig_iter.get();
- ir_rvalue *ir = (ir_rvalue *)iter.get();
+ foreach_two_lists(formal_node, &ir->callee->parameters,
+ actual_node, &ir->actual_parameters) {
+ ir_variable *sig_param = (ir_variable *) formal_node;
+ ir_rvalue *ir = (ir_rvalue *) actual_node;
ir_rvalue *new_ir = ir;
if (sig_param->data.mode != ir_var_function_in
@@ -222,7 +221,6 @@ ir_tree_grafting_visitor::visit_enter(ir_call *ir)
ir->replace_with(new_ir);
return visit_stop;
}
- sig_iter.next();
}
if (ir->return_deref && check_graft(ir, ir->return_deref->var) == visit_stop)
diff --git a/mesalib/src/glsl/s_expression.cpp b/mesalib/src/glsl/s_expression.cpp
index 1bdf6bca6..6906ff0eb 100644
--- a/mesalib/src/glsl/s_expression.cpp
+++ b/mesalib/src/glsl/s_expression.cpp
@@ -162,8 +162,8 @@ void s_symbol::print()
void s_list::print()
{
printf("(");
- foreach_iter(exec_list_iterator, it, this->subexpressions) {
- s_expression *expr = (s_expression*) it.get();
+ foreach_list(n, &this->subexpressions) {
+ s_expression *expr = (s_expression *) n;
expr->print();
if (!expr->next->is_tail_sentinel())
printf(" ");
@@ -201,11 +201,11 @@ s_match(s_expression *top, unsigned n, s_pattern *pattern, bool partial)
return false;
unsigned i = 0;
- foreach_iter(exec_list_iterator, it, list->subexpressions) {
+ foreach_list(node, &list->subexpressions) {
if (i >= n)
return partial; /* More actual items than the pattern expected */
- s_expression *expr = (s_expression *) it.get();
+ s_expression *expr = (s_expression *) node;
if (expr == NULL || !pattern[i].match(expr))
return false;
diff --git a/mesalib/src/mapi/glapi/gen/ARB_shader_image_load_store.xml b/mesalib/src/mapi/glapi/gen/ARB_shader_image_load_store.xml
new file mode 100644
index 000000000..7ccfca41d
--- /dev/null
+++ b/mesalib/src/mapi/glapi/gen/ARB_shader_image_load_store.xml
@@ -0,0 +1,89 @@
+<?xml version="1.0"?>
+<!DOCTYPE OpenGLAPI SYSTEM "gl_API.dtd">
+
+<OpenGLAPI>
+
+<category name="GL_ARB_shader_image_load_store" number="115">
+
+<enum name="VERTEX_ATTRIB_ARRAY_BARRIER_BIT" value="0x00000001"/>
+<enum name="ELEMENT_ARRAY_BARRIER_BIT" value="0x00000002"/>
+<enum name="UNIFORM_BARRIER_BIT" value="0x00000004"/>
+<enum name="TEXTURE_FETCH_BARRIER_BIT" value="0x00000008"/>
+<enum name="SHADER_IMAGE_ACCESS_BARRIER_BIT" value="0x00000020"/>
+<enum name="COMMAND_BARRIER_BIT" value="0x00000040"/>
+<enum name="PIXEL_BUFFER_BARRIER_BIT" value="0x00000080"/>
+<enum name="TEXTURE_UPDATE_BARRIER_BIT" value="0x00000100"/>
+<enum name="BUFFER_UPDATE_BARRIER_BIT" value="0x00000200"/>
+<enum name="FRAMEBUFFER_BARRIER_BIT" value="0x00000400"/>
+<enum name="TRANSFORM_FEEDBACK_BARRIER_BIT" value="0x00000800"/>
+<enum name="ATOMIC_COUNTER_BARRIER_BIT" value="0x00001000"/>
+<enum name="ALL_BARRIER_BITS" value="0xFFFFFFFF"/>
+<enum name="MAX_IMAGE_UNITS" value="0x8F38"/>
+<enum name="MAX_COMBINED_IMAGE_UNITS_AND_FRAGMENT_OUTPUTS" value="0x8F39"/>
+<enum name="IMAGE_BINDING_NAME" value="0x8F3A"/>
+<enum name="IMAGE_BINDING_LEVEL" value="0x8F3B"/>
+<enum name="IMAGE_BINDING_LAYERED" value="0x8F3C"/>
+<enum name="IMAGE_BINDING_LAYER" value="0x8F3D"/>
+<enum name="IMAGE_BINDING_ACCESS" value="0x8F3E"/>
+<enum name="IMAGE_1D" value="0x904C"/>
+<enum name="IMAGE_2D" value="0x904D"/>
+<enum name="IMAGE_3D" value="0x904E"/>
+<enum name="IMAGE_2D_RECT" value="0x904F"/>
+<enum name="IMAGE_CUBE" value="0x9050"/>
+<enum name="IMAGE_BUFFER" value="0x9051"/>
+<enum name="IMAGE_1D_ARRAY" value="0x9052"/>
+<enum name="IMAGE_2D_ARRAY" value="0x9053"/>
+<enum name="IMAGE_CUBE_MAP_ARRAY" value="0x9054"/>
+<enum name="IMAGE_2D_MULTISAMPLE" value="0x9055"/>
+<enum name="IMAGE_2D_MULTISAMPLE_ARRAY" value="0x9056"/>
+<enum name="INT_IMAGE_1D" value="0x9057"/>
+<enum name="INT_IMAGE_2D" value="0x9058"/>
+<enum name="INT_IMAGE_3D" value="0x9059"/>
+<enum name="INT_IMAGE_2D_RECT" value="0x905A"/>
+<enum name="INT_IMAGE_CUBE" value="0x905B"/>
+<enum name="INT_IMAGE_BUFFER" value="0x905C"/>
+<enum name="INT_IMAGE_1D_ARRAY" value="0x905D"/>
+<enum name="INT_IMAGE_2D_ARRAY" value="0x905E"/>
+<enum name="INT_IMAGE_CUBE_MAP_ARRAY" value="0x905F"/>
+<enum name="INT_IMAGE_2D_MULTISAMPLE" value="0x9060"/>
+<enum name="INT_IMAGE_2D_MULTISAMPLE_ARRAY" value="0x9061"/>
+<enum name="UNSIGNED_INT_IMAGE_1D" value="0x9062"/>
+<enum name="UNSIGNED_INT_IMAGE_2D" value="0x9063"/>
+<enum name="UNSIGNED_INT_IMAGE_3D" value="0x9064"/>
+<enum name="UNSIGNED_INT_IMAGE_2D_RECT" value="0x9065"/>
+<enum name="UNSIGNED_INT_IMAGE_CUBE" value="0x9066"/>
+<enum name="UNSIGNED_INT_IMAGE_BUFFER" value="0x9067"/>
+<enum name="UNSIGNED_INT_IMAGE_1D_ARRAY" value="0x9068"/>
+<enum name="UNSIGNED_INT_IMAGE_2D_ARRAY" value="0x9069"/>
+<enum name="UNSIGNED_INT_IMAGE_CUBE_MAP_ARRAY" value="0x906A"/>
+<enum name="UNSIGNED_INT_IMAGE_2D_MULTISAMPLE" value="0x906B"/>
+<enum name="UNSIGNED_INT_IMAGE_2D_MULTISAMPLE_ARRAY" value="0x906C"/>
+<enum name="MAX_IMAGE_SAMPLES" value="0x906D"/>
+<enum name="IMAGE_BINDING_FORMAT" value="0x906E"/>
+<enum name="IMAGE_FORMAT_COMPATIBILITY_TYPE" value="0x90C7"/>
+<enum name="IMAGE_FORMAT_COMPATIBILITY_BY_SIZE" value="0x90C8"/>
+<enum name="IMAGE_FORMAT_COMPATIBILITY_BY_CLASS" value="0x90C9"/>
+<enum name="MAX_VERTEX_IMAGE_UNIFORMS" value="0x90CA"/>
+<enum name="MAX_TESS_CONTROL_IMAGE_UNIFORMS" value="0x90CB"/>
+<enum name="MAX_TESS_EVALUATION_IMAGE_UNIFORMS" value="0x90CC"/>
+<enum name="MAX_GEOMETRY_IMAGE_UNIFORMS" value="0x90CD"/>
+<enum name="MAX_FRAGMENT_IMAGE_UNIFORMS" value="0x90CE"/>
+<enum name="MAX_COMBINED_IMAGE_UNIFORMS" value="0x90CF"/>
+
+<function name="BindImageTexture" offset="assign">
+ <param name="unit" type="GLuint"/>
+ <param name="texture" type="GLuint"/>
+ <param name="level" type="GLint"/>
+ <param name="layered" type="GLboolean"/>
+ <param name="layer" type="GLint"/>
+ <param name="access" type="GLenum"/>
+ <param name="format" type="GLenum"/>
+</function>
+
+<function name="MemoryBarrier" offset="assign">
+ <param name="barriers" type="GLbitfield"/>
+</function>
+
+</category>
+
+</OpenGLAPI>
diff --git a/mesalib/src/mapi/glapi/gen/Makefile.am b/mesalib/src/mapi/glapi/gen/Makefile.am
index 65bd9137c..d5c20b71e 100644
--- a/mesalib/src/mapi/glapi/gen/Makefile.am
+++ b/mesalib/src/mapi/glapi/gen/Makefile.am
@@ -113,6 +113,7 @@ API_XML = \
ARB_sampler_objects.xml \
ARB_seamless_cube_map.xml \
ARB_shader_atomic_counters.xml \
+ ARB_shader_image_load_store.xml \
ARB_sync.xml \
ARB_texture_buffer_object.xml \
ARB_texture_buffer_range.xml \
diff --git a/mesalib/src/mapi/glapi/gen/gl_API.xml b/mesalib/src/mapi/glapi/gen/gl_API.xml
index 697b2ecce..ff65b489a 100644
--- a/mesalib/src/mapi/glapi/gen/gl_API.xml
+++ b/mesalib/src/mapi/glapi/gen/gl_API.xml
@@ -8312,6 +8312,8 @@
<xi:include href="ARB_shader_atomic_counters.xml" xmlns:xi="http://www.w3.org/2001/XInclude"/>
+<xi:include href="ARB_shader_image_load_store.xml" xmlns:xi="http://www.w3.org/2001/XInclude"/>
+
<xi:include href="ARB_texture_storage.xml" xmlns:xi="http://www.w3.org/2001/XInclude"/>
<!-- ARB extension #118 -->
diff --git a/mesalib/src/mapi/glapi/gen/gl_genexec.py b/mesalib/src/mapi/glapi/gen/gl_genexec.py
index b557b3b99..b7ac16b06 100644
--- a/mesalib/src/mapi/glapi/gen/gl_genexec.py
+++ b/mesalib/src/mapi/glapi/gen/gl_genexec.py
@@ -108,6 +108,7 @@ header = """/**
#include "main/varray.h"
#include "main/viewport.h"
#include "main/shaderapi.h"
+#include "main/shaderimage.h"
#include "main/uniforms.h"
#include "main/syncobj.h"
#include "main/formatquery.h"
diff --git a/mesalib/src/mesa/Makefile.am b/mesalib/src/mesa/Makefile.am
index 884383652..cb038a5eb 100644
--- a/mesalib/src/mesa/Makefile.am
+++ b/mesalib/src/mesa/Makefile.am
@@ -36,18 +36,18 @@ endif
gldir = $(includedir)/GL
gl_HEADERS = $(top_srcdir)/include/GL/*.h
-.PHONY: main/git_sha1.h.tmp
-main/git_sha1.h.tmp:
+.PHONY: $(BUILDDIR)main/git_sha1.h.tmp
+$(BUILDDIR)main/git_sha1.h.tmp:
@touch main/git_sha1.h.tmp
- @if test -d ../../.git; then \
+ @if test -d $(top_srcdir)/.git; then \
if which git > /dev/null; then \
- git log -n 1 --oneline | \
+ git --git-dir=$(top_srcdir)/.git log -n 1 --oneline | \
sed 's/^\([^ ]*\) .*/#define MESA_GIT_SHA1 "git-\1"/' \
> main/git_sha1.h.tmp ; \
fi \
fi
-main/git_sha1.h: main/git_sha1.h.tmp
+$(BUILDDIR)main/git_sha1.h: $(BUILDDIR)main/git_sha1.h.tmp
@echo "updating main/git_sha1.h"
@if ! cmp -s main/git_sha1.h.tmp main/git_sha1.h; then \
mv main/git_sha1.h.tmp main/git_sha1.h ;\
@@ -63,8 +63,8 @@ BUILDDIR = $(builddir)/
include Makefile.sources
BUILT_SOURCES = \
- main/git_sha1.h \
main/get_hash.h \
+ $(BUILDDIR)main/git_sha1.h \
$(BUILDDIR)program/program_parse.tab.c \
$(BUILDDIR)program/lex.yy.c
CLEANFILES = \
diff --git a/mesalib/src/mesa/Makefile.sources b/mesalib/src/mesa/Makefile.sources
index 39525bc5b..d14823db9 100644
--- a/mesalib/src/mesa/Makefile.sources
+++ b/mesalib/src/mesa/Makefile.sources
@@ -81,6 +81,7 @@ MAIN_FILES = \
$(SRCDIR)main/scissor.c \
$(SRCDIR)main/set.c \
$(SRCDIR)main/shaderapi.c \
+ $(SRCDIR)main/shaderimage.c \
$(SRCDIR)main/shaderobj.c \
$(SRCDIR)main/shader_query.cpp \
$(SRCDIR)main/shared.c \
diff --git a/mesalib/src/mesa/SConscript b/mesalib/src/mesa/SConscript
index bb9b304ef..77e2aaa7e 100644
--- a/mesalib/src/mesa/SConscript
+++ b/mesalib/src/mesa/SConscript
@@ -110,6 +110,7 @@ main_sources = [
'main/scissor.c',
'main/set.c',
'main/shaderapi.c',
+ 'main/shaderimage.c',
'main/shaderobj.c',
'main/shader_query.cpp',
'main/shared.c',
diff --git a/mesalib/src/mesa/drivers/common/driverfuncs.c b/mesalib/src/mesa/drivers/common/driverfuncs.c
index f18568827..e8dcb2476 100644
--- a/mesalib/src/mesa/drivers/common/driverfuncs.c
+++ b/mesalib/src/mesa/drivers/common/driverfuncs.c
@@ -302,8 +302,7 @@ _mesa_init_driver_state(struct gl_context *ctx)
ctx->Driver.LogicOpcode(ctx, ctx->Color.LogicOp);
ctx->Driver.PointSize(ctx, ctx->Point.Size);
ctx->Driver.PolygonStipple(ctx, (const GLubyte *) ctx->PolygonStipple);
- ctx->Driver.Scissor(ctx, ctx->Scissor.X, ctx->Scissor.Y,
- ctx->Scissor.Width, ctx->Scissor.Height);
+ ctx->Driver.Scissor(ctx);
ctx->Driver.ShadeModel(ctx, ctx->Light.ShadeModel);
ctx->Driver.StencilFuncSeparate(ctx, GL_FRONT,
ctx->Stencil.Function[0],
diff --git a/mesalib/src/mesa/drivers/dri/common/utils.c b/mesalib/src/mesa/drivers/dri/common/utils.c
index 9c9483209..3e35fe2d0 100644
--- a/mesalib/src/mesa/drivers/dri/common/utils.c
+++ b/mesalib/src/mesa/drivers/dri/common/utils.c
@@ -308,6 +308,7 @@ driCreateConfigs(gl_format format,
__DRI_ATTRIB_TEXTURE_2D_BIT |
__DRI_ATTRIB_TEXTURE_RECTANGLE_BIT;
+ modes->yInverted = GL_TRUE;
modes->sRGBCapable = is_srgb;
}
}
diff --git a/mesalib/src/mesa/drivers/dri/swrast/swrast.c b/mesalib/src/mesa/drivers/dri/swrast/swrast.c
index 79a27408f..30e6805e9 100644
--- a/mesalib/src/mesa/drivers/dri/swrast/swrast.c
+++ b/mesalib/src/mesa/drivers/dri/swrast/swrast.c
@@ -618,15 +618,11 @@ update_state( struct gl_context *ctx, GLuint new_state )
}
static void
-viewport(struct gl_context *ctx, GLint x, GLint y, GLsizei w, GLsizei h)
+viewport(struct gl_context *ctx)
{
struct gl_framebuffer *draw = ctx->WinSysDrawBuffer;
struct gl_framebuffer *read = ctx->WinSysReadBuffer;
- (void) x;
- (void) y;
- (void) w;
- (void) h;
swrast_check_and_update_window_size(ctx, draw);
swrast_check_and_update_window_size(ctx, read);
}
diff --git a/mesalib/src/mesa/drivers/windows/gdi/wmesa.c b/mesalib/src/mesa/drivers/windows/gdi/wmesa.c
index d6eb82392..c1a9c28b1 100644
--- a/mesalib/src/mesa/drivers/windows/gdi/wmesa.c
+++ b/mesalib/src/mesa/drivers/windows/gdi/wmesa.c
@@ -484,9 +484,7 @@ wmesa_resize_buffers(struct gl_context *ctx, struct gl_framebuffer *buffer,
* we get the viewport set correctly, even if the app does not call
* glViewport and relies on the defaults.
*/
-static void wmesa_viewport(struct gl_context *ctx,
- GLint x, GLint y,
- GLsizei width, GLsizei height)
+static void wmesa_viewport(struct gl_context *ctx)
{
GLuint new_width, new_height;
diff --git a/mesalib/src/mesa/main/clear.c b/mesalib/src/mesa/main/clear.c
index f0b525fa0..077c5fca3 100644
--- a/mesalib/src/mesa/main/clear.c
+++ b/mesalib/src/mesa/main/clear.c
@@ -179,7 +179,11 @@ _mesa_Clear( GLbitfield mask )
if (mask & GL_COLOR_BUFFER_BIT) {
GLuint i;
for (i = 0; i < ctx->DrawBuffer->_NumColorDrawBuffers; i++) {
- bufferMask |= (1 << ctx->DrawBuffer->_ColorDrawBufferIndexes[i]);
+ GLint buf = ctx->DrawBuffer->_ColorDrawBufferIndexes[i];
+
+ if (buf >= 0) {
+ bufferMask |= 1 << buf;
+ }
}
}
@@ -274,7 +278,7 @@ make_color_buffer_mask(struct gl_context *ctx, GLint drawbuffer)
break;
default:
{
- GLuint buf = ctx->DrawBuffer->_ColorDrawBufferIndexes[drawbuffer];
+ GLint buf = ctx->DrawBuffer->_ColorDrawBufferIndexes[drawbuffer];
if (buf >= 0 && att[buf].Renderbuffer) {
mask |= 1 << buf;
diff --git a/mesalib/src/mesa/main/condrender.c b/mesalib/src/mesa/main/condrender.c
index 2632f7a1a..0ad1e5c2a 100644
--- a/mesalib/src/mesa/main/condrender.c
+++ b/mesalib/src/mesa/main/condrender.c
@@ -40,17 +40,38 @@
void GLAPIENTRY
_mesa_BeginConditionalRender(GLuint queryId, GLenum mode)
{
- struct gl_query_object *q;
+ struct gl_query_object *q = NULL;
GET_CURRENT_CONTEXT(ctx);
- if (!ctx->Extensions.NV_conditional_render || ctx->Query.CondRenderQuery ||
- queryId == 0) {
+ /* Section 2.14 (Conditional Rendering) of the OpenGL 3.0 spec says:
+ *
+ * "If BeginConditionalRender is called while conditional rendering is
+ * in progress, or if EndConditionalRender is called while conditional
+ * rendering is not in progress, the error INVALID_OPERATION is
+ * generated."
+ */
+ if (!ctx->Extensions.NV_conditional_render || ctx->Query.CondRenderQuery) {
_mesa_error(ctx, GL_INVALID_OPERATION, "glBeginConditionalRender()");
return;
}
ASSERT(ctx->Query.CondRenderMode == GL_NONE);
+ /* Section 2.14 (Conditional Rendering) of the OpenGL 3.0 spec says:
+ *
+ * "The error INVALID_VALUE is generated if <id> is not the name of an
+ * existing query object query."
+ */
+ if (queryId != 0)
+ q = _mesa_lookup_query_object(ctx, queryId);
+
+ if (!q) {
+ _mesa_error(ctx, GL_INVALID_VALUE,
+ "glBeginConditionalRender(bad queryId=%u)", queryId);
+ return;
+ }
+ ASSERT(q->Id == queryId);
+
switch (mode) {
case GL_QUERY_WAIT:
case GL_QUERY_NO_WAIT:
@@ -64,14 +85,12 @@ _mesa_BeginConditionalRender(GLuint queryId, GLenum mode)
return;
}
- q = _mesa_lookup_query_object(ctx, queryId);
- if (!q) {
- _mesa_error(ctx, GL_INVALID_VALUE,
- "glBeginConditionalRender(bad queryId=%u)", queryId);
- return;
- }
- ASSERT(q->Id == queryId);
-
+ /* Section 2.14 (Conditional Rendering) of the OpenGL 3.0 spec says:
+ *
+ * "The error INVALID_OPERATION is generated if <id> is the name of a
+ * query object with a target other than SAMPLES_PASSED, or <id> is the
+ * name of a query currently in progress."
+ */
if ((q->Target != GL_SAMPLES_PASSED &&
q->Target != GL_ANY_SAMPLES_PASSED &&
q->Target != GL_ANY_SAMPLES_PASSED_CONSERVATIVE) || q->Active) {
diff --git a/mesalib/src/mesa/main/config.h b/mesalib/src/mesa/main/config.h
index 22bbfa0cf..ff9da779b 100644
--- a/mesalib/src/mesa/main/config.h
+++ b/mesalib/src/mesa/main/config.h
@@ -175,6 +175,9 @@
#define MAX_COMBINED_ATOMIC_BUFFERS (MAX_UNIFORM_BUFFERS * 6)
/* Size of an atomic counter in bytes according to ARB_shader_atomic_counters */
#define ATOMIC_COUNTER_SIZE 4
+#define MAX_IMAGE_UNIFORMS 16
+/* 6 is for vertex, hull, domain, geometry, fragment, and compute shader. */
+#define MAX_IMAGE_UNITS (MAX_IMAGE_UNIFORMS * 6)
/*@}*/
/**
diff --git a/mesalib/src/mesa/main/dd.h b/mesalib/src/mesa/main/dd.h
index 6e73691ea..6c084afa3 100644
--- a/mesalib/src/mesa/main/dd.h
+++ b/mesalib/src/mesa/main/dd.h
@@ -39,6 +39,7 @@ struct gl_buffer_object;
struct gl_context;
struct gl_display_list;
struct gl_framebuffer;
+struct gl_image_unit;
struct gl_pixelstore_attrib;
struct gl_program;
struct gl_renderbuffer;
@@ -484,7 +485,7 @@ struct dd_function_table {
/** Enable or disable writing into the depth buffer */
void (*DepthMask)(struct gl_context *ctx, GLboolean flag);
/** Specify mapping of depth values from NDC to window coordinates */
- void (*DepthRange)(struct gl_context *ctx, GLclampd nearval, GLclampd farval);
+ void (*DepthRange)(struct gl_context *ctx);
/** Specify the current buffer for writing */
void (*DrawBuffer)( struct gl_context *ctx, GLenum buffer );
/** Specify the buffers for writing for fragment programs*/
@@ -524,7 +525,7 @@ struct dd_function_table {
/** Set rasterization mode */
void (*RenderMode)(struct gl_context *ctx, GLenum mode );
/** Define the scissor box */
- void (*Scissor)(struct gl_context *ctx, GLint x, GLint y, GLsizei w, GLsizei h);
+ void (*Scissor)(struct gl_context *ctx);
/** Select flat or smooth shading */
void (*ShadeModel)(struct gl_context *ctx, GLenum mode);
/** OpenGL 2.0 two-sided StencilFunc */
@@ -546,7 +547,7 @@ struct dd_function_table {
struct gl_texture_object *texObj,
GLenum pname, const GLfloat *params);
/** Set the viewport */
- void (*Viewport)(struct gl_context *ctx, GLint x, GLint y, GLsizei w, GLsizei h);
+ void (*Viewport)(struct gl_context *ctx);
/*@}*/
@@ -910,6 +911,19 @@ struct dd_function_table {
* non-zero status should be returned for the duration of the reset.
*/
GLenum (*GetGraphicsResetStatus)(struct gl_context *ctx);
+
+ /**
+ * \name GL_ARB_shader_image_load_store interface.
+ */
+ /** @{ */
+ void (*BindImageTexture)(struct gl_context *ctx,
+ struct gl_image_unit *unit,
+ struct gl_texture_object *texObj,
+ GLint level, GLboolean layered, GLint layer,
+ GLenum access, GLenum format);
+
+ void (*MemoryBarrier)(struct gl_context *ctx, GLbitfield barriers);
+ /** @} */
};
diff --git a/mesalib/src/mesa/main/extensions.c b/mesalib/src/mesa/main/extensions.c
index 89d47931a..2e0ccc3b6 100644
--- a/mesalib/src/mesa/main/extensions.c
+++ b/mesalib/src/mesa/main/extensions.c
@@ -126,6 +126,7 @@ static const struct extension extension_table[] = {
{ "GL_ARB_seamless_cube_map", o(ARB_seamless_cube_map), GL, 2009 },
{ "GL_ARB_shader_atomic_counters", o(ARB_shader_atomic_counters), GL, 2011 },
{ "GL_ARB_shader_bit_encoding", o(ARB_shader_bit_encoding), GL, 2010 },
+ { "GL_ARB_shader_image_load_store", o(ARB_shader_image_load_store), GL, 2011 },
{ "GL_ARB_shader_objects", o(dummy_true), GL, 2002 },
{ "GL_ARB_shader_stencil_export", o(ARB_shader_stencil_export), GL, 2009 },
{ "GL_ARB_shader_texture_lod", o(ARB_shader_texture_lod), GL, 2009 },
diff --git a/mesalib/src/mesa/main/format_pack.c b/mesalib/src/mesa/main/format_pack.c
index 826fc10a6..41f5f99c1 100644
--- a/mesalib/src/mesa/main/format_pack.c
+++ b/mesalib/src/mesa/main/format_pack.c
@@ -1824,6 +1824,56 @@ pack_float_XBGR32323232_FLOAT(const GLfloat src[4], void *dst)
d[3] = 1.0;
}
+/* MESA_FORMAT_ABGR2101010 */
+
+static void
+pack_ubyte_ABGR2101010(const GLubyte src[4], void *dst)
+{
+ GLuint *d = ((GLuint *) dst);
+ GLushort r = UBYTE_TO_USHORT(src[RCOMP]);
+ GLushort g = UBYTE_TO_USHORT(src[GCOMP]);
+ GLushort b = UBYTE_TO_USHORT(src[BCOMP]);
+ GLushort a = UBYTE_TO_USHORT(src[ACOMP]);
+ *d = PACK_COLOR_2101010_US(a, b, g, r);
+}
+
+static void
+pack_float_ABGR2101010(const GLfloat src[4], void *dst)
+{
+ GLuint *d = ((GLuint *) dst);
+ GLushort r, g, b, a;
+ UNCLAMPED_FLOAT_TO_USHORT(r, src[RCOMP]);
+ UNCLAMPED_FLOAT_TO_USHORT(g, src[GCOMP]);
+ UNCLAMPED_FLOAT_TO_USHORT(b, src[BCOMP]);
+ UNCLAMPED_FLOAT_TO_USHORT(a, src[ACOMP]);
+ *d = PACK_COLOR_2101010_US(a, b, g, r);
+}
+
+/*
+ * MESA_FORMAT_SIGNED_RG88
+ */
+
+static void
+pack_float_SIGNED_RG88(const GLfloat src[4], void *dst)
+{
+ GLushort *d = (GLushort *) dst;
+ GLbyte r = FLOAT_TO_BYTE(CLAMP(src[RCOMP], -1.0f, 1.0f));
+ GLbyte g = FLOAT_TO_BYTE(CLAMP(src[GCOMP], -1.0f, 1.0f));
+ *d = (r << 8) | (g & 0xff);
+}
+
+/*
+ * MESA_FORMAT_SIGNED_RG1616
+ */
+
+static void
+pack_float_SIGNED_RG1616(const GLfloat src[4], void *dst)
+{
+ GLuint *d = (GLuint *) dst;
+ GLshort r = FLOAT_TO_SHORT(CLAMP(src[RCOMP], -1.0f, 1.0f));
+ GLshort g = FLOAT_TO_SHORT(CLAMP(src[GCOMP], -1.0f, 1.0f));
+ *d = (r << 16) | (g & 0xffff);
+}
/**
* Return a function that can pack a GLubyte rgba[4] color.
@@ -1978,6 +2028,8 @@ _mesa_get_pack_ubyte_rgba_function(gl_format format)
table[MESA_FORMAT_XBGR32323232_UINT] = NULL;
table[MESA_FORMAT_XBGR32323232_SINT] = NULL;
+ table[MESA_FORMAT_ABGR2101010] = pack_ubyte_ABGR2101010;
+
initialized = GL_TRUE;
}
@@ -2136,6 +2188,11 @@ _mesa_get_pack_float_rgba_function(gl_format format)
table[MESA_FORMAT_XBGR32323232_UINT] = NULL;
table[MESA_FORMAT_XBGR32323232_SINT] = NULL;
+ table[MESA_FORMAT_ABGR2101010] = pack_float_ABGR2101010;
+
+ table[MESA_FORMAT_SIGNED_RG88] = pack_float_SIGNED_RG88;
+ table[MESA_FORMAT_SIGNED_RG1616] = pack_float_SIGNED_RG1616;
+
initialized = GL_TRUE;
}
diff --git a/mesalib/src/mesa/main/format_unpack.c b/mesalib/src/mesa/main/format_unpack.c
index 0a8b8b183..28a50f31e 100644
--- a/mesalib/src/mesa/main/format_unpack.c
+++ b/mesalib/src/mesa/main/format_unpack.c
@@ -2268,6 +2268,44 @@ unpack_XBGR32323232_SINT(const void *src, GLfloat dst[][4], GLuint n)
}
}
+static void
+unpack_ABGR2101010(const void *src, GLfloat dst[][4], GLuint n)
+{
+ const GLuint *s = ((const GLuint *) src);
+ GLuint i;
+ for (i = 0; i < n; i++) {
+ dst[i][RCOMP] = ((s[i] >> 0) & 0x3ff) * (1.0F / 1023.0F);
+ dst[i][GCOMP] = ((s[i] >> 10) & 0x3ff) * (1.0F / 1023.0F);
+ dst[i][BCOMP] = ((s[i] >> 20) & 0x3ff) * (1.0F / 1023.0F);
+ dst[i][ACOMP] = ((s[i] >> 30) & 0x03) * (1.0F / 3.0F);
+ }
+}
+
+static void
+unpack_SIGNED_RG88(const void *src, GLfloat dst[][4], GLuint n)
+{
+ const GLushort *s = ((const GLushort *) src);
+ GLuint i;
+ for (i = 0; i < n; i++) {
+ dst[i][RCOMP] = BYTE_TO_FLOAT_TEX( (GLbyte) (s[i] >> 8) );
+ dst[i][GCOMP] = BYTE_TO_FLOAT_TEX( (GLbyte) (s[i] & 0xff) );
+ dst[i][BCOMP] = 0.0F;
+ dst[i][ACOMP] = 1.0F;
+ }
+}
+
+static void
+unpack_SIGNED_RG1616(const void *src, GLfloat dst[][4], GLuint n)
+{
+ const GLuint *s = ((const GLuint *) src);
+ GLuint i;
+ for (i = 0; i < n; i++) {
+ dst[i][RCOMP] = SHORT_TO_FLOAT_TEX( (GLshort) (s[i] >> 16) );
+ dst[i][GCOMP] = SHORT_TO_FLOAT_TEX( (GLshort) (s[i] & 0xffff) );
+ dst[i][BCOMP] = 0.0F;
+ dst[i][ACOMP] = 1.0F;
+ }
+}
/**
* Return the unpacker function for the given format.
@@ -2481,6 +2519,11 @@ get_unpack_rgba_function(gl_format format)
table[MESA_FORMAT_XBGR32323232_UINT] = unpack_XBGR32323232_UINT;
table[MESA_FORMAT_XBGR32323232_SINT] = unpack_XBGR32323232_SINT;
+ table[MESA_FORMAT_ABGR2101010] = unpack_ABGR2101010;
+
+ table[MESA_FORMAT_SIGNED_RG88] = unpack_SIGNED_RG88;
+ table[MESA_FORMAT_SIGNED_RG1616] = unpack_SIGNED_RG1616;
+
initialized = GL_TRUE;
}
@@ -3582,6 +3625,20 @@ unpack_int_rgba_XBGR32323232_UINT(const GLuint *src, GLuint dst[][4], GLuint n)
}
}
+static void
+unpack_int_rgba_ABGR2101010(const GLuint *src, GLuint dst[][4], GLuint n)
+{
+ unsigned int i;
+
+ for (i = 0; i < n; i++) {
+ GLuint tmp = src[i];
+ dst[i][0] = (tmp >> 0) & 0x3ff;
+ dst[i][1] = (tmp >> 10) & 0x3ff;
+ dst[i][2] = (tmp >> 20) & 0x3ff;
+ dst[i][3] = (tmp >> 30) & 0x3;
+ }
+}
+
void
_mesa_unpack_uint_rgba_row(gl_format format, GLuint n,
const void *src, GLuint dst[][4])
@@ -3782,6 +3839,10 @@ _mesa_unpack_uint_rgba_row(gl_format format, GLuint n,
unpack_int_rgba_XBGR32323232_UINT(src, dst, n);
break;
+ case MESA_FORMAT_ABGR2101010:
+ unpack_int_rgba_ABGR2101010(src, dst, n);
+ break;
+
default:
_mesa_problem(NULL, "%s: bad format %s", __FUNCTION__,
_mesa_get_format_name(format));
diff --git a/mesalib/src/mesa/main/formats.c b/mesalib/src/mesa/main/formats.c
index 7e0ec2319..1246c4d92 100644
--- a/mesalib/src/mesa/main/formats.c
+++ b/mesalib/src/mesa/main/formats.c
@@ -1763,6 +1763,33 @@ static struct gl_format_info format_info[MESA_FORMAT_COUNT] =
0, 0, 0, 0, 0,
1, 1, 16
},
+ {
+ MESA_FORMAT_ABGR2101010,
+ "MESA_FORMAT_ABGR2101010",
+ GL_RGBA,
+ GL_UNSIGNED_NORMALIZED,
+ 10, 10, 10, 2,
+ 0, 0, 0, 0, 0,
+ 1, 1, 4
+ },
+ {
+ MESA_FORMAT_SIGNED_RG88,
+ "MESA_FORMAT_SIGNED_RG88",
+ GL_RG,
+ GL_SIGNED_NORMALIZED,
+ 8, 8, 0, 0,
+ 0, 0, 0, 0, 0,
+ 1, 1, 2
+ },
+ {
+ MESA_FORMAT_SIGNED_RG1616,
+ "MESA_FORMAT_SIGNED_RG1616",
+ GL_RG,
+ GL_SIGNED_NORMALIZED,
+ 16, 16, 0, 0,
+ 0, 0, 0, 0, 0,
+ 1, 1, 4
+ },
};
@@ -2841,6 +2868,21 @@ _mesa_format_to_type_and_comps(gl_format format,
*comps = 4;
return;
+ case MESA_FORMAT_ABGR2101010:
+ *datatype = GL_UNSIGNED_INT_2_10_10_10_REV;
+ *comps = 4;
+ return;
+
+ case MESA_FORMAT_SIGNED_RG88:
+ *datatype = GL_BYTE;
+ *comps = 2;
+ return;
+
+ case MESA_FORMAT_SIGNED_RG1616:
+ *datatype = GL_SHORT;
+ *comps = 2;
+ return;
+
case MESA_FORMAT_COUNT:
assert(0);
return;
@@ -3382,6 +3424,18 @@ _mesa_format_matches_format_and_type(gl_format gl_format,
case MESA_FORMAT_XBGR32323232_UINT:
case MESA_FORMAT_XBGR32323232_SINT:
return GL_FALSE;
+
+ case MESA_FORMAT_ABGR2101010:
+ return format == GL_RGBA && type == GL_UNSIGNED_INT_2_10_10_10_REV &&
+ !swapBytes;
+
+ case MESA_FORMAT_SIGNED_RG88:
+ return format == GL_RG && type == GL_BYTE && !littleEndian &&
+ !swapBytes;
+
+ case MESA_FORMAT_SIGNED_RG1616:
+ return format == GL_RG && type == GL_SHORT && !littleEndian &&
+ !swapBytes;
}
return GL_FALSE;
diff --git a/mesalib/src/mesa/main/formats.h b/mesalib/src/mesa/main/formats.h
index 0c91aeaac..a1f0d226a 100644
--- a/mesalib/src/mesa/main/formats.h
+++ b/mesalib/src/mesa/main/formats.h
@@ -304,6 +304,11 @@ typedef enum
MESA_FORMAT_XBGR32323232_UINT, /* ... */
MESA_FORMAT_XBGR32323232_SINT, /* ... */
+ MESA_FORMAT_ABGR2101010,
+
+ MESA_FORMAT_SIGNED_RG88,
+ MESA_FORMAT_SIGNED_RG1616,
+
MESA_FORMAT_COUNT
} gl_format;
diff --git a/mesalib/src/mesa/main/get.c b/mesalib/src/mesa/main/get.c
index 6e55e9956..b13f9a3db 100644
--- a/mesalib/src/mesa/main/get.c
+++ b/mesalib/src/mesa/main/get.c
@@ -145,6 +145,7 @@ enum value_extra {
EXTRA_GLSL_130,
EXTRA_EXT_UBO_GS4,
EXTRA_EXT_ATOMICS_GS4,
+ EXTRA_EXT_SHADER_IMAGE_GS4,
};
#define NO_EXTRA NULL
@@ -344,6 +345,11 @@ static const int extra_ARB_shader_atomic_counters_and_geometry_shader[] = {
EXTRA_END
};
+static const int extra_ARB_shader_image_load_store_and_geometry_shader[] = {
+ EXTRA_EXT_SHADER_IMAGE_GS4,
+ EXTRA_END
+};
+
EXTRA_EXT(ARB_texture_cube_map);
EXTRA_EXT(EXT_texture_array);
EXTRA_EXT(NV_fog_distance);
@@ -382,6 +388,7 @@ EXTRA_EXT(ARB_texture_multisample);
EXTRA_EXT(ARB_texture_gather);
EXTRA_EXT(ARB_shader_atomic_counters);
EXTRA_EXT(ARB_draw_indirect);
+EXTRA_EXT(ARB_shader_image_load_store);
static const int
extra_ARB_color_buffer_float_or_glcore[] = {
@@ -1071,6 +1078,11 @@ check_extra(struct gl_context *ctx, const char *func, const struct value_desc *d
api_found = (ctx->Extensions.ARB_shader_atomic_counters &&
_mesa_has_geometry_shaders(ctx));
break;
+ case EXTRA_EXT_SHADER_IMAGE_GS4:
+ api_check = GL_TRUE;
+ api_found = (ctx->Extensions.ARB_shader_image_load_store &&
+ _mesa_has_geometry_shaders(ctx));
+ break;
case EXTRA_END:
break;
default: /* *e is a offset into the extension struct */
@@ -1811,6 +1823,64 @@ find_value_indexed(const char *func, GLenum pname, GLuint index, union value *v)
if (index >= ctx->Const.Program[MESA_SHADER_VERTEX].MaxAttribs)
goto invalid_value;
v->value_int = ctx->Array.ArrayObj->VertexBinding[VERT_ATTRIB_GENERIC(index)].Stride;
+
+ /* ARB_shader_image_load_store */
+ case GL_IMAGE_BINDING_NAME: {
+ struct gl_texture_object *t;
+
+ if (!ctx->Extensions.ARB_shader_image_load_store)
+ goto invalid_enum;
+ if (index >= ctx->Const.MaxImageUnits)
+ goto invalid_value;
+
+ t = ctx->ImageUnits[index].TexObj;
+ v->value_int = (t ? t->Name : 0);
+ return TYPE_INT;
+ }
+
+ case GL_IMAGE_BINDING_LEVEL:
+ if (!ctx->Extensions.ARB_shader_image_load_store)
+ goto invalid_enum;
+ if (index >= ctx->Const.MaxImageUnits)
+ goto invalid_value;
+
+ v->value_int = ctx->ImageUnits[index].Level;
+ return TYPE_INT;
+
+ case GL_IMAGE_BINDING_LAYERED:
+ if (!ctx->Extensions.ARB_shader_image_load_store)
+ goto invalid_enum;
+ if (index >= ctx->Const.MaxImageUnits)
+ goto invalid_value;
+
+ v->value_int = ctx->ImageUnits[index].Layered;
+ return TYPE_INT;
+
+ case GL_IMAGE_BINDING_LAYER:
+ if (!ctx->Extensions.ARB_shader_image_load_store)
+ goto invalid_enum;
+ if (index >= ctx->Const.MaxImageUnits)
+ goto invalid_value;
+
+ v->value_int = ctx->ImageUnits[index].Layer;
+ return TYPE_INT;
+
+ case GL_IMAGE_BINDING_ACCESS:
+ if (!ctx->Extensions.ARB_shader_image_load_store)
+ goto invalid_enum;
+ if (index >= ctx->Const.MaxImageUnits)
+ goto invalid_value;
+
+ v->value_int = ctx->ImageUnits[index].Access;
+ return TYPE_INT;
+
+ case GL_IMAGE_BINDING_FORMAT:
+ if (!ctx->Extensions.ARB_shader_image_load_store)
+ goto invalid_enum;
+ if (index >= ctx->Const.MaxImageUnits)
+ goto invalid_value;
+
+ v->value_int = ctx->ImageUnits[index].Format;
return TYPE_INT;
}
diff --git a/mesalib/src/mesa/main/get_hash_params.py b/mesalib/src/mesa/main/get_hash_params.py
index 7f025a980..6195d630d 100644
--- a/mesalib/src/mesa/main/get_hash_params.py
+++ b/mesalib/src/mesa/main/get_hash_params.py
@@ -742,6 +742,15 @@ descriptor=[
# GL_ARB_vertex_attrib_binding
[ "MAX_VERTEX_ATTRIB_RELATIVE_OFFSET", "CONTEXT_ENUM(Const.MaxVertexAttribRelativeOffset), NO_EXTRA" ],
[ "MAX_VERTEX_ATTRIB_BINDINGS", "CONTEXT_ENUM(Const.MaxVertexAttribBindings), NO_EXTRA" ],
+
+# GL_ARB_shader_image_load_store
+ [ "MAX_IMAGE_UNITS", "CONTEXT_INT(Const.MaxImageUnits), extra_ARB_shader_image_load_store"],
+ [ "MAX_COMBINED_IMAGE_UNITS_AND_FRAGMENT_OUTPUTS", "CONTEXT_INT(Const.MaxCombinedImageUnitsAndFragmentOutputs), extra_ARB_shader_image_load_store"],
+ [ "MAX_IMAGE_SAMPLES", "CONTEXT_INT(Const.MaxImageSamples), extra_ARB_shader_image_load_store"],
+ [ "MAX_VERTEX_IMAGE_UNIFORMS", "CONTEXT_INT(Const.Program[MESA_SHADER_VERTEX].MaxImageUniforms), extra_ARB_shader_image_load_store"],
+ [ "MAX_GEOMETRY_IMAGE_UNIFORMS", "CONTEXT_INT(Const.Program[MESA_SHADER_GEOMETRY].MaxImageUniforms), extra_ARB_shader_image_load_store_and_geometry_shader"],
+ [ "MAX_FRAGMENT_IMAGE_UNIFORMS", "CONTEXT_INT(Const.Program[MESA_SHADER_FRAGMENT].MaxImageUniforms), extra_ARB_shader_image_load_store"],
+ [ "MAX_COMBINED_IMAGE_UNIFORMS", "CONTEXT_INT(Const.MaxCombinedImageUniforms), extra_ARB_shader_image_load_store"],
]},
# Enums restricted to OpenGL Core profile
diff --git a/mesalib/src/mesa/main/mtypes.h b/mesalib/src/mesa/main/mtypes.h
index f23cd8118..33df682cf 100644
--- a/mesalib/src/mesa/main/mtypes.h
+++ b/mesalib/src/mesa/main/mtypes.h
@@ -1230,6 +1230,9 @@ struct gl_texture_object
/** GL_OES_EGL_image_external */
GLint RequiredTextureImageUnits;
+
+ /** GL_ARB_shader_image_load_store */
+ GLenum ImageFormatCompatibilityType;
};
@@ -2402,6 +2405,32 @@ struct gl_shader
*/
GLenum OutputType;
} Geom;
+
+ /**
+ * Map from image uniform index to image unit (set by glUniform1i())
+ *
+ * An image uniform index is associated with each image uniform by
+ * the linker. The image index associated with each uniform is
+ * stored in the \c gl_uniform_storage::image field.
+ */
+ GLubyte ImageUnits[MAX_IMAGE_UNIFORMS];
+
+ /**
+ * Access qualifier specified in the shader for each image uniform
+ * index. Either \c GL_READ_ONLY, \c GL_WRITE_ONLY or \c
+ * GL_READ_WRITE.
+ *
+ * It may be different, though only more strict than the value of
+ * \c gl_image_unit::Access for the corresponding image unit.
+ */
+ GLenum ImageAccess[MAX_IMAGE_UNIFORMS];
+
+ /**
+ * Number of image uniforms defined in the shader. It specifies
+ * the number of valid elements in the \c ImageUnits and \c
+ * ImageAccess arrays above.
+ */
+ GLuint NumImages;
};
@@ -3089,9 +3118,13 @@ struct gl_program_constants
GLuint MaxUniformBlocks;
GLuint MaxCombinedUniformComponents;
GLuint MaxTextureImageUnits;
+
/* GL_ARB_shader_atomic_counters */
GLuint MaxAtomicBuffers;
GLuint MaxAtomicCounters;
+
+ /* GL_ARB_shader_image_load_store */
+ GLuint MaxImageUniforms;
};
@@ -3312,6 +3345,12 @@ struct gl_constants
/** GL_ARB_vertex_attrib_binding */
GLint MaxVertexAttribRelativeOffset;
GLint MaxVertexAttribBindings;
+
+ /* GL_ARB_shader_image_load_store */
+ GLuint MaxImageUnits;
+ GLuint MaxCombinedImageUnitsAndFragmentOutputs;
+ GLuint MaxImageSamples;
+ GLuint MaxCombinedImageUniforms;
};
@@ -3359,6 +3398,7 @@ struct gl_extensions
GLboolean ARB_seamless_cube_map;
GLboolean ARB_shader_atomic_counters;
GLboolean ARB_shader_bit_encoding;
+ GLboolean ARB_shader_image_load_store;
GLboolean ARB_shader_stencil_export;
GLboolean ARB_shader_texture_lod;
GLboolean ARB_shading_language_packing;
@@ -3737,6 +3777,11 @@ struct gl_driver_flags
* gl_context::AtomicBufferBindings
*/
GLbitfield NewAtomicBuffer;
+
+ /**
+ * gl_context::ImageUnits
+ */
+ GLbitfield NewImageUnits;
};
struct gl_uniform_buffer_binding
@@ -3754,6 +3799,60 @@ struct gl_uniform_buffer_binding
};
/**
+ * ARB_shader_image_load_store image unit.
+ */
+struct gl_image_unit
+{
+ /**
+ * Texture object bound to this unit.
+ */
+ struct gl_texture_object *TexObj;
+
+ /**
+ * Level of the texture object bound to this unit.
+ */
+ GLuint Level;
+
+ /**
+ * \c GL_TRUE if the whole level is bound as an array of layers, \c
+ * GL_FALSE if only some specific layer of the texture is bound.
+ * \sa Layer
+ */
+ GLboolean Layered;
+
+ /**
+ * Layer of the texture object bound to this unit, or zero if the
+ * whole level is bound.
+ */
+ GLuint Layer;
+
+ /**
+ * Access allowed to this texture image. Either \c GL_READ_ONLY,
+ * \c GL_WRITE_ONLY or \c GL_READ_WRITE.
+ */
+ GLenum Access;
+
+ /**
+ * GL internal format that determines the interpretation of the
+ * image memory when shader image operations are performed through
+ * this unit.
+ */
+ GLenum Format;
+
+ /**
+ * Mesa format corresponding to \c Format.
+ */
+ gl_format _ActualFormat;
+
+ /**
+ * GL_TRUE if the state of this image unit is valid and access from
+ * the shader is allowed. Otherwise loads from this unit should
+ * return zero and stores should have no effect.
+ */
+ GLboolean _Valid;
+};
+
+/**
* Binding point for an atomic counter buffer object.
*/
struct gl_atomic_buffer_binding
@@ -3945,6 +4044,11 @@ struct gl_context
struct gl_atomic_buffer_binding
AtomicBufferBindings[MAX_COMBINED_ATOMIC_BUFFERS];
+ /**
+ * Array of image units for ARB_shader_image_load_store.
+ */
+ struct gl_image_unit ImageUnits[MAX_IMAGE_UNITS];
+
/*@}*/
struct gl_meta_state *Meta; /**< for "meta" operations */
diff --git a/mesalib/src/mesa/main/scissor.c b/mesalib/src/mesa/main/scissor.c
index 0eddaa6c1..ac86bd591 100644
--- a/mesalib/src/mesa/main/scissor.c
+++ b/mesalib/src/mesa/main/scissor.c
@@ -79,7 +79,7 @@ _mesa_set_scissor(struct gl_context *ctx,
ctx->Scissor.Height = height;
if (ctx->Driver.Scissor)
- ctx->Driver.Scissor( ctx, x, y, width, height );
+ ctx->Driver.Scissor(ctx);
}
diff --git a/mesalib/src/mesa/main/shaderimage.c b/mesalib/src/mesa/main/shaderimage.c
new file mode 100644
index 000000000..80c469366
--- /dev/null
+++ b/mesalib/src/mesa/main/shaderimage.c
@@ -0,0 +1,488 @@
+/*
+ * 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.
+ *
+ * Authors:
+ * Francisco Jerez <currojerez@riseup.net>
+ */
+
+#include <assert.h>
+
+#include "shaderimage.h"
+#include "mtypes.h"
+#include "formats.h"
+#include "errors.h"
+#include "context.h"
+#include "texobj.h"
+#include "teximage.h"
+
+/*
+ * Define endian-invariant aliases for some mesa formats that are
+ * defined in terms of their channel layout from LSB to MSB in a
+ * 32-bit word. The actual byte offsets matter here because the user
+ * is allowed to bit-cast one format into another and get predictable
+ * results.
+ */
+#ifdef MESA_BIG_ENDIAN
+# define MESA_FORMAT_RGBA_8 MESA_FORMAT_RGBA8888
+# define MESA_FORMAT_RG_16 MESA_FORMAT_RG1616
+# define MESA_FORMAT_RG_8 MESA_FORMAT_RG88
+# define MESA_FORMAT_SIGNED_RGBA_8 MESA_FORMAT_SIGNED_RGBA8888
+# define MESA_FORMAT_SIGNED_RG_16 MESA_FORMAT_SIGNED_RG1616
+# define MESA_FORMAT_SIGNED_RG_8 MESA_FORMAT_SIGNED_RG88
+#else
+# define MESA_FORMAT_RGBA_8 MESA_FORMAT_RGBA8888_REV
+# define MESA_FORMAT_RG_16 MESA_FORMAT_GR1616
+# define MESA_FORMAT_RG_8 MESA_FORMAT_GR88
+# define MESA_FORMAT_SIGNED_RGBA_8 MESA_FORMAT_SIGNED_RGBA8888_REV
+# define MESA_FORMAT_SIGNED_RG_16 MESA_FORMAT_SIGNED_GR1616
+# define MESA_FORMAT_SIGNED_RG_8 MESA_FORMAT_SIGNED_RG88_REV
+#endif
+
+static gl_format
+get_image_format(GLenum format)
+{
+ switch (format) {
+ case GL_RGBA32F:
+ return MESA_FORMAT_RGBA_FLOAT32;
+
+ case GL_RGBA16F:
+ return MESA_FORMAT_RGBA_FLOAT16;
+
+ case GL_RG32F:
+ return MESA_FORMAT_RG_FLOAT32;
+
+ case GL_RG16F:
+ return MESA_FORMAT_RG_FLOAT16;
+
+ case GL_R11F_G11F_B10F:
+ return MESA_FORMAT_R11_G11_B10_FLOAT;
+
+ case GL_R32F:
+ return MESA_FORMAT_R_FLOAT32;
+
+ case GL_R16F:
+ return MESA_FORMAT_R_FLOAT16;
+
+ case GL_RGBA32UI:
+ return MESA_FORMAT_RGBA_UINT32;
+
+ case GL_RGBA16UI:
+ return MESA_FORMAT_RGBA_UINT16;
+
+ case GL_RGB10_A2UI:
+ return MESA_FORMAT_ABGR2101010_UINT;
+
+ case GL_RGBA8UI:
+ return MESA_FORMAT_RGBA_UINT8;
+
+ case GL_RG32UI:
+ return MESA_FORMAT_RG_UINT32;
+
+ case GL_RG16UI:
+ return MESA_FORMAT_RG_UINT16;
+
+ case GL_RG8UI:
+ return MESA_FORMAT_RG_UINT8;
+
+ case GL_R32UI:
+ return MESA_FORMAT_R_UINT32;
+
+ case GL_R16UI:
+ return MESA_FORMAT_R_UINT16;
+
+ case GL_R8UI:
+ return MESA_FORMAT_R_UINT8;
+
+ case GL_RGBA32I:
+ return MESA_FORMAT_RGBA_INT32;
+
+ case GL_RGBA16I:
+ return MESA_FORMAT_RGBA_INT16;
+
+ case GL_RGBA8I:
+ return MESA_FORMAT_RGBA_INT8;
+
+ case GL_RG32I:
+ return MESA_FORMAT_RG_INT32;
+
+ case GL_RG16I:
+ return MESA_FORMAT_RG_INT16;
+
+ case GL_RG8I:
+ return MESA_FORMAT_RG_INT8;
+
+ case GL_R32I:
+ return MESA_FORMAT_R_INT32;
+
+ case GL_R16I:
+ return MESA_FORMAT_R_INT16;
+
+ case GL_R8I:
+ return MESA_FORMAT_R_INT8;
+
+ case GL_RGBA16:
+ return MESA_FORMAT_RGBA_16;
+
+ case GL_RGB10_A2:
+ return MESA_FORMAT_ABGR2101010;
+
+ case GL_RGBA8:
+ return MESA_FORMAT_RGBA_8;
+
+ case GL_RG16:
+ return MESA_FORMAT_RG_16;
+
+ case GL_RG8:
+ return MESA_FORMAT_RG_8;
+
+ case GL_R16:
+ return MESA_FORMAT_R16;
+
+ case GL_R8:
+ return MESA_FORMAT_R8;
+
+ case GL_RGBA16_SNORM:
+ return MESA_FORMAT_SIGNED_RGBA_16;
+
+ case GL_RGBA8_SNORM:
+ return MESA_FORMAT_SIGNED_RGBA_8;
+
+ case GL_RG16_SNORM:
+ return MESA_FORMAT_SIGNED_RG_16;
+
+ case GL_RG8_SNORM:
+ return MESA_FORMAT_SIGNED_RG_8;
+
+ case GL_R16_SNORM:
+ return MESA_FORMAT_SIGNED_R16;
+
+ case GL_R8_SNORM:
+ return MESA_FORMAT_SIGNED_R8;
+
+ default:
+ return MESA_FORMAT_NONE;
+ }
+}
+
+enum image_format_class
+{
+ /** Not a valid image format. */
+ IMAGE_FORMAT_CLASS_NONE = 0,
+
+ /** Classes of image formats you can cast into each other. */
+ /** \{ */
+ IMAGE_FORMAT_CLASS_1X8,
+ IMAGE_FORMAT_CLASS_1X16,
+ IMAGE_FORMAT_CLASS_1X32,
+ IMAGE_FORMAT_CLASS_2X8,
+ IMAGE_FORMAT_CLASS_2X16,
+ IMAGE_FORMAT_CLASS_2X32,
+ IMAGE_FORMAT_CLASS_10_11_11,
+ IMAGE_FORMAT_CLASS_4X8,
+ IMAGE_FORMAT_CLASS_4X16,
+ IMAGE_FORMAT_CLASS_4X32,
+ IMAGE_FORMAT_CLASS_2_10_10_10
+ /** \} */
+};
+
+static enum image_format_class
+get_image_format_class(gl_format format)
+{
+ switch (format) {
+ case MESA_FORMAT_RGBA_FLOAT32:
+ return IMAGE_FORMAT_CLASS_4X32;
+
+ case MESA_FORMAT_RGBA_FLOAT16:
+ return IMAGE_FORMAT_CLASS_4X16;
+
+ case MESA_FORMAT_RG_FLOAT32:
+ return IMAGE_FORMAT_CLASS_2X32;
+
+ case MESA_FORMAT_RG_FLOAT16:
+ return IMAGE_FORMAT_CLASS_2X16;
+
+ case MESA_FORMAT_R11_G11_B10_FLOAT:
+ return IMAGE_FORMAT_CLASS_10_11_11;
+
+ case MESA_FORMAT_R_FLOAT32:
+ return IMAGE_FORMAT_CLASS_1X32;
+
+ case MESA_FORMAT_R_FLOAT16:
+ return IMAGE_FORMAT_CLASS_1X16;
+
+ case MESA_FORMAT_RGBA_UINT32:
+ return IMAGE_FORMAT_CLASS_4X32;
+
+ case MESA_FORMAT_RGBA_UINT16:
+ return IMAGE_FORMAT_CLASS_4X16;
+
+ case MESA_FORMAT_ABGR2101010_UINT:
+ return IMAGE_FORMAT_CLASS_2_10_10_10;
+
+ case MESA_FORMAT_RGBA_UINT8:
+ return IMAGE_FORMAT_CLASS_4X8;
+
+ case MESA_FORMAT_RG_UINT32:
+ return IMAGE_FORMAT_CLASS_2X32;
+
+ case MESA_FORMAT_RG_UINT16:
+ return IMAGE_FORMAT_CLASS_2X16;
+
+ case MESA_FORMAT_RG_UINT8:
+ return IMAGE_FORMAT_CLASS_2X8;
+
+ case MESA_FORMAT_R_UINT32:
+ return IMAGE_FORMAT_CLASS_1X32;
+
+ case MESA_FORMAT_R_UINT16:
+ return IMAGE_FORMAT_CLASS_1X16;
+
+ case MESA_FORMAT_R_UINT8:
+ return IMAGE_FORMAT_CLASS_1X8;
+
+ case MESA_FORMAT_RGBA_INT32:
+ return IMAGE_FORMAT_CLASS_4X32;
+
+ case MESA_FORMAT_RGBA_INT16:
+ return IMAGE_FORMAT_CLASS_4X16;
+
+ case MESA_FORMAT_RGBA_INT8:
+ return IMAGE_FORMAT_CLASS_4X8;
+
+ case MESA_FORMAT_RG_INT32:
+ return IMAGE_FORMAT_CLASS_2X32;
+
+ case MESA_FORMAT_RG_INT16:
+ return IMAGE_FORMAT_CLASS_2X16;
+
+ case MESA_FORMAT_RG_INT8:
+ return IMAGE_FORMAT_CLASS_2X8;
+
+ case MESA_FORMAT_R_INT32:
+ return IMAGE_FORMAT_CLASS_1X32;
+
+ case MESA_FORMAT_R_INT16:
+ return IMAGE_FORMAT_CLASS_1X16;
+
+ case MESA_FORMAT_R_INT8:
+ return IMAGE_FORMAT_CLASS_1X8;
+
+ case MESA_FORMAT_RGBA_16:
+ return IMAGE_FORMAT_CLASS_4X16;
+
+ case MESA_FORMAT_ABGR2101010:
+ return IMAGE_FORMAT_CLASS_2_10_10_10;
+
+ case MESA_FORMAT_RGBA_8:
+ return IMAGE_FORMAT_CLASS_4X8;
+
+ case MESA_FORMAT_RG_16:
+ return IMAGE_FORMAT_CLASS_2X16;
+
+ case MESA_FORMAT_RG_8:
+ return IMAGE_FORMAT_CLASS_2X8;
+
+ case MESA_FORMAT_R16:
+ return IMAGE_FORMAT_CLASS_1X16;
+
+ case MESA_FORMAT_R8:
+ return IMAGE_FORMAT_CLASS_1X8;
+
+ case MESA_FORMAT_SIGNED_RGBA_16:
+ return IMAGE_FORMAT_CLASS_4X16;
+
+ case MESA_FORMAT_SIGNED_RGBA_8:
+ return IMAGE_FORMAT_CLASS_4X8;
+
+ case MESA_FORMAT_SIGNED_RG_16:
+ return IMAGE_FORMAT_CLASS_2X16;
+
+ case MESA_FORMAT_SIGNED_RG_8:
+ return IMAGE_FORMAT_CLASS_2X8;
+
+ case MESA_FORMAT_SIGNED_R16:
+ return IMAGE_FORMAT_CLASS_1X16;
+
+ case MESA_FORMAT_SIGNED_R8:
+ return IMAGE_FORMAT_CLASS_1X8;
+
+ default:
+ return IMAGE_FORMAT_CLASS_NONE;
+ }
+}
+
+static GLboolean
+validate_image_unit(struct gl_context *ctx, struct gl_image_unit *u)
+{
+ struct gl_texture_object *t = u->TexObj;
+ struct gl_texture_image *img;
+
+ if (!t || u->Level < t->BaseLevel ||
+ u->Level > t->_MaxLevel)
+ return GL_FALSE;
+
+ _mesa_test_texobj_completeness(ctx, t);
+
+ if ((u->Level == t->BaseLevel && !t->_BaseComplete) ||
+ (u->Level != t->BaseLevel && !t->_MipmapComplete))
+ return GL_FALSE;
+
+ if (_mesa_tex_target_is_layered(t->Target) &&
+ u->Layer >= _mesa_get_texture_layers(t, u->Level))
+ return GL_FALSE;
+
+ if (t->Target == GL_TEXTURE_CUBE_MAP)
+ img = t->Image[u->Layer][u->Level];
+ else
+ img = t->Image[0][u->Level];
+
+ if (!img || img->Border ||
+ get_image_format_class(img->TexFormat) == IMAGE_FORMAT_CLASS_NONE ||
+ img->NumSamples > ctx->Const.MaxImageSamples)
+ return GL_FALSE;
+
+ switch (t->ImageFormatCompatibilityType) {
+ case GL_IMAGE_FORMAT_COMPATIBILITY_BY_SIZE:
+ if (_mesa_get_format_bytes(img->TexFormat) !=
+ _mesa_get_format_bytes(u->_ActualFormat))
+ return GL_FALSE;
+ break;
+
+ case GL_IMAGE_FORMAT_COMPATIBILITY_BY_CLASS:
+ if (get_image_format_class(img->TexFormat) !=
+ get_image_format_class(u->_ActualFormat))
+ return GL_FALSE;
+ break;
+
+ default:
+ assert(!"Unexpected image format compatibility type");
+ }
+
+ return GL_TRUE;
+}
+
+void
+_mesa_validate_image_units(struct gl_context *ctx)
+{
+ int i;
+
+ for (i = 0; i < ctx->Const.MaxImageUnits; ++i) {
+ struct gl_image_unit *u = &ctx->ImageUnits[i];
+ u->_Valid = validate_image_unit(ctx, u);
+ }
+}
+
+static GLboolean
+validate_bind_image_texture(struct gl_context *ctx, GLuint unit,
+ GLuint texture, GLint level, GLboolean layered,
+ GLint layer, GLenum access, GLenum format)
+{
+ assert(ctx->Const.MaxImageUnits <= MAX_IMAGE_UNITS);
+
+ if (unit >= ctx->Const.MaxImageUnits) {
+ _mesa_error(ctx, GL_INVALID_VALUE, "glBindImageTexture(unit)");
+ return GL_FALSE;
+ }
+
+ if (level < 0) {
+ _mesa_error(ctx, GL_INVALID_VALUE, "glBindImageTexture(level)");
+ return GL_FALSE;
+ }
+
+ if (layer < 0) {
+ _mesa_error(ctx, GL_INVALID_VALUE, "glBindImageTexture(layer)");
+ return GL_FALSE;
+ }
+
+ if (access != GL_READ_ONLY &&
+ access != GL_WRITE_ONLY &&
+ access != GL_READ_WRITE) {
+ _mesa_error(ctx, GL_INVALID_VALUE, "glBindImageTexture(access)");
+ return GL_FALSE;
+ }
+
+ if (!get_image_format(format)) {
+ _mesa_error(ctx, GL_INVALID_VALUE, "glBindImageTexture(format)");
+ return GL_FALSE;
+ }
+
+ return GL_TRUE;
+}
+
+void GLAPIENTRY
+_mesa_BindImageTexture(GLuint unit, GLuint texture, GLint level,
+ GLboolean layered, GLint layer, GLenum access,
+ GLenum format)
+{
+ GET_CURRENT_CONTEXT(ctx);
+ struct gl_texture_object *t = NULL;
+ struct gl_image_unit *u;
+
+ if (!validate_bind_image_texture(ctx, unit, texture, level,
+ layered, layer, access, format))
+ return;
+
+ u = &ctx->ImageUnits[unit];
+
+ FLUSH_VERTICES(ctx, 0);
+ ctx->NewDriverState |= ctx->DriverFlags.NewImageUnits;
+
+ if (texture) {
+ t = _mesa_lookup_texture(ctx, texture);
+ if (!t) {
+ _mesa_error(ctx, GL_INVALID_VALUE, "glBindImageTexture(texture)");
+ return;
+ }
+
+ _mesa_reference_texobj(&u->TexObj, t);
+ u->Level = level;
+ u->Access = access;
+ u->Format = format;
+ u->_ActualFormat = get_image_format(format);
+
+ if (_mesa_tex_target_is_layered(t->Target)) {
+ u->Layered = layered;
+ u->Layer = (layered ? 0 : layer);
+ } else {
+ u->Layered = GL_FALSE;
+ u->Layer = 0;
+ }
+
+ } else {
+ _mesa_reference_texobj(&u->TexObj, NULL);
+ }
+
+ u->_Valid = validate_image_unit(ctx, u);
+
+ if (ctx->Driver.BindImageTexture)
+ ctx->Driver.BindImageTexture(ctx, u, t, level, layered,
+ layer, access, format);
+}
+
+void GLAPIENTRY
+_mesa_MemoryBarrier(GLbitfield barriers)
+{
+ GET_CURRENT_CONTEXT(ctx);
+
+ if (ctx->Driver.MemoryBarrier)
+ ctx->Driver.MemoryBarrier(ctx, barriers);
+}
diff --git a/mesalib/src/mesa/main/shaderimage.h b/mesalib/src/mesa/main/shaderimage.h
new file mode 100644
index 000000000..aaecc5d29
--- /dev/null
+++ b/mesalib/src/mesa/main/shaderimage.h
@@ -0,0 +1,51 @@
+/*
+ * 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.
+ *
+ * Authors:
+ * Francisco Jerez <currojerez@riseup.net>
+ */
+
+#ifndef SHADERIMAGE_H
+#define SHADERIMAGE_H
+
+#include "glheader.h"
+
+struct gl_context;
+
+/**
+ * Recalculate the \c _Valid flag of a context's shader image units.
+ *
+ * To be called when the state of any texture bound to an image unit
+ * changes.
+ */
+void
+_mesa_validate_image_units(struct gl_context *ctx);
+
+void GLAPIENTRY
+_mesa_BindImageTexture(GLuint unit, GLuint texture, GLint level,
+ GLboolean layered, GLint layer, GLenum access,
+ GLenum format);
+
+void GLAPIENTRY
+_mesa_MemoryBarrier(GLbitfield barriers);
+
+#endif
diff --git a/mesalib/src/mesa/main/texcompress.c b/mesalib/src/mesa/main/texcompress.c
index e71d0c411..47ad30605 100644
--- a/mesalib/src/mesa/main/texcompress.c
+++ b/mesalib/src/mesa/main/texcompress.c
@@ -263,6 +263,43 @@ _mesa_get_compressed_formats(struct gl_context *ctx, GLint *formats)
else {
n += 3;
}
+
+ /* The ES and desktop GL specs diverge here.
+ *
+ * In desktop OpenGL, the driver can perform online compression of
+ * uncompressed texture data. GL_NUM_COMPRESSED_TEXTURE_FORMATS and
+ * GL_COMPRESSED_TEXTURE_FORMATS give the application a list of
+ * formats that it could ask the driver to compress with some
+ * expectation of quality. The GL_ARB_texture_compression spec
+ * calls this "suitable for general-purpose usage." As noted
+ * above, this means GL_COMPRESSED_RGBA_S3TC_DXT1_EXT is not
+ * included in the list.
+ *
+ * In OpenGL ES, the driver never performs compression.
+ * GL_NUM_COMPRESSED_TEXTURE_FORMATS and
+ * GL_COMPRESSED_TEXTURE_FORMATS give the application a list of
+ * formats that the driver can receive from the application. It
+ * is the *complete* list of formats. The
+ * GL_EXT_texture_compression_s3tc spec says:
+ *
+ * "New State for OpenGL ES 2.0.25 and 3.0.2 Specifications
+ *
+ * The queries for NUM_COMPRESSED_TEXTURE_FORMATS and
+ * COMPRESSED_TEXTURE_FORMATS include
+ * COMPRESSED_RGB_S3TC_DXT1_EXT,
+ * COMPRESSED_RGBA_S3TC_DXT1_EXT,
+ * COMPRESSED_RGBA_S3TC_DXT3_EXT, and
+ * COMPRESSED_RGBA_S3TC_DXT5_EXT."
+ *
+ * Note that the addition is only to the OpenGL ES specification!
+ */
+ if (_mesa_is_gles(ctx)) {
+ if (formats) {
+ formats[n++] = GL_COMPRESSED_RGBA_S3TC_DXT1_EXT;
+ } else {
+ n += 1;
+ }
+ }
}
/* The GL_OES_compressed_ETC1_RGB8_texture spec says:
diff --git a/mesalib/src/mesa/main/teximage.c b/mesalib/src/mesa/main/teximage.c
index 9c3f1e86e..8aac54e9d 100644
--- a/mesalib/src/mesa/main/teximage.c
+++ b/mesalib/src/mesa/main/teximage.c
@@ -1088,6 +1088,93 @@ _mesa_get_texture_dimensions(GLenum target)
/**
+ * Check if a texture target can have more than one layer.
+ */
+GLboolean
+_mesa_tex_target_is_layered(GLenum target)
+{
+ switch (target) {
+ case GL_TEXTURE_1D:
+ case GL_PROXY_TEXTURE_1D:
+ case GL_TEXTURE_2D:
+ case GL_PROXY_TEXTURE_2D:
+ case GL_TEXTURE_RECTANGLE:
+ case GL_PROXY_TEXTURE_RECTANGLE:
+ case GL_TEXTURE_2D_MULTISAMPLE:
+ case GL_PROXY_TEXTURE_2D_MULTISAMPLE:
+ case GL_TEXTURE_BUFFER:
+ case GL_TEXTURE_CUBE_MAP_POSITIVE_X:
+ case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
+ case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
+ case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
+ case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
+ case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
+ case GL_TEXTURE_EXTERNAL_OES:
+ return GL_FALSE;
+
+ case GL_TEXTURE_3D:
+ case GL_PROXY_TEXTURE_3D:
+ case GL_TEXTURE_CUBE_MAP:
+ case GL_PROXY_TEXTURE_CUBE_MAP:
+ case GL_TEXTURE_1D_ARRAY:
+ case GL_PROXY_TEXTURE_1D_ARRAY:
+ case GL_TEXTURE_2D_ARRAY:
+ case GL_PROXY_TEXTURE_2D_ARRAY:
+ case GL_TEXTURE_CUBE_MAP_ARRAY:
+ case GL_PROXY_TEXTURE_CUBE_MAP_ARRAY:
+ case GL_TEXTURE_2D_MULTISAMPLE_ARRAY:
+ case GL_PROXY_TEXTURE_2D_MULTISAMPLE_ARRAY:
+ return GL_TRUE;
+
+ default:
+ assert(!"Invalid texture target.");
+ return GL_FALSE;
+ }
+}
+
+
+/**
+ * Return the number of layers present in the given level of an array,
+ * cubemap or 3D texture. If the texture is not layered return zero.
+ */
+GLuint
+_mesa_get_texture_layers(const struct gl_texture_object *texObj, GLint level)
+{
+ assert(level >= 0 && level < MAX_TEXTURE_LEVELS);
+
+ switch (texObj->Target) {
+ case GL_TEXTURE_1D:
+ case GL_TEXTURE_2D:
+ case GL_TEXTURE_RECTANGLE:
+ case GL_TEXTURE_2D_MULTISAMPLE:
+ case GL_TEXTURE_BUFFER:
+ case GL_TEXTURE_EXTERNAL_OES:
+ return 0;
+
+ case GL_TEXTURE_CUBE_MAP:
+ return 6;
+
+ case GL_TEXTURE_1D_ARRAY: {
+ struct gl_texture_image *img = texObj->Image[0][level];
+ return img ? img->Height : 0;
+ }
+
+ case GL_TEXTURE_3D:
+ case GL_TEXTURE_2D_ARRAY:
+ case GL_TEXTURE_CUBE_MAP_ARRAY:
+ case GL_TEXTURE_2D_MULTISAMPLE_ARRAY: {
+ struct gl_texture_image *img = texObj->Image[0][level];
+ return img ? img->Depth : 0;
+ }
+
+ default:
+ assert(!"Invalid texture target.");
+ return 0;
+ }
+}
+
+
+/**
* Return the maximum number of mipmap levels for the given target
* and the dimensions.
* The dimensions are expected not to include the border.
diff --git a/mesalib/src/mesa/main/teximage.h b/mesalib/src/mesa/main/teximage.h
index 0b5786340..80a0a57b5 100644
--- a/mesalib/src/mesa/main/teximage.h
+++ b/mesalib/src/mesa/main/teximage.h
@@ -138,6 +138,12 @@ _mesa_tex_target_to_face(GLenum target);
extern GLint
_mesa_get_texture_dimensions(GLenum target);
+extern GLboolean
+_mesa_tex_target_is_layered(GLenum target);
+
+extern GLuint
+_mesa_get_texture_layers(const struct gl_texture_object *texObj, GLint level);
+
extern GLsizei
_mesa_get_tex_max_num_levels(GLenum target, GLsizei width, GLsizei height,
GLsizei depth);
diff --git a/mesalib/src/mesa/main/texobj.c b/mesalib/src/mesa/main/texobj.c
index d6510fefd..3c64c4376 100644
--- a/mesalib/src/mesa/main/texobj.c
+++ b/mesalib/src/mesa/main/texobj.c
@@ -157,6 +157,7 @@ _mesa_initialize_texture_object( struct gl_context *ctx,
obj->Sampler.sRGBDecode = GL_DECODE_EXT;
obj->BufferObjectFormat = GL_R8;
obj->_BufferObjectFormat = MESA_FORMAT_R8;
+ obj->ImageFormatCompatibilityType = GL_IMAGE_FORMAT_COMPATIBILITY_BY_SIZE;
}
@@ -1099,6 +1100,25 @@ unbind_texobj_from_texunits(struct gl_context *ctx,
/**
+ * Check if the given texture object is bound to any shader image unit
+ * and unbind it if that's the case.
+ */
+static void
+unbind_texobj_from_imgunits(struct gl_context *ctx,
+ struct gl_texture_object *texObj)
+{
+ int i;
+
+ for (i = 0; i < ctx->Const.MaxImageUnits; i++) {
+ struct gl_image_unit *unit = &ctx->ImageUnits[i];
+
+ if (texObj == unit->TexObj)
+ _mesa_reference_texobj(&unit->TexObj, NULL);
+ }
+}
+
+
+/**
* Delete named textures.
*
* \param n number of textures to be deleted.
@@ -1145,6 +1165,12 @@ _mesa_DeleteTextures( GLsizei n, const GLuint *textures)
*/
unbind_texobj_from_texunits(ctx, delObj);
+ /* Check if this texture is currently bound to any shader
+ * image unit. If so, unbind it.
+ * See section 3.9.X of GL_ARB_shader_image_load_store.
+ */
+ unbind_texobj_from_imgunits(ctx, delObj);
+
_mesa_unlock_texture(ctx, delObj);
ctx->NewState |= _NEW_TEXTURE;
diff --git a/mesalib/src/mesa/main/texparam.c b/mesalib/src/mesa/main/texparam.c
index 94e498d20..7c59d119f 100644
--- a/mesalib/src/mesa/main/texparam.c
+++ b/mesalib/src/mesa/main/texparam.c
@@ -1808,6 +1808,12 @@ _mesa_GetTexParameteriv( GLenum target, GLenum pname, GLint *params )
*params = obj->Sampler.sRGBDecode;
break;
+ case GL_IMAGE_FORMAT_COMPATIBILITY_TYPE:
+ if (!ctx->Extensions.ARB_shader_image_load_store)
+ goto invalid_pname;
+ *params = obj->ImageFormatCompatibilityType;
+ break;
+
default:
goto invalid_pname;
}
diff --git a/mesalib/src/mesa/main/texstate.c b/mesalib/src/mesa/main/texstate.c
index ad80dcfaa..7720965a8 100644
--- a/mesalib/src/mesa/main/texstate.c
+++ b/mesalib/src/mesa/main/texstate.c
@@ -35,6 +35,7 @@
#include "context.h"
#include "enums.h"
#include "macros.h"
+#include "shaderimage.h"
#include "texobj.h"
#include "teximage.h"
#include "texstate.h"
@@ -674,6 +675,8 @@ update_texture_state( struct gl_context *ctx )
if (!fprog || !vprog)
update_texgen(ctx);
+
+ _mesa_validate_image_units(ctx);
}
diff --git a/mesalib/src/mesa/main/texstore.c b/mesalib/src/mesa/main/texstore.c
index 5adbd5dc9..8eaf43a6a 100644
--- a/mesalib/src/mesa/main/texstore.c
+++ b/mesalib/src/mesa/main/texstore.c
@@ -2191,6 +2191,7 @@ _mesa_texstore_snorm88(TEXSTORE_PARAMS)
const GLenum baseFormat = _mesa_get_format_base_format(dstFormat);
ASSERT(dstFormat == MESA_FORMAT_SIGNED_AL88 ||
+ dstFormat == MESA_FORMAT_SIGNED_RG88 ||
dstFormat == MESA_FORMAT_SIGNED_RG88_REV);
ASSERT(_mesa_get_format_bytes(dstFormat) == 2);
@@ -2210,13 +2211,27 @@ _mesa_texstore_snorm88(TEXSTORE_PARAMS)
for (img = 0; img < srcDepth; img++) {
GLbyte *dstRow = (GLbyte *) dstSlices[img];
for (row = 0; row < srcHeight; row++) {
- GLbyte *dst = dstRow;
- for (col = 0; col < srcWidth; col++) {
- dst[0] = FLOAT_TO_BYTE_TEX(src[0]);
- dst[1] = FLOAT_TO_BYTE_TEX(src[1]);
- src += 2;
- dst += 2;
+ GLushort *dst = (GLushort *) dstRow;
+
+ if (dstFormat == MESA_FORMAT_SIGNED_AL88 ||
+ dstFormat == MESA_FORMAT_SIGNED_RG88_REV) {
+ for (col = 0; col < srcWidth; col++) {
+ GLubyte l = FLOAT_TO_BYTE_TEX(src[0]);
+ GLubyte a = FLOAT_TO_BYTE_TEX(src[1]);
+
+ dst[col] = PACK_COLOR_88_REV(l, a);
+ src += 2;
+ }
+ } else {
+ for (col = 0; col < srcWidth; col++) {
+ GLubyte l = FLOAT_TO_BYTE_TEX(src[0]);
+ GLubyte a = FLOAT_TO_BYTE_TEX(src[1]);
+
+ dst[col] = PACK_COLOR_88(l, a);
+ src += 2;
+ }
}
+
dstRow += dstRowStride;
}
}
@@ -2278,6 +2293,7 @@ _mesa_texstore_snorm1616(TEXSTORE_PARAMS)
const GLenum baseFormat = _mesa_get_format_base_format(dstFormat);
ASSERT(dstFormat == MESA_FORMAT_SIGNED_AL1616 ||
+ dstFormat == MESA_FORMAT_SIGNED_RG1616 ||
dstFormat == MESA_FORMAT_SIGNED_GR1616);
ASSERT(_mesa_get_format_bytes(dstFormat) == 4);
@@ -2297,17 +2313,29 @@ _mesa_texstore_snorm1616(TEXSTORE_PARAMS)
for (img = 0; img < srcDepth; img++) {
GLubyte *dstRow = dstSlices[img];
for (row = 0; row < srcHeight; row++) {
- GLshort *dst = (GLshort *) dstRow;
- for (col = 0; col < srcWidth; col++) {
- GLushort l, a;
+ GLuint *dst = (GLuint *) dstRow;
- UNCLAMPED_FLOAT_TO_SHORT(l, src[0]);
- UNCLAMPED_FLOAT_TO_SHORT(a, src[1]);
- dst[0] = l;
- dst[1] = a;
- src += 2;
- dst += 2;
+ if (dstFormat == MESA_FORMAT_SIGNED_AL1616 ||
+ dstFormat == MESA_FORMAT_SIGNED_GR1616) {
+ for (col = 0; col < srcWidth; col++) {
+ GLushort l, a;
+
+ UNCLAMPED_FLOAT_TO_SHORT(l, src[0]);
+ UNCLAMPED_FLOAT_TO_SHORT(a, src[1]);
+ dst[col] = PACK_COLOR_1616_REV(l, a);
+ src += 2;
+ }
+ } else {
+ for (col = 0; col < srcWidth; col++) {
+ GLushort l, a;
+
+ UNCLAMPED_FLOAT_TO_SHORT(l, src[0]);
+ UNCLAMPED_FLOAT_TO_SHORT(a, src[1]);
+ dst[col] = PACK_COLOR_1616_REV(l, a);
+ src += 2;
+ }
}
+
dstRow += dstRowStride;
}
}
@@ -3559,6 +3587,50 @@ _mesa_texstore_abgr2101010_uint(TEXSTORE_PARAMS)
}
static GLboolean
+_mesa_texstore_abgr2101010(TEXSTORE_PARAMS)
+{
+ const GLenum baseFormat = _mesa_get_format_base_format(dstFormat);
+
+ ASSERT(dstFormat == MESA_FORMAT_ABGR2101010);
+ ASSERT(_mesa_get_format_bytes(dstFormat) == 4);
+
+ {
+ /* general path */
+ const GLfloat *tempImage = _mesa_make_temp_float_image(ctx, dims,
+ baseInternalFormat,
+ baseFormat,
+ srcWidth, srcHeight, srcDepth,
+ srcFormat, srcType, srcAddr,
+ srcPacking,
+ ctx->_ImageTransferState);
+ const GLfloat *src = tempImage;
+ GLint img, row, col;
+ if (!tempImage)
+ return GL_FALSE;
+ for (img = 0; img < srcDepth; img++) {
+ GLubyte *dstRow = dstSlices[img];
+
+ for (row = 0; row < srcHeight; row++) {
+ GLuint *dstUI = (GLuint *) dstRow;
+ for (col = 0; col < srcWidth; col++) {
+ GLushort a,r,g,b;
+
+ UNCLAMPED_FLOAT_TO_USHORT(a, src[ACOMP]);
+ UNCLAMPED_FLOAT_TO_USHORT(r, src[RCOMP]);
+ UNCLAMPED_FLOAT_TO_USHORT(g, src[GCOMP]);
+ UNCLAMPED_FLOAT_TO_USHORT(b, src[BCOMP]);
+ dstUI[col] = PACK_COLOR_2101010_US(a, b, g, r);
+ src += 4;
+ }
+ dstRow += dstRowStride;
+ }
+ }
+ free((void *) tempImage);
+ }
+ return GL_TRUE;
+}
+
+static GLboolean
_mesa_texstore_null(TEXSTORE_PARAMS)
{
(void) ctx; (void) dims;
@@ -3782,6 +3854,11 @@ _mesa_get_texstore_func(gl_format format)
table[MESA_FORMAT_XBGR32323232_UINT] = _mesa_texstore_rgba_uint32;
table[MESA_FORMAT_XBGR32323232_SINT] = _mesa_texstore_rgba_int32;
+ table[MESA_FORMAT_ABGR2101010] = _mesa_texstore_abgr2101010;
+
+ table[MESA_FORMAT_SIGNED_RG88] = _mesa_texstore_snorm88;
+ table[MESA_FORMAT_SIGNED_RG1616] = _mesa_texstore_snorm1616;
+
initialized = GL_TRUE;
}
diff --git a/mesalib/src/mesa/main/viewport.c b/mesalib/src/mesa/main/viewport.c
index 91578ba9d..3aaab2d46 100644
--- a/mesalib/src/mesa/main/viewport.c
+++ b/mesalib/src/mesa/main/viewport.c
@@ -99,7 +99,7 @@ _mesa_set_viewport(struct gl_context *ctx, GLint x, GLint y,
/* Many drivers will use this call to check for window size changes
* and reallocate the z/stencil/accum/etc buffers if needed.
*/
- ctx->Driver.Viewport(ctx, x, y, width, height);
+ ctx->Driver.Viewport(ctx);
}
}
@@ -143,7 +143,7 @@ _mesa_DepthRange(GLclampd nearval, GLclampd farval)
#endif
if (ctx->Driver.DepthRange) {
- ctx->Driver.DepthRange(ctx, nearval, farval);
+ ctx->Driver.DepthRange(ctx);
}
}
diff --git a/mesalib/src/mesa/program/ir_to_mesa.cpp b/mesalib/src/mesa/program/ir_to_mesa.cpp
index f6c229c7d..85d414259 100644
--- a/mesalib/src/mesa/program/ir_to_mesa.cpp
+++ b/mesalib/src/mesa/program/ir_to_mesa.cpp
@@ -665,8 +665,8 @@ ir_to_mesa_visitor::find_variable_storage(ir_variable *var)
variable_storage *entry;
- foreach_iter(exec_list_iterator, iter, this->variables) {
- entry = (variable_storage *)iter.get();
+ foreach_list(node, &this->variables) {
+ entry = (variable_storage *) node;
if (entry->var == var)
return entry;
@@ -801,8 +801,8 @@ ir_to_mesa_visitor::visit(ir_function *ir)
assert(sig);
- foreach_iter(exec_list_iterator, iter, sig->body) {
- ir_instruction *ir = (ir_instruction *)iter.get();
+ foreach_list(node, &sig->body) {
+ ir_instruction *ir = (ir_instruction *) node;
ir->accept(this);
}
@@ -1868,8 +1868,8 @@ ir_to_mesa_visitor::visit(ir_constant *ir)
src_reg temp_base = get_temp(ir->type);
dst_reg temp = dst_reg(temp_base);
- foreach_iter(exec_list_iterator, iter, ir->components) {
- ir_constant *field_value = (ir_constant *)iter.get();
+ foreach_list(node, &ir->components) {
+ ir_constant *field_value = (ir_constant *) node;
int size = type_size(field_value->type);
assert(size > 0);
@@ -2338,8 +2338,8 @@ set_branchtargets(ir_to_mesa_visitor *v,
mesa_instructions[loop_stack[loop_stack_pos]].BranchTarget = i;
break;
case OPCODE_CAL:
- foreach_iter(exec_list_iterator, iter, v->function_signatures) {
- function_entry *entry = (function_entry *)iter.get();
+ foreach_list(n, &v->function_signatures) {
+ function_entry *entry = (function_entry *) n;
if (entry->sig_id == mesa_instructions[i].BranchTarget) {
mesa_instructions[i].BranchTarget = entry->inst;
@@ -2620,8 +2620,8 @@ ir_to_mesa_visitor::copy_propagate(void)
int *acp_level = rzalloc_array(mem_ctx, int, this->next_temp * 4);
int level = 0;
- foreach_iter(exec_list_iterator, iter, this->instructions) {
- ir_to_mesa_instruction *inst = (ir_to_mesa_instruction *)iter.get();
+ foreach_list(node, &this->instructions) {
+ ir_to_mesa_instruction *inst = (ir_to_mesa_instruction *) node;
assert(inst->dst.file != PROGRAM_TEMPORARY
|| inst->dst.index < this->next_temp);
@@ -2825,7 +2825,7 @@ get_mesa_program(struct gl_context *ctx,
prog->NumTemporaries = v.next_temp;
int num_instructions = 0;
- foreach_iter(exec_list_iterator, iter, v.instructions) {
+ foreach_list(node, &v.instructions) {
num_instructions++;
}
@@ -2841,8 +2841,8 @@ get_mesa_program(struct gl_context *ctx,
*/
mesa_inst = mesa_instructions;
i = 0;
- foreach_iter(exec_list_iterator, iter, v.instructions) {
- const ir_to_mesa_instruction *inst = (ir_to_mesa_instruction *)iter.get();
+ foreach_list(node, &v.instructions) {
+ const ir_to_mesa_instruction *inst = (ir_to_mesa_instruction *) node;
mesa_inst->Opcode = inst->op;
mesa_inst->CondUpdate = inst->cond_update;
diff --git a/mesalib/src/mesa/state_tracker/st_atom_framebuffer.c b/mesalib/src/mesa/state_tracker/st_atom_framebuffer.c
index 51f079cda..a77fe54ae 100644
--- a/mesalib/src/mesa/state_tracker/st_atom_framebuffer.c
+++ b/mesalib/src/mesa/state_tracker/st_atom_framebuffer.c
@@ -65,12 +65,14 @@ update_framebuffer_state( struct st_context *st )
/* Examine Mesa's ctx->DrawBuffer->_ColorDrawBuffers state
* to determine which surfaces to draw to
*/
- framebuffer->nr_cbufs = 0;
+ framebuffer->nr_cbufs = fb->_NumColorDrawBuffers;
+
for (i = 0; i < fb->_NumColorDrawBuffers; i++) {
+ pipe_surface_reference(&framebuffer->cbufs[i], NULL);
+
strb = st_renderbuffer(fb->_ColorDrawBuffers[i]);
if (strb) {
- /*printf("--------- framebuffer surface rtt %p\n", strb->rtt);*/
if (strb->is_rtt ||
(strb->texture && util_format_is_srgb(strb->texture->format))) {
/* rendering to a GL texture, may have to update surface */
@@ -78,13 +80,12 @@ update_framebuffer_state( struct st_context *st )
}
if (strb->surface) {
- pipe_surface_reference(&framebuffer->cbufs[framebuffer->nr_cbufs],
- strb->surface);
- framebuffer->nr_cbufs++;
+ pipe_surface_reference(&framebuffer->cbufs[i], strb->surface);
}
strb->defined = GL_TRUE; /* we'll be drawing something */
}
}
+
for (i = framebuffer->nr_cbufs; i < PIPE_MAX_COLOR_BUFS; i++) {
pipe_surface_reference(&framebuffer->cbufs[i], NULL);
}
@@ -113,7 +114,8 @@ update_framebuffer_state( struct st_context *st )
#ifdef DEBUG
/* Make sure the resource binding flags were set properly */
for (i = 0; i < framebuffer->nr_cbufs; i++) {
- assert(framebuffer->cbufs[i]->texture->bind & PIPE_BIND_RENDER_TARGET);
+ assert(!framebuffer->cbufs[i] ||
+ framebuffer->cbufs[i]->texture->bind & PIPE_BIND_RENDER_TARGET);
}
if (framebuffer->zsbuf) {
assert(framebuffer->zsbuf->texture->bind & PIPE_BIND_DEPTH_STENCIL);
diff --git a/mesalib/src/mesa/state_tracker/st_atom_msaa.c b/mesalib/src/mesa/state_tracker/st_atom_msaa.c
index fb760460c..2f3a42e02 100644
--- a/mesalib/src/mesa/state_tracker/st_atom_msaa.c
+++ b/mesalib/src/mesa/state_tracker/st_atom_msaa.c
@@ -31,6 +31,7 @@
#include "st_atom.h"
#include "cso_cache/cso_context.h"
+#include "util/u_framebuffer.h"
/* Second state atom for user clip planes:
@@ -38,14 +39,9 @@
static void update_sample_mask( struct st_context *st )
{
unsigned sample_mask = 0xffffffff;
- unsigned sample_count = 1;
struct pipe_framebuffer_state *framebuffer = &st->state.framebuffer;
-
/* dependency here on bound surface (or rather, sample count) is worrying */
- if (framebuffer->zsbuf)
- sample_count = framebuffer->zsbuf->texture->nr_samples;
- else if (framebuffer->cbufs[0])
- sample_count = framebuffer->cbufs[0]->texture->nr_samples;
+ unsigned sample_count = util_framebuffer_get_num_samples(framebuffer);
if (st->ctx->Multisample.Enabled && sample_count > 1) {
/* unlike in gallium/d3d10 the mask is only active if msaa is enabled */
diff --git a/mesalib/src/mesa/state_tracker/st_cb_blit.c b/mesalib/src/mesa/state_tracker/st_cb_blit.c
index a236a08e9..82c2e38e5 100644
--- a/mesalib/src/mesa/state_tracker/st_cb_blit.c
+++ b/mesalib/src/mesa/state_tracker/st_cb_blit.c
@@ -44,6 +44,34 @@
static void
+st_adjust_blit_for_msaa_resolve(struct pipe_blit_info *blit)
+{
+ /* Even though we do multisample resolves at the time of the blit, OpenGL
+ * specification defines them as if they happen at the time of rendering,
+ * which means that the type of averaging we do during the resolve should
+ * only depend on the source format; the destination format should be
+ * ignored. But, specification doesn't seem to be strict about it.
+ *
+ * It has been observed that mulitisample resolves produce slightly better
+ * looking images when averaging is done using destination format. NVIDIA's
+ * proprietary OpenGL driver also follows this approach.
+ *
+ * When multisampling, if the source and destination formats are equal
+ * (aside from the color space), we choose to blit in sRGB space to get
+ * this higher quality image.
+ */
+ if (blit->src.resource->nr_samples > 1 &&
+ blit->dst.resource->nr_samples <= 1) {
+ blit->dst.format = blit->dst.resource->format;
+
+ if (util_format_is_srgb(blit->dst.resource->format))
+ blit->src.format = util_format_srgb(blit->src.resource->format);
+ else
+ blit->src.format = util_format_linear(blit->src.resource->format);
+ }
+}
+
+static void
st_BlitFramebuffer(struct gl_context *ctx,
GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1,
GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1,
@@ -192,6 +220,8 @@ st_BlitFramebuffer(struct gl_context *ctx,
blit.src.box.z = srcAtt->Zoffset + srcAtt->CubeMapFace;
blit.src.format = util_format_linear(srcObj->pt->format);
+ st_adjust_blit_for_msaa_resolve(&blit);
+
st->pipe->blit(st->pipe, &blit);
}
}
@@ -227,6 +257,8 @@ st_BlitFramebuffer(struct gl_context *ctx,
blit.src.box.z = srcSurf->u.tex.first_layer;
blit.src.format = util_format_linear(srcSurf->format);
+ st_adjust_blit_for_msaa_resolve(&blit);
+
st->pipe->blit(st->pipe, &blit);
}
}
diff --git a/mesalib/src/mesa/state_tracker/st_cb_clear.c b/mesalib/src/mesa/state_tracker/st_cb_clear.c
index 887e58bd9..79124b3da 100644
--- a/mesalib/src/mesa/state_tracker/st_cb_clear.c
+++ b/mesalib/src/mesa/state_tracker/st_cb_clear.c
@@ -399,6 +399,19 @@ is_color_masked(struct gl_context *ctx, int i)
/**
+ * Return if all of the stencil bits are masked.
+ */
+static INLINE GLboolean
+is_stencil_disabled(struct gl_context *ctx, struct gl_renderbuffer *rb)
+{
+ const GLuint stencilMax = 0xff;
+
+ assert(_mesa_get_format_bits(rb->Format, GL_STENCIL_BITS) > 0);
+ return (ctx->Stencil.WriteMask[0] & stencilMax) == 0;
+}
+
+
+/**
* Return if any of the stencil bits are masked.
*/
static INLINE GLboolean
@@ -431,9 +444,9 @@ st_Clear(struct gl_context *ctx, GLbitfield mask)
if (mask & BUFFER_BITS_COLOR) {
for (i = 0; i < ctx->DrawBuffer->_NumColorDrawBuffers; i++) {
- GLuint b = ctx->DrawBuffer->_ColorDrawBufferIndexes[i];
+ GLint b = ctx->DrawBuffer->_ColorDrawBufferIndexes[i];
- if (mask & (1 << b)) {
+ if (b >= 0 && mask & (1 << b)) {
struct gl_renderbuffer *rb
= ctx->DrawBuffer->Attachment[b].Renderbuffer;
struct st_renderbuffer *strb = st_renderbuffer(rb);
@@ -457,7 +470,7 @@ st_Clear(struct gl_context *ctx, GLbitfield mask)
if (mask & BUFFER_BIT_DEPTH) {
struct st_renderbuffer *strb = st_renderbuffer(depthRb);
- if (strb->surface) {
+ if (strb->surface && ctx->Depth.Mask) {
if (is_scissor_enabled(ctx, depthRb))
quad_buffers |= PIPE_CLEAR_DEPTH;
else
@@ -467,7 +480,7 @@ st_Clear(struct gl_context *ctx, GLbitfield mask)
if (mask & BUFFER_BIT_STENCIL) {
struct st_renderbuffer *strb = st_renderbuffer(stencilRb);
- if (strb->surface) {
+ if (strb->surface && !is_stencil_disabled(ctx, stencilRb)) {
if (is_scissor_enabled(ctx, stencilRb) ||
is_stencil_masked(ctx, stencilRb))
quad_buffers |= PIPE_CLEAR_STENCIL;
@@ -476,14 +489,23 @@ st_Clear(struct gl_context *ctx, GLbitfield mask)
}
}
- /*
- * If we're going to use clear_with_quad() for any reason, use it for
- * everything possible.
+ /* Always clear depth and stencil together.
+ * This can only happen when the stencil writemask is not a full mask.
+ */
+ if (quad_buffers & PIPE_CLEAR_DEPTHSTENCIL &&
+ clear_buffers & PIPE_CLEAR_DEPTHSTENCIL) {
+ quad_buffers |= clear_buffers & PIPE_CLEAR_DEPTHSTENCIL;
+ clear_buffers &= ~PIPE_CLEAR_DEPTHSTENCIL;
+ }
+
+ /* Only use quad-based clearing for the renderbuffers which cannot
+ * use pipe->clear. We want to always use pipe->clear for the other
+ * renderbuffers, because it's likely to be faster.
*/
if (quad_buffers) {
- quad_buffers |= clear_buffers;
clear_with_quad(ctx, quad_buffers);
- } else if (clear_buffers) {
+ }
+ if (clear_buffers) {
/* We can't translate the clear color to the colorbuffer format,
* because different colorbuffers may have different formats.
*/
diff --git a/mesalib/src/mesa/state_tracker/st_cb_fbo.c b/mesalib/src/mesa/state_tracker/st_cb_fbo.c
index 70baa9965..daa94df92 100644
--- a/mesalib/src/mesa/state_tracker/st_cb_fbo.c
+++ b/mesalib/src/mesa/state_tracker/st_cb_fbo.c
@@ -680,7 +680,10 @@ st_DrawBuffers(struct gl_context *ctx, GLsizei count, const GLenum *buffers)
/* add the renderbuffers on demand */
for (i = 0; i < fb->_NumColorDrawBuffers; i++) {
gl_buffer_index idx = fb->_ColorDrawBufferIndexes[i];
- st_manager_add_color_renderbuffer(st, fb, idx);
+
+ if (idx >= 0) {
+ st_manager_add_color_renderbuffer(st, fb, idx);
+ }
}
}
diff --git a/mesalib/src/mesa/state_tracker/st_cb_viewport.c b/mesalib/src/mesa/state_tracker/st_cb_viewport.c
index d654ed6e7..f0e97296f 100644
--- a/mesalib/src/mesa/state_tracker/st_cb_viewport.c
+++ b/mesalib/src/mesa/state_tracker/st_cb_viewport.c
@@ -48,8 +48,7 @@ st_ws_framebuffer(struct gl_framebuffer *fb)
return NULL;
}
-static void st_viewport(struct gl_context * ctx, GLint x, GLint y,
- GLsizei width, GLsizei height)
+static void st_viewport(struct gl_context *ctx)
{
struct st_context *st = ctx->st;
struct st_framebuffer *stdraw;
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 73c39eb77..f1b354429 100644
--- a/mesalib/src/mesa/state_tracker/st_glsl_to_tgsi.cpp
+++ b/mesalib/src/mesa/state_tracker/st_glsl_to_tgsi.cpp
@@ -897,8 +897,8 @@ glsl_to_tgsi_visitor::add_constant(gl_register_file file,
/* Search immediate storage to see if we already have an identical
* immediate that we can use instead of adding a duplicate entry.
*/
- foreach_iter(exec_list_iterator, iter, this->immediates) {
- entry = (immediate_storage *)iter.get();
+ foreach_list(node, &this->immediates) {
+ entry = (immediate_storage *) node;
if (entry->size == size &&
entry->type == datatype &&
@@ -1040,8 +1040,8 @@ glsl_to_tgsi_visitor::find_variable_storage(ir_variable *var)
variable_storage *entry;
- foreach_iter(exec_list_iterator, iter, this->variables) {
- entry = (variable_storage *)iter.get();
+ foreach_list(node, &this->variables) {
+ entry = (variable_storage *) node;
if (entry->var == var)
return entry;
@@ -1179,8 +1179,8 @@ glsl_to_tgsi_visitor::visit(ir_function *ir)
assert(sig);
- foreach_iter(exec_list_iterator, iter, sig->body) {
- ir_instruction *ir = (ir_instruction *)iter.get();
+ foreach_list(node, &sig->body) {
+ ir_instruction *ir = (ir_instruction *) node;
ir->accept(this);
}
@@ -2455,8 +2455,8 @@ glsl_to_tgsi_visitor::visit(ir_constant *ir)
st_src_reg temp_base = get_temp(ir->type);
st_dst_reg temp = st_dst_reg(temp_base);
- foreach_iter(exec_list_iterator, iter, ir->components) {
- ir_constant *field_value = (ir_constant *)iter.get();
+ foreach_list(node, &ir->components) {
+ ir_constant *field_value = (ir_constant *) node;
int size = type_size(field_value->type);
assert(size > 0);
@@ -2572,8 +2572,8 @@ glsl_to_tgsi_visitor::get_function_signature(ir_function_signature *sig)
{
function_entry *entry;
- foreach_iter(exec_list_iterator, iter, this->function_signatures) {
- entry = (function_entry *)iter.get();
+ foreach_list(node, &this->function_signatures) {
+ entry = (function_entry *) node;
if (entry->sig == sig)
return entry;
@@ -2585,8 +2585,8 @@ glsl_to_tgsi_visitor::get_function_signature(ir_function_signature *sig)
entry->bgn_inst = NULL;
/* Allocate storage for all the parameters. */
- foreach_iter(exec_list_iterator, iter, sig->parameters) {
- ir_variable *param = (ir_variable *)iter.get();
+ foreach_list(node, &sig->parameters) {
+ ir_variable *param = (ir_variable *) node;
variable_storage *storage;
storage = find_variable_storage(param);
@@ -2617,10 +2617,10 @@ glsl_to_tgsi_visitor::visit(ir_call *ir)
int i;
/* Process in parameters. */
- exec_list_iterator sig_iter = sig->parameters.iterator();
- foreach_iter(exec_list_iterator, iter, *ir) {
- ir_rvalue *param_rval = (ir_rvalue *)iter.get();
- ir_variable *param = (ir_variable *)sig_iter.get();
+ foreach_two_lists(formal_node, &sig->parameters,
+ actual_node, &ir->actual_parameters) {
+ ir_rvalue *param_rval = (ir_rvalue *) actual_node;
+ ir_variable *param = (ir_variable *) formal_node;
if (param->data.mode == ir_var_function_in ||
param->data.mode == ir_var_function_inout) {
@@ -2643,20 +2643,17 @@ glsl_to_tgsi_visitor::visit(ir_call *ir)
r.index++;
}
}
-
- sig_iter.next();
}
- assert(!sig_iter.has_next());
/* Emit call instruction */
call_inst = emit(ir, TGSI_OPCODE_CAL);
call_inst->function = entry;
/* Process out parameters. */
- sig_iter = sig->parameters.iterator();
- foreach_iter(exec_list_iterator, iter, *ir) {
- ir_rvalue *param_rval = (ir_rvalue *)iter.get();
- ir_variable *param = (ir_variable *)sig_iter.get();
+ foreach_two_lists(formal_node, &sig->parameters,
+ actual_node, &ir->actual_parameters) {
+ ir_rvalue *param_rval = (ir_rvalue *) actual_node;
+ ir_variable *param = (ir_variable *) formal_node;
if (param->data.mode == ir_var_function_out ||
param->data.mode == ir_var_function_inout) {
@@ -2679,10 +2676,7 @@ glsl_to_tgsi_visitor::visit(ir_call *ir)
r.index++;
}
}
-
- sig_iter.next();
}
- assert(!sig_iter.has_next());
/* Process return value. */
this->result = entry->return_reg;
@@ -3070,8 +3064,8 @@ count_resources(glsl_to_tgsi_visitor *v, gl_program *prog)
{
v->samplers_used = 0;
- foreach_iter(exec_list_iterator, iter, v->instructions) {
- glsl_to_tgsi_instruction *inst = (glsl_to_tgsi_instruction *)iter.get();
+ foreach_list(node, &v->instructions) {
+ glsl_to_tgsi_instruction *inst = (glsl_to_tgsi_instruction *) node;
if (is_tex_instruction(inst->op)) {
v->samplers_used |= 1 << inst->sampler;
@@ -3216,8 +3210,8 @@ glsl_to_tgsi_visitor::simplify_cmp(void)
memset(tempWrites, 0, sizeof(unsigned) * MAX_TEMPS);
memset(outputWrites, 0, sizeof(outputWrites));
- foreach_iter(exec_list_iterator, iter, this->instructions) {
- glsl_to_tgsi_instruction *inst = (glsl_to_tgsi_instruction *)iter.get();
+ foreach_list(node, &this->instructions) {
+ glsl_to_tgsi_instruction *inst = (glsl_to_tgsi_instruction *) node;
unsigned prevWriteMask = 0;
/* Give up if we encounter relative addressing or flow control. */
@@ -3262,8 +3256,8 @@ glsl_to_tgsi_visitor::simplify_cmp(void)
void
glsl_to_tgsi_visitor::rename_temp_register(int index, int new_index)
{
- foreach_iter(exec_list_iterator, iter, this->instructions) {
- glsl_to_tgsi_instruction *inst = (glsl_to_tgsi_instruction *)iter.get();
+ foreach_list(node, &this->instructions) {
+ glsl_to_tgsi_instruction *inst = (glsl_to_tgsi_instruction *) node;
unsigned j;
for (j=0; j < num_inst_src_regs(inst->op); j++) {
@@ -3286,8 +3280,8 @@ glsl_to_tgsi_visitor::get_first_temp_read(int index)
int loop_start = -1; /* index of the first active BGNLOOP (if any) */
unsigned i = 0, j;
- foreach_iter(exec_list_iterator, iter, this->instructions) {
- glsl_to_tgsi_instruction *inst = (glsl_to_tgsi_instruction *)iter.get();
+ foreach_list(node, &this->instructions) {
+ glsl_to_tgsi_instruction *inst = (glsl_to_tgsi_instruction *) node;
for (j=0; j < num_inst_src_regs(inst->op); j++) {
if (inst->src[j].file == PROGRAM_TEMPORARY &&
@@ -3318,8 +3312,8 @@ glsl_to_tgsi_visitor::get_first_temp_write(int index)
int loop_start = -1; /* index of the first active BGNLOOP (if any) */
int i = 0;
- foreach_iter(exec_list_iterator, iter, this->instructions) {
- glsl_to_tgsi_instruction *inst = (glsl_to_tgsi_instruction *)iter.get();
+ foreach_list(node, &this->instructions) {
+ glsl_to_tgsi_instruction *inst = (glsl_to_tgsi_instruction *) node;
if (inst->dst.file == PROGRAM_TEMPORARY && inst->dst.index == index) {
return (depth == 0) ? i : loop_start;
@@ -3347,8 +3341,8 @@ glsl_to_tgsi_visitor::get_last_temp_read(int index)
int last = -1; /* index of last instruction that reads the temporary */
unsigned i = 0, j;
- foreach_iter(exec_list_iterator, iter, this->instructions) {
- glsl_to_tgsi_instruction *inst = (glsl_to_tgsi_instruction *)iter.get();
+ foreach_list(node, &this->instructions) {
+ glsl_to_tgsi_instruction *inst = (glsl_to_tgsi_instruction *) node;
for (j=0; j < num_inst_src_regs(inst->op); j++) {
if (inst->src[j].file == PROGRAM_TEMPORARY &&
@@ -3378,8 +3372,8 @@ glsl_to_tgsi_visitor::get_last_temp_write(int index)
int last = -1; /* index of last instruction that writes to the temporary */
int i = 0;
- foreach_iter(exec_list_iterator, iter, this->instructions) {
- glsl_to_tgsi_instruction *inst = (glsl_to_tgsi_instruction *)iter.get();
+ foreach_list(node, &this->instructions) {
+ glsl_to_tgsi_instruction *inst = (glsl_to_tgsi_instruction *) node;
if (inst->dst.file == PROGRAM_TEMPORARY && inst->dst.index == index)
last = (depth == 0) ? i : -2;
@@ -3427,8 +3421,8 @@ glsl_to_tgsi_visitor::copy_propagate(void)
int *acp_level = rzalloc_array(mem_ctx, int, this->next_temp * 4);
int level = 0;
- foreach_iter(exec_list_iterator, iter, this->instructions) {
- glsl_to_tgsi_instruction *inst = (glsl_to_tgsi_instruction *)iter.get();
+ foreach_list(node, &this->instructions) {
+ glsl_to_tgsi_instruction *inst = (glsl_to_tgsi_instruction *) node;
assert(inst->dst.file != PROGRAM_TEMPORARY
|| inst->dst.index < this->next_temp);
@@ -3624,13 +3618,13 @@ glsl_to_tgsi_visitor::eliminate_dead_code(void)
int last_read = get_last_temp_read(i);
int j = 0;
- foreach_iter(exec_list_iterator, iter, this->instructions) {
- glsl_to_tgsi_instruction *inst = (glsl_to_tgsi_instruction *)iter.get();
+ foreach_list_safe(node, &this->instructions) {
+ glsl_to_tgsi_instruction *inst = (glsl_to_tgsi_instruction *) node;
if (inst->dst.file == PROGRAM_TEMPORARY && inst->dst.index == i &&
j > last_read)
{
- iter.remove();
+ inst->remove();
delete inst;
}
@@ -3661,8 +3655,8 @@ glsl_to_tgsi_visitor::eliminate_dead_code_advanced(void)
int level = 0;
int removed = 0;
- foreach_iter(exec_list_iterator, iter, this->instructions) {
- glsl_to_tgsi_instruction *inst = (glsl_to_tgsi_instruction *)iter.get();
+ foreach_list(node, &this->instructions) {
+ glsl_to_tgsi_instruction *inst = (glsl_to_tgsi_instruction *) node;
assert(inst->dst.file != PROGRAM_TEMPORARY
|| inst->dst.index < this->next_temp);
@@ -3769,13 +3763,13 @@ glsl_to_tgsi_visitor::eliminate_dead_code_advanced(void)
/* Now actually remove the instructions that are completely dead and update
* the writemask of other instructions with dead channels.
*/
- foreach_iter(exec_list_iterator, iter, this->instructions) {
- glsl_to_tgsi_instruction *inst = (glsl_to_tgsi_instruction *)iter.get();
+ foreach_list_safe(node, &this->instructions) {
+ glsl_to_tgsi_instruction *inst = (glsl_to_tgsi_instruction *) node;
if (!inst->dead_mask || !inst->dst.writemask)
continue;
else if ((inst->dst.writemask & ~inst->dead_mask) == 0) {
- iter.remove();
+ inst->remove();
delete inst;
removed++;
} else
@@ -3956,8 +3950,8 @@ get_pixel_transfer_visitor(struct st_fragment_program *fp,
/* Now copy the instructions from the original glsl_to_tgsi_visitor into the
* new visitor. */
- foreach_iter(exec_list_iterator, iter, original->instructions) {
- glsl_to_tgsi_instruction *inst = (glsl_to_tgsi_instruction *)iter.get();
+ foreach_list(node, &original->instructions) {
+ glsl_to_tgsi_instruction *inst = (glsl_to_tgsi_instruction *) node;
glsl_to_tgsi_instruction *newinst;
st_src_reg src_regs[3];
@@ -4040,8 +4034,8 @@ get_bitmap_visitor(struct st_fragment_program *fp,
/* Now copy the instructions from the original glsl_to_tgsi_visitor into the
* new visitor. */
- foreach_iter(exec_list_iterator, iter, original->instructions) {
- glsl_to_tgsi_instruction *inst = (glsl_to_tgsi_instruction *)iter.get();
+ foreach_list(node, &original->instructions) {
+ glsl_to_tgsi_instruction *inst = (glsl_to_tgsi_instruction *) node;
glsl_to_tgsi_instruction *newinst;
st_src_reg src_regs[3];
@@ -4962,8 +4956,8 @@ st_translate_program(
goto out;
}
i = 0;
- foreach_iter(exec_list_iterator, iter, program->immediates) {
- immediate_storage *imm = (immediate_storage *)iter.get();
+ foreach_list(node, &program->immediates) {
+ immediate_storage *imm = (immediate_storage *) node;
assert(i < program->num_immediates);
t->immediates[i++] = emit_immediate(t, imm->values, imm->type, imm->size);
}
@@ -4978,10 +4972,9 @@ st_translate_program(
/* Emit each instruction in turn:
*/
- foreach_iter(exec_list_iterator, iter, program->instructions) {
+ foreach_list(n, &program->instructions) {
set_insn_start(t, ureg_get_instruction_number(ureg));
- compile_tgsi_instruction(t, (glsl_to_tgsi_instruction *)iter.get(),
- clamp_color);
+ compile_tgsi_instruction(t, (glsl_to_tgsi_instruction *) n, clamp_color);
}
/* Fix up all emitted labels:
@@ -5089,8 +5082,8 @@ get_mesa_program(struct gl_context *ctx,
do {
progress = GL_FALSE;
- foreach_iter(exec_list_iterator, iter, v->function_signatures) {
- function_entry *entry = (function_entry *)iter.get();
+ foreach_list(node, &v->function_signatures) {
+ function_entry *entry = (function_entry *) node;
if (!entry->bgn_inst) {
v->current_function = entry;
diff --git a/mesalib/src/mesa/swrast/s_texfetch.c b/mesalib/src/mesa/swrast/s_texfetch.c
index 0196aede1..b886e6586 100644
--- a/mesalib/src/mesa/swrast/s_texfetch.c
+++ b/mesalib/src/mesa/swrast/s_texfetch.c
@@ -1286,6 +1286,24 @@ texfetch_funcs[] =
NULL,
NULL
},
+ {
+ MESA_FORMAT_ABGR2101010,
+ NULL,
+ NULL,
+ NULL
+ },
+ {
+ MESA_FORMAT_SIGNED_RG88,
+ NULL,
+ NULL,
+ NULL
+ },
+ {
+ MESA_FORMAT_SIGNED_RG1616,
+ NULL,
+ NULL,
+ NULL
+ },
};