diff options
Diffstat (limited to 'src/mesa/drivers/dri/r600/r600_fragprog_emit.c')
-rw-r--r-- | src/mesa/drivers/dri/r600/r600_fragprog_emit.c | 344 |
1 files changed, 0 insertions, 344 deletions
diff --git a/src/mesa/drivers/dri/r600/r600_fragprog_emit.c b/src/mesa/drivers/dri/r600/r600_fragprog_emit.c deleted file mode 100644 index de1e38b816..0000000000 --- a/src/mesa/drivers/dri/r600/r600_fragprog_emit.c +++ /dev/null @@ -1,344 +0,0 @@ -/* - * Copyright (C) 2005 Ben Skeggs. - * - * All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice (including the - * next paragraph) shall be included in all copies or substantial - * portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. - * IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE - * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION - * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION - * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - */ - -/** - * \file - * - * Emit the r600_fragment_program_code that can be understood by the hardware. - * Input is a pre-transformed radeon_program. - * - * \author Ben Skeggs <darktama@iinet.net.au> - * - * \author Jerome Glisse <j.glisse@gmail.com> - * - * \todo FogOption - */ - -#include "r600_fragprog.h" - -#include "radeon_program_pair.h" -#include "r600_fragprog_swizzle.h" -#include "r600_reg.h" - - -#define PROG_CODE \ - struct r600_fragment_program_compiler *c = (struct r600_fragment_program_compiler*)data; \ - struct r600_fragment_program_code *code = c->code - -#define error(fmt, args...) do { \ - fprintf(stderr, "%s::%s(): " fmt "\n", \ - __FILE__, __FUNCTION__, ##args); \ - } while(0) - - -static GLboolean emit_const(void* data, GLuint file, GLuint index, GLuint *hwindex) -{ - PROG_CODE; - - for (*hwindex = 0; *hwindex < code->const_nr; ++*hwindex) { - if (code->constant[*hwindex].File == file && - code->constant[*hwindex].Index == index) - break; - } - - if (*hwindex >= code->const_nr) { - if (*hwindex >= PFS_NUM_CONST_REGS) { - error("Out of hw constants!\n"); - return GL_FALSE; - } - - code->const_nr++; - code->constant[*hwindex].File = file; - code->constant[*hwindex].Index = index; - } - - return GL_TRUE; -} - - -/** - * Mark a temporary register as used. - */ -static void use_temporary(struct r600_fragment_program_code *code, GLuint index) -{ - if (index > code->max_temp_idx) - code->max_temp_idx = index; -} - - -static GLuint translate_rgb_opcode(GLuint opcode) -{ - switch(opcode) { - case OPCODE_CMP: return R600_ALU_OUTC_CMP; - case OPCODE_DP3: return R600_ALU_OUTC_DP3; - case OPCODE_DP4: return R600_ALU_OUTC_DP4; - case OPCODE_FRC: return R600_ALU_OUTC_FRC; - default: - error("translate_rgb_opcode(%i): Unknown opcode", opcode); - /* fall through */ - case OPCODE_NOP: - /* fall through */ - case OPCODE_MAD: return R600_ALU_OUTC_MAD; - case OPCODE_MAX: return R600_ALU_OUTC_MAX; - case OPCODE_MIN: return R600_ALU_OUTC_MIN; - case OPCODE_REPL_ALPHA: return R600_ALU_OUTC_REPL_ALPHA; - } -} - -static GLuint translate_alpha_opcode(GLuint opcode) -{ - switch(opcode) { - case OPCODE_CMP: return R600_ALU_OUTA_CMP; - case OPCODE_DP3: return R600_ALU_OUTA_DP4; - case OPCODE_DP4: return R600_ALU_OUTA_DP4; - case OPCODE_EX2: return R600_ALU_OUTA_EX2; - case OPCODE_FRC: return R600_ALU_OUTA_FRC; - case OPCODE_LG2: return R600_ALU_OUTA_LG2; - default: - error("translate_rgb_opcode(%i): Unknown opcode", opcode); - /* fall through */ - case OPCODE_NOP: - /* fall through */ - case OPCODE_MAD: return R600_ALU_OUTA_MAD; - case OPCODE_MAX: return R600_ALU_OUTA_MAX; - case OPCODE_MIN: return R600_ALU_OUTA_MIN; - case OPCODE_RCP: return R600_ALU_OUTA_RCP; - case OPCODE_RSQ: return R600_ALU_OUTA_RSQ; - } -} - -/** - * Emit one paired ALU instruction. - */ -static GLboolean emit_alu(void* data, struct radeon_pair_instruction* inst) -{ - PROG_CODE; - - if (code->alu.length >= PFS_MAX_ALU_INST) { - error("Too many ALU instructions"); - return GL_FALSE; - } - - int ip = code->alu.length++; - int j; - code->node[code->cur_node].alu_end++; - - code->alu.inst[ip].inst0 = translate_rgb_opcode(inst->RGB.Opcode); - code->alu.inst[ip].inst2 = translate_alpha_opcode(inst->Alpha.Opcode); - - for(j = 0; j < 3; ++j) { - GLuint src = inst->RGB.Src[j].Index | (inst->RGB.Src[j].Constant << 5); - if (!inst->RGB.Src[j].Constant) - use_temporary(code, inst->RGB.Src[j].Index); - code->alu.inst[ip].inst1 |= src << (6*j); - - src = inst->Alpha.Src[j].Index | (inst->Alpha.Src[j].Constant << 5); - if (!inst->Alpha.Src[j].Constant) - use_temporary(code, inst->Alpha.Src[j].Index); - code->alu.inst[ip].inst3 |= src << (6*j); - - GLuint arg = r600FPTranslateRGBSwizzle(inst->RGB.Arg[j].Source, inst->RGB.Arg[j].Swizzle); - arg |= inst->RGB.Arg[j].Abs << 6; - arg |= inst->RGB.Arg[j].Negate << 5; - code->alu.inst[ip].inst0 |= arg << (7*j); - - arg = r600FPTranslateAlphaSwizzle(inst->Alpha.Arg[j].Source, inst->Alpha.Arg[j].Swizzle); - arg |= inst->Alpha.Arg[j].Abs << 6; - arg |= inst->Alpha.Arg[j].Negate << 5; - code->alu.inst[ip].inst2 |= arg << (7*j); - } - - if (inst->RGB.Saturate) - code->alu.inst[ip].inst0 |= R600_ALU_OUTC_CLAMP; - if (inst->Alpha.Saturate) - code->alu.inst[ip].inst2 |= R600_ALU_OUTA_CLAMP; - - if (inst->RGB.WriteMask) { - use_temporary(code, inst->RGB.DestIndex); - code->alu.inst[ip].inst1 |= - (inst->RGB.DestIndex << R600_ALU_DSTC_SHIFT) | - (inst->RGB.WriteMask << R600_ALU_DSTC_REG_MASK_SHIFT); - } - if (inst->RGB.OutputWriteMask) { - code->alu.inst[ip].inst1 |= (inst->RGB.OutputWriteMask << R600_ALU_DSTC_OUTPUT_MASK_SHIFT); - code->node[code->cur_node].flags |= R600_RGBA_OUT; - } - - if (inst->Alpha.WriteMask) { - use_temporary(code, inst->Alpha.DestIndex); - code->alu.inst[ip].inst3 |= - (inst->Alpha.DestIndex << R600_ALU_DSTA_SHIFT) | - R600_ALU_DSTA_REG; - } - if (inst->Alpha.OutputWriteMask) { - code->alu.inst[ip].inst3 |= R600_ALU_DSTA_OUTPUT; - code->node[code->cur_node].flags |= R600_RGBA_OUT; - } - if (inst->Alpha.DepthWriteMask) { - code->alu.inst[ip].inst3 |= R600_ALU_DSTA_DEPTH; - code->node[code->cur_node].flags |= R600_W_OUT; - c->fp->WritesDepth = GL_TRUE; - } - - return GL_TRUE; -} - - -/** - * Finish the current node without advancing to the next one. - */ -static GLboolean finish_node(struct r600_fragment_program_compiler *c) -{ - struct r600_fragment_program_code *code = c->code; - struct r600_fragment_program_node *node = &code->node[code->cur_node]; - - if (node->alu_end < 0) { - /* Generate a single NOP for this node */ - struct radeon_pair_instruction inst; - _mesa_bzero(&inst, sizeof(inst)); - if (!emit_alu(c, &inst)) - return GL_FALSE; - } - - if (node->tex_end < 0) { - if (code->cur_node == 0) { - node->tex_end = 0; - } else { - error("Node %i has no TEX instructions", code->cur_node); - return GL_FALSE; - } - } else { - if (code->cur_node == 0) - code->first_node_has_tex = 1; - } - - return GL_TRUE; -} - - -/** - * Begin a block of texture instructions. - * Create the necessary indirection. - */ -static GLboolean begin_tex(void* data) -{ - PROG_CODE; - - if (code->cur_node == 0) { - if (code->node[0].alu_end < 0 && - code->node[0].tex_end < 0) - return GL_TRUE; - } - - if (code->cur_node == 3) { - error("Too many texture indirections"); - return GL_FALSE; - } - - if (!finish_node(c)) - return GL_FALSE; - - struct r600_fragment_program_node *node = &code->node[++code->cur_node]; - node->alu_offset = code->alu.length; - node->alu_end = -1; - node->tex_offset = code->tex.length; - node->tex_end = -1; - return GL_TRUE; -} - - -static GLboolean emit_tex(void* data, struct prog_instruction* inst) -{ - PROG_CODE; - - if (code->tex.length >= PFS_MAX_TEX_INST) { - error("Too many TEX instructions"); - return GL_FALSE; - } - - GLuint unit = inst->TexSrcUnit; - GLuint dest = inst->DstReg.Index; - GLuint opcode; - - switch(inst->Opcode) { - case OPCODE_KIL: opcode = R600_TEX_OP_KIL; break; - case OPCODE_TEX: opcode = R600_TEX_OP_LD; break; - case OPCODE_TXB: opcode = R600_TEX_OP_TXB; break; - case OPCODE_TXP: opcode = R600_TEX_OP_TXP; break; - default: - error("Unknown texture opcode %i", inst->Opcode); - return GL_FALSE; - } - - if (inst->Opcode == OPCODE_KIL) { - unit = 0; - dest = 0; - } else { - use_temporary(code, dest); - } - - use_temporary(code, inst->SrcReg[0].Index); - - code->node[code->cur_node].tex_end++; - code->tex.inst[code->tex.length++] = - (inst->SrcReg[0].Index << R600_SRC_ADDR_SHIFT) | - (dest << R600_DST_ADDR_SHIFT) | - (unit << R600_TEX_ID_SHIFT) | - (opcode << R600_TEX_INST_SHIFT); - return GL_TRUE; -} - - -static const struct radeon_pair_handler pair_handler = { - .EmitConst = &emit_const, - .EmitPaired = &emit_alu, - .EmitTex = &emit_tex, - .BeginTexBlock = &begin_tex, - .MaxHwTemps = PFS_NUM_TEMP_REGS -}; - -/** - * Final compilation step: Turn the intermediate radeon_program into - * machine-readable instructions. - */ -GLboolean r600FragmentProgramEmit(struct r600_fragment_program_compiler *compiler) -{ - struct r600_fragment_program_code *code = compiler->code; - - _mesa_bzero(code, sizeof(struct r600_fragment_program_code)); - code->node[0].alu_end = -1; - code->node[0].tex_end = -1; - - if (!radeonPairProgram(compiler->r600->radeon.glCtx, compiler->program, &pair_handler, compiler)) - return GL_FALSE; - - if (!finish_node(compiler)) - return GL_FALSE; - - return GL_TRUE; -} - |