Path: blob/21.2-virgl/src/gallium/drivers/r600/r700_asm.c
4570 views
/*1* Copyright 2010 Jerome Glisse <[email protected]>2*3* Permission is hereby granted, free of charge, to any person obtaining a4* copy of this software and associated documentation files (the "Software"),5* to deal in the Software without restriction, including without limitation6* on the rights to use, copy, modify, merge, publish, distribute, sub7* license, and/or sell copies of the Software, and to permit persons to whom8* the Software is furnished to do so, subject to the following conditions:9*10* The above copyright notice and this permission notice (including the next11* paragraph) shall be included in all copies or substantial portions of the12* Software.13*14* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR15* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,16* FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL17* THE AUTHOR(S) AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM,18* DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR19* OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE20* USE OR OTHER DEALINGS IN THE SOFTWARE.21*/22#include "r600_asm.h"23#include "r700_sq.h"2425void r700_bytecode_cf_vtx_build(uint32_t *bytecode, const struct r600_bytecode_cf *cf)26{27unsigned count = (cf->ndw / 4) - 1;28*bytecode++ = S_SQ_CF_WORD0_ADDR(cf->addr >> 1);29*bytecode++ = S_SQ_CF_WORD1_CF_INST(r600_isa_cf_opcode(ISA_CC_R700, cf->op)) |30S_SQ_CF_WORD1_BARRIER(1) |31S_SQ_CF_WORD1_COUNT(count) |32S_SQ_CF_WORD1_COUNT_3(count >> 3)|33S_SQ_CF_WORD1_END_OF_PROGRAM(cf->end_of_program);34}3536int r700_bytecode_alu_build(struct r600_bytecode *bc, struct r600_bytecode_alu *alu, unsigned id)37{38bc->bytecode[id++] = S_SQ_ALU_WORD0_SRC0_SEL(alu->src[0].sel) |39S_SQ_ALU_WORD0_SRC0_REL(alu->src[0].rel) |40S_SQ_ALU_WORD0_SRC0_CHAN(alu->src[0].chan) |41S_SQ_ALU_WORD0_SRC0_NEG(alu->src[0].neg) |42S_SQ_ALU_WORD0_SRC1_SEL(alu->src[1].sel) |43S_SQ_ALU_WORD0_SRC1_REL(alu->src[1].rel) |44S_SQ_ALU_WORD0_SRC1_CHAN(alu->src[1].chan) |45S_SQ_ALU_WORD0_SRC1_NEG(alu->src[1].neg) |46S_SQ_ALU_WORD0_PRED_SEL(alu->pred_sel) |47S_SQ_ALU_WORD0_LAST(alu->last);4849/* don't replace gpr by pv or ps for destination register */50if (alu->is_op3) {51assert(!alu->src[0].abs && !alu->src[1].abs && !alu->src[2].abs);52bc->bytecode[id++] = S_SQ_ALU_WORD1_DST_GPR(alu->dst.sel) |53S_SQ_ALU_WORD1_DST_CHAN(alu->dst.chan) |54S_SQ_ALU_WORD1_DST_REL(alu->dst.rel) |55S_SQ_ALU_WORD1_CLAMP(alu->dst.clamp) |56S_SQ_ALU_WORD1_OP3_SRC2_SEL(alu->src[2].sel) |57S_SQ_ALU_WORD1_OP3_SRC2_REL(alu->src[2].rel) |58S_SQ_ALU_WORD1_OP3_SRC2_CHAN(alu->src[2].chan) |59S_SQ_ALU_WORD1_OP3_SRC2_NEG(alu->src[2].neg) |60S_SQ_ALU_WORD1_OP3_ALU_INST(r600_isa_alu_opcode(bc->isa->hw_class, alu->op)) |61S_SQ_ALU_WORD1_BANK_SWIZZLE(alu->bank_swizzle);62} else {63bc->bytecode[id++] = S_SQ_ALU_WORD1_DST_GPR(alu->dst.sel) |64S_SQ_ALU_WORD1_DST_CHAN(alu->dst.chan) |65S_SQ_ALU_WORD1_DST_REL(alu->dst.rel) |66S_SQ_ALU_WORD1_CLAMP(alu->dst.clamp) |67S_SQ_ALU_WORD1_OP2_SRC0_ABS(alu->src[0].abs) |68S_SQ_ALU_WORD1_OP2_SRC1_ABS(alu->src[1].abs) |69S_SQ_ALU_WORD1_OP2_WRITE_MASK(alu->dst.write) |70S_SQ_ALU_WORD1_OP2_OMOD(alu->omod) |71S_SQ_ALU_WORD1_OP2_ALU_INST(r600_isa_alu_opcode(bc->isa->hw_class, alu->op)) |72S_SQ_ALU_WORD1_BANK_SWIZZLE(alu->bank_swizzle) |73S_SQ_ALU_WORD1_OP2_UPDATE_EXECUTE_MASK(alu->execute_mask) |74S_SQ_ALU_WORD1_OP2_UPDATE_PRED(alu->update_pred);75}76return 0;77}7879void r700_bytecode_alu_read(struct r600_bytecode *bc,80struct r600_bytecode_alu *alu, uint32_t word0, uint32_t word1)81{82/* WORD0 */83alu->src[0].sel = G_SQ_ALU_WORD0_SRC0_SEL(word0);84alu->src[0].rel = G_SQ_ALU_WORD0_SRC0_REL(word0);85alu->src[0].chan = G_SQ_ALU_WORD0_SRC0_CHAN(word0);86alu->src[0].neg = G_SQ_ALU_WORD0_SRC0_NEG(word0);87alu->src[1].sel = G_SQ_ALU_WORD0_SRC1_SEL(word0);88alu->src[1].rel = G_SQ_ALU_WORD0_SRC1_REL(word0);89alu->src[1].chan = G_SQ_ALU_WORD0_SRC1_CHAN(word0);90alu->src[1].neg = G_SQ_ALU_WORD0_SRC1_NEG(word0);91alu->index_mode = G_SQ_ALU_WORD0_INDEX_MODE(word0);92alu->pred_sel = G_SQ_ALU_WORD0_PRED_SEL(word0);93alu->last = G_SQ_ALU_WORD0_LAST(word0);9495/* WORD1 */96alu->bank_swizzle = G_SQ_ALU_WORD1_BANK_SWIZZLE(word1);97if (alu->bank_swizzle)98alu->bank_swizzle_force = alu->bank_swizzle;99alu->dst.sel = G_SQ_ALU_WORD1_DST_GPR(word1);100alu->dst.rel = G_SQ_ALU_WORD1_DST_REL(word1);101alu->dst.chan = G_SQ_ALU_WORD1_DST_CHAN(word1);102alu->dst.clamp = G_SQ_ALU_WORD1_CLAMP(word1);103if (G_SQ_ALU_WORD1_ENCODING(word1)) /*ALU_DWORD1_OP3*/104{105alu->is_op3 = 1;106alu->src[2].sel = G_SQ_ALU_WORD1_OP3_SRC2_SEL(word1);107alu->src[2].rel = G_SQ_ALU_WORD1_OP3_SRC2_REL(word1);108alu->src[2].chan = G_SQ_ALU_WORD1_OP3_SRC2_CHAN(word1);109alu->src[2].neg = G_SQ_ALU_WORD1_OP3_SRC2_NEG(word1);110alu->op = r600_isa_alu_by_opcode(bc->isa,111G_SQ_ALU_WORD1_OP3_ALU_INST(word1), 1);112}113else /*ALU_DWORD1_OP2*/114{115alu->src[0].abs = G_SQ_ALU_WORD1_OP2_SRC0_ABS(word1);116alu->src[1].abs = G_SQ_ALU_WORD1_OP2_SRC1_ABS(word1);117alu->op = r600_isa_alu_by_opcode(bc->isa,118G_SQ_ALU_WORD1_OP2_ALU_INST(word1), 0);119alu->omod = G_SQ_ALU_WORD1_OP2_OMOD(word1);120alu->dst.write = G_SQ_ALU_WORD1_OP2_WRITE_MASK(word1);121alu->update_pred = G_SQ_ALU_WORD1_OP2_UPDATE_PRED(word1);122alu->execute_mask =123G_SQ_ALU_WORD1_OP2_UPDATE_EXECUTE_MASK(word1);124}125}126127int r700_bytecode_fetch_mem_build(struct r600_bytecode *bc, struct r600_bytecode_vtx *mem, unsigned id)128{129unsigned opcode = r600_isa_fetch_opcode(bc->isa->hw_class, mem->op) >> 8;130131bc->bytecode[id++] = S_SQ_MEM_RD_WORD0_MEM_INST(2) |132S_SQ_MEM_RD_WORD0_ELEM_SIZE(mem->elem_size) |133S_SQ_MEM_RD_WORD0_FETCH_WHOLE_QUAD(0) |134S_SQ_MEM_RD_WORD0_MEM_OP(opcode) |135S_SQ_MEM_RD_WORD0_UNCACHED(mem->uncached) |136S_SQ_MEM_RD_WORD0_INDEXED(mem->indexed) |137S_SQ_MEM_RD_WORD0_SRC_SEL_Y(mem->src_sel_y) |138S_SQ_MEM_RD_WORD0_SRC_GPR(mem->src_gpr) |139S_SQ_MEM_RD_WORD0_SRC_REL(mem->src_rel) |140S_SQ_MEM_RD_WORD0_SRC_SEL_X(mem->src_sel_x) |141S_SQ_MEM_RD_WORD0_BURST_COUNT(mem->burst_count) |142S_SQ_MEM_RD_WORD0_LDS_REQ(0) |143S_SQ_MEM_RD_WORD0_COALESCED_READ(0);144145bc->bytecode[id++] = S_SQ_MEM_RD_WORD1_DST_GPR(mem->dst_gpr) |146S_SQ_MEM_RD_WORD1_DST_REL(mem->dst_rel) |147S_SQ_MEM_RD_WORD1_DST_SEL_X(mem->dst_sel_x) |148S_SQ_MEM_RD_WORD1_DST_SEL_Y(mem->dst_sel_y) |149S_SQ_MEM_RD_WORD1_DST_SEL_W(mem->dst_sel_w) |150S_SQ_MEM_RD_WORD1_DST_SEL_Z(mem->dst_sel_z) |151S_SQ_MEM_RD_WORD1_DATA_FORMAT(mem->data_format) |152S_SQ_MEM_RD_WORD1_NUM_FORMAT_ALL(mem->num_format_all) |153S_SQ_MEM_RD_WORD1_FORMAT_COMP_ALL(mem->format_comp_all) |154S_SQ_MEM_RD_WORD1_SRF_MODE_ALL(mem->srf_mode_all);155156bc->bytecode[id++] = S_SQ_MEM_RD_WORD2_ARRAY_BASE(mem->array_base) |157S_SQ_MEM_RD_WORD2_ENDIAN_SWAP(0) |158S_SQ_MEM_RD_WORD2_ARRAY_SIZE(mem->array_size);159160161bc->bytecode[id++] = 0; /* MEM ops are 4 word aligned */162163return 0;164}165166167