1f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/* 2f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Copyright (C) 2010 Corbin Simpson 3f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Copyright (C) 2010 Marek Olšák <maraeo@gmail.com> 4f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * 5f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * All Rights Reserved. 6f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * 7f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Permission is hereby granted, free of charge, to any person obtaining 8f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * a copy of this software and associated documentation files (the 9f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * "Software"), to deal in the Software without restriction, including 10f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * without limitation the rights to use, copy, modify, merge, publish, 11f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * distribute, sublicense, and/or sell copies of the Software, and to 12f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * permit persons to whom the Software is furnished to do so, subject to 13f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * the following conditions: 14f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * 15f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * The above copyright notice and this permission notice (including the 16f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * next paragraph) shall be included in all copies or substantial 17f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * portions of the Software. 18f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * 19f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 20f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 21f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 22f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE 23f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 24f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 25f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 26f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * 27f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */ 28f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 29f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "radeon_program_tex.h" 30f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 31f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "radeon_compiler_util.h" 32f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 33f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/* Series of transformations to be done on textures. */ 34f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 35f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic struct rc_src_register shadow_fail_value(struct r300_fragment_program_compiler *compiler, 36f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org int tmu) 37f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 38f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct rc_src_register reg = { 0, 0, 0, 0, 0, 0 }; 39f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 40f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org reg.File = RC_FILE_NONE; 41f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org reg.Swizzle = combine_swizzles(RC_SWIZZLE_0000, 42f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org compiler->state.unit[tmu].texture_swizzle); 43f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return reg; 44f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 45f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 46f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic struct rc_src_register shadow_pass_value(struct r300_fragment_program_compiler *compiler, 47f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org int tmu) 48f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 49f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct rc_src_register reg = { 0, 0, 0, 0, 0, 0 }; 50f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 51f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org reg.File = RC_FILE_NONE; 52f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org reg.Swizzle = combine_swizzles(RC_SWIZZLE_1111, 53f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org compiler->state.unit[tmu].texture_swizzle); 54f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return reg; 55f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 56f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 57f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic void scale_texcoords(struct r300_fragment_program_compiler *compiler, 58f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct rc_instruction *inst, 59f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org unsigned state_constant) 60f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 61f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct rc_instruction *inst_mov; 62f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 63f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org unsigned temp = rc_find_free_temporary(&compiler->Base); 64f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 65f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org inst_mov = rc_insert_new_instruction(&compiler->Base, inst->Prev); 66f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 67f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org inst_mov->U.I.Opcode = RC_OPCODE_MUL; 68f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org inst_mov->U.I.DstReg.File = RC_FILE_TEMPORARY; 69f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org inst_mov->U.I.DstReg.Index = temp; 70f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org inst_mov->U.I.SrcReg[0] = inst->U.I.SrcReg[0]; 71f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org inst_mov->U.I.SrcReg[1].File = RC_FILE_CONSTANT; 72f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org inst_mov->U.I.SrcReg[1].Index = 73f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org rc_constants_add_state(&compiler->Base.Program.Constants, 74f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org state_constant, inst->U.I.TexSrcUnit); 75f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 76f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org reset_srcreg(&inst->U.I.SrcReg[0]); 77f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org inst->U.I.SrcReg[0].File = RC_FILE_TEMPORARY; 78f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org inst->U.I.SrcReg[0].Index = temp; 79f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 80f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 81f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic void projective_divide(struct r300_fragment_program_compiler *compiler, 82f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct rc_instruction *inst) 83f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 84f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct rc_instruction *inst_mul, *inst_rcp; 85f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 86f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org unsigned temp = rc_find_free_temporary(&compiler->Base); 87f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 88f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org inst_rcp = rc_insert_new_instruction(&compiler->Base, inst->Prev); 89f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org inst_rcp->U.I.Opcode = RC_OPCODE_RCP; 90f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org inst_rcp->U.I.DstReg.File = RC_FILE_TEMPORARY; 91f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org inst_rcp->U.I.DstReg.Index = temp; 92f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org inst_rcp->U.I.DstReg.WriteMask = RC_MASK_W; 93f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org inst_rcp->U.I.SrcReg[0] = inst->U.I.SrcReg[0]; 94f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* Because the input can be arbitrarily swizzled, 95f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * read the component mapped to W. */ 96f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org inst_rcp->U.I.SrcReg[0].Swizzle = 97f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org RC_MAKE_SWIZZLE_SMEAR(GET_SWZ(inst->U.I.SrcReg[0].Swizzle, 3)); 98f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 99f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org inst_mul = rc_insert_new_instruction(&compiler->Base, inst->Prev); 100f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org inst_mul->U.I.Opcode = RC_OPCODE_MUL; 101f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org inst_mul->U.I.DstReg.File = RC_FILE_TEMPORARY; 102f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org inst_mul->U.I.DstReg.Index = temp; 103f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org inst_mul->U.I.SrcReg[0] = inst->U.I.SrcReg[0]; 104f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org inst_mul->U.I.SrcReg[1].File = RC_FILE_TEMPORARY; 105f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org inst_mul->U.I.SrcReg[1].Index = temp; 106f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org inst_mul->U.I.SrcReg[1].Swizzle = RC_SWIZZLE_WWWW; 107f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 108f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org reset_srcreg(&inst->U.I.SrcReg[0]); 109f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org inst->U.I.Opcode = RC_OPCODE_TEX; 110f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org inst->U.I.SrcReg[0].File = RC_FILE_TEMPORARY; 111f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org inst->U.I.SrcReg[0].Index = temp; 112f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 113f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 114f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/** 115f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Transform TEX, TXP, TXB, and KIL instructions in the following ways: 116f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * - implement texture compare (shadow extensions) 117f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * - extract non-native source / destination operands 118f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * - premultiply texture coordinates for RECT 119f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * - extract operand swizzles 120f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * - introduce a temporary register when write masks are needed 121f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */ 122f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgint radeonTransformTEX( 123f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct radeon_compiler * c, 124f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct rc_instruction * inst, 125f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org void* data) 126f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 127f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct r300_fragment_program_compiler *compiler = 128f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org (struct r300_fragment_program_compiler*)data; 129f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org rc_wrap_mode wrapmode = compiler->state.unit[inst->U.I.TexSrcUnit].wrap_mode; 130f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org int is_rect = inst->U.I.TexSrcTarget == RC_TEXTURE_RECT || 131f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org compiler->state.unit[inst->U.I.TexSrcUnit].non_normalized_coords; 132f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 133f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (inst->U.I.Opcode != RC_OPCODE_TEX && 134f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org inst->U.I.Opcode != RC_OPCODE_TXB && 135f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org inst->U.I.Opcode != RC_OPCODE_TXP && 136f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org inst->U.I.Opcode != RC_OPCODE_TXD && 137f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org inst->U.I.Opcode != RC_OPCODE_TXL && 138f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org inst->U.I.Opcode != RC_OPCODE_KIL) 139f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return 0; 140f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 141f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* ARB_shadow & EXT_shadow_funcs */ 142f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (inst->U.I.Opcode != RC_OPCODE_KIL && 143f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ((c->Program.ShadowSamplers & (1 << inst->U.I.TexSrcUnit)) || 144f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org (compiler->state.unit[inst->U.I.TexSrcUnit].compare_mode_enabled))) { 145f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org rc_compare_func comparefunc = compiler->state.unit[inst->U.I.TexSrcUnit].texture_compare_func; 146f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 147f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (comparefunc == RC_COMPARE_FUNC_NEVER || comparefunc == RC_COMPARE_FUNC_ALWAYS) { 148f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org inst->U.I.Opcode = RC_OPCODE_MOV; 149f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 150f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (comparefunc == RC_COMPARE_FUNC_ALWAYS) { 151f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org inst->U.I.SrcReg[0] = shadow_pass_value(compiler, inst->U.I.TexSrcUnit); 152f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } else { 153f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org inst->U.I.SrcReg[0] = shadow_fail_value(compiler, inst->U.I.TexSrcUnit); 154f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 155f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 156f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return 1; 157f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } else { 158f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct rc_instruction * inst_rcp = NULL; 159f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct rc_instruction *inst_mul, *inst_add, *inst_cmp; 160f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org unsigned tmp_texsample; 161f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org unsigned tmp_sum; 162f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org int pass, fail; 163f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 164f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* Save the output register. */ 165f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct rc_dst_register output_reg = inst->U.I.DstReg; 166f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org unsigned saturate_mode = inst->U.I.SaturateMode; 167f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 168f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* Redirect TEX to a new temp. */ 169f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org tmp_texsample = rc_find_free_temporary(c); 170f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org inst->U.I.SaturateMode = 0; 171f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org inst->U.I.DstReg.File = RC_FILE_TEMPORARY; 172f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org inst->U.I.DstReg.Index = tmp_texsample; 173f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org inst->U.I.DstReg.WriteMask = RC_MASK_XYZW; 174f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 175f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org tmp_sum = rc_find_free_temporary(c); 176f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 177f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (inst->U.I.Opcode == RC_OPCODE_TXP) { 178f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* Compute 1/W. */ 179f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org inst_rcp = rc_insert_new_instruction(c, inst); 180f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org inst_rcp->U.I.Opcode = RC_OPCODE_RCP; 181f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org inst_rcp->U.I.DstReg.File = RC_FILE_TEMPORARY; 182f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org inst_rcp->U.I.DstReg.Index = tmp_sum; 183f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org inst_rcp->U.I.DstReg.WriteMask = RC_MASK_W; 184f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org inst_rcp->U.I.SrcReg[0] = inst->U.I.SrcReg[0]; 185f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org inst_rcp->U.I.SrcReg[0].Swizzle = 186f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org RC_MAKE_SWIZZLE_SMEAR(GET_SWZ(inst->U.I.SrcReg[0].Swizzle, 3)); 187f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 188f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 189f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* Divide Z by W (if it's TXP) and saturate. */ 190f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org inst_mul = rc_insert_new_instruction(c, inst_rcp ? inst_rcp : inst); 191f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org inst_mul->U.I.Opcode = inst->U.I.Opcode == RC_OPCODE_TXP ? RC_OPCODE_MUL : RC_OPCODE_MOV; 192f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org inst_mul->U.I.DstReg.File = RC_FILE_TEMPORARY; 193f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org inst_mul->U.I.DstReg.Index = tmp_sum; 194f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org inst_mul->U.I.DstReg.WriteMask = RC_MASK_W; 195f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org inst_mul->U.I.SaturateMode = RC_SATURATE_ZERO_ONE; 196f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org inst_mul->U.I.SrcReg[0] = inst->U.I.SrcReg[0]; 197f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org inst_mul->U.I.SrcReg[0].Swizzle = 198f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org RC_MAKE_SWIZZLE_SMEAR(GET_SWZ(inst->U.I.SrcReg[0].Swizzle, 2)); 199f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (inst->U.I.Opcode == RC_OPCODE_TXP) { 200f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org inst_mul->U.I.SrcReg[1].File = RC_FILE_TEMPORARY; 201f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org inst_mul->U.I.SrcReg[1].Index = tmp_sum; 202f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org inst_mul->U.I.SrcReg[1].Swizzle = RC_SWIZZLE_WWWW; 203f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 204f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 205f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* Add the depth texture value. */ 206f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org inst_add = rc_insert_new_instruction(c, inst_mul); 207f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org inst_add->U.I.Opcode = RC_OPCODE_ADD; 208f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org inst_add->U.I.DstReg.File = RC_FILE_TEMPORARY; 209f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org inst_add->U.I.DstReg.Index = tmp_sum; 210f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org inst_add->U.I.DstReg.WriteMask = RC_MASK_W; 211f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org inst_add->U.I.SrcReg[0].File = RC_FILE_TEMPORARY; 212f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org inst_add->U.I.SrcReg[0].Index = tmp_sum; 213f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org inst_add->U.I.SrcReg[0].Swizzle = RC_SWIZZLE_WWWW; 214f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org inst_add->U.I.SrcReg[1].File = RC_FILE_TEMPORARY; 215f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org inst_add->U.I.SrcReg[1].Index = tmp_texsample; 216f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org inst_add->U.I.SrcReg[1].Swizzle = RC_SWIZZLE_XXXX; 217f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 218f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* Note that SrcReg[0] is r, SrcReg[1] is tex and: 219f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * LESS: r < tex <=> -tex+r < 0 220f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * GEQUAL: r >= tex <=> not (-tex+r < 0) 221f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * GREATER: r > tex <=> tex-r < 0 222f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * LEQUAL: r <= tex <=> not ( tex-r < 0) 223f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * EQUAL: GEQUAL 224f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * NOTEQUAL:LESS 225f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */ 226f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 227f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* This negates either r or tex: */ 228f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (comparefunc == RC_COMPARE_FUNC_LESS || comparefunc == RC_COMPARE_FUNC_GEQUAL || 229f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org comparefunc == RC_COMPARE_FUNC_EQUAL || comparefunc == RC_COMPARE_FUNC_NOTEQUAL) 230f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org inst_add->U.I.SrcReg[1].Negate = inst_add->U.I.SrcReg[1].Negate ^ RC_MASK_XYZW; 231f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org else 232f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org inst_add->U.I.SrcReg[0].Negate = inst_add->U.I.SrcReg[0].Negate ^ RC_MASK_XYZW; 233f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 234f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* This negates the whole expresion: */ 235f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (comparefunc == RC_COMPARE_FUNC_LESS || comparefunc == RC_COMPARE_FUNC_GREATER || 236f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org comparefunc == RC_COMPARE_FUNC_NOTEQUAL) { 237f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org pass = 1; 238f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org fail = 2; 239f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } else { 240f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org pass = 2; 241f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org fail = 1; 242f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 243f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 244f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org inst_cmp = rc_insert_new_instruction(c, inst_add); 245f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org inst_cmp->U.I.Opcode = RC_OPCODE_CMP; 246f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org inst_cmp->U.I.SaturateMode = saturate_mode; 247f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org inst_cmp->U.I.DstReg = output_reg; 248f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org inst_cmp->U.I.SrcReg[0].File = RC_FILE_TEMPORARY; 249f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org inst_cmp->U.I.SrcReg[0].Index = tmp_sum; 250f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org inst_cmp->U.I.SrcReg[0].Swizzle = 251f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org combine_swizzles(RC_SWIZZLE_WWWW, 252f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org compiler->state.unit[inst->U.I.TexSrcUnit].texture_swizzle); 253f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org inst_cmp->U.I.SrcReg[pass] = shadow_pass_value(compiler, inst->U.I.TexSrcUnit); 254f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org inst_cmp->U.I.SrcReg[fail] = shadow_fail_value(compiler, inst->U.I.TexSrcUnit); 255f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 256f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org assert(tmp_texsample != tmp_sum); 257f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 258f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 259f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 260f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* R300 cannot sample from rectangles and the wrap mode fallback needs 261f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * normalized coordinates anyway. */ 262f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (inst->U.I.Opcode != RC_OPCODE_KIL && 263f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org is_rect && (!c->is_r500 || wrapmode != RC_WRAP_NONE)) { 264f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org scale_texcoords(compiler, inst, RC_STATE_R300_TEXRECT_FACTOR); 265f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org inst->U.I.TexSrcTarget = RC_TEXTURE_2D; 266f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 267f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 268f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* Divide by W if needed. */ 269f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (inst->U.I.Opcode == RC_OPCODE_TXP && 270f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org (wrapmode == RC_WRAP_REPEAT || wrapmode == RC_WRAP_MIRRORED_REPEAT || 271f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org compiler->state.unit[inst->U.I.TexSrcUnit].clamp_and_scale_before_fetch)) { 272f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org projective_divide(compiler, inst); 273f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 274f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 275f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* Texture wrap modes don't work on NPOT textures. 276f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * 277f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Non-wrapped/clamped texcoords with NPOT are free in HW. Repeat and 278f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * mirroring are not. If we need to repeat, we do: 279f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * 280f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * MUL temp, texcoord, <scaling factor constant> 281f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * FRC temp, temp ; Discard integer portion of coords 282f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * 283f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * This gives us coords in [0, 1]. 284f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * 285f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Mirroring is trickier. We're going to start out like repeat: 286f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * 287f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * MUL temp, texcoord, <scaling factor constant> ; De-mirror across axes 288f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * MUL temp, temp, 0.5 ; Pattern repeats in [0, 2] 289f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * ; so scale to [0, 1] 290f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * FRC temp, temp ; Make the pattern repeat 291f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * MAD temp, temp, 2, -1 ; Move the pattern to [-1, 1] 292f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * ADD temp, 1, -abs(temp) ; Now comes a neat trick: use abs to mirror the pattern. 293f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * ; The pattern is backwards, so reverse it (1-x). 294f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * 295f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * This gives us coords in [0, 1]. 296f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * 297f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * ~ C & M. ;) 298f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */ 299f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (inst->U.I.Opcode != RC_OPCODE_KIL && 300f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org wrapmode != RC_WRAP_NONE) { 301f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct rc_instruction *inst_mov; 302f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org unsigned temp = rc_find_free_temporary(c); 303f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 304f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (wrapmode == RC_WRAP_REPEAT) { 305f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* Both instructions will be paired up. */ 306f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct rc_instruction *inst_frc = rc_insert_new_instruction(c, inst->Prev); 307f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 308f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org inst_frc->U.I.Opcode = RC_OPCODE_FRC; 309f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org inst_frc->U.I.DstReg.File = RC_FILE_TEMPORARY; 310f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org inst_frc->U.I.DstReg.Index = temp; 311f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org inst_frc->U.I.DstReg.WriteMask = RC_MASK_XYZ; 312f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org inst_frc->U.I.SrcReg[0] = inst->U.I.SrcReg[0]; 313f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } else if (wrapmode == RC_WRAP_MIRRORED_REPEAT) { 314f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* 315f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Function: 316f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * f(v) = 1 - abs(frac(v * 0.5) * 2 - 1) 317f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * 318f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Code: 319f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * MUL temp, src0, 0.5 320f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * FRC temp, temp 321f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * MAD temp, temp, 2, -1 322f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * ADD temp, 1, -abs(temp) 323f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */ 324f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 325f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct rc_instruction *inst_mul, *inst_frc, *inst_mad, *inst_add; 326f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org unsigned two, two_swizzle; 327f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 328f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org inst_mul = rc_insert_new_instruction(c, inst->Prev); 329f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 330f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org inst_mul->U.I.Opcode = RC_OPCODE_MUL; 331f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org inst_mul->U.I.DstReg.File = RC_FILE_TEMPORARY; 332f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org inst_mul->U.I.DstReg.Index = temp; 333f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org inst_mul->U.I.DstReg.WriteMask = RC_MASK_XYZ; 334f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org inst_mul->U.I.SrcReg[0] = inst->U.I.SrcReg[0]; 335f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org inst_mul->U.I.SrcReg[1].Swizzle = RC_SWIZZLE_HHHH; 336f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 337f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org inst_frc = rc_insert_new_instruction(c, inst->Prev); 338f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 339f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org inst_frc->U.I.Opcode = RC_OPCODE_FRC; 340f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org inst_frc->U.I.DstReg.File = RC_FILE_TEMPORARY; 341f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org inst_frc->U.I.DstReg.Index = temp; 342f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org inst_frc->U.I.DstReg.WriteMask = RC_MASK_XYZ; 343f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org inst_frc->U.I.SrcReg[0].File = RC_FILE_TEMPORARY; 344f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org inst_frc->U.I.SrcReg[0].Index = temp; 345f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org inst_frc->U.I.SrcReg[0].Swizzle = RC_SWIZZLE_XYZ0; 346f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 347f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org two = rc_constants_add_immediate_scalar(&c->Program.Constants, 2, &two_swizzle); 348f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org inst_mad = rc_insert_new_instruction(c, inst->Prev); 349f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 350f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org inst_mad->U.I.Opcode = RC_OPCODE_MAD; 351f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org inst_mad->U.I.DstReg.File = RC_FILE_TEMPORARY; 352f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org inst_mad->U.I.DstReg.Index = temp; 353f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org inst_mad->U.I.DstReg.WriteMask = RC_MASK_XYZ; 354f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org inst_mad->U.I.SrcReg[0].File = RC_FILE_TEMPORARY; 355f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org inst_mad->U.I.SrcReg[0].Index = temp; 356f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org inst_mad->U.I.SrcReg[0].Swizzle = RC_SWIZZLE_XYZ0; 357f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org inst_mad->U.I.SrcReg[1].File = RC_FILE_CONSTANT; 358f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org inst_mad->U.I.SrcReg[1].Index = two; 359f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org inst_mad->U.I.SrcReg[1].Swizzle = two_swizzle; 360f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org inst_mad->U.I.SrcReg[2].Swizzle = RC_SWIZZLE_1111; 361f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org inst_mad->U.I.SrcReg[2].Negate = RC_MASK_XYZ; 362f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 363f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org inst_add = rc_insert_new_instruction(c, inst->Prev); 364f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 365f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org inst_add->U.I.Opcode = RC_OPCODE_ADD; 366f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org inst_add->U.I.DstReg.File = RC_FILE_TEMPORARY; 367f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org inst_add->U.I.DstReg.Index = temp; 368f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org inst_add->U.I.DstReg.WriteMask = RC_MASK_XYZ; 369f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org inst_add->U.I.SrcReg[0].Swizzle = RC_SWIZZLE_1111; 370f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org inst_add->U.I.SrcReg[1].File = RC_FILE_TEMPORARY; 371f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org inst_add->U.I.SrcReg[1].Index = temp; 372f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org inst_add->U.I.SrcReg[1].Swizzle = RC_SWIZZLE_XYZ0; 373f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org inst_add->U.I.SrcReg[1].Abs = 1; 374f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org inst_add->U.I.SrcReg[1].Negate = RC_MASK_XYZ; 375f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } else if (wrapmode == RC_WRAP_MIRRORED_CLAMP) { 376f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* 377f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Mirrored clamp modes are bloody simple, we just use abs 378f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * to mirror [0, 1] into [-1, 0]. This works for 379f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * all modes i.e. CLAMP, CLAMP_TO_EDGE, and CLAMP_TO_BORDER. 380f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */ 381f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct rc_instruction *inst_mov; 382f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 383f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org inst_mov = rc_insert_new_instruction(c, inst->Prev); 384f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 385f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org inst_mov->U.I.Opcode = RC_OPCODE_MOV; 386f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org inst_mov->U.I.DstReg.File = RC_FILE_TEMPORARY; 387f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org inst_mov->U.I.DstReg.Index = temp; 388f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org inst_mov->U.I.DstReg.WriteMask = RC_MASK_XYZ; 389f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org inst_mov->U.I.SrcReg[0] = inst->U.I.SrcReg[0]; 390f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org inst_mov->U.I.SrcReg[0].Abs = 1; 391f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 392f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 393f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* Preserve W for TXP/TXB. */ 394f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org inst_mov = rc_insert_new_instruction(c, inst->Prev); 395f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 396f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org inst_mov->U.I.Opcode = RC_OPCODE_MOV; 397f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org inst_mov->U.I.DstReg.File = RC_FILE_TEMPORARY; 398f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org inst_mov->U.I.DstReg.Index = temp; 399f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org inst_mov->U.I.DstReg.WriteMask = RC_MASK_W; 400f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org inst_mov->U.I.SrcReg[0] = inst->U.I.SrcReg[0]; 401f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 402f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org reset_srcreg(&inst->U.I.SrcReg[0]); 403f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org inst->U.I.SrcReg[0].File = RC_FILE_TEMPORARY; 404f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org inst->U.I.SrcReg[0].Index = temp; 405f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 406f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 407f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* NPOT -> POT conversion for 3D textures. */ 408f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (inst->U.I.Opcode != RC_OPCODE_KIL && 409f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org compiler->state.unit[inst->U.I.TexSrcUnit].clamp_and_scale_before_fetch) { 410f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct rc_instruction *inst_mov; 411f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org unsigned temp = rc_find_free_temporary(c); 412f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 413f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* Saturate XYZ. */ 414f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org inst_mov = rc_insert_new_instruction(c, inst->Prev); 415f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org inst_mov->U.I.Opcode = RC_OPCODE_MOV; 416f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org inst_mov->U.I.SaturateMode = RC_SATURATE_ZERO_ONE; 417f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org inst_mov->U.I.DstReg.File = RC_FILE_TEMPORARY; 418f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org inst_mov->U.I.DstReg.Index = temp; 419f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org inst_mov->U.I.DstReg.WriteMask = RC_MASK_XYZ; 420f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org inst_mov->U.I.SrcReg[0] = inst->U.I.SrcReg[0]; 421f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 422f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* Copy W. */ 423f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org inst_mov = rc_insert_new_instruction(c, inst->Prev); 424f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org inst_mov->U.I.Opcode = RC_OPCODE_MOV; 425f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org inst_mov->U.I.DstReg.File = RC_FILE_TEMPORARY; 426f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org inst_mov->U.I.DstReg.Index = temp; 427f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org inst_mov->U.I.DstReg.WriteMask = RC_MASK_W; 428f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org inst_mov->U.I.SrcReg[0] = inst->U.I.SrcReg[0]; 429f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 430f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org reset_srcreg(&inst->U.I.SrcReg[0]); 431f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org inst->U.I.SrcReg[0].File = RC_FILE_TEMPORARY; 432f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org inst->U.I.SrcReg[0].Index = temp; 433f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 434f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org scale_texcoords(compiler, inst, RC_STATE_R300_TEXSCALE_FACTOR); 435f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 436f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 437f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* Convert SNORM-encoded ATI1N sampled as UNORM to SNORM. 438f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Formula: dst = tex > 0.5 ? tex*2-2 : tex*2 439f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */ 440f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (inst->U.I.Opcode != RC_OPCODE_KIL && 441f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org compiler->state.unit[inst->U.I.TexSrcUnit].convert_unorm_to_snorm) { 442f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org unsigned two, two_swizzle; 443f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct rc_instruction *inst_mul, *inst_mad, *inst_cnd; 444f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 445f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org two = rc_constants_add_immediate_scalar(&c->Program.Constants, 2.35, &two_swizzle); 446f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 447f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org inst_mul = rc_insert_new_instruction(c, inst); 448f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org inst_mul->U.I.Opcode = RC_OPCODE_MUL; 449f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org inst_mul->U.I.DstReg.File = RC_FILE_TEMPORARY; 450f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org inst_mul->U.I.DstReg.Index = rc_find_free_temporary(c); 451f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org inst_mul->U.I.SrcReg[0].File = RC_FILE_TEMPORARY; 452f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org inst_mul->U.I.SrcReg[0].Index = rc_find_free_temporary(c); /* redirected TEX output */ 453f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org inst_mul->U.I.SrcReg[1].File = RC_FILE_CONSTANT; /* 2 */ 454f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org inst_mul->U.I.SrcReg[1].Index = two; 455f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org inst_mul->U.I.SrcReg[1].Swizzle = two_swizzle; 456f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 457f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org inst_mad = rc_insert_new_instruction(c, inst_mul); 458f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org inst_mad->U.I.Opcode = RC_OPCODE_MAD; 459f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org inst_mad->U.I.DstReg.File = RC_FILE_TEMPORARY; 460f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org inst_mad->U.I.DstReg.Index = rc_find_free_temporary(c); 461f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org inst_mad->U.I.SrcReg[0] = inst_mul->U.I.SrcReg[0]; /* redirected TEX output */ 462f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org inst_mad->U.I.SrcReg[1] = inst_mul->U.I.SrcReg[1]; /* 2 */ 463f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org inst_mad->U.I.SrcReg[2] = inst_mul->U.I.SrcReg[1]; /* 2 */ 464f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org inst_mad->U.I.SrcReg[2].Negate = RC_MASK_XYZW; 465f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 466f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org inst_cnd = rc_insert_new_instruction(c, inst_mad); 467f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org inst_cnd->U.I.Opcode = RC_OPCODE_CND; 468f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org inst_cnd->U.I.SaturateMode = inst->U.I.SaturateMode; 469f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org inst_cnd->U.I.DstReg = inst->U.I.DstReg; 470f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org inst_cnd->U.I.SrcReg[0].File = RC_FILE_TEMPORARY; 471f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org inst_cnd->U.I.SrcReg[0].Index = inst_mad->U.I.DstReg.Index; 472f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org inst_cnd->U.I.SrcReg[0].Swizzle = compiler->state.unit[inst->U.I.TexSrcUnit].texture_swizzle; 473f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org inst_cnd->U.I.SrcReg[1].File = RC_FILE_TEMPORARY; 474f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org inst_cnd->U.I.SrcReg[1].Index = inst_mul->U.I.DstReg.Index; 475f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org inst_cnd->U.I.SrcReg[1].Swizzle = compiler->state.unit[inst->U.I.TexSrcUnit].texture_swizzle; 476f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org inst_cnd->U.I.SrcReg[2] = inst_mul->U.I.SrcReg[0]; /* redirected TEX output */ 477f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 478f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org inst->U.I.SaturateMode = 0; 479f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org inst->U.I.DstReg.File = RC_FILE_TEMPORARY; 480f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org inst->U.I.DstReg.Index = inst_mul->U.I.SrcReg[0].Index; 481f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org inst->U.I.DstReg.WriteMask = RC_MASK_XYZW; 482f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 483f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 484f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* Cannot write texture to output registers or with saturate (all chips), 485f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * or with masks (non-r500). */ 486f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (inst->U.I.Opcode != RC_OPCODE_KIL && 487f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org (inst->U.I.DstReg.File != RC_FILE_TEMPORARY || 488f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org inst->U.I.SaturateMode || 489f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org (!c->is_r500 && inst->U.I.DstReg.WriteMask != RC_MASK_XYZW))) { 490f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct rc_instruction * inst_mov = rc_insert_new_instruction(c, inst); 491f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 492f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org inst_mov->U.I.Opcode = RC_OPCODE_MOV; 493f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org inst_mov->U.I.SaturateMode = inst->U.I.SaturateMode; 494f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org inst_mov->U.I.DstReg = inst->U.I.DstReg; 495f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org inst_mov->U.I.SrcReg[0].File = RC_FILE_TEMPORARY; 496f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org inst_mov->U.I.SrcReg[0].Index = rc_find_free_temporary(c); 497f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 498f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org inst->U.I.SaturateMode = 0; 499f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org inst->U.I.DstReg.File = RC_FILE_TEMPORARY; 500f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org inst->U.I.DstReg.Index = inst_mov->U.I.SrcReg[0].Index; 501f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org inst->U.I.DstReg.WriteMask = RC_MASK_XYZW; 502f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 503f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 504f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* Cannot read texture coordinate from constants file */ 505f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if (inst->U.I.SrcReg[0].File != RC_FILE_TEMPORARY && inst->U.I.SrcReg[0].File != RC_FILE_INPUT) { 506f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct rc_instruction * inst_mov = rc_insert_new_instruction(c, inst->Prev); 507f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 508f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org inst_mov->U.I.Opcode = RC_OPCODE_MOV; 509f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org inst_mov->U.I.DstReg.File = RC_FILE_TEMPORARY; 510f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org inst_mov->U.I.DstReg.Index = rc_find_free_temporary(c); 511f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org inst_mov->U.I.SrcReg[0] = inst->U.I.SrcReg[0]; 512f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 513f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org reset_srcreg(&inst->U.I.SrcReg[0]); 514f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org inst->U.I.SrcReg[0].File = RC_FILE_TEMPORARY; 515f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org inst->U.I.SrcReg[0].Index = inst_mov->U.I.DstReg.Index; 516f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 517f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 518f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return 1; 519f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 520