11c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák/* 21c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák * Copyright (C) 2005 Ben Skeggs. 31c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák * 41c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák * All Rights Reserved. 51c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák * 61c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák * Permission is hereby granted, free of charge, to any person obtaining 71c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák * a copy of this software and associated documentation files (the 81c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák * "Software"), to deal in the Software without restriction, including 91c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák * without limitation the rights to use, copy, modify, merge, publish, 101c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák * distribute, sublicense, and/or sell copies of the Software, and to 111c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák * permit persons to whom the Software is furnished to do so, subject to 121c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák * the following conditions: 131c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák * 141c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák * The above copyright notice and this permission notice (including the 151c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák * next paragraph) shall be included in all copies or substantial 161c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák * portions of the Software. 171c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák * 181c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 191c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 201c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 211c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák * IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE 221c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 231c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 241c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 251c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák * 261c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák */ 271c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák 281c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák/** 291c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák * \file 301c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák * 311c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák * Emit the r300_fragment_program_code that can be understood by the hardware. 321c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák * Input is a pre-transformed radeon_program. 331c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák * 341c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák * \author Ben Skeggs <darktama@iinet.net.au> 351c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák * 361c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák * \author Jerome Glisse <j.glisse@gmail.com> 371c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák */ 381c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák 391c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák#include "r300_fragprog.h" 401c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák 411c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák#include "../r300_reg.h" 421c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák 431c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák#include "radeon_program_pair.h" 441c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák#include "r300_fragprog_swizzle.h" 451c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák 461c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák 471c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšákstruct r300_emit_state { 481c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák struct r300_fragment_program_compiler * compiler; 491c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák 501c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák unsigned current_node : 2; 511c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák unsigned node_first_tex : 8; 521c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák unsigned node_first_alu : 8; 531c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák uint32_t node_flags; 541c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák}; 551c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák 561c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák#define PROG_CODE \ 571c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák struct r300_fragment_program_compiler *c = emit->compiler; \ 581c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák struct r300_fragment_program_code *code = &c->code->code.r300 591c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák 601c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák#define error(fmt, args...) do { \ 611c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák rc_error(&c->Base, "%s::%s(): " fmt "\n", \ 621c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák __FILE__, __FUNCTION__, ##args); \ 631c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák } while(0) 641c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák 651c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšákstatic unsigned int get_msbs_alu(unsigned int bits) 661c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák{ 671c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák return (bits >> 6) & 0x7; 681c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák} 691c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák 701c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák/** 711c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák * @param lsbs The number of least significant bits 721c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák */ 731c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšákstatic unsigned int get_msbs_tex(unsigned int bits, unsigned int lsbs) 741c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák{ 751c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák return (bits >> lsbs) & 0x15; 761c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák} 771c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák 781c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák#define R400_EXT_GET_MSBS(x, lsbs, mask) (((x) >> lsbs) & mask) 791c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák 801c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák/** 811c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák * Mark a temporary register as used. 821c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák */ 831c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšákstatic void use_temporary(struct r300_fragment_program_code *code, unsigned int index) 841c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák{ 851c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák if (index > code->pixsize) 861c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák code->pixsize = index; 871c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák} 881c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák 891c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšákstatic unsigned int use_source(struct r300_fragment_program_code* code, struct rc_pair_instruction_source src) 901c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák{ 911c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák if (!src.Used) 921c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák return 0; 931c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák 941c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák if (src.File == RC_FILE_CONSTANT) { 951c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák return src.Index | (1 << 5); 961c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák } else if (src.File == RC_FILE_TEMPORARY || src.File == RC_FILE_INPUT) { 971c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák use_temporary(code, src.Index); 981c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák return src.Index & 0x1f; 991c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák } 1001c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák 1011c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák return 0; 1021c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák} 1031c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák 1041c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák 1051c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšákstatic unsigned int translate_rgb_opcode(struct r300_fragment_program_compiler * c, rc_opcode opcode) 1061c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák{ 1071c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák switch(opcode) { 1081c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák case RC_OPCODE_CMP: return R300_ALU_OUTC_CMP; 1091c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák case RC_OPCODE_CND: return R300_ALU_OUTC_CND; 1101c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák case RC_OPCODE_DP3: return R300_ALU_OUTC_DP3; 1111c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák case RC_OPCODE_DP4: return R300_ALU_OUTC_DP4; 1121c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák case RC_OPCODE_FRC: return R300_ALU_OUTC_FRC; 1131c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák default: 1141c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák error("translate_rgb_opcode: Unknown opcode %s", rc_get_opcode_info(opcode)->Name); 1151c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák /* fall through */ 1161c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák case RC_OPCODE_NOP: 1171c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák /* fall through */ 1181c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák case RC_OPCODE_MAD: return R300_ALU_OUTC_MAD; 1191c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák case RC_OPCODE_MAX: return R300_ALU_OUTC_MAX; 1201c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák case RC_OPCODE_MIN: return R300_ALU_OUTC_MIN; 1211c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák case RC_OPCODE_REPL_ALPHA: return R300_ALU_OUTC_REPL_ALPHA; 1221c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák } 1231c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák} 1241c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák 1251c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšákstatic unsigned int translate_alpha_opcode(struct r300_fragment_program_compiler * c, rc_opcode opcode) 1261c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák{ 1271c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák switch(opcode) { 1281c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák case RC_OPCODE_CMP: return R300_ALU_OUTA_CMP; 1291c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák case RC_OPCODE_CND: return R300_ALU_OUTA_CND; 1301c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák case RC_OPCODE_DP3: return R300_ALU_OUTA_DP4; 1311c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák case RC_OPCODE_DP4: return R300_ALU_OUTA_DP4; 1321c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák case RC_OPCODE_EX2: return R300_ALU_OUTA_EX2; 1331c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák case RC_OPCODE_FRC: return R300_ALU_OUTA_FRC; 1341c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák case RC_OPCODE_LG2: return R300_ALU_OUTA_LG2; 1351c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák default: 1361c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák error("translate_rgb_opcode: Unknown opcode %s", rc_get_opcode_info(opcode)->Name); 1371c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák /* fall through */ 1381c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák case RC_OPCODE_NOP: 1391c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák /* fall through */ 1401c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák case RC_OPCODE_MAD: return R300_ALU_OUTA_MAD; 1411c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák case RC_OPCODE_MAX: return R300_ALU_OUTA_MAX; 1421c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák case RC_OPCODE_MIN: return R300_ALU_OUTA_MIN; 1431c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák case RC_OPCODE_RCP: return R300_ALU_OUTA_RCP; 1441c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák case RC_OPCODE_RSQ: return R300_ALU_OUTA_RSQ; 1451c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák } 1461c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák} 1471c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák 1481c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák/** 1491c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák * Emit one paired ALU instruction. 1501c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák */ 1511c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšákstatic int emit_alu(struct r300_emit_state * emit, struct rc_pair_instruction* inst) 1521c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák{ 1531c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák int ip; 1541c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák int j; 1551c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák PROG_CODE; 1561c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák 1571c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák if (code->alu.length >= c->Base.max_alu_insts) { 1581c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák error("Too many ALU instructions"); 1591c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák return 0; 1601c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák } 1611c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák 1621c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák ip = code->alu.length++; 1631c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák 1641c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák code->alu.inst[ip].rgb_inst = translate_rgb_opcode(c, inst->RGB.Opcode); 1651c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák code->alu.inst[ip].alpha_inst = translate_alpha_opcode(c, inst->Alpha.Opcode); 1661c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák 1671c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák for(j = 0; j < 3; ++j) { 1681c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák /* Set the RGB address */ 1691c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák unsigned int src = use_source(code, inst->RGB.Src[j]); 1701c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák unsigned int arg; 1711c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák if (inst->RGB.Src[j].Index >= R300_PFS_NUM_TEMP_REGS) 1721c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák code->alu.inst[ip].r400_ext_addr |= R400_ADDR_EXT_RGB_MSB_BIT(j); 1731c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák 1741c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák code->alu.inst[ip].rgb_addr |= src << (6*j); 1751c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák 1761c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák /* Set the Alpha address */ 1771c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák src = use_source(code, inst->Alpha.Src[j]); 1781c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák if (inst->Alpha.Src[j].Index >= R300_PFS_NUM_TEMP_REGS) 1791c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák code->alu.inst[ip].r400_ext_addr |= R400_ADDR_EXT_A_MSB_BIT(j); 1801c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák 1811c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák code->alu.inst[ip].alpha_addr |= src << (6*j); 1821c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák 1831c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák arg = r300FPTranslateRGBSwizzle(inst->RGB.Arg[j].Source, inst->RGB.Arg[j].Swizzle); 1841c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák arg |= inst->RGB.Arg[j].Abs << 6; 1851c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák arg |= inst->RGB.Arg[j].Negate << 5; 1861c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák code->alu.inst[ip].rgb_inst |= arg << (7*j); 1871c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák 1881c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák arg = r300FPTranslateAlphaSwizzle(inst->Alpha.Arg[j].Source, inst->Alpha.Arg[j].Swizzle); 1891c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák arg |= inst->Alpha.Arg[j].Abs << 6; 1901c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák arg |= inst->Alpha.Arg[j].Negate << 5; 1911c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák code->alu.inst[ip].alpha_inst |= arg << (7*j); 1921c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák } 1931c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák 1941c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák /* Presubtract */ 1951c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák if (inst->RGB.Src[RC_PAIR_PRESUB_SRC].Used) { 1961c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák switch(inst->RGB.Src[RC_PAIR_PRESUB_SRC].Index) { 1971c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák case RC_PRESUB_BIAS: 1981c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák code->alu.inst[ip].rgb_inst |= 1991c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák R300_ALU_SRCP_1_MINUS_2_SRC0; 2001c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák break; 2011c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák case RC_PRESUB_ADD: 2021c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák code->alu.inst[ip].rgb_inst |= 2031c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák R300_ALU_SRCP_SRC1_PLUS_SRC0; 2041c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák break; 2051c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák case RC_PRESUB_SUB: 2061c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák code->alu.inst[ip].rgb_inst |= 2071c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák R300_ALU_SRCP_SRC1_MINUS_SRC0; 2081c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák break; 2091c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák case RC_PRESUB_INV: 2101c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák code->alu.inst[ip].rgb_inst |= 2111c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák R300_ALU_SRCP_1_MINUS_SRC0; 2121c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák break; 2131c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák default: 2141c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák break; 2151c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák } 2161c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák } 2171c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák 2181c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák if (inst->Alpha.Src[RC_PAIR_PRESUB_SRC].Used) { 2191c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák switch(inst->Alpha.Src[RC_PAIR_PRESUB_SRC].Index) { 2201c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák case RC_PRESUB_BIAS: 2211c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák code->alu.inst[ip].alpha_inst |= 2221c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák R300_ALU_SRCP_1_MINUS_2_SRC0; 2231c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák break; 2241c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák case RC_PRESUB_ADD: 2251c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák code->alu.inst[ip].alpha_inst |= 2261c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák R300_ALU_SRCP_SRC1_PLUS_SRC0; 2271c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák break; 2281c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák case RC_PRESUB_SUB: 2291c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák code->alu.inst[ip].alpha_inst |= 2301c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák R300_ALU_SRCP_SRC1_MINUS_SRC0; 2311c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák break; 2321c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák case RC_PRESUB_INV: 2331c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák code->alu.inst[ip].alpha_inst |= 2341c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák R300_ALU_SRCP_1_MINUS_SRC0; 2351c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák break; 2361c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák default: 2371c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák break; 2381c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák } 2391c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák } 2401c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák 2411c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák if (inst->RGB.Saturate) 2421c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák code->alu.inst[ip].rgb_inst |= R300_ALU_OUTC_CLAMP; 2431c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák if (inst->Alpha.Saturate) 2441c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák code->alu.inst[ip].alpha_inst |= R300_ALU_OUTA_CLAMP; 2451c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák 2461c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák if (inst->RGB.WriteMask) { 2471c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák use_temporary(code, inst->RGB.DestIndex); 2481c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák if (inst->RGB.DestIndex >= R300_PFS_NUM_TEMP_REGS) 2491c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák code->alu.inst[ip].r400_ext_addr |= R400_ADDRD_EXT_RGB_MSB_BIT; 2501c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák code->alu.inst[ip].rgb_addr |= 2511c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák ((inst->RGB.DestIndex & 0x1f) << R300_ALU_DSTC_SHIFT) | 2521c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák (inst->RGB.WriteMask << R300_ALU_DSTC_REG_MASK_SHIFT); 2531c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák } 2541c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák if (inst->RGB.OutputWriteMask) { 2551c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák code->alu.inst[ip].rgb_addr |= 2561c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák (inst->RGB.OutputWriteMask << R300_ALU_DSTC_OUTPUT_MASK_SHIFT) | 2571c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák R300_RGB_TARGET(inst->RGB.Target); 2581c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák emit->node_flags |= R300_RGBA_OUT; 2591c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák } 2601c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák 2611c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák if (inst->Alpha.WriteMask) { 2621c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák use_temporary(code, inst->Alpha.DestIndex); 2631c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák if (inst->Alpha.DestIndex >= R300_PFS_NUM_TEMP_REGS) 2641c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák code->alu.inst[ip].r400_ext_addr |= R400_ADDRD_EXT_A_MSB_BIT; 2651c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák code->alu.inst[ip].alpha_addr |= 2661c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák ((inst->Alpha.DestIndex & 0x1f) << R300_ALU_DSTA_SHIFT) | 2671c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák R300_ALU_DSTA_REG; 2681c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák } 2691c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák if (inst->Alpha.OutputWriteMask) { 2701c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák code->alu.inst[ip].alpha_addr |= R300_ALU_DSTA_OUTPUT | 2711c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák R300_ALPHA_TARGET(inst->Alpha.Target); 2721c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák emit->node_flags |= R300_RGBA_OUT; 2731c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák } 2741c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák if (inst->Alpha.DepthWriteMask) { 2751c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák code->alu.inst[ip].alpha_addr |= R300_ALU_DSTA_DEPTH; 2761c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák emit->node_flags |= R300_W_OUT; 2771c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák c->code->writes_depth = 1; 2781c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák } 2791c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák if (inst->Nop) 2801c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák code->alu.inst[ip].rgb_inst |= R300_ALU_INSERT_NOP; 2811c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák 282e945fb04d04c33da5e77d22d739c5740a522a61eTom Stellard /* Handle Output Modifier 283e945fb04d04c33da5e77d22d739c5740a522a61eTom Stellard * According to the r300 docs, there is no RC_OMOD_DISABLE for r300 */ 284e945fb04d04c33da5e77d22d739c5740a522a61eTom Stellard if (inst->RGB.Omod) { 285e945fb04d04c33da5e77d22d739c5740a522a61eTom Stellard if (inst->RGB.Omod == RC_OMOD_DISABLE) { 286e945fb04d04c33da5e77d22d739c5740a522a61eTom Stellard rc_error(&c->Base, "RC_OMOD_DISABLE not supported"); 287e945fb04d04c33da5e77d22d739c5740a522a61eTom Stellard } 288e945fb04d04c33da5e77d22d739c5740a522a61eTom Stellard code->alu.inst[ip].rgb_inst |= 289e945fb04d04c33da5e77d22d739c5740a522a61eTom Stellard (inst->RGB.Omod << R300_ALU_OUTC_MOD_SHIFT); 290e945fb04d04c33da5e77d22d739c5740a522a61eTom Stellard } 291e945fb04d04c33da5e77d22d739c5740a522a61eTom Stellard if (inst->Alpha.Omod) { 292e945fb04d04c33da5e77d22d739c5740a522a61eTom Stellard if (inst->Alpha.Omod == RC_OMOD_DISABLE) { 293e945fb04d04c33da5e77d22d739c5740a522a61eTom Stellard rc_error(&c->Base, "RC_OMOD_DISABLE not supported"); 294e945fb04d04c33da5e77d22d739c5740a522a61eTom Stellard } 295e945fb04d04c33da5e77d22d739c5740a522a61eTom Stellard code->alu.inst[ip].alpha_inst |= 296e945fb04d04c33da5e77d22d739c5740a522a61eTom Stellard (inst->Alpha.Omod << R300_ALU_OUTC_MOD_SHIFT); 297e945fb04d04c33da5e77d22d739c5740a522a61eTom Stellard } 2981c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák return 1; 2991c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák} 3001c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák 3011c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák 3021c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák/** 3031c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák * Finish the current node without advancing to the next one. 3041c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák */ 3051c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšákstatic int finish_node(struct r300_emit_state * emit) 3061c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák{ 3071c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák struct r300_fragment_program_compiler * c = emit->compiler; 3081c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák struct r300_fragment_program_code *code = &emit->compiler->code->code.r300; 3091c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák unsigned alu_offset; 3101c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák unsigned alu_end; 3111c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák unsigned tex_offset; 3121c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák unsigned tex_end; 3131c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák 3141c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák unsigned int alu_offset_msbs, alu_end_msbs; 3151c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák 3161c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák if (code->alu.length == emit->node_first_alu) { 3171c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák /* Generate a single NOP for this node */ 3181c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák struct rc_pair_instruction inst; 3191c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák memset(&inst, 0, sizeof(inst)); 3201c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák if (!emit_alu(emit, &inst)) 3211c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák return 0; 3221c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák } 3231c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák 3241c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák alu_offset = emit->node_first_alu; 3251c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák alu_end = code->alu.length - alu_offset - 1; 3261c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák tex_offset = emit->node_first_tex; 3271c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák tex_end = code->tex.length - tex_offset - 1; 3281c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák 3291c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák if (code->tex.length == emit->node_first_tex) { 3301c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák if (emit->current_node > 0) { 3311c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák error("Node %i has no TEX instructions", emit->current_node); 3321c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák return 0; 3331c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák } 3341c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák 3351c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák tex_end = 0; 3361c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák } else { 3371c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák if (emit->current_node == 0) 3381c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák code->config |= R300_PFS_CNTL_FIRST_NODE_HAS_TEX; 3391c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák } 3401c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák 3411c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák /* Write the config register. 3421c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák * Note: The order in which the words for each node are written 3431c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák * is not correct here and needs to be fixed up once we're entirely 3441c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák * done 3451c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák * 3461c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák * Also note that the register specification from AMD is slightly 3471c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák * incorrect in its description of this register. */ 3481c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák code->code_addr[emit->current_node] = 3491c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák ((alu_offset << R300_ALU_START_SHIFT) 3501c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák & R300_ALU_START_MASK) 3511c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák | ((alu_end << R300_ALU_SIZE_SHIFT) 3521c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák & R300_ALU_SIZE_MASK) 3531c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák | ((tex_offset << R300_TEX_START_SHIFT) 3541c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák & R300_TEX_START_MASK) 3551c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák | ((tex_end << R300_TEX_SIZE_SHIFT) 3561c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák & R300_TEX_SIZE_MASK) 3571c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák | emit->node_flags 3581c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák | (get_msbs_tex(tex_offset, 5) 3591c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák << R400_TEX_START_MSB_SHIFT) 3601c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák | (get_msbs_tex(tex_end, 5) 3611c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák << R400_TEX_SIZE_MSB_SHIFT) 3621c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák ; 3631c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák 3641c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák /* Write r400 extended instruction fields. These will be ignored on 3651c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák * r300 cards. */ 3661c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák alu_offset_msbs = get_msbs_alu(alu_offset); 3671c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák alu_end_msbs = get_msbs_alu(alu_end); 3681c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák switch(emit->current_node) { 3691c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák case 0: 3701c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák code->r400_code_offset_ext |= 3711c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák alu_offset_msbs << R400_ALU_START3_MSB_SHIFT 3721c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák | alu_end_msbs << R400_ALU_SIZE3_MSB_SHIFT; 3731c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák break; 3741c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák case 1: 3751c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák code->r400_code_offset_ext |= 3761c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák alu_offset_msbs << R400_ALU_START2_MSB_SHIFT 3771c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák | alu_end_msbs << R400_ALU_SIZE2_MSB_SHIFT; 3781c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák break; 3791c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák case 2: 3801c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák code->r400_code_offset_ext |= 3811c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák alu_offset_msbs << R400_ALU_START1_MSB_SHIFT 3821c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák | alu_end_msbs << R400_ALU_SIZE1_MSB_SHIFT; 3831c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák break; 3841c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák case 3: 3851c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák code->r400_code_offset_ext |= 3861c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák alu_offset_msbs << R400_ALU_START0_MSB_SHIFT 3871c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák | alu_end_msbs << R400_ALU_SIZE0_MSB_SHIFT; 3881c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák break; 3891c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák } 3901c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák return 1; 3911c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák} 3921c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák 3931c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák 3941c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák/** 3951c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák * Begin a block of texture instructions. 3961c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák * Create the necessary indirection. 3971c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák */ 3981c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšákstatic int begin_tex(struct r300_emit_state * emit) 3991c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák{ 4001c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák PROG_CODE; 4011c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák 4021c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák if (code->alu.length == emit->node_first_alu && 4031c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák code->tex.length == emit->node_first_tex) { 4041c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák return 1; 4051c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák } 4061c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák 4071c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák if (emit->current_node == 3) { 4081c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák error("Too many texture indirections"); 4091c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák return 0; 4101c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák } 4111c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák 4121c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák if (!finish_node(emit)) 4131c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák return 0; 4141c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák 4151c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák emit->current_node++; 4161c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák emit->node_first_tex = code->tex.length; 4171c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák emit->node_first_alu = code->alu.length; 4181c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák emit->node_flags = 0; 4191c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák return 1; 4201c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák} 4211c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák 4221c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák 4231c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšákstatic int emit_tex(struct r300_emit_state * emit, struct rc_instruction * inst) 4241c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák{ 4251c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák unsigned int unit; 4261c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák unsigned int dest; 4271c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák unsigned int opcode; 4281c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák PROG_CODE; 4291c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák 4301c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák if (code->tex.length >= emit->compiler->Base.max_tex_insts) { 4311c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák error("Too many TEX instructions"); 4321c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák return 0; 4331c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák } 4341c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák 4351c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák unit = inst->U.I.TexSrcUnit; 4361c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák dest = inst->U.I.DstReg.Index; 4371c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák 4381c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák switch(inst->U.I.Opcode) { 4391c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák case RC_OPCODE_KIL: opcode = R300_TEX_OP_KIL; break; 4401c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák case RC_OPCODE_TEX: opcode = R300_TEX_OP_LD; break; 4411c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák case RC_OPCODE_TXB: opcode = R300_TEX_OP_TXB; break; 4421c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák case RC_OPCODE_TXP: opcode = R300_TEX_OP_TXP; break; 4431c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák default: 4441c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák error("Unknown texture opcode %s", rc_get_opcode_info(inst->U.I.Opcode)->Name); 4451c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák return 0; 4461c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák } 4471c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák 4481c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák if (inst->U.I.Opcode == RC_OPCODE_KIL) { 4491c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák unit = 0; 4501c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák dest = 0; 4511c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák } else { 4521c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák use_temporary(code, dest); 4531c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák } 4541c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák 4551c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák use_temporary(code, inst->U.I.SrcReg[0].Index); 4561c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák 4571c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák code->tex.inst[code->tex.length++] = 4581c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák ((inst->U.I.SrcReg[0].Index << R300_SRC_ADDR_SHIFT) 4591c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák & R300_SRC_ADDR_MASK) 4601c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák | ((dest << R300_DST_ADDR_SHIFT) 4611c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák & R300_DST_ADDR_MASK) 4621c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák | (unit << R300_TEX_ID_SHIFT) 4631c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák | (opcode << R300_TEX_INST_SHIFT) 4641c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák | (inst->U.I.SrcReg[0].Index >= R300_PFS_NUM_TEMP_REGS ? 4651c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák R400_SRC_ADDR_EXT_BIT : 0) 4661c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák | (dest >= R300_PFS_NUM_TEMP_REGS ? 4671c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák R400_DST_ADDR_EXT_BIT : 0) 4681c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák ; 4691c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák return 1; 4701c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák} 4711c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák 4721c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák 4731c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák/** 4741c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák * Final compilation step: Turn the intermediate radeon_program into 4751c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák * machine-readable instructions. 4761c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák */ 4771c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšákvoid r300BuildFragmentProgramHwCode(struct radeon_compiler *c, void *user) 4781c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák{ 4791c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák struct r300_fragment_program_compiler *compiler = (struct r300_fragment_program_compiler*)c; 4801c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák struct r300_emit_state emit; 4811c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák struct r300_fragment_program_code *code = &compiler->code->code.r300; 4821c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák unsigned int tex_end; 4831c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák 4841c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák memset(&emit, 0, sizeof(emit)); 4851c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák emit.compiler = compiler; 4861c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák 4871c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák memset(code, 0, sizeof(struct r300_fragment_program_code)); 4881c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák 4891c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák for(struct rc_instruction * inst = compiler->Base.Program.Instructions.Next; 4901c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák inst != &compiler->Base.Program.Instructions && !compiler->Base.Error; 4911c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák inst = inst->Next) { 4921c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák if (inst->Type == RC_INSTRUCTION_NORMAL) { 4931c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák if (inst->U.I.Opcode == RC_OPCODE_BEGIN_TEX) { 4941c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák begin_tex(&emit); 4951c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák continue; 4961c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák } 4971c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák 4981c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák emit_tex(&emit, inst); 4991c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák } else { 5001c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák emit_alu(&emit, &inst->U.P); 5011c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák } 5021c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák } 5031c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák 5041c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák if (code->pixsize >= compiler->Base.max_temp_regs) 5051c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák rc_error(&compiler->Base, "Too many hardware temporaries used.\n"); 5061c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák 5071c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák if (compiler->Base.Error) 5081c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák return; 5091c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák 5101c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák /* Finish the program */ 5111c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák finish_node(&emit); 5121c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák 5131c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák code->config |= emit.current_node; /* FIRST_NODE_HAS_TEX set by finish_node */ 5141c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák 5151c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák /* Set r400 extended instruction fields. These values will be ignored 5161c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák * on r300 cards. */ 5171c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák code->r400_code_offset_ext |= 5181c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák (get_msbs_alu(0) 5191c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák << R400_ALU_OFFSET_MSB_SHIFT) 5201c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák | (get_msbs_alu(code->alu.length - 1) 5211c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák << R400_ALU_SIZE_MSB_SHIFT); 5221c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák 5231c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák tex_end = code->tex.length ? code->tex.length - 1 : 0; 5241c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák code->code_offset = 5251c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák ((0 << R300_PFS_CNTL_ALU_OFFSET_SHIFT) 5261c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák & R300_PFS_CNTL_ALU_OFFSET_MASK) 5271c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák | (((code->alu.length - 1) << R300_PFS_CNTL_ALU_END_SHIFT) 5281c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák & R300_PFS_CNTL_ALU_END_MASK) 5291c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák | ((0 << R300_PFS_CNTL_TEX_OFFSET_SHIFT) 5301c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák & R300_PFS_CNTL_TEX_OFFSET_MASK) 5311c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák | ((tex_end << R300_PFS_CNTL_TEX_END_SHIFT) 5321c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák & R300_PFS_CNTL_TEX_END_MASK) 5331c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák | (get_msbs_tex(0, 5) << R400_TEX_START_MSB_SHIFT) 5341c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák | (get_msbs_tex(tex_end, 6) << R400_TEX_SIZE_MSB_SHIFT) 5351c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák ; 5361c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák 5371c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák if (emit.current_node < 3) { 5381c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák int shift = 3 - emit.current_node; 5391c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák int i; 5401c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák for(i = emit.current_node; i >= 0; --i) 5411c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák code->code_addr[shift + i] = code->code_addr[i]; 5421c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák for(i = 0; i < shift; ++i) 5431c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák code->code_addr[i] = 0; 5441c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák } 5451c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák 5461c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák if (code->pixsize >= R300_PFS_NUM_TEMP_REGS 5471c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák || code->alu.length > R300_PFS_MAX_ALU_INST 5481c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák || code->tex.length > R300_PFS_MAX_TEX_INST) { 5491c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák 5501c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák code->r390_mode = 1; 5511c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák } 5521c2c4ddbd1e97bfd13430521e5c09cb5ce8e36e6Marek Olšák} 553