2 * Copyright © 2014 Intel Corporation
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),
6 * to deal in the Software without restriction, including without limitation
7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 * and/or sell copies of the Software, and to permit persons to whom the
9 * Software is furnished to do so, subject to the following conditions:
11 * The above copyright notice and this permission notice (including the next
12 * paragraph) shall be included in all copies or substantial portions of the
15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
18 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
21 * DEALINGS IN THE SOFTWARE.
25 * \file lower_const_arrays_to_uniforms.cpp
27 * Lower constant arrays to uniform arrays.
29 * Some driver backends (such as i965 and nouveau) don't handle constant arrays
30 * gracefully, instead treating them as ordinary writable temporary arrays.
31 * Since arrays can be large, this often means spilling them to scratch memory,
32 * which usually involves a large number of instructions.
34 * This must be called prior to link_set_uniform_initializers(); we need the
35 * linker to process our new uniform's constant initializer.
37 * This should be called after optimizations, since those can result in
38 * splitting and removing arrays that are indexed by constant expressions.
41 #include "ir_visitor.h"
42 #include "ir_rvalue_visitor.h"
43 #include "compiler/glsl_types.h"
46 class lower_const_array_visitor
: public ir_rvalue_visitor
{
48 lower_const_array_visitor(exec_list
*insts
)
56 visit_list_elements(this, instructions
);
60 void handle_rvalue(ir_rvalue
**rvalue
);
63 exec_list
*instructions
;
68 lower_const_array_visitor::handle_rvalue(ir_rvalue
**rvalue
)
73 ir_dereference_array
*dra
= (*rvalue
)->as_dereference_array();
77 ir_constant
*con
= dra
->array
->as_constant();
78 if (!con
|| !con
->type
->is_array())
81 void *mem_ctx
= ralloc_parent(con
);
83 char *uniform_name
= ralloc_asprintf(mem_ctx
, "constarray__%p", dra
);
86 new(mem_ctx
) ir_variable(con
->type
, uniform_name
, ir_var_uniform
);
87 uni
->constant_initializer
= con
;
88 uni
->constant_value
= con
;
89 uni
->data
.has_initializer
= true;
90 uni
->data
.how_declared
= ir_var_hidden
;
91 uni
->data
.read_only
= true;
92 /* Assume the whole thing is accessed. */
93 uni
->data
.max_array_access
= uni
->type
->length
- 1;
94 instructions
->push_head(uni
);
96 ir_dereference_variable
*varref
= new(mem_ctx
) ir_dereference_variable(uni
);
97 *rvalue
= new(mem_ctx
) ir_dereference_array(varref
, dra
->array_index
);
102 } /* anonymous namespace */
105 lower_const_arrays_to_uniforms(exec_list
*instructions
)
107 lower_const_array_visitor
v(instructions
);