summaryrefslogtreecommitdiffstats
path: root/src/mesa/state_tracker
diff options
context:
space:
mode:
authorGert Wollny <[email protected]>2017-06-30 08:55:17 +0200
committerNicolai Hähnle <[email protected]>2017-09-06 11:49:52 +0200
commit09ffe274b050c3433996c0ee2f773e9d107a3fa6 (patch)
treef7dc2fddd34d6790138837461a3916bc242e57a4 /src/mesa/state_tracker
parent33b7728bf9582ec6912ab8d29c590de27595b851 (diff)
mesa/st: glsl_to_tgsi: tie in new temporary register merge approach
This patch replaces the old register lifetime estiamtion and rename mapping evaluation with the new one. Performance to compare between the current and the new implementation were measured by running the shader-db in one thread. ----------------------------------------------------------- old new(std::sort) ---------------- time ./run -j1 shaders -------------------- real 5.80s 5.75s user 5.75s 5.70s sys 0.05s 0.05s ---- valgrind --tool=callgrind --dump-instr=yes------------ merge 0.08% 0.18% estimate lifetime 0.02% 0.11% evaluate mapping (incl=0.3%) 0.04% apply mapping 0.03% 0.02% --- perf (approximate because of statistic sampling) ---- merge (total) 0.09% 0.16% estimate lifetime 0.03% 0.10% evaluate mapping (incl=0.02%) 0.04% apply mapping 0.04% 0.04% Reviewed-by: Nicolai Hähnle <[email protected]>
Diffstat (limited to 'src/mesa/state_tracker')
-rw-r--r--src/mesa/state_tracker/st_glsl_to_tgsi.cpp66
1 files changed, 16 insertions, 50 deletions
diff --git a/src/mesa/state_tracker/st_glsl_to_tgsi.cpp b/src/mesa/state_tracker/st_glsl_to_tgsi.cpp
index 7ccb6e25d68..026aea5d53d 100644
--- a/src/mesa/state_tracker/st_glsl_to_tgsi.cpp
+++ b/src/mesa/state_tracker/st_glsl_to_tgsi.cpp
@@ -55,7 +55,7 @@
#include "st_format.h"
#include "st_nir.h"
#include "st_shader_cache.h"
-#include "st_glsl_to_tgsi_private.h"
+#include "st_glsl_to_tgsi_temprename.h"
#include "util/hash_table.h"
#include <algorithm>
@@ -574,7 +574,7 @@ glsl_to_tgsi_visitor::emit_asm(ir_instruction *ir, unsigned op,
if (swz > 1) {
dinst->src[j].double_reg2 = true;
dinst->src[j].index++;
- }
+ }
if (swz & 1)
dinst->src[j].swizzle = MAKE_SWIZZLE4(SWIZZLE_Z, SWIZZLE_W, SWIZZLE_Z, SWIZZLE_W);
@@ -2066,7 +2066,7 @@ glsl_to_tgsi_visitor::visit_expression(ir_expression* ir, st_src_reg *op)
st_src_reg temp = get_temp(glsl_type::uvec4_type);
st_dst_reg temp_dst = st_dst_reg(temp);
unsigned orig_swz = op[0].swizzle;
- /*
+ /*
* To convert unsigned to 64-bit:
* zero Y channel, copy X channel.
*/
@@ -2554,8 +2554,8 @@ glsl_to_tgsi_visitor::visit(ir_dereference_array *ir)
if (index) {
if (this->prog->Target == GL_VERTEX_PROGRAM_ARB &&
- src.file == PROGRAM_INPUT)
- element_size = attrib_type_size(ir->type, true);
+ src.file == PROGRAM_INPUT)
+ element_size = attrib_type_size(ir->type, true);
if (is_2D) {
src.index2D = index->value.i[0];
src.has_index2 = true;
@@ -2841,7 +2841,7 @@ glsl_to_tgsi_visitor::emit_block_mov(ir_assignment *ir, const struct glsl_type *
if (type->is_dual_slot()) {
l->index++;
if (r->is_double_vertex_input == false)
- r->index++;
+ r->index++;
}
}
@@ -5136,54 +5136,20 @@ glsl_to_tgsi_visitor::merge_two_dsts(void)
void
glsl_to_tgsi_visitor::merge_registers(void)
{
- int *last_reads = ralloc_array(mem_ctx, int, this->next_temp);
- int *first_writes = ralloc_array(mem_ctx, int, this->next_temp);
- struct rename_reg_pair *renames = rzalloc_array(mem_ctx, struct rename_reg_pair, this->next_temp);
- int i, j;
- /* Read the indices of the last read and first write to each temp register
- * into an array so that we don't have to traverse the instruction list as
- * much. */
- for (i = 0; i < this->next_temp; i++) {
- last_reads[i] = -1;
- first_writes[i] = -1;
- }
- get_last_temp_read_first_temp_write(last_reads, first_writes);
+ struct lifetime *lifetimes =
+ rzalloc_array(mem_ctx, struct lifetime, this->next_temp);
- /* Start looking for registers with non-overlapping usages that can be
- * merged together. */
- for (i = 0; i < this->next_temp; i++) {
- /* Don't touch unused registers. */
- if (last_reads[i] < 0 || first_writes[i] < 0) continue;
-
- for (j = 0; j < this->next_temp; j++) {
- /* Don't touch unused registers. */
- if (last_reads[j] < 0 || first_writes[j] < 0) continue;
-
- /* We can merge the two registers if the first write to j is after or
- * in the same instruction as the last read from i. Note that the
- * register at index i will always be used earlier or at the same time
- * as the register at index j. */
- if (first_writes[i] <= first_writes[j] &&
- last_reads[i] <= first_writes[j]) {
- renames[j].new_reg = i;
- renames[j].valid = true;
-
- /* Update the first_writes and last_reads arrays with the new
- * values for the merged register index, and mark the newly unused
- * register index as such. */
- assert(last_reads[j] >= last_reads[i]);
- last_reads[i] = last_reads[j];
- first_writes[j] = -1;
- last_reads[j] = -1;
- }
- }
+ if (get_temp_registers_required_lifetimes(mem_ctx, &this->instructions,
+ this->next_temp, lifetimes)) {
+ struct rename_reg_pair *renames =
+ rzalloc_array(mem_ctx, struct rename_reg_pair, this->next_temp);
+ get_temp_registers_remapping(mem_ctx, this->next_temp, lifetimes, renames);
+ rename_temp_registers(renames);
+ ralloc_free(renames);
}
- rename_temp_registers(renames);
- ralloc_free(renames);
- ralloc_free(last_reads);
- ralloc_free(first_writes);
+ ralloc_free(lifetimes);
}
/* Reassign indices to temporary registers by reusing unused indices created