1f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/* 2f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Copyright 2009 Nicolai Hähnle <nhaehnle@gmail.com> 3f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * 4f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Permission is hereby granted, free of charge, to any person obtaining a 5f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * copy of this software and associated documentation files (the "Software"), 6f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * to deal in the Software without restriction, including without limitation 7f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * on the rights to use, copy, modify, merge, publish, distribute, sub 8f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * license, and/or sell copies of the Software, and to permit persons to whom 9f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * the Software is furnished to do so, subject to the following conditions: 10f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * 11f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * The above copyright notice and this permission notice (including the next 12f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * paragraph) shall be included in all copies or substantial portions of the 13f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Software. 14f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * 15f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL 18f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * THE AUTHOR(S) AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM, 19f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR 20f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE 21f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * USE OR OTHER DEALINGS IN THE SOFTWARE. */ 22f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 23f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "radeon_compiler.h" 24f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 25f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include <stdarg.h> 26f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include <stdio.h> 27f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include <stdlib.h> 28f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 29f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "radeon_dataflow.h" 30f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "radeon_program.h" 31f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "radeon_program_pair.h" 32f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "radeon_compiler_util.h" 33f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 34f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 35f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgvoid rc_init(struct radeon_compiler * c) 36f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 37f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org memset(c, 0, sizeof(*c)); 38f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 39f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org memory_pool_init(&c->Pool); 40f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org c->Program.Instructions.Prev = &c->Program.Instructions; 41f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org c->Program.Instructions.Next = &c->Program.Instructions; 42f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org c->Program.Instructions.U.I.Opcode = RC_OPCODE_ILLEGAL_OPCODE; 43f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 44f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 45f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgvoid rc_destroy(struct radeon_compiler * c) 46f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 47f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org rc_constants_destroy(&c->Program.Constants); 48f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org memory_pool_destroy(&c->Pool); 49f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org free(c->ErrorMsg); 50f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 51f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 52f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgvoid rc_debug(struct radeon_compiler * c, const char * fmt, ...) 53f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 54f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org va_list ap; 55f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 56f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (!(c->Debug & RC_DBG_LOG)) 57f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return; 58f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 59f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org va_start(ap, fmt); 60f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org vfprintf(stderr, fmt, ap); 61f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org va_end(ap); 62f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 63f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 64f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgvoid rc_error(struct radeon_compiler * c, const char * fmt, ...) 65f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 66f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org va_list ap; 67f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 68f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org c->Error = 1; 69f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 70f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (!c->ErrorMsg) { 71f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* Only remember the first error */ 72f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org char buf[1024]; 73f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org int written; 74f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 75f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org va_start(ap, fmt); 76f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org written = vsnprintf(buf, sizeof(buf), fmt, ap); 77f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org va_end(ap); 78f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 79f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (written < sizeof(buf)) { 80f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org c->ErrorMsg = strdup(buf); 81f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } else { 82f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org c->ErrorMsg = malloc(written + 1); 83f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 84f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org va_start(ap, fmt); 85f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org vsnprintf(c->ErrorMsg, written + 1, fmt, ap); 86f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org va_end(ap); 87f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 88f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 89f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 90f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (c->Debug & RC_DBG_LOG) { 91f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org fprintf(stderr, "r300compiler error: "); 92f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 93f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org va_start(ap, fmt); 94f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org vfprintf(stderr, fmt, ap); 95f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org va_end(ap); 96f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 97f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 98f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 99f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgint rc_if_fail_helper(struct radeon_compiler * c, const char * file, int line, const char * assertion) 100f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 101f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org rc_error(c, "ICE at %s:%i: assertion failed: %s\n", file, line, assertion); 102f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return 1; 103f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 104f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 105f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/** 106f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Recompute c->Program.InputsRead and c->Program.OutputsWritten 107f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * based on which inputs and outputs are actually referenced 108f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * in program instructions. 109f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */ 110f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgvoid rc_calculate_inputs_outputs(struct radeon_compiler * c) 111f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 112f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct rc_instruction *inst; 113f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 114f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org c->Program.InputsRead = 0; 115f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org c->Program.OutputsWritten = 0; 116f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 117f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org for(inst = c->Program.Instructions.Next; inst != &c->Program.Instructions; inst = inst->Next) 118f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org { 119f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org const struct rc_opcode_info * opcode = rc_get_opcode_info(inst->U.I.Opcode); 120f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org int i; 121f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 122f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org for (i = 0; i < opcode->NumSrcRegs; ++i) { 123f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (inst->U.I.SrcReg[i].File == RC_FILE_INPUT) 124f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org c->Program.InputsRead |= 1 << inst->U.I.SrcReg[i].Index; 125f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 126f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 127f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (opcode->HasDstReg) { 128f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (inst->U.I.DstReg.File == RC_FILE_OUTPUT) 129f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org c->Program.OutputsWritten |= 1 << inst->U.I.DstReg.Index; 130f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 131f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 132f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 133f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 134f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/** 135f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Rewrite the program such that everything that source the given input 136f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * register will source new_input instead. 137f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */ 138f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgvoid rc_move_input(struct radeon_compiler * c, unsigned input, struct rc_src_register new_input) 139f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 140f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct rc_instruction * inst; 141f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 142f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org c->Program.InputsRead &= ~(1 << input); 143f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 144f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org for(inst = c->Program.Instructions.Next; inst != &c->Program.Instructions; inst = inst->Next) { 145f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org const struct rc_opcode_info * opcode = rc_get_opcode_info(inst->U.I.Opcode); 146f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org unsigned i; 147f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 148f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org for(i = 0; i < opcode->NumSrcRegs; ++i) { 149f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (inst->U.I.SrcReg[i].File == RC_FILE_INPUT && inst->U.I.SrcReg[i].Index == input) { 150f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org inst->U.I.SrcReg[i].File = new_input.File; 151f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org inst->U.I.SrcReg[i].Index = new_input.Index; 152f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org inst->U.I.SrcReg[i].Swizzle = combine_swizzles(new_input.Swizzle, inst->U.I.SrcReg[i].Swizzle); 153f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (!inst->U.I.SrcReg[i].Abs) { 154f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org inst->U.I.SrcReg[i].Negate ^= new_input.Negate; 155f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org inst->U.I.SrcReg[i].Abs = new_input.Abs; 156f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 157f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 158f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org c->Program.InputsRead |= 1 << new_input.Index; 159f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 160f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 161f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 162f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 163f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 164f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 165f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/** 166f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Rewrite the program such that everything that writes into the given 167f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * output register will instead write to new_output. The new_output 168f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * writemask is honoured. 169f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */ 170f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgvoid rc_move_output(struct radeon_compiler * c, unsigned output, unsigned new_output, unsigned writemask) 171f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 172f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct rc_instruction * inst; 173f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 174f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org c->Program.OutputsWritten &= ~(1 << output); 175f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 176f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org for(inst = c->Program.Instructions.Next; inst != &c->Program.Instructions; inst = inst->Next) { 177f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org const struct rc_opcode_info * opcode = rc_get_opcode_info(inst->U.I.Opcode); 178f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 179f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (opcode->HasDstReg) { 180f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (inst->U.I.DstReg.File == RC_FILE_OUTPUT && inst->U.I.DstReg.Index == output) { 181f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org inst->U.I.DstReg.Index = new_output; 182f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org inst->U.I.DstReg.WriteMask &= writemask; 183f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 184f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org c->Program.OutputsWritten |= 1 << new_output; 185f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 186f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 187f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 188f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 189f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 190f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 191f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/** 192f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Rewrite the program such that a given output is duplicated. 193f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */ 194f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgvoid rc_copy_output(struct radeon_compiler * c, unsigned output, unsigned dup_output) 195f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 196f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org unsigned tempreg = rc_find_free_temporary(c); 197f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct rc_instruction * inst; 198f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 199f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org for(inst = c->Program.Instructions.Next; inst != &c->Program.Instructions; inst = inst->Next) { 200f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org const struct rc_opcode_info * opcode = rc_get_opcode_info(inst->U.I.Opcode); 201f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 202f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (opcode->HasDstReg) { 203f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (inst->U.I.DstReg.File == RC_FILE_OUTPUT && inst->U.I.DstReg.Index == output) { 204f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org inst->U.I.DstReg.File = RC_FILE_TEMPORARY; 205f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org inst->U.I.DstReg.Index = tempreg; 206f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 207f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 208f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 209f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 210f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org inst = rc_insert_new_instruction(c, c->Program.Instructions.Prev); 211f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org inst->U.I.Opcode = RC_OPCODE_MOV; 212f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org inst->U.I.DstReg.File = RC_FILE_OUTPUT; 213f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org inst->U.I.DstReg.Index = output; 214f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 215f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org inst->U.I.SrcReg[0].File = RC_FILE_TEMPORARY; 216f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org inst->U.I.SrcReg[0].Index = tempreg; 217f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org inst->U.I.SrcReg[0].Swizzle = RC_SWIZZLE_XYZW; 218f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 219f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org inst = rc_insert_new_instruction(c, c->Program.Instructions.Prev); 220f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org inst->U.I.Opcode = RC_OPCODE_MOV; 221f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org inst->U.I.DstReg.File = RC_FILE_OUTPUT; 222f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org inst->U.I.DstReg.Index = dup_output; 223f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 224f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org inst->U.I.SrcReg[0].File = RC_FILE_TEMPORARY; 225f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org inst->U.I.SrcReg[0].Index = tempreg; 226f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org inst->U.I.SrcReg[0].Swizzle = RC_SWIZZLE_XYZW; 227f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 228f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org c->Program.OutputsWritten |= 1 << dup_output; 229f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 230f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 231f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 232f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/** 233f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Introduce standard code fragment to deal with fragment.position. 234f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */ 235f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgvoid rc_transform_fragment_wpos(struct radeon_compiler * c, unsigned wpos, unsigned new_input, 236f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org int full_vtransform) 237f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 238f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org unsigned tempregi = rc_find_free_temporary(c); 239f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct rc_instruction * inst_rcp; 240f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct rc_instruction * inst_mul; 241f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct rc_instruction * inst_mad; 242f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct rc_instruction * inst; 243f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 244f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org c->Program.InputsRead &= ~(1 << wpos); 245f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org c->Program.InputsRead |= 1 << new_input; 246f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 247f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* perspective divide */ 248f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org inst_rcp = rc_insert_new_instruction(c, &c->Program.Instructions); 249f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org inst_rcp->U.I.Opcode = RC_OPCODE_RCP; 250f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 251f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org inst_rcp->U.I.DstReg.File = RC_FILE_TEMPORARY; 252f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org inst_rcp->U.I.DstReg.Index = tempregi; 253f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org inst_rcp->U.I.DstReg.WriteMask = RC_MASK_W; 254f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 255f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org inst_rcp->U.I.SrcReg[0].File = RC_FILE_INPUT; 256f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org inst_rcp->U.I.SrcReg[0].Index = new_input; 257f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org inst_rcp->U.I.SrcReg[0].Swizzle = RC_SWIZZLE_WWWW; 258f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 259f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org inst_mul = rc_insert_new_instruction(c, inst_rcp); 260f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org inst_mul->U.I.Opcode = RC_OPCODE_MUL; 261f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 262f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org inst_mul->U.I.DstReg.File = RC_FILE_TEMPORARY; 263f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org inst_mul->U.I.DstReg.Index = tempregi; 264f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org inst_mul->U.I.DstReg.WriteMask = RC_MASK_XYZ; 265f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 266f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org inst_mul->U.I.SrcReg[0].File = RC_FILE_INPUT; 267f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org inst_mul->U.I.SrcReg[0].Index = new_input; 268f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 269f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org inst_mul->U.I.SrcReg[1].File = RC_FILE_TEMPORARY; 270f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org inst_mul->U.I.SrcReg[1].Index = tempregi; 271f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org inst_mul->U.I.SrcReg[1].Swizzle = RC_SWIZZLE_WWWW; 272f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 273f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* viewport transformation */ 274f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org inst_mad = rc_insert_new_instruction(c, inst_mul); 275f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org inst_mad->U.I.Opcode = RC_OPCODE_MAD; 276f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 277f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org inst_mad->U.I.DstReg.File = RC_FILE_TEMPORARY; 278f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org inst_mad->U.I.DstReg.Index = tempregi; 279f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org inst_mad->U.I.DstReg.WriteMask = RC_MASK_XYZ; 280f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 281f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org inst_mad->U.I.SrcReg[0].File = RC_FILE_TEMPORARY; 282f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org inst_mad->U.I.SrcReg[0].Index = tempregi; 283f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org inst_mad->U.I.SrcReg[0].Swizzle = RC_SWIZZLE_XYZ0; 284f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 285f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org inst_mad->U.I.SrcReg[1].File = RC_FILE_CONSTANT; 286f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org inst_mad->U.I.SrcReg[1].Swizzle = RC_SWIZZLE_XYZ0; 287f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 288f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org inst_mad->U.I.SrcReg[2].File = RC_FILE_CONSTANT; 289f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org inst_mad->U.I.SrcReg[2].Swizzle = RC_SWIZZLE_XYZ0; 290f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 291f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (full_vtransform) { 292f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org inst_mad->U.I.SrcReg[1].Index = rc_constants_add_state(&c->Program.Constants, RC_STATE_R300_VIEWPORT_SCALE, 0); 293f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org inst_mad->U.I.SrcReg[2].Index = rc_constants_add_state(&c->Program.Constants, RC_STATE_R300_VIEWPORT_OFFSET, 0); 294f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } else { 295f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org inst_mad->U.I.SrcReg[1].Index = 296f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org inst_mad->U.I.SrcReg[2].Index = rc_constants_add_state(&c->Program.Constants, RC_STATE_R300_WINDOW_DIMENSION, 0); 297f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 298f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 299f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org for (inst = inst_mad->Next; inst != &c->Program.Instructions; inst = inst->Next) { 300f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org const struct rc_opcode_info * opcode = rc_get_opcode_info(inst->U.I.Opcode); 301f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org unsigned i; 302f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 303f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org for(i = 0; i < opcode->NumSrcRegs; i++) { 304f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (inst->U.I.SrcReg[i].File == RC_FILE_INPUT && 305f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org inst->U.I.SrcReg[i].Index == wpos) { 306f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org inst->U.I.SrcReg[i].File = RC_FILE_TEMPORARY; 307f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org inst->U.I.SrcReg[i].Index = tempregi; 308f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 309f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 310f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 311f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 312f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 313f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 314f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/** 315f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * The FACE input in hardware contains 1 if it's a back face, 0 otherwise. 316f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Gallium and OpenGL define it the other way around. 317f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * 318f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * So let's just negate FACE at the beginning of the shader and rewrite the rest 319f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * of the shader to read from the newly allocated temporary. 320f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */ 321f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgvoid rc_transform_fragment_face(struct radeon_compiler *c, unsigned face) 322f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 323f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org unsigned tempregi = rc_find_free_temporary(c); 324f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct rc_instruction *inst_add; 325f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct rc_instruction *inst; 326f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 327f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* perspective divide */ 328f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org inst_add = rc_insert_new_instruction(c, &c->Program.Instructions); 329f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org inst_add->U.I.Opcode = RC_OPCODE_ADD; 330f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 331f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org inst_add->U.I.DstReg.File = RC_FILE_TEMPORARY; 332f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org inst_add->U.I.DstReg.Index = tempregi; 333f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org inst_add->U.I.DstReg.WriteMask = RC_MASK_X; 334f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 335f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org inst_add->U.I.SrcReg[0].File = RC_FILE_NONE; 336f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org inst_add->U.I.SrcReg[0].Swizzle = RC_SWIZZLE_1111; 337f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 338f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org inst_add->U.I.SrcReg[1].File = RC_FILE_INPUT; 339f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org inst_add->U.I.SrcReg[1].Index = face; 340f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org inst_add->U.I.SrcReg[1].Swizzle = RC_SWIZZLE_XXXX; 341f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org inst_add->U.I.SrcReg[1].Negate = RC_MASK_XYZW; 342f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 343f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org for (inst = inst_add->Next; inst != &c->Program.Instructions; inst = inst->Next) { 344f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org const struct rc_opcode_info * opcode = rc_get_opcode_info(inst->U.I.Opcode); 345f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org unsigned i; 346f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 347f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org for(i = 0; i < opcode->NumSrcRegs; i++) { 348f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (inst->U.I.SrcReg[i].File == RC_FILE_INPUT && 349f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org inst->U.I.SrcReg[i].Index == face) { 350f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org inst->U.I.SrcReg[i].File = RC_FILE_TEMPORARY; 351f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org inst->U.I.SrcReg[i].Index = tempregi; 352f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 353f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 354f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 355f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 356f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 357f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic void reg_count_callback(void * userdata, struct rc_instruction * inst, 358f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org rc_register_file file, unsigned int index, unsigned int mask) 359f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 360f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct rc_program_stats *s = userdata; 361f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (file == RC_FILE_TEMPORARY) 362f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org (int)index > s->num_temp_regs ? s->num_temp_regs = index : 0; 363f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (file == RC_FILE_INLINE) 364f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org s->num_inline_literals++; 365f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 366f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 367f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgvoid rc_get_stats(struct radeon_compiler *c, struct rc_program_stats *s) 368f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 369f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct rc_instruction * tmp; 370f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org memset(s, 0, sizeof(*s)); 371f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 372f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org for(tmp = c->Program.Instructions.Next; tmp != &c->Program.Instructions; 373f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org tmp = tmp->Next){ 374f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org const struct rc_opcode_info * info; 375f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org rc_for_all_reads_mask(tmp, reg_count_callback, s); 376f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (tmp->Type == RC_INSTRUCTION_NORMAL) { 377f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org info = rc_get_opcode_info(tmp->U.I.Opcode); 378f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (info->Opcode == RC_OPCODE_BEGIN_TEX) 379f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org continue; 380f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (tmp->U.I.PreSub.Opcode != RC_PRESUB_NONE) 381f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org s->num_presub_ops++; 382f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } else { 383f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (tmp->U.P.RGB.Src[RC_PAIR_PRESUB_SRC].Used) 384f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org s->num_presub_ops++; 385f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (tmp->U.P.Alpha.Src[RC_PAIR_PRESUB_SRC].Used) 386f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org s->num_presub_ops++; 387f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* Assuming alpha will never be a flow control or 388f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * a tex instruction. */ 389f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (tmp->U.P.Alpha.Opcode != RC_OPCODE_NOP) 390f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org s->num_alpha_insts++; 391f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (tmp->U.P.RGB.Opcode != RC_OPCODE_NOP) 392f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org s->num_rgb_insts++; 393f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (tmp->U.P.RGB.Omod != RC_OMOD_MUL_1 && 394f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org tmp->U.P.RGB.Omod != RC_OMOD_DISABLE) { 395f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org s->num_omod_ops++; 396f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 397f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (tmp->U.P.Alpha.Omod != RC_OMOD_MUL_1 && 398f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org tmp->U.P.Alpha.Omod != RC_OMOD_DISABLE) { 399f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org s->num_omod_ops++; 400f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 401f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org info = rc_get_opcode_info(tmp->U.P.RGB.Opcode); 402f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 403f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (info->IsFlowControl) 404f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org s->num_fc_insts++; 405f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (info->HasTexture) 406f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org s->num_tex_insts++; 407f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org s->num_insts++; 408f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 409f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* Increment here because the reg_count_callback store the max 410f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * temporary reg index in s->nun_temp_regs. */ 411f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org s->num_temp_regs++; 412f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 413f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 414f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic void print_stats(struct radeon_compiler * c) 415f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 416f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct rc_program_stats s; 417f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 418f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (c->initial_num_insts <= 5) 419f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return; 420f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 421f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org rc_get_stats(c, &s); 422f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 423f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org switch (c->type) { 424f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case RC_VERTEX_PROGRAM: 425f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org fprintf(stderr,"~~~~~~~~~ VERTEX PROGRAM ~~~~~~~~\n" 426f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org "~%4u Instructions\n" 427f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org "~%4u Flow Control Instructions\n" 428f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org "~%4u Temporary Registers\n" 429f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org "~~~~~~~~~~~~~~ END ~~~~~~~~~~~~~~\n", 430f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org s.num_insts, s.num_fc_insts, s.num_temp_regs); 431f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org break; 432f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 433f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org case RC_FRAGMENT_PROGRAM: 434f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org fprintf(stderr,"~~~~~~~~ FRAGMENT PROGRAM ~~~~~~~\n" 435f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org "~%4u Instructions\n" 436f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org "~%4u Vector Instructions (RGB)\n" 437f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org "~%4u Scalar Instructions (Alpha)\n" 438f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org "~%4u Flow Control Instructions\n" 439f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org "~%4u Texture Instructions\n" 440f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org "~%4u Presub Operations\n" 441f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org "~%4u OMOD Operations\n" 442f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org "~%4u Temporary Registers\n" 443f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org "~%4u Inline Literals\n" 444f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org "~~~~~~~~~~~~~~ END ~~~~~~~~~~~~~~\n", 445f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org s.num_insts, s.num_rgb_insts, s.num_alpha_insts, 446f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org s.num_fc_insts, s.num_tex_insts, s.num_presub_ops, 447f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org s.num_omod_ops, s.num_temp_regs, s.num_inline_literals); 448f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org break; 449f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org default: 450f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org assert(0); 451f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 452f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 453f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 454f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic const char *shader_name[RC_NUM_PROGRAM_TYPES] = { 455f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org "Vertex Program", 456f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org "Fragment Program" 457f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}; 458f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 459f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgvoid rc_run_compiler_passes(struct radeon_compiler *c, struct radeon_compiler_pass *list) 460f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 461f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org for (unsigned i = 0; list[i].name; i++) { 462f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (list[i].predicate) { 463f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org list[i].run(c, list[i].user); 464f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 465f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (c->Error) 466f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return; 467f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 468f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if ((c->Debug & RC_DBG_LOG) && list[i].dump) { 469f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org fprintf(stderr, "%s: after '%s'\n", shader_name[c->type], list[i].name); 470f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org rc_print_program(&c->Program); 471f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 472f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 473f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 474f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 475f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 476f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/* Executes a list of compiler passes given in the parameter 'list'. */ 477f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgvoid rc_run_compiler(struct radeon_compiler *c, struct radeon_compiler_pass *list) 478f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 479f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct rc_program_stats s; 480f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 481f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org rc_get_stats(c, &s); 482f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org c->initial_num_insts = s.num_insts; 483f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 484f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (c->Debug & RC_DBG_LOG) { 485f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org fprintf(stderr, "%s: before compilation\n", shader_name[c->type]); 486f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org rc_print_program(&c->Program); 487f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 488f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 489f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org rc_run_compiler_passes(c, list); 490f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 491f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (c->Debug & RC_DBG_STATS) 492f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org print_stats(c); 493f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 494f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 495f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgvoid rc_validate_final_shader(struct radeon_compiler *c, void *user) 496f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 497f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* Check the number of constants. */ 498f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (c->Program.Constants.Count > c->max_constants) { 499f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org rc_error(c, "Too many constants. Max: %i, Got: %i\n", 500f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org c->max_constants, c->Program.Constants.Count); 501f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 502f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 503