151125a21eafc29c925cac3655b46cfd8ef55f764Ted Kremenek/* 24241b3d1ad87e9a593bbc6cdf0f49435d5aec235Ted Kremenek * Copyright (C) 2005 Ben Skeggs. 34241b3d1ad87e9a593bbc6cdf0f49435d5aec235Ted Kremenek * 44241b3d1ad87e9a593bbc6cdf0f49435d5aec235Ted Kremenek * All Rights Reserved. 54241b3d1ad87e9a593bbc6cdf0f49435d5aec235Ted Kremenek * 64241b3d1ad87e9a593bbc6cdf0f49435d5aec235Ted Kremenek * Permission is hereby granted, free of charge, to any person obtaining 74241b3d1ad87e9a593bbc6cdf0f49435d5aec235Ted Kremenek * a copy of this software and associated documentation files (the 84241b3d1ad87e9a593bbc6cdf0f49435d5aec235Ted Kremenek * "Software"), to deal in the Software without restriction, including 94241b3d1ad87e9a593bbc6cdf0f49435d5aec235Ted Kremenek * without limitation the rights to use, copy, modify, merge, publish, 1051125a21eafc29c925cac3655b46cfd8ef55f764Ted Kremenek * distribute, sublicense, and/or sell copies of the Software, and to 1151125a21eafc29c925cac3655b46cfd8ef55f764Ted Kremenek * permit persons to whom the Software is furnished to do so, subject to 12b2213dc3dd8f58b611b91d2fce4834a767efcba7Jeffrey Yasskin * the following conditions: 13b2213dc3dd8f58b611b91d2fce4834a767efcba7Jeffrey Yasskin * 14b2213dc3dd8f58b611b91d2fce4834a767efcba7Jeffrey Yasskin * The above copyright notice and this permission notice (including the 15b2213dc3dd8f58b611b91d2fce4834a767efcba7Jeffrey Yasskin * next paragraph) shall be included in all copies or substantial 164241b3d1ad87e9a593bbc6cdf0f49435d5aec235Ted Kremenek * portions of the Software. 174241b3d1ad87e9a593bbc6cdf0f49435d5aec235Ted Kremenek * 184241b3d1ad87e9a593bbc6cdf0f49435d5aec235Ted Kremenek * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 195a4f98ff943e6a501b0fe47ade007c9bbf96cb88Argyrios Kyrtzidis * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 205a4f98ff943e6a501b0fe47ade007c9bbf96cb88Argyrios Kyrtzidis * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 214241b3d1ad87e9a593bbc6cdf0f49435d5aec235Ted Kremenek * IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE 224a0f5f1646637fcf90eb236b5a46f40e5a5dd739Ted Kremenek * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 231309f9a3b225ea846e5822691c39a77423125505Ted Kremenek * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 2463bbe5312cd89ce0ceb684bff68c5baef636e93cTed Kremenek * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 254241b3d1ad87e9a593bbc6cdf0f49435d5aec235Ted Kremenek * 264241b3d1ad87e9a593bbc6cdf0f49435d5aec235Ted Kremenek */ 27f6f5ef4aaa66b60270e84d1fe1292886369d2f38Ted Kremenek 284241b3d1ad87e9a593bbc6cdf0f49435d5aec235Ted Kremenek/** 29ede5a4ba111f0590879670b6cb07f4d6d0bd9075Ted Kremenek * \file 304a0f5f1646637fcf90eb236b5a46f40e5a5dd739Ted Kremenek * 314a0f5f1646637fcf90eb236b5a46f40e5a5dd739Ted Kremenek * Emit the r300_fragment_program_code that can be understood by the hardware. 3263bbe5312cd89ce0ceb684bff68c5baef636e93cTed Kremenek * Input is a pre-transformed radeon_program. 335fe4d9deb543a19f557e3d85c5f33867af97cd96Ted Kremenek * 3418c66fdc3c4008d335885695fe36fb5353c5f672Ted Kremenek * \author Ben Skeggs <darktama@iinet.net.au> 354241b3d1ad87e9a593bbc6cdf0f49435d5aec235Ted Kremenek * 364241b3d1ad87e9a593bbc6cdf0f49435d5aec235Ted Kremenek * \author Jerome Glisse <j.glisse@gmail.com> 374a0f5f1646637fcf90eb236b5a46f40e5a5dd739Ted Kremenek */ 3811062b118476368fa5b294954713e5df97d8599fTed Kremenek 395a4f98ff943e6a501b0fe47ade007c9bbf96cb88Argyrios Kyrtzidis#include "r300_fragprog.h" 409ef6537a894c33003359b1f9b9676e9178e028b7Ted Kremenek 415a4f98ff943e6a501b0fe47ade007c9bbf96cb88Argyrios Kyrtzidis#include "../r300_reg.h" 425fe4d9deb543a19f557e3d85c5f33867af97cd96Ted Kremenek 4311062b118476368fa5b294954713e5df97d8599fTed Kremenek#include "radeon_program_pair.h" 44cf118d41f7930a18dce97416ef7834a62642f587Ted Kremenek#include "r300_fragprog_swizzle.h" 45cf118d41f7930a18dce97416ef7834a62642f587Ted Kremenek 46cf118d41f7930a18dce97416ef7834a62642f587Ted Kremenek 47cf118d41f7930a18dce97416ef7834a62642f587Ted Kremenekstruct r300_emit_state { 48cf118d41f7930a18dce97416ef7834a62642f587Ted Kremenek struct r300_fragment_program_compiler * compiler; 491eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 50bda1efd0daf6fca9f515c6ce38d1ed71a3cca5b7Zhongxing Xu unsigned current_node : 2; 51bda1efd0daf6fca9f515c6ce38d1ed71a3cca5b7Zhongxing Xu unsigned node_first_tex : 8; 52bda1efd0daf6fca9f515c6ce38d1ed71a3cca5b7Zhongxing Xu unsigned node_first_alu : 8; 53c5619d901a68dc27a9e310a6a831f03efebcd950Zhongxing Xu uint32_t node_flags; 5438b02b912e1a55c912f603c4369431264d36a381Zhongxing Xu}; 55d2592a34a059e7cbb2b11dc53649ac4912422909Argyrios Kyrtzidis 56a19f4af7a94835ce4693bfe12d6270754e79eb56Anna Zaks#define PROG_CODE \ 57d2592a34a059e7cbb2b11dc53649ac4912422909Argyrios Kyrtzidis struct r300_fragment_program_compiler *c = emit->compiler; \ 58d2592a34a059e7cbb2b11dc53649ac4912422909Argyrios Kyrtzidis struct r300_fragment_program_code *code = &c->code->code.r300 59d2592a34a059e7cbb2b11dc53649ac4912422909Argyrios Kyrtzidis 60d2592a34a059e7cbb2b11dc53649ac4912422909Argyrios Kyrtzidis#define error(fmt, args...) do { \ 61e36de1fe51c39d9161915dd3dbef880954af6476Ted Kremenek rc_error(&c->Base, "%s::%s(): " fmt "\n", \ 621eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump __FILE__, __FUNCTION__, ##args); \ 634c4cb527a44037d076da82ad9d12b4e655e64dbbTed Kremenek } while(0) 64b38911f16b4943548db6a3695fc6ae23070b25d2Ted Kremenek 654c4cb527a44037d076da82ad9d12b4e655e64dbbTed Kremenekstatic unsigned int get_msbs_alu(unsigned int bits) 661eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump{ 67ee98546b0d5f3439c4a590b0d7d1545af794a0ecTed Kremenek return (bits >> 6) & 0x7; 68596f0a1e54f610926e8bfded9efa1c639f824dedTed Kremenek} 69ee98546b0d5f3439c4a590b0d7d1545af794a0ecTed Kremenek 701eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump/** 719c378f705405d37f49795d5e915989de774fe11fTed Kremenek * @param lsbs The number of least significant bits 72ffe0f43806d4823271c2406c1fccc2373115c36aTed Kremenek */ 73b38911f16b4943548db6a3695fc6ae23070b25d2Ted Kremenekstatic unsigned int get_msbs_tex(unsigned int bits, unsigned int lsbs) 74ee98546b0d5f3439c4a590b0d7d1545af794a0ecTed Kremenek{ 75ee98546b0d5f3439c4a590b0d7d1545af794a0ecTed Kremenek return (bits >> lsbs) & 0x15; 76c5619d901a68dc27a9e310a6a831f03efebcd950Zhongxing Xu} 77c5619d901a68dc27a9e310a6a831f03efebcd950Zhongxing Xu 78ee98546b0d5f3439c4a590b0d7d1545af794a0ecTed Kremenek#define R400_EXT_GET_MSBS(x, lsbs, mask) (((x) >> lsbs) & mask) 79d767d81290288c030f3be0be1d3e62b9c8df51dcTed Kremenek 804c4cb527a44037d076da82ad9d12b4e655e64dbbTed Kremenek/** 814c4cb527a44037d076da82ad9d12b4e655e64dbbTed Kremenek * Mark a temporary register as used. 821eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump */ 835fe4d9deb543a19f557e3d85c5f33867af97cd96Ted Kremenekstatic void use_temporary(struct r300_fragment_program_code *code, unsigned int index) 841eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump{ 855fe4d9deb543a19f557e3d85c5f33867af97cd96Ted Kremenek if (index > code->pixsize) 861eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump code->pixsize = index; 875d5480380d7b7c3590a0283ddf239220e514e576Ted Kremenek} 881eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 895fe4d9deb543a19f557e3d85c5f33867af97cd96Ted Kremenekstatic unsigned int use_source(struct r300_fragment_program_code* code, struct rc_pair_instruction_source src) 901eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump{ 919c378f705405d37f49795d5e915989de774fe11fTed Kremenek if (!src.Used) 921eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump return 0; 93d767d81290288c030f3be0be1d3e62b9c8df51dcTed Kremenek 94d767d81290288c030f3be0be1d3e62b9c8df51dcTed Kremenek if (src.File == RC_FILE_CONSTANT) { 95b38911f16b4943548db6a3695fc6ae23070b25d2Ted Kremenek return src.Index | (1 << 5); 965fe4d9deb543a19f557e3d85c5f33867af97cd96Ted Kremenek } else if (src.File == RC_FILE_TEMPORARY || src.File == RC_FILE_INPUT) { 97ffe0f43806d4823271c2406c1fccc2373115c36aTed Kremenek use_temporary(code, src.Index); 98f24af5bc2e01ca8e7396ed997378a77fddfa521eTed Kremenek return src.Index & 0x1f; 991eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump } 100b38911f16b4943548db6a3695fc6ae23070b25d2Ted Kremenek 101b38911f16b4943548db6a3695fc6ae23070b25d2Ted Kremenek return 0; 102f24af5bc2e01ca8e7396ed997378a77fddfa521eTed Kremenek} 1031eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 1041eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 1054a0f5f1646637fcf90eb236b5a46f40e5a5dd739Ted Kremenekstatic unsigned int translate_rgb_opcode(struct r300_fragment_program_compiler * c, rc_opcode opcode) 1064a0f5f1646637fcf90eb236b5a46f40e5a5dd739Ted Kremenek{ 1074a0f5f1646637fcf90eb236b5a46f40e5a5dd739Ted Kremenek switch(opcode) { 1081eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump case RC_OPCODE_CMP: return R300_ALU_OUTC_CMP; 1094323a57627e796dcfdfdb7d47672dc09ed308edaTed Kremenek case RC_OPCODE_CND: return R300_ALU_OUTC_CND; 11018c66fdc3c4008d335885695fe36fb5353c5f672Ted Kremenek case RC_OPCODE_DP3: return R300_ALU_OUTC_DP3; 1111eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump case RC_OPCODE_DP4: return R300_ALU_OUTC_DP4; 1124a0f5f1646637fcf90eb236b5a46f40e5a5dd739Ted Kremenek case RC_OPCODE_FRC: return R300_ALU_OUTC_FRC; 1134c4cb527a44037d076da82ad9d12b4e655e64dbbTed Kremenek default: 1141eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump error("translate_rgb_opcode: Unknown opcode %s", rc_get_opcode_info(opcode)->Name); 1154a0f5f1646637fcf90eb236b5a46f40e5a5dd739Ted Kremenek /* fall through */ 1164c4cb527a44037d076da82ad9d12b4e655e64dbbTed Kremenek case RC_OPCODE_NOP: 117c5619d901a68dc27a9e310a6a831f03efebcd950Zhongxing Xu /* fall through */ 1184a0f5f1646637fcf90eb236b5a46f40e5a5dd739Ted Kremenek case RC_OPCODE_MAD: return R300_ALU_OUTC_MAD; 119c5619d901a68dc27a9e310a6a831f03efebcd950Zhongxing Xu case RC_OPCODE_MAX: return R300_ALU_OUTC_MAX; 12018c66fdc3c4008d335885695fe36fb5353c5f672Ted Kremenek case RC_OPCODE_MIN: return R300_ALU_OUTC_MIN; 121e3115e257163321ecde429aeae75f1702f099d4cTed Kremenek case RC_OPCODE_REPL_ALPHA: return R300_ALU_OUTC_REPL_ALPHA; 12218c66fdc3c4008d335885695fe36fb5353c5f672Ted Kremenek } 123e40b69de464bc695afcaf7ef9602ad727d77b981Ted Kremenek} 124e40b69de464bc695afcaf7ef9602ad727d77b981Ted Kremenek 125e40b69de464bc695afcaf7ef9602ad727d77b981Ted Kremenekstatic unsigned int translate_alpha_opcode(struct r300_fragment_program_compiler * c, rc_opcode opcode) 12618c66fdc3c4008d335885695fe36fb5353c5f672Ted Kremenek{ 127e3115e257163321ecde429aeae75f1702f099d4cTed Kremenek switch(opcode) { 128c5619d901a68dc27a9e310a6a831f03efebcd950Zhongxing Xu case RC_OPCODE_CMP: return R300_ALU_OUTA_CMP; 1294a0f5f1646637fcf90eb236b5a46f40e5a5dd739Ted Kremenek case RC_OPCODE_CND: return R300_ALU_OUTA_CND; 1300f9063c116b7c3b05d8042b5976463c2dae04861Ted Kremenek case RC_OPCODE_DP3: return R300_ALU_OUTA_DP4; 131c5619d901a68dc27a9e310a6a831f03efebcd950Zhongxing Xu case RC_OPCODE_DP4: return R300_ALU_OUTA_DP4; 1321eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump case RC_OPCODE_EX2: return R300_ALU_OUTA_EX2; 1331eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump case RC_OPCODE_FRC: return R300_ALU_OUTA_FRC; 13425e695b2d574d919cc1bbddf3a2efe073d449b1cZhongxing Xu case RC_OPCODE_LG2: return R300_ALU_OUTA_LG2; 13525e695b2d574d919cc1bbddf3a2efe073d449b1cZhongxing Xu default: 1365032ffe4259e7d436f2eb19e5a29fdae559e7c12Zhongxing Xu error("translate_rgb_opcode: Unknown opcode %s", rc_get_opcode_info(opcode)->Name); 1375032ffe4259e7d436f2eb19e5a29fdae559e7c12Zhongxing Xu /* fall through */ 1385032ffe4259e7d436f2eb19e5a29fdae559e7c12Zhongxing Xu case RC_OPCODE_NOP: 1395032ffe4259e7d436f2eb19e5a29fdae559e7c12Zhongxing Xu /* fall through */ 140b317f8f5ca8737a5bbad97a3f7566a2dbd2ed61bZhongxing Xu case RC_OPCODE_MAD: return R300_ALU_OUTA_MAD; 141b317f8f5ca8737a5bbad97a3f7566a2dbd2ed61bZhongxing Xu case RC_OPCODE_MAX: return R300_ALU_OUTA_MAX; 142a5937bbfd19e61d651a58b0f0ffeef68457902a5Ted Kremenek case RC_OPCODE_MIN: return R300_ALU_OUTA_MIN; 143a5937bbfd19e61d651a58b0f0ffeef68457902a5Ted Kremenek case RC_OPCODE_RCP: return R300_ALU_OUTA_RCP; 144a5937bbfd19e61d651a58b0f0ffeef68457902a5Ted Kremenek case RC_OPCODE_RSQ: return R300_ALU_OUTA_RSQ; 145c5619d901a68dc27a9e310a6a831f03efebcd950Zhongxing Xu } 146c5619d901a68dc27a9e310a6a831f03efebcd950Zhongxing Xu} 14718c66fdc3c4008d335885695fe36fb5353c5f672Ted Kremenek 148b317f8f5ca8737a5bbad97a3f7566a2dbd2ed61bZhongxing Xu/** 14952c3196a89a26cebcf069dd140c3396b743b8e33Ted Kremenek * Emit one paired ALU instruction. 15052c3196a89a26cebcf069dd140c3396b743b8e33Ted Kremenek */ 151c5619d901a68dc27a9e310a6a831f03efebcd950Zhongxing Xustatic int emit_alu(struct r300_emit_state * emit, struct rc_pair_instruction* inst) 1521eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump{ 15318c66fdc3c4008d335885695fe36fb5353c5f672Ted Kremenek int ip; 1545fe4d9deb543a19f557e3d85c5f33867af97cd96Ted Kremenek int j; 1555fe4d9deb543a19f557e3d85c5f33867af97cd96Ted Kremenek PROG_CODE; 1565fe4d9deb543a19f557e3d85c5f33867af97cd96Ted Kremenek 157c5619d901a68dc27a9e310a6a831f03efebcd950Zhongxing Xu if (code->alu.length >= c->Base.max_alu_insts) { 158c5619d901a68dc27a9e310a6a831f03efebcd950Zhongxing Xu error("Too many ALU instructions"); 159c5619d901a68dc27a9e310a6a831f03efebcd950Zhongxing Xu return 0; 160c5619d901a68dc27a9e310a6a831f03efebcd950Zhongxing Xu } 161c5619d901a68dc27a9e310a6a831f03efebcd950Zhongxing Xu 1621eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump ip = code->alu.length++; 163c5619d901a68dc27a9e310a6a831f03efebcd950Zhongxing Xu 1649c378f705405d37f49795d5e915989de774fe11fTed Kremenek code->alu.inst[ip].rgb_inst = translate_rgb_opcode(c, inst->RGB.Opcode); 165c5619d901a68dc27a9e310a6a831f03efebcd950Zhongxing Xu code->alu.inst[ip].alpha_inst = translate_alpha_opcode(c, inst->Alpha.Opcode); 1664a0f5f1646637fcf90eb236b5a46f40e5a5dd739Ted Kremenek 1674a0f5f1646637fcf90eb236b5a46f40e5a5dd739Ted Kremenek for(j = 0; j < 3; ++j) { 1684a0f5f1646637fcf90eb236b5a46f40e5a5dd739Ted Kremenek /* Set the RGB address */ 1690e8a3c743b9b3e3039e329a1736122d3b5b5fed9Ted Kremenek unsigned int src = use_source(code, inst->RGB.Src[j]); 1701eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump unsigned int arg; 171ffe0f43806d4823271c2406c1fccc2373115c36aTed Kremenek if (inst->RGB.Src[j].Index >= R300_PFS_NUM_TEMP_REGS) 1721eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump code->alu.inst[ip].r400_ext_addr |= R400_ADDR_EXT_RGB_MSB_BIT(j); 1734a0f5f1646637fcf90eb236b5a46f40e5a5dd739Ted Kremenek 1749c378f705405d37f49795d5e915989de774fe11fTed Kremenek code->alu.inst[ip].rgb_addr |= src << (6*j); 17552c3196a89a26cebcf069dd140c3396b743b8e33Ted Kremenek 17652c3196a89a26cebcf069dd140c3396b743b8e33Ted Kremenek /* Set the Alpha address */ 1771eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump src = use_source(code, inst->Alpha.Src[j]); 1789c378f705405d37f49795d5e915989de774fe11fTed Kremenek if (inst->Alpha.Src[j].Index >= R300_PFS_NUM_TEMP_REGS) 17952c3196a89a26cebcf069dd140c3396b743b8e33Ted Kremenek code->alu.inst[ip].r400_ext_addr |= R400_ADDR_EXT_A_MSB_BIT(j); 18052c3196a89a26cebcf069dd140c3396b743b8e33Ted Kremenek 1811eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump code->alu.inst[ip].alpha_addr |= src << (6*j); 1824a0f5f1646637fcf90eb236b5a46f40e5a5dd739Ted Kremenek 1834a0f5f1646637fcf90eb236b5a46f40e5a5dd739Ted Kremenek arg = r300FPTranslateRGBSwizzle(inst->RGB.Arg[j].Source, inst->RGB.Arg[j].Swizzle); 1843148eb4a75f70f2636075c364d03104223f004d3Ted Kremenek arg |= inst->RGB.Arg[j].Abs << 6; 1854a0f5f1646637fcf90eb236b5a46f40e5a5dd739Ted Kremenek arg |= inst->RGB.Arg[j].Negate << 5; 1863148eb4a75f70f2636075c364d03104223f004d3Ted Kremenek code->alu.inst[ip].rgb_inst |= arg << (7*j); 1874a0f5f1646637fcf90eb236b5a46f40e5a5dd739Ted Kremenek 188c5619d901a68dc27a9e310a6a831f03efebcd950Zhongxing Xu arg = r300FPTranslateAlphaSwizzle(inst->Alpha.Arg[j].Source, inst->Alpha.Arg[j].Swizzle); 189c5619d901a68dc27a9e310a6a831f03efebcd950Zhongxing Xu arg |= inst->Alpha.Arg[j].Abs << 6; 1904a0f5f1646637fcf90eb236b5a46f40e5a5dd739Ted Kremenek arg |= inst->Alpha.Arg[j].Negate << 5; 1914a0f5f1646637fcf90eb236b5a46f40e5a5dd739Ted Kremenek code->alu.inst[ip].alpha_inst |= arg << (7*j); 1924a0f5f1646637fcf90eb236b5a46f40e5a5dd739Ted Kremenek } 1931eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 1944a0f5f1646637fcf90eb236b5a46f40e5a5dd739Ted Kremenek /* Presubtract */ 1954a0f5f1646637fcf90eb236b5a46f40e5a5dd739Ted Kremenek if (inst->RGB.Src[RC_PAIR_PRESUB_SRC].Used) { 1964a0f5f1646637fcf90eb236b5a46f40e5a5dd739Ted Kremenek switch(inst->RGB.Src[RC_PAIR_PRESUB_SRC].Index) { 1974a0f5f1646637fcf90eb236b5a46f40e5a5dd739Ted Kremenek case RC_PRESUB_BIAS: 198c5619d901a68dc27a9e310a6a831f03efebcd950Zhongxing Xu code->alu.inst[ip].rgb_inst |= 199c5619d901a68dc27a9e310a6a831f03efebcd950Zhongxing Xu R300_ALU_SRCP_1_MINUS_2_SRC0; 2004a0f5f1646637fcf90eb236b5a46f40e5a5dd739Ted Kremenek break; 2014a0f5f1646637fcf90eb236b5a46f40e5a5dd739Ted Kremenek case RC_PRESUB_ADD: 2024a0f5f1646637fcf90eb236b5a46f40e5a5dd739Ted Kremenek code->alu.inst[ip].rgb_inst |= 2034a0f5f1646637fcf90eb236b5a46f40e5a5dd739Ted Kremenek R300_ALU_SRCP_SRC1_PLUS_SRC0; 2044a0f5f1646637fcf90eb236b5a46f40e5a5dd739Ted Kremenek break; 2054a0f5f1646637fcf90eb236b5a46f40e5a5dd739Ted Kremenek case RC_PRESUB_SUB: 2064a0f5f1646637fcf90eb236b5a46f40e5a5dd739Ted Kremenek code->alu.inst[ip].rgb_inst |= 207c5619d901a68dc27a9e310a6a831f03efebcd950Zhongxing Xu R300_ALU_SRCP_SRC1_MINUS_SRC0; 208c5619d901a68dc27a9e310a6a831f03efebcd950Zhongxing Xu break; 2091eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump case RC_PRESUB_INV: 210c5619d901a68dc27a9e310a6a831f03efebcd950Zhongxing Xu code->alu.inst[ip].rgb_inst |= 2111eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump R300_ALU_SRCP_1_MINUS_SRC0; 212c5619d901a68dc27a9e310a6a831f03efebcd950Zhongxing Xu break; 213c5619d901a68dc27a9e310a6a831f03efebcd950Zhongxing Xu default: 214c5619d901a68dc27a9e310a6a831f03efebcd950Zhongxing Xu break; 2159c378f705405d37f49795d5e915989de774fe11fTed Kremenek } 216c5619d901a68dc27a9e310a6a831f03efebcd950Zhongxing Xu } 2171eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 218c5619d901a68dc27a9e310a6a831f03efebcd950Zhongxing Xu if (inst->Alpha.Src[RC_PAIR_PRESUB_SRC].Used) { 219d767d81290288c030f3be0be1d3e62b9c8df51dcTed Kremenek switch(inst->Alpha.Src[RC_PAIR_PRESUB_SRC].Index) { 220d767d81290288c030f3be0be1d3e62b9c8df51dcTed Kremenek case RC_PRESUB_BIAS: 221d767d81290288c030f3be0be1d3e62b9c8df51dcTed Kremenek code->alu.inst[ip].alpha_inst |= 222d767d81290288c030f3be0be1d3e62b9c8df51dcTed Kremenek R300_ALU_SRCP_1_MINUS_2_SRC0; 223c5619d901a68dc27a9e310a6a831f03efebcd950Zhongxing Xu break; 224c5619d901a68dc27a9e310a6a831f03efebcd950Zhongxing Xu case RC_PRESUB_ADD: 22538b02b912e1a55c912f603c4369431264d36a381Zhongxing Xu code->alu.inst[ip].alpha_inst |= 22638b02b912e1a55c912f603c4369431264d36a381Zhongxing Xu R300_ALU_SRCP_SRC1_PLUS_SRC0; 22738b02b912e1a55c912f603c4369431264d36a381Zhongxing Xu break; 2281eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump case RC_PRESUB_SUB: 229c5619d901a68dc27a9e310a6a831f03efebcd950Zhongxing Xu code->alu.inst[ip].alpha_inst |= 23038b02b912e1a55c912f603c4369431264d36a381Zhongxing Xu R300_ALU_SRCP_SRC1_MINUS_SRC0; 2319c378f705405d37f49795d5e915989de774fe11fTed Kremenek break; 2321eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump case RC_PRESUB_INV: 2337177dee8aee4b432911c91f1b788963bec0cac9fDaniel Dunbar code->alu.inst[ip].alpha_inst |= 23438b02b912e1a55c912f603c4369431264d36a381Zhongxing Xu R300_ALU_SRCP_1_MINUS_SRC0; 2354a0f5f1646637fcf90eb236b5a46f40e5a5dd739Ted Kremenek break; 2364a0f5f1646637fcf90eb236b5a46f40e5a5dd739Ted Kremenek default: 23738b02b912e1a55c912f603c4369431264d36a381Zhongxing Xu break; 2384241b3d1ad87e9a593bbc6cdf0f49435d5aec235Ted Kremenek } 239d2592a34a059e7cbb2b11dc53649ac4912422909Argyrios Kyrtzidis } 240e96de2dfde487211fb52f9139cdcae64d051a406Zhongxing Xu 2414241b3d1ad87e9a593bbc6cdf0f49435d5aec235Ted Kremenek if (inst->RGB.Saturate) 242686775deca8b8685eb90801495880e3abdd844c2Chris Lattner code->alu.inst[ip].rgb_inst |= R300_ALU_OUTC_CLAMP; 243686775deca8b8685eb90801495880e3abdd844c2Chris Lattner if (inst->Alpha.Saturate) 2441eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump code->alu.inst[ip].alpha_inst |= R300_ALU_OUTA_CLAMP; 2454241b3d1ad87e9a593bbc6cdf0f49435d5aec235Ted Kremenek 2464241b3d1ad87e9a593bbc6cdf0f49435d5aec235Ted Kremenek if (inst->RGB.WriteMask) { 2474241b3d1ad87e9a593bbc6cdf0f49435d5aec235Ted Kremenek use_temporary(code, inst->RGB.DestIndex); 2484241b3d1ad87e9a593bbc6cdf0f49435d5aec235Ted Kremenek if (inst->RGB.DestIndex >= R300_PFS_NUM_TEMP_REGS) 2494241b3d1ad87e9a593bbc6cdf0f49435d5aec235Ted Kremenek code->alu.inst[ip].r400_ext_addr |= R400_ADDRD_EXT_RGB_MSB_BIT; 2504241b3d1ad87e9a593bbc6cdf0f49435d5aec235Ted Kremenek code->alu.inst[ip].rgb_addr |= 2514241b3d1ad87e9a593bbc6cdf0f49435d5aec235Ted Kremenek ((inst->RGB.DestIndex & 0x1f) << R300_ALU_DSTC_SHIFT) | 2524241b3d1ad87e9a593bbc6cdf0f49435d5aec235Ted Kremenek (inst->RGB.WriteMask << R300_ALU_DSTC_REG_MASK_SHIFT); 2534241b3d1ad87e9a593bbc6cdf0f49435d5aec235Ted Kremenek } 25438b02b912e1a55c912f603c4369431264d36a381Zhongxing Xu if (inst->RGB.OutputWriteMask) { 25538b02b912e1a55c912f603c4369431264d36a381Zhongxing Xu code->alu.inst[ip].rgb_addr |= 25638b02b912e1a55c912f603c4369431264d36a381Zhongxing Xu (inst->RGB.OutputWriteMask << R300_ALU_DSTC_OUTPUT_MASK_SHIFT) | 25738b02b912e1a55c912f603c4369431264d36a381Zhongxing Xu R300_RGB_TARGET(inst->RGB.Target); 2585fe4d9deb543a19f557e3d85c5f33867af97cd96Ted Kremenek emit->node_flags |= R300_RGBA_OUT; 2595fe4d9deb543a19f557e3d85c5f33867af97cd96Ted Kremenek } 2605fe4d9deb543a19f557e3d85c5f33867af97cd96Ted Kremenek 2611eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump if (inst->Alpha.WriteMask) { 26239b4c6c98d391b25c376782cf92346aa88c96f7eTed Kremenek use_temporary(code, inst->Alpha.DestIndex); 26339b4c6c98d391b25c376782cf92346aa88c96f7eTed Kremenek if (inst->Alpha.DestIndex >= R300_PFS_NUM_TEMP_REGS) 264d767d81290288c030f3be0be1d3e62b9c8df51dcTed Kremenek code->alu.inst[ip].r400_ext_addr |= R400_ADDRD_EXT_A_MSB_BIT; 265d767d81290288c030f3be0be1d3e62b9c8df51dcTed Kremenek code->alu.inst[ip].alpha_addr |= 266d767d81290288c030f3be0be1d3e62b9c8df51dcTed Kremenek ((inst->Alpha.DestIndex & 0x1f) << R300_ALU_DSTA_SHIFT) | 267d767d81290288c030f3be0be1d3e62b9c8df51dcTed Kremenek R300_ALU_DSTA_REG; 268d767d81290288c030f3be0be1d3e62b9c8df51dcTed Kremenek } 269d767d81290288c030f3be0be1d3e62b9c8df51dcTed Kremenek if (inst->Alpha.OutputWriteMask) { 270d767d81290288c030f3be0be1d3e62b9c8df51dcTed Kremenek code->alu.inst[ip].alpha_addr |= R300_ALU_DSTA_OUTPUT | 271d767d81290288c030f3be0be1d3e62b9c8df51dcTed Kremenek R300_ALPHA_TARGET(inst->Alpha.Target); 272d767d81290288c030f3be0be1d3e62b9c8df51dcTed Kremenek emit->node_flags |= R300_RGBA_OUT; 2734241b3d1ad87e9a593bbc6cdf0f49435d5aec235Ted Kremenek } 27438b02b912e1a55c912f603c4369431264d36a381Zhongxing Xu if (inst->Alpha.DepthWriteMask) { 27538b02b912e1a55c912f603c4369431264d36a381Zhongxing Xu code->alu.inst[ip].alpha_addr |= R300_ALU_DSTA_DEPTH; 27638b02b912e1a55c912f603c4369431264d36a381Zhongxing Xu emit->node_flags |= R300_W_OUT; 27738b02b912e1a55c912f603c4369431264d36a381Zhongxing Xu c->code->writes_depth = 1; 27838b02b912e1a55c912f603c4369431264d36a381Zhongxing Xu } 27938b02b912e1a55c912f603c4369431264d36a381Zhongxing Xu if (inst->Nop) 28018c66fdc3c4008d335885695fe36fb5353c5f672Ted Kremenek code->alu.inst[ip].rgb_inst |= R300_ALU_INSERT_NOP; 28138b02b912e1a55c912f603c4369431264d36a381Zhongxing Xu 2821eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump /* Handle Output Modifier 28338b02b912e1a55c912f603c4369431264d36a381Zhongxing Xu * According to the r300 docs, there is no RC_OMOD_DISABLE for r300 */ 284c77a55126fcad66fb086f8e100a494caa2496a2dZhongxing Xu if (inst->RGB.Omod) { 28538b02b912e1a55c912f603c4369431264d36a381Zhongxing Xu if (inst->RGB.Omod == RC_OMOD_DISABLE) { 2864a0f5f1646637fcf90eb236b5a46f40e5a5dd739Ted Kremenek rc_error(&c->Base, "RC_OMOD_DISABLE not supported"); 2874241b3d1ad87e9a593bbc6cdf0f49435d5aec235Ted Kremenek } 2889c378f705405d37f49795d5e915989de774fe11fTed Kremenek code->alu.inst[ip].rgb_inst |= 289ede5a4ba111f0590879670b6cb07f4d6d0bd9075Ted Kremenek (inst->RGB.Omod << R300_ALU_OUTC_MOD_SHIFT); 290ede5a4ba111f0590879670b6cb07f4d6d0bd9075Ted Kremenek } 291ede5a4ba111f0590879670b6cb07f4d6d0bd9075Ted Kremenek if (inst->Alpha.Omod) { 2924241b3d1ad87e9a593bbc6cdf0f49435d5aec235Ted Kremenek if (inst->Alpha.Omod == RC_OMOD_DISABLE) { 2934241b3d1ad87e9a593bbc6cdf0f49435d5aec235Ted Kremenek rc_error(&c->Base, "RC_OMOD_DISABLE not supported"); 2949c378f705405d37f49795d5e915989de774fe11fTed Kremenek } 295ede5a4ba111f0590879670b6cb07f4d6d0bd9075Ted Kremenek code->alu.inst[ip].alpha_inst |= 296ede5a4ba111f0590879670b6cb07f4d6d0bd9075Ted Kremenek (inst->Alpha.Omod << R300_ALU_OUTC_MOD_SHIFT); 297ede5a4ba111f0590879670b6cb07f4d6d0bd9075Ted Kremenek } 29838b02b912e1a55c912f603c4369431264d36a381Zhongxing Xu return 1; 299824c547dc5d4451b9dbacc56621592fa010878f4Ted Kremenek} 300824c547dc5d4451b9dbacc56621592fa010878f4Ted Kremenek 301824c547dc5d4451b9dbacc56621592fa010878f4Ted Kremenek 3024a0f5f1646637fcf90eb236b5a46f40e5a5dd739Ted Kremenek/** 303d767d81290288c030f3be0be1d3e62b9c8df51dcTed Kremenek * Finish the current node without advancing to the next one. 304d767d81290288c030f3be0be1d3e62b9c8df51dcTed Kremenek */ 3054241b3d1ad87e9a593bbc6cdf0f49435d5aec235Ted Kremenekstatic int finish_node(struct r300_emit_state * emit) 3064a0f5f1646637fcf90eb236b5a46f40e5a5dd739Ted Kremenek{ 3071eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump struct r300_fragment_program_compiler * c = emit->compiler; 30839b4c6c98d391b25c376782cf92346aa88c96f7eTed Kremenek struct r300_fragment_program_code *code = &emit->compiler->code->code.r300; 30939b4c6c98d391b25c376782cf92346aa88c96f7eTed Kremenek unsigned alu_offset; 310c5619d901a68dc27a9e310a6a831f03efebcd950Zhongxing Xu unsigned alu_end; 3114241b3d1ad87e9a593bbc6cdf0f49435d5aec235Ted Kremenek unsigned tex_offset; 31238b02b912e1a55c912f603c4369431264d36a381Zhongxing Xu unsigned tex_end; 31338b02b912e1a55c912f603c4369431264d36a381Zhongxing Xu 3147ebde953bb050caa69f791fc1de449d435c6a36fTed Kremenek unsigned int alu_offset_msbs, alu_end_msbs; 31538b02b912e1a55c912f603c4369431264d36a381Zhongxing Xu 3167ebde953bb050caa69f791fc1de449d435c6a36fTed Kremenek if (code->alu.length == emit->node_first_alu) { 31738b02b912e1a55c912f603c4369431264d36a381Zhongxing Xu /* Generate a single NOP for this node */ 31838b02b912e1a55c912f603c4369431264d36a381Zhongxing Xu struct rc_pair_instruction inst; 31938b02b912e1a55c912f603c4369431264d36a381Zhongxing Xu memset(&inst, 0, sizeof(inst)); 3201eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump if (!emit_alu(emit, &inst)) 32138b02b912e1a55c912f603c4369431264d36a381Zhongxing Xu return 0; 3227ebde953bb050caa69f791fc1de449d435c6a36fTed Kremenek } 32338b02b912e1a55c912f603c4369431264d36a381Zhongxing Xu 3241eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump alu_offset = emit->node_first_alu; 32538b02b912e1a55c912f603c4369431264d36a381Zhongxing Xu alu_end = code->alu.length - alu_offset - 1; 3261eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump tex_offset = emit->node_first_tex; 32738b02b912e1a55c912f603c4369431264d36a381Zhongxing Xu tex_end = code->tex.length - tex_offset - 1; 3281eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 32938b02b912e1a55c912f603c4369431264d36a381Zhongxing Xu if (code->tex.length == emit->node_first_tex) { 3301eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump if (emit->current_node > 0) { 33138b02b912e1a55c912f603c4369431264d36a381Zhongxing Xu error("Node %i has no TEX instructions", emit->current_node); 3321eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump return 0; 33338b02b912e1a55c912f603c4369431264d36a381Zhongxing Xu } 3341eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 3351eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump tex_end = 0; 3364241b3d1ad87e9a593bbc6cdf0f49435d5aec235Ted Kremenek } else { 33738b02b912e1a55c912f603c4369431264d36a381Zhongxing Xu if (emit->current_node == 0) 3381eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump code->config |= R300_PFS_CNTL_FIRST_NODE_HAS_TEX; 33938b02b912e1a55c912f603c4369431264d36a381Zhongxing Xu } 3401eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 34138b02b912e1a55c912f603c4369431264d36a381Zhongxing Xu /* Write the config register. 3421eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump * Note: The order in which the words for each node are written 34338b02b912e1a55c912f603c4369431264d36a381Zhongxing Xu * is not correct here and needs to be fixed up once we're entirely 34438b02b912e1a55c912f603c4369431264d36a381Zhongxing Xu * done 3455fe4d9deb543a19f557e3d85c5f33867af97cd96Ted Kremenek * 3465fe4d9deb543a19f557e3d85c5f33867af97cd96Ted Kremenek * Also note that the register specification from AMD is slightly 34738b02b912e1a55c912f603c4369431264d36a381Zhongxing Xu * incorrect in its description of this register. */ 34838b02b912e1a55c912f603c4369431264d36a381Zhongxing Xu code->code_addr[emit->current_node] = 34938b02b912e1a55c912f603c4369431264d36a381Zhongxing Xu ((alu_offset << R300_ALU_START_SHIFT) 350c5619d901a68dc27a9e310a6a831f03efebcd950Zhongxing Xu & R300_ALU_START_MASK) 351fe9e543a2a363df7fcaa899367d3b2580b63b27cTed Kremenek | ((alu_end << R300_ALU_SIZE_SHIFT) 35238b02b912e1a55c912f603c4369431264d36a381Zhongxing Xu & R300_ALU_SIZE_MASK) 353cf118d41f7930a18dce97416ef7834a62642f587Ted Kremenek | ((tex_offset << R300_TEX_START_SHIFT) 35438b02b912e1a55c912f603c4369431264d36a381Zhongxing Xu & R300_TEX_START_MASK) 35538b02b912e1a55c912f603c4369431264d36a381Zhongxing Xu | ((tex_end << R300_TEX_SIZE_SHIFT) 35638b02b912e1a55c912f603c4369431264d36a381Zhongxing Xu & R300_TEX_SIZE_MASK) 35738b02b912e1a55c912f603c4369431264d36a381Zhongxing Xu | emit->node_flags 358d767d81290288c030f3be0be1d3e62b9c8df51dcTed Kremenek | (get_msbs_tex(tex_offset, 5) 359d767d81290288c030f3be0be1d3e62b9c8df51dcTed Kremenek << R400_TEX_START_MSB_SHIFT) 360d767d81290288c030f3be0be1d3e62b9c8df51dcTed Kremenek | (get_msbs_tex(tex_end, 5) 361d767d81290288c030f3be0be1d3e62b9c8df51dcTed Kremenek << R400_TEX_SIZE_MSB_SHIFT) 362d767d81290288c030f3be0be1d3e62b9c8df51dcTed Kremenek ; 363d767d81290288c030f3be0be1d3e62b9c8df51dcTed Kremenek 364d767d81290288c030f3be0be1d3e62b9c8df51dcTed Kremenek /* Write r400 extended instruction fields. These will be ignored on 365d767d81290288c030f3be0be1d3e62b9c8df51dcTed Kremenek * r300 cards. */ 3664241b3d1ad87e9a593bbc6cdf0f49435d5aec235Ted Kremenek alu_offset_msbs = get_msbs_alu(alu_offset); 367cf118d41f7930a18dce97416ef7834a62642f587Ted Kremenek alu_end_msbs = get_msbs_alu(alu_end); 368f6f5ef4aaa66b60270e84d1fe1292886369d2f38Ted Kremenek switch(emit->current_node) { 369c5619d901a68dc27a9e310a6a831f03efebcd950Zhongxing Xu case 0: 370f6f5ef4aaa66b60270e84d1fe1292886369d2f38Ted Kremenek code->r400_code_offset_ext |= 3711eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump alu_offset_msbs << R400_ALU_START3_MSB_SHIFT 372f6f5ef4aaa66b60270e84d1fe1292886369d2f38Ted Kremenek | alu_end_msbs << R400_ALU_SIZE3_MSB_SHIFT; 3739c378f705405d37f49795d5e915989de774fe11fTed Kremenek break; 374c5619d901a68dc27a9e310a6a831f03efebcd950Zhongxing Xu case 1: 375f6f5ef4aaa66b60270e84d1fe1292886369d2f38Ted Kremenek code->r400_code_offset_ext |= 376f6f5ef4aaa66b60270e84d1fe1292886369d2f38Ted Kremenek alu_offset_msbs << R400_ALU_START2_MSB_SHIFT 3771eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump | alu_end_msbs << R400_ALU_SIZE2_MSB_SHIFT; 378f6f5ef4aaa66b60270e84d1fe1292886369d2f38Ted Kremenek break; 3791eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump case 2: 3809c378f705405d37f49795d5e915989de774fe11fTed Kremenek code->r400_code_offset_ext |= 381c5619d901a68dc27a9e310a6a831f03efebcd950Zhongxing Xu alu_offset_msbs << R400_ALU_START1_MSB_SHIFT 382f6f5ef4aaa66b60270e84d1fe1292886369d2f38Ted Kremenek | alu_end_msbs << R400_ALU_SIZE1_MSB_SHIFT; 3831eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump break; 3849c378f705405d37f49795d5e915989de774fe11fTed Kremenek case 3: 385cc2c6eb04d882466c7cfbb544c251d7e0ba0f356Ted Kremenek code->r400_code_offset_ext |= 386cc2c6eb04d882466c7cfbb544c251d7e0ba0f356Ted Kremenek alu_offset_msbs << R400_ALU_START0_MSB_SHIFT 387cc2c6eb04d882466c7cfbb544c251d7e0ba0f356Ted Kremenek | alu_end_msbs << R400_ALU_SIZE0_MSB_SHIFT; 3881eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump break; 389c5619d901a68dc27a9e310a6a831f03efebcd950Zhongxing Xu } 390c5619d901a68dc27a9e310a6a831f03efebcd950Zhongxing Xu return 1; 391f6f5ef4aaa66b60270e84d1fe1292886369d2f38Ted Kremenek} 392fee96e043108b6e24e7d4c5464bf89ac970a7f81Ted Kremenek 393fee96e043108b6e24e7d4c5464bf89ac970a7f81Ted Kremenek 394fee96e043108b6e24e7d4c5464bf89ac970a7f81Ted Kremenek/** 395fee96e043108b6e24e7d4c5464bf89ac970a7f81Ted Kremenek * Begin a block of texture instructions. 396fee96e043108b6e24e7d4c5464bf89ac970a7f81Ted Kremenek * Create the necessary indirection. 397fee96e043108b6e24e7d4c5464bf89ac970a7f81Ted Kremenek */ 398fee96e043108b6e24e7d4c5464bf89ac970a7f81Ted Kremenekstatic int begin_tex(struct r300_emit_state * emit) 399fee96e043108b6e24e7d4c5464bf89ac970a7f81Ted Kremenek{ 400fee96e043108b6e24e7d4c5464bf89ac970a7f81Ted Kremenek PROG_CODE; 401fee96e043108b6e24e7d4c5464bf89ac970a7f81Ted Kremenek 4021eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump if (code->alu.length == emit->node_first_alu && 403f6f5ef4aaa66b60270e84d1fe1292886369d2f38Ted Kremenek code->tex.length == emit->node_first_tex) { 404f6f5ef4aaa66b60270e84d1fe1292886369d2f38Ted Kremenek return 1; 4051eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump } 406f6f5ef4aaa66b60270e84d1fe1292886369d2f38Ted Kremenek 407f6f5ef4aaa66b60270e84d1fe1292886369d2f38Ted Kremenek if (emit->current_node == 3) { 4081eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump error("Too many texture indirections"); 4091eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump return 0; 4105a4f98ff943e6a501b0fe47ade007c9bbf96cb88Argyrios Kyrtzidis } 4115a4f98ff943e6a501b0fe47ade007c9bbf96cb88Argyrios Kyrtzidis 4124241b3d1ad87e9a593bbc6cdf0f49435d5aec235Ted Kremenek if (!finish_node(emit)) 4134241b3d1ad87e9a593bbc6cdf0f49435d5aec235Ted Kremenek return 0; 4144a0f5f1646637fcf90eb236b5a46f40e5a5dd739Ted Kremenek 4154a0f5f1646637fcf90eb236b5a46f40e5a5dd739Ted Kremenek emit->current_node++; 4164a0f5f1646637fcf90eb236b5a46f40e5a5dd739Ted Kremenek emit->node_first_tex = code->tex.length; 4179ef6537a894c33003359b1f9b9676e9178e028b7Ted Kremenek emit->node_first_alu = code->alu.length; 4189ef6537a894c33003359b1f9b9676e9178e028b7Ted Kremenek emit->node_flags = 0; 419c5619d901a68dc27a9e310a6a831f03efebcd950Zhongxing Xu return 1; 4204a0f5f1646637fcf90eb236b5a46f40e5a5dd739Ted Kremenek} 4211eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 4224a0f5f1646637fcf90eb236b5a46f40e5a5dd739Ted Kremenek 4234a0f5f1646637fcf90eb236b5a46f40e5a5dd739Ted Kremenekstatic int emit_tex(struct r300_emit_state * emit, struct rc_instruction * inst) 4244a0f5f1646637fcf90eb236b5a46f40e5a5dd739Ted Kremenek{ 4251eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump unsigned int unit; 4264a0f5f1646637fcf90eb236b5a46f40e5a5dd739Ted Kremenek unsigned int dest; 4274a0f5f1646637fcf90eb236b5a46f40e5a5dd739Ted Kremenek unsigned int opcode; 4284a0f5f1646637fcf90eb236b5a46f40e5a5dd739Ted Kremenek PROG_CODE; 4291eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 4304a0f5f1646637fcf90eb236b5a46f40e5a5dd739Ted Kremenek if (code->tex.length >= emit->compiler->Base.max_tex_insts) { 4314a0f5f1646637fcf90eb236b5a46f40e5a5dd739Ted Kremenek error("Too many TEX instructions"); 4324a0f5f1646637fcf90eb236b5a46f40e5a5dd739Ted Kremenek return 0; 4331eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump } 4344a0f5f1646637fcf90eb236b5a46f40e5a5dd739Ted Kremenek 4354a0f5f1646637fcf90eb236b5a46f40e5a5dd739Ted Kremenek unit = inst->U.I.TexSrcUnit; 4364a0f5f1646637fcf90eb236b5a46f40e5a5dd739Ted Kremenek dest = inst->U.I.DstReg.Index; 4371eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 4384a0f5f1646637fcf90eb236b5a46f40e5a5dd739Ted Kremenek switch(inst->U.I.Opcode) { 4394a0f5f1646637fcf90eb236b5a46f40e5a5dd739Ted Kremenek case RC_OPCODE_KIL: opcode = R300_TEX_OP_KIL; break; 4404a0f5f1646637fcf90eb236b5a46f40e5a5dd739Ted Kremenek case RC_OPCODE_TEX: opcode = R300_TEX_OP_LD; break; 4414a0f5f1646637fcf90eb236b5a46f40e5a5dd739Ted Kremenek case RC_OPCODE_TXB: opcode = R300_TEX_OP_TXB; break; 4421eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump case RC_OPCODE_TXP: opcode = R300_TEX_OP_TXP; break; 4439ef6537a894c33003359b1f9b9676e9178e028b7Ted Kremenek default: 4449ef6537a894c33003359b1f9b9676e9178e028b7Ted Kremenek error("Unknown texture opcode %s", rc_get_opcode_info(inst->U.I.Opcode)->Name); 445c5619d901a68dc27a9e310a6a831f03efebcd950Zhongxing Xu return 0; 4464a0f5f1646637fcf90eb236b5a46f40e5a5dd739Ted Kremenek } 4471eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 4484a0f5f1646637fcf90eb236b5a46f40e5a5dd739Ted Kremenek if (inst->U.I.Opcode == RC_OPCODE_KIL) { 4494a0f5f1646637fcf90eb236b5a46f40e5a5dd739Ted Kremenek unit = 0; 4504a0f5f1646637fcf90eb236b5a46f40e5a5dd739Ted Kremenek dest = 0; 4511eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump } else { 4524a0f5f1646637fcf90eb236b5a46f40e5a5dd739Ted Kremenek use_temporary(code, dest); 4534a0f5f1646637fcf90eb236b5a46f40e5a5dd739Ted Kremenek } 4544a0f5f1646637fcf90eb236b5a46f40e5a5dd739Ted Kremenek 4551eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump use_temporary(code, inst->U.I.SrcReg[0].Index); 4564a0f5f1646637fcf90eb236b5a46f40e5a5dd739Ted Kremenek 4574a0f5f1646637fcf90eb236b5a46f40e5a5dd739Ted Kremenek code->tex.inst[code->tex.length++] = 4584a0f5f1646637fcf90eb236b5a46f40e5a5dd739Ted Kremenek ((inst->U.I.SrcReg[0].Index << R300_SRC_ADDR_SHIFT) 4591eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump & R300_SRC_ADDR_MASK) 4604a0f5f1646637fcf90eb236b5a46f40e5a5dd739Ted Kremenek | ((dest << R300_DST_ADDR_SHIFT) 4614a0f5f1646637fcf90eb236b5a46f40e5a5dd739Ted Kremenek & R300_DST_ADDR_MASK) 4624a0f5f1646637fcf90eb236b5a46f40e5a5dd739Ted Kremenek | (unit << R300_TEX_ID_SHIFT) 4631eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump | (opcode << R300_TEX_INST_SHIFT) 4644a0f5f1646637fcf90eb236b5a46f40e5a5dd739Ted Kremenek | (inst->U.I.SrcReg[0].Index >= R300_PFS_NUM_TEMP_REGS ? 4654a0f5f1646637fcf90eb236b5a46f40e5a5dd739Ted Kremenek R400_SRC_ADDR_EXT_BIT : 0) 4664a0f5f1646637fcf90eb236b5a46f40e5a5dd739Ted Kremenek | (dest >= R300_PFS_NUM_TEMP_REGS ? 4674a0f5f1646637fcf90eb236b5a46f40e5a5dd739Ted Kremenek R400_DST_ADDR_EXT_BIT : 0) 4681eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump ; 4694a0f5f1646637fcf90eb236b5a46f40e5a5dd739Ted Kremenek return 1; 4704a0f5f1646637fcf90eb236b5a46f40e5a5dd739Ted Kremenek} 4714241b3d1ad87e9a593bbc6cdf0f49435d5aec235Ted Kremenek 472 473/** 474 * Final compilation step: Turn the intermediate radeon_program into 475 * machine-readable instructions. 476 */ 477void r300BuildFragmentProgramHwCode(struct radeon_compiler *c, void *user) 478{ 479 struct r300_fragment_program_compiler *compiler = (struct r300_fragment_program_compiler*)c; 480 struct r300_emit_state emit; 481 struct r300_fragment_program_code *code = &compiler->code->code.r300; 482 unsigned int tex_end; 483 484 memset(&emit, 0, sizeof(emit)); 485 emit.compiler = compiler; 486 487 memset(code, 0, sizeof(struct r300_fragment_program_code)); 488 489 for(struct rc_instruction * inst = compiler->Base.Program.Instructions.Next; 490 inst != &compiler->Base.Program.Instructions && !compiler->Base.Error; 491 inst = inst->Next) { 492 if (inst->Type == RC_INSTRUCTION_NORMAL) { 493 if (inst->U.I.Opcode == RC_OPCODE_BEGIN_TEX) { 494 begin_tex(&emit); 495 continue; 496 } 497 498 emit_tex(&emit, inst); 499 } else { 500 emit_alu(&emit, &inst->U.P); 501 } 502 } 503 504 if (code->pixsize >= compiler->Base.max_temp_regs) 505 rc_error(&compiler->Base, "Too many hardware temporaries used.\n"); 506 507 if (compiler->Base.Error) 508 return; 509 510 /* Finish the program */ 511 finish_node(&emit); 512 513 code->config |= emit.current_node; /* FIRST_NODE_HAS_TEX set by finish_node */ 514 515 /* Set r400 extended instruction fields. These values will be ignored 516 * on r300 cards. */ 517 code->r400_code_offset_ext |= 518 (get_msbs_alu(0) 519 << R400_ALU_OFFSET_MSB_SHIFT) 520 | (get_msbs_alu(code->alu.length - 1) 521 << R400_ALU_SIZE_MSB_SHIFT); 522 523 tex_end = code->tex.length ? code->tex.length - 1 : 0; 524 code->code_offset = 525 ((0 << R300_PFS_CNTL_ALU_OFFSET_SHIFT) 526 & R300_PFS_CNTL_ALU_OFFSET_MASK) 527 | (((code->alu.length - 1) << R300_PFS_CNTL_ALU_END_SHIFT) 528 & R300_PFS_CNTL_ALU_END_MASK) 529 | ((0 << R300_PFS_CNTL_TEX_OFFSET_SHIFT) 530 & R300_PFS_CNTL_TEX_OFFSET_MASK) 531 | ((tex_end << R300_PFS_CNTL_TEX_END_SHIFT) 532 & R300_PFS_CNTL_TEX_END_MASK) 533 | (get_msbs_tex(0, 5) << R400_TEX_START_MSB_SHIFT) 534 | (get_msbs_tex(tex_end, 6) << R400_TEX_SIZE_MSB_SHIFT) 535 ; 536 537 if (emit.current_node < 3) { 538 int shift = 3 - emit.current_node; 539 int i; 540 for(i = emit.current_node; i >= 0; --i) 541 code->code_addr[shift + i] = code->code_addr[i]; 542 for(i = 0; i < shift; ++i) 543 code->code_addr[i] = 0; 544 } 545 546 if (code->pixsize >= R300_PFS_NUM_TEMP_REGS 547 || code->alu.length > R300_PFS_MAX_ALU_INST 548 || code->tex.length > R300_PFS_MAX_TEX_INST) { 549 550 code->r390_mode = 1; 551 } 552} 553