summaryrefslogtreecommitdiff
path: root/lib/mesa/src/broadcom/compiler/vir_lower_uniforms.c
diff options
context:
space:
mode:
Diffstat (limited to 'lib/mesa/src/broadcom/compiler/vir_lower_uniforms.c')
-rw-r--r--lib/mesa/src/broadcom/compiler/vir_lower_uniforms.c209
1 files changed, 0 insertions, 209 deletions
diff --git a/lib/mesa/src/broadcom/compiler/vir_lower_uniforms.c b/lib/mesa/src/broadcom/compiler/vir_lower_uniforms.c
deleted file mode 100644
index 7f3bb8460..000000000
--- a/lib/mesa/src/broadcom/compiler/vir_lower_uniforms.c
+++ /dev/null
@@ -1,209 +0,0 @@
-/*
- * Copyright © 2014 Broadcom
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice (including the next
- * paragraph) shall be included in all copies or substantial portions of the
- * Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
- * IN THE SOFTWARE.
- */
-
-/**
- * @file v3d_vir_lower_uniforms.c
- *
- * This is the pre-code-generation pass for fixing up instructions that try to
- * read from multiple uniform values.
- */
-
-#include "v3d_compiler.h"
-#include "util/hash_table.h"
-#include "util/u_math.h"
-
-static inline uint32_t
-index_hash(const void *key)
-{
- return (uintptr_t)key;
-}
-
-static inline bool
-index_compare(const void *a, const void *b)
-{
- return a == b;
-}
-
-static void
-add_uniform(struct hash_table *ht, struct qreg reg)
-{
- struct hash_entry *entry;
- void *key = (void *)(uintptr_t)(reg.index + 1);
-
- entry = _mesa_hash_table_search(ht, key);
- if (entry) {
- entry->data++;
- } else {
- _mesa_hash_table_insert(ht, key, (void *)(uintptr_t)1);
- }
-}
-
-static void
-remove_uniform(struct hash_table *ht, struct qreg reg)
-{
- struct hash_entry *entry;
- void *key = (void *)(uintptr_t)(reg.index + 1);
-
- entry = _mesa_hash_table_search(ht, key);
- assert(entry);
- entry->data = (void *)(((uintptr_t) entry->data) - 1);
- if (entry->data == NULL)
- _mesa_hash_table_remove(ht, entry);
-}
-
-static bool
-is_lowerable_uniform(struct qinst *inst, int i)
-{
- if (inst->src[i].file != QFILE_UNIF)
- return false;
- if (vir_has_implicit_uniform(inst))
- return i != vir_get_implicit_uniform_src(inst);
- return true;
-}
-
-/* Returns the number of different uniform values referenced by the
- * instruction.
- */
-static uint32_t
-vir_get_instruction_uniform_count(struct qinst *inst)
-{
- uint32_t count = 0;
-
- for (int i = 0; i < vir_get_nsrc(inst); i++) {
- if (inst->src[i].file != QFILE_UNIF)
- continue;
-
- bool is_duplicate = false;
- for (int j = 0; j < i; j++) {
- if (inst->src[j].file == QFILE_UNIF &&
- inst->src[j].index == inst->src[i].index) {
- is_duplicate = true;
- break;
- }
- }
- if (!is_duplicate)
- count++;
- }
-
- return count;
-}
-
-void
-vir_lower_uniforms(struct v3d_compile *c)
-{
- struct hash_table *ht =
- _mesa_hash_table_create(c, index_hash, index_compare);
-
- /* Walk the instruction list, finding which instructions have more
- * than one uniform referenced, and add those uniform values to the
- * ht.
- */
- vir_for_each_inst_inorder(inst, c) {
- uint32_t nsrc = vir_get_nsrc(inst);
-
- if (vir_get_instruction_uniform_count(inst) <= 1)
- continue;
-
- for (int i = 0; i < nsrc; i++) {
- if (is_lowerable_uniform(inst, i))
- add_uniform(ht, inst->src[i]);
- }
- }
-
- while (ht->entries) {
- /* Find the most commonly used uniform in instructions that
- * need a uniform lowered.
- */
- uint32_t max_count = 0;
- uint32_t max_index = 0;
- struct hash_entry *entry;
- hash_table_foreach(ht, entry) {
- uint32_t count = (uintptr_t)entry->data;
- uint32_t index = (uintptr_t)entry->key - 1;
- if (count > max_count) {
- max_count = count;
- max_index = index;
- }
- }
-
- struct qreg unif = vir_reg(QFILE_UNIF, max_index);
-
- /* Now, find the instructions using this uniform and make them
- * reference a temp instead.
- */
- vir_for_each_block(block, c) {
- struct qinst *mov = NULL;
-
- vir_for_each_inst(inst, block) {
- uint32_t nsrc = vir_get_nsrc(inst);
-
- uint32_t count = vir_get_instruction_uniform_count(inst);
-
- if (count <= 1)
- continue;
-
- /* If the block doesn't have a load of the
- * uniform yet, add it. We could potentially
- * do better and CSE MOVs from multiple blocks
- * into dominating blocks, except that may
- * cause troubles for register allocation.
- */
- if (!mov) {
- mov = vir_mul_inst(V3D_QPU_M_MOV,
- vir_get_temp(c),
- unif, c->undef);
- list_add(&mov->link,
- &block->instructions);
- c->defs[mov->dst.index] = mov;
- }
-
- bool removed = false;
- for (int i = 0; i < nsrc; i++) {
- if (is_lowerable_uniform(inst, i) &&
- inst->src[i].index == max_index) {
- inst->src[i].file =
- mov->dst.file;
- inst->src[i].index =
- mov->dst.index;
- remove_uniform(ht, unif);
- removed = true;
- }
- }
- if (removed)
- count--;
-
- /* If the instruction doesn't need lowering any more,
- * then drop it from the list.
- */
- if (count <= 1) {
- for (int i = 0; i < nsrc; i++) {
- if (is_lowerable_uniform(inst, i))
- remove_uniform(ht, inst->src[i]);
- }
- }
- }
- }
- }
-
- _mesa_hash_table_destroy(ht, NULL);
-}