diff options
Diffstat (limited to 'src/mesa/drivers/dri/r600')
-rw-r--r-- | src/mesa/drivers/dri/r600/r600_fragprog.c | 699 | ||||
-rw-r--r-- | src/mesa/drivers/dri/r600/r600_fragprog.h | 132 | ||||
-rw-r--r-- | src/mesa/drivers/dri/r600/r600_fragprog_emit.c | 344 | ||||
-rw-r--r-- | src/mesa/drivers/dri/r600/r600_fragprog_swizzle.c | 227 | ||||
-rw-r--r-- | src/mesa/drivers/dri/r600/r600_fragprog_swizzle.h | 42 | ||||
-rw-r--r-- | src/mesa/drivers/dri/r600/r600_ioctl.c | 565 | ||||
-rw-r--r-- | src/mesa/drivers/dri/r600/r600_ioctl.h | 44 | ||||
-rw-r--r-- | src/mesa/drivers/dri/r600/r600_render.c | 539 | ||||
-rw-r--r-- | src/mesa/drivers/dri/r600/r600_shader.c | 74 | ||||
-rw-r--r-- | src/mesa/drivers/dri/r600/r600_state.c | 2248 | ||||
-rw-r--r-- | src/mesa/drivers/dri/r600/r600_state.h | 65 | ||||
-rw-r--r-- | src/mesa/drivers/dri/r600/r600_tex.c | 347 | ||||
-rw-r--r-- | src/mesa/drivers/dri/r600/r600_tex.h | 54 | ||||
-rw-r--r-- | src/mesa/drivers/dri/r600/r600_texstate.c | 476 | ||||
-rw-r--r-- | src/mesa/drivers/dri/r600/r600_vertprog.c | 1479 | ||||
-rw-r--r-- | src/mesa/drivers/dri/r600/r600_vertprog.h | 35 |
16 files changed, 0 insertions, 7370 deletions
diff --git a/src/mesa/drivers/dri/r600/r600_fragprog.c b/src/mesa/drivers/dri/r600/r600_fragprog.c deleted file mode 100644 index c836723fb05..00000000000 --- a/src/mesa/drivers/dri/r600/r600_fragprog.c +++ /dev/null @@ -1,699 +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 - * - * Fragment program compiler. Perform transformations on the intermediate - * representation until the program is in a form where we can translate - * it more or less directly into machine-readable form. - * - * \author Ben Skeggs <[email protected]> - * \author Jerome Glisse <[email protected]> - */ - -#include "main/glheader.h" -#include "main/macros.h" -#include "main/enums.h" -#include "shader/prog_instruction.h" -#include "shader/prog_parameter.h" -#include "shader/prog_print.h" - -#include "r600_context.h" -#include "r600_fragprog.h" -#include "r600_fragprog_swizzle.h" -#include "r600_state.h" - -#include "radeon_nqssadce.h" -#include "radeon_program_alu.h" - - -static void reset_srcreg(struct prog_src_register* reg) -{ - _mesa_bzero(reg, sizeof(*reg)); - reg->Swizzle = SWIZZLE_NOOP; -} - -static struct prog_src_register shadow_ambient(struct gl_program *program, int tmu) -{ - gl_state_index fail_value_tokens[STATE_LENGTH] = { - STATE_INTERNAL, STATE_SHADOW_AMBIENT, 0, 0, 0 - }; - struct prog_src_register reg = { 0, }; - - fail_value_tokens[2] = tmu; - reg.File = PROGRAM_STATE_VAR; - reg.Index = _mesa_add_state_reference(program->Parameters, fail_value_tokens); - reg.Swizzle = SWIZZLE_WWWW; - return reg; -} - -/** - * Transform TEX, TXP, TXB, and KIL instructions in the following way: - * - premultiply texture coordinates for RECT - * - extract operand swizzles - * - introduce a temporary register when write masks are needed - * - * \todo If/when r5xx uses the radeon_program architecture, this can probably - * be reused. - */ -static GLboolean transform_TEX( - struct radeon_transform_context *t, - struct prog_instruction* orig_inst, void* data) -{ - struct r600_fragment_program_compiler *compiler = - (struct r600_fragment_program_compiler*)data; - struct prog_instruction inst = *orig_inst; - struct prog_instruction* tgt; - GLboolean destredirect = GL_FALSE; - - if (inst.Opcode != OPCODE_TEX && - inst.Opcode != OPCODE_TXB && - inst.Opcode != OPCODE_TXP && - inst.Opcode != OPCODE_KIL) - return GL_FALSE; - - if (inst.Opcode != OPCODE_KIL && - t->Program->ShadowSamplers & (1 << inst.TexSrcUnit)) { - GLuint comparefunc = GL_NEVER + compiler->fp->state.unit[inst.TexSrcUnit].texture_compare_func; - - if (comparefunc == GL_NEVER || comparefunc == GL_ALWAYS) { - tgt = radeonAppendInstructions(t->Program, 1); - - tgt->Opcode = OPCODE_MOV; - tgt->DstReg = inst.DstReg; - if (comparefunc == GL_ALWAYS) { - tgt->SrcReg[0].File = PROGRAM_BUILTIN; - tgt->SrcReg[0].Swizzle = SWIZZLE_1111; - } else { - tgt->SrcReg[0] = shadow_ambient(t->Program, inst.TexSrcUnit); - } - return GL_TRUE; - } - - inst.DstReg.File = PROGRAM_TEMPORARY; - inst.DstReg.Index = radeonFindFreeTemporary(t); - inst.DstReg.WriteMask = WRITEMASK_XYZW; - } - - - /* Hardware uses [0..1]x[0..1] range for rectangle textures - * instead of [0..Width]x[0..Height]. - * Add a scaling instruction. - */ - if (inst.Opcode != OPCODE_KIL && inst.TexSrcTarget == TEXTURE_RECT_INDEX) { - gl_state_index tokens[STATE_LENGTH] = { - STATE_INTERNAL, STATE_R600_TEXRECT_FACTOR, 0, 0, - 0 - }; - - int tempreg = radeonFindFreeTemporary(t); - int factor_index; - - tokens[2] = inst.TexSrcUnit; - factor_index = _mesa_add_state_reference(t->Program->Parameters, tokens); - - tgt = radeonAppendInstructions(t->Program, 1); - - tgt->Opcode = OPCODE_MUL; - tgt->DstReg.File = PROGRAM_TEMPORARY; - tgt->DstReg.Index = tempreg; - tgt->SrcReg[0] = inst.SrcReg[0]; - tgt->SrcReg[1].File = PROGRAM_STATE_VAR; - tgt->SrcReg[1].Index = factor_index; - - reset_srcreg(&inst.SrcReg[0]); - inst.SrcReg[0].File = PROGRAM_TEMPORARY; - inst.SrcReg[0].Index = tempreg; - } - - if (inst.Opcode != OPCODE_KIL) { - if (inst.DstReg.File != PROGRAM_TEMPORARY || - inst.DstReg.WriteMask != WRITEMASK_XYZW) { - int tempreg = radeonFindFreeTemporary(t); - - inst.DstReg.File = PROGRAM_TEMPORARY; - inst.DstReg.Index = tempreg; - inst.DstReg.WriteMask = WRITEMASK_XYZW; - destredirect = GL_TRUE; - } - } - - if (inst.SrcReg[0].File != PROGRAM_TEMPORARY && inst.SrcReg[0].File != PROGRAM_INPUT) { - int tmpreg = radeonFindFreeTemporary(t); - tgt = radeonAppendInstructions(t->Program, 1); - tgt->Opcode = OPCODE_MOV; - tgt->DstReg.File = PROGRAM_TEMPORARY; - tgt->DstReg.Index = tmpreg; - tgt->SrcReg[0] = inst.SrcReg[0]; - - reset_srcreg(&inst.SrcReg[0]); - inst.SrcReg[0].File = PROGRAM_TEMPORARY; - inst.SrcReg[0].Index = tmpreg; - } - - tgt = radeonAppendInstructions(t->Program, 1); - _mesa_copy_instructions(tgt, &inst, 1); - - if (inst.Opcode != OPCODE_KIL && - t->Program->ShadowSamplers & (1 << inst.TexSrcUnit)) { - GLuint comparefunc = GL_NEVER + compiler->fp->state.unit[inst.TexSrcUnit].texture_compare_func; - GLuint depthmode = compiler->fp->state.unit[inst.TexSrcUnit].depth_texture_mode; - int rcptemp = radeonFindFreeTemporary(t); - int pass, fail; - - tgt = radeonAppendInstructions(t->Program, 3); - - tgt[0].Opcode = OPCODE_RCP; - tgt[0].DstReg.File = PROGRAM_TEMPORARY; - tgt[0].DstReg.Index = rcptemp; - tgt[0].DstReg.WriteMask = WRITEMASK_W; - tgt[0].SrcReg[0] = inst.SrcReg[0]; - tgt[0].SrcReg[0].Swizzle = SWIZZLE_WWWW; - - tgt[1].Opcode = OPCODE_MAD; - tgt[1].DstReg = inst.DstReg; - tgt[1].DstReg.WriteMask = orig_inst->DstReg.WriteMask; - tgt[1].SrcReg[0] = inst.SrcReg[0]; - tgt[1].SrcReg[0].Swizzle = SWIZZLE_ZZZZ; - tgt[1].SrcReg[1].File = PROGRAM_TEMPORARY; - tgt[1].SrcReg[1].Index = rcptemp; - tgt[1].SrcReg[1].Swizzle = SWIZZLE_WWWW; - tgt[1].SrcReg[2].File = PROGRAM_TEMPORARY; - tgt[1].SrcReg[2].Index = inst.DstReg.Index; - if (depthmode == 0) /* GL_LUMINANCE */ - tgt[1].SrcReg[2].Swizzle = MAKE_SWIZZLE4(SWIZZLE_X, SWIZZLE_Y, SWIZZLE_Z, SWIZZLE_Z); - else if (depthmode == 2) /* GL_ALPHA */ - tgt[1].SrcReg[2].Swizzle = SWIZZLE_WWWW; - - /* Recall that SrcReg[0] is tex, SrcReg[2] is r and: - * r < tex <=> -tex+r < 0 - * r >= tex <=> not (-tex+r < 0 */ - if (comparefunc == GL_LESS || comparefunc == GL_GEQUAL) - tgt[1].SrcReg[2].NegateBase = tgt[0].SrcReg[2].NegateBase ^ NEGATE_XYZW; - else - tgt[1].SrcReg[0].NegateBase = tgt[0].SrcReg[0].NegateBase ^ NEGATE_XYZW; - - tgt[2].Opcode = OPCODE_CMP; - tgt[2].DstReg = orig_inst->DstReg; - tgt[2].SrcReg[0].File = PROGRAM_TEMPORARY; - tgt[2].SrcReg[0].Index = tgt[1].DstReg.Index; - - if (comparefunc == GL_LESS || comparefunc == GL_GREATER) { - pass = 1; - fail = 2; - } else { - pass = 2; - fail = 1; - } - - tgt[2].SrcReg[pass].File = PROGRAM_BUILTIN; - tgt[2].SrcReg[pass].Swizzle = SWIZZLE_1111; - tgt[2].SrcReg[fail] = shadow_ambient(t->Program, inst.TexSrcUnit); - } else if (destredirect) { - tgt = radeonAppendInstructions(t->Program, 1); - - tgt->Opcode = OPCODE_MOV; - tgt->DstReg = orig_inst->DstReg; - tgt->SrcReg[0].File = PROGRAM_TEMPORARY; - tgt->SrcReg[0].Index = inst.DstReg.Index; - } - - return GL_TRUE; -} - - -static void update_params(r600ContextPtr r600, struct r600_fragment_program *fp) -{ - struct gl_fragment_program *mp = &fp->mesa_program; - - /* Ask Mesa nicely to fill in ParameterValues for us */ - if (mp->Base.Parameters) - _mesa_load_state_parameters(r600->radeon.glCtx, mp->Base.Parameters); -} - - -/** - * Transform the program to support fragment.position. - * - * Introduce a small fragment at the start of the program that will be - * the only code that directly reads the FRAG_ATTRIB_WPOS input. - * All other code pieces that reference that input will be rewritten - * to read from a newly allocated temporary. - * - * \todo if/when r5xx supports the radeon_program architecture, this is a - * likely candidate for code sharing. - */ -static void insert_WPOS_trailer(struct r600_fragment_program_compiler *compiler) -{ - GLuint InputsRead = compiler->fp->mesa_program.Base.InputsRead; - - if (!(InputsRead & FRAG_BIT_WPOS)) - return; - - static gl_state_index tokens[STATE_LENGTH] = { - STATE_INTERNAL, STATE_R600_WINDOW_DIMENSION, 0, 0, 0 - }; - struct prog_instruction *fpi; - GLuint window_index; - int i = 0; - GLuint tempregi = _mesa_find_free_register(compiler->program, PROGRAM_TEMPORARY); - - _mesa_insert_instructions(compiler->program, 0, 3); - fpi = compiler->program->Instructions; - - /* perspective divide */ - fpi[i].Opcode = OPCODE_RCP; - - fpi[i].DstReg.File = PROGRAM_TEMPORARY; - fpi[i].DstReg.Index = tempregi; - fpi[i].DstReg.WriteMask = WRITEMASK_W; - fpi[i].DstReg.CondMask = COND_TR; - - fpi[i].SrcReg[0].File = PROGRAM_INPUT; - fpi[i].SrcReg[0].Index = FRAG_ATTRIB_WPOS; - fpi[i].SrcReg[0].Swizzle = SWIZZLE_WWWW; - i++; - - fpi[i].Opcode = OPCODE_MUL; - - fpi[i].DstReg.File = PROGRAM_TEMPORARY; - fpi[i].DstReg.Index = tempregi; - fpi[i].DstReg.WriteMask = WRITEMASK_XYZ; - fpi[i].DstReg.CondMask = COND_TR; - - fpi[i].SrcReg[0].File = PROGRAM_INPUT; - fpi[i].SrcReg[0].Index = FRAG_ATTRIB_WPOS; - fpi[i].SrcReg[0].Swizzle = SWIZZLE_XYZW; - - fpi[i].SrcReg[1].File = PROGRAM_TEMPORARY; - fpi[i].SrcReg[1].Index = tempregi; - fpi[i].SrcReg[1].Swizzle = SWIZZLE_WWWW; - i++; - - /* viewport transformation */ - window_index = _mesa_add_state_reference(compiler->program->Parameters, tokens); - - fpi[i].Opcode = OPCODE_MAD; - - fpi[i].DstReg.File = PROGRAM_TEMPORARY; - fpi[i].DstReg.Index = tempregi; - fpi[i].DstReg.WriteMask = WRITEMASK_XYZ; - fpi[i].DstReg.CondMask = COND_TR; - - fpi[i].SrcReg[0].File = PROGRAM_TEMPORARY; - fpi[i].SrcReg[0].Index = tempregi; - fpi[i].SrcReg[0].Swizzle = - MAKE_SWIZZLE4(SWIZZLE_X, SWIZZLE_Y, SWIZZLE_Z, SWIZZLE_ZERO); - - fpi[i].SrcReg[1].File = PROGRAM_STATE_VAR; - fpi[i].SrcReg[1].Index = window_index; - fpi[i].SrcReg[1].Swizzle = - MAKE_SWIZZLE4(SWIZZLE_X, SWIZZLE_Y, SWIZZLE_Z, SWIZZLE_ZERO); - - fpi[i].SrcReg[2].File = PROGRAM_STATE_VAR; - fpi[i].SrcReg[2].Index = window_index; - fpi[i].SrcReg[2].Swizzle = - MAKE_SWIZZLE4(SWIZZLE_X, SWIZZLE_Y, SWIZZLE_Z, SWIZZLE_ZERO); - i++; - - for (; i < compiler->program->NumInstructions; ++i) { - int reg; - for (reg = 0; reg < 3; reg++) { - if (fpi[i].SrcReg[reg].File == PROGRAM_INPUT && - fpi[i].SrcReg[reg].Index == FRAG_ATTRIB_WPOS) { - fpi[i].SrcReg[reg].File = PROGRAM_TEMPORARY; - fpi[i].SrcReg[reg].Index = tempregi; - } - } - } -} - - -static void nqssadce_init(struct nqssadce_state* s) -{ - s->Outputs[FRAG_RESULT_COLOR].Sourced = WRITEMASK_XYZW; - s->Outputs[FRAG_RESULT_DEPTH].Sourced = WRITEMASK_W; -} - - -static GLuint build_dtm(GLuint depthmode) -{ - switch(depthmode) { - default: - case GL_LUMINANCE: return 0; - case GL_INTENSITY: return 1; - case GL_ALPHA: return 2; - } -} - -static GLuint build_func(GLuint comparefunc) -{ - return comparefunc - GL_NEVER; -} - - -/** - * Collect all external state that is relevant for compiling the given - * fragment program. - */ -static void build_state( - r600ContextPtr r600, - struct r600_fragment_program *fp, - struct r600_fragment_program_external_state *state) -{ - int unit; - - _mesa_bzero(state, sizeof(*state)); - - for(unit = 0; unit < 16; ++unit) { - if (fp->mesa_program.Base.ShadowSamplers & (1 << unit)) { - struct gl_texture_object* tex = r600->radeon.glCtx->Texture.Unit[unit]._Current; - - state->unit[unit].depth_texture_mode = build_dtm(tex->DepthMode); - state->unit[unit].texture_compare_func = build_func(tex->CompareFunc); - } - } -} - - -void r600TranslateFragmentShader(r600ContextPtr r600, - struct r600_fragment_program *fp) -{ - struct r600_fragment_program_external_state state; - - build_state(r600, fp, &state); - if (_mesa_memcmp(&fp->state, &state, sizeof(state))) { - /* TODO: cache compiled programs */ - fp->translated = GL_FALSE; - _mesa_memcpy(&fp->state, &state, sizeof(state)); - } - - if (!fp->translated) { - struct r600_fragment_program_compiler compiler; - - compiler.r600 = r600; - compiler.fp = fp; - compiler.code = &fp->code; - compiler.program = _mesa_clone_program(r600->radeon.glCtx, &fp->mesa_program.Base); - - if (RADEON_DEBUG & DEBUG_PIXEL) { - _mesa_printf("Fragment Program: Initial program:\n"); - _mesa_print_program(compiler.program); - } - - insert_WPOS_trailer(&compiler); - - struct radeon_program_transformation transformations[] = { - { &transform_TEX, &compiler }, - { &radeonTransformALU, 0 }, - { &radeonTransformTrigSimple, 0 } - }; - radeonLocalTransform( - r600->radeon.glCtx, - compiler.program, - 3, transformations); - - if (RADEON_DEBUG & DEBUG_PIXEL) { - _mesa_printf("Fragment Program: After native rewrite:\n"); - _mesa_print_program(compiler.program); - } - - struct radeon_nqssadce_descr nqssadce = { - .Init = &nqssadce_init, - .IsNativeSwizzle = &r600FPIsNativeSwizzle, - .BuildSwizzle = &r600FPBuildSwizzle, - .RewriteDepthOut = GL_TRUE - }; - radeonNqssaDce(r600->radeon.glCtx, compiler.program, &nqssadce); - - if (RADEON_DEBUG & DEBUG_PIXEL) { - _mesa_printf("Compiler: after NqSSA-DCE:\n"); - _mesa_print_program(compiler.program); - } - - if (!r600FragmentProgramEmit(&compiler)) - fp->error = GL_TRUE; - - /* Subtle: Rescue any parameters that have been added during transformations */ - _mesa_free_parameter_list(fp->mesa_program.Base.Parameters); - fp->mesa_program.Base.Parameters = compiler.program->Parameters; - compiler.program->Parameters = 0; - - _mesa_reference_program(r600->radeon.glCtx, &compiler.program, NULL); - - if (!fp->error) - fp->translated = GL_TRUE; - if (fp->error || (RADEON_DEBUG & DEBUG_PIXEL)) - r600FragmentProgramDump(fp, &fp->code); - r600UpdateStateParameters(r600->radeon.glCtx, _NEW_PROGRAM); - } - - update_params(r600, fp); -} - -/* just some random things... */ -void r600FragmentProgramDump( - struct r600_fragment_program *fp, - struct r600_fragment_program_code *code) -{ - int n, i, j; - static int pc = 0; - - fprintf(stderr, "pc=%d*************************************\n", pc++); - - fprintf(stderr, "Hardware program\n"); - fprintf(stderr, "----------------\n"); - - for (n = 0; n < (code->cur_node + 1); n++) { - fprintf(stderr, "NODE %d: alu_offset: %d, tex_offset: %d, " - "alu_end: %d, tex_end: %d, flags: %08x\n", n, - code->node[n].alu_offset, - code->node[n].tex_offset, - code->node[n].alu_end, code->node[n].tex_end, - code->node[n].flags); - - if (n > 0 || code->first_node_has_tex) { - fprintf(stderr, " TEX:\n"); - for (i = code->node[n].tex_offset; - i <= code->node[n].tex_offset + code->node[n].tex_end; - ++i) { - const char *instr; - - switch ((code->tex. - inst[i] >> R600_TEX_INST_SHIFT) & - 15) { - case R600_TEX_OP_LD: - instr = "TEX"; - break; - case R600_TEX_OP_KIL: - instr = "KIL"; - break; - case R600_TEX_OP_TXP: - instr = "TXP"; - break; - case R600_TEX_OP_TXB: - instr = "TXB"; - break; - default: - instr = "UNKNOWN"; - } - - fprintf(stderr, - " %s t%i, %c%i, texture[%i] (%08x)\n", - instr, - (code->tex. - inst[i] >> R600_DST_ADDR_SHIFT) & 31, - 't', - (code->tex. - inst[i] >> R600_SRC_ADDR_SHIFT) & 31, - (code->tex. - inst[i] & R600_TEX_ID_MASK) >> - R600_TEX_ID_SHIFT, - code->tex.inst[i]); - } - } - - for (i = code->node[n].alu_offset; - i <= code->node[n].alu_offset + code->node[n].alu_end; ++i) { - char srcc[3][10], dstc[20]; - char srca[3][10], dsta[20]; - char argc[3][20]; - char arga[3][20]; - char flags[5], tmp[10]; - - for (j = 0; j < 3; ++j) { - int regc = code->alu.inst[i].inst1 >> (j * 6); - int rega = code->alu.inst[i].inst3 >> (j * 6); - - sprintf(srcc[j], "%c%i", - (regc & 32) ? 'c' : 't', regc & 31); - sprintf(srca[j], "%c%i", - (rega & 32) ? 'c' : 't', rega & 31); - } - - dstc[0] = 0; - sprintf(flags, "%s%s%s", - (code->alu.inst[i]. - inst1 & R600_ALU_DSTC_REG_X) ? "x" : "", - (code->alu.inst[i]. - inst1 & R600_ALU_DSTC_REG_Y) ? "y" : "", - (code->alu.inst[i]. - inst1 & R600_ALU_DSTC_REG_Z) ? "z" : ""); - if (flags[0] != 0) { - sprintf(dstc, "t%i.%s ", - (code->alu.inst[i]. - inst1 >> R600_ALU_DSTC_SHIFT) & 31, - flags); - } - sprintf(flags, "%s%s%s", - (code->alu.inst[i]. - inst1 & R600_ALU_DSTC_OUTPUT_X) ? "x" : "", - (code->alu.inst[i]. - inst1 & R600_ALU_DSTC_OUTPUT_Y) ? "y" : "", - (code->alu.inst[i]. - inst1 & R600_ALU_DSTC_OUTPUT_Z) ? "z" : ""); - if (flags[0] != 0) { - sprintf(tmp, "o%i.%s", - (code->alu.inst[i]. - inst1 >> R600_ALU_DSTC_SHIFT) & 31, - flags); - strcat(dstc, tmp); - } - - dsta[0] = 0; - if (code->alu.inst[i].inst3 & R600_ALU_DSTA_REG) { - sprintf(dsta, "t%i.w ", - (code->alu.inst[i]. - inst3 >> R600_ALU_DSTA_SHIFT) & 31); - } - if (code->alu.inst[i].inst3 & R600_ALU_DSTA_OUTPUT) { - sprintf(tmp, "o%i.w ", - (code->alu.inst[i]. - inst3 >> R600_ALU_DSTA_SHIFT) & 31); - strcat(dsta, tmp); - } - if (code->alu.inst[i].inst3 & R600_ALU_DSTA_DEPTH) { - strcat(dsta, "Z"); - } - - fprintf(stderr, - "%3i: xyz: %3s %3s %3s -> %-20s (%08x)\n" - " w: %3s %3s %3s -> %-20s (%08x)\n", i, - srcc[0], srcc[1], srcc[2], dstc, - code->alu.inst[i].inst1, srca[0], srca[1], - srca[2], dsta, code->alu.inst[i].inst3); - - for (j = 0; j < 3; ++j) { - int regc = code->alu.inst[i].inst0 >> (j * 7); - int rega = code->alu.inst[i].inst2 >> (j * 7); - int d; - char buf[20]; - - d = regc & 31; - if (d < 12) { - switch (d % 4) { - case R600_ALU_ARGC_SRC0C_XYZ: - sprintf(buf, "%s.xyz", - srcc[d / 4]); - break; - case R600_ALU_ARGC_SRC0C_XXX: - sprintf(buf, "%s.xxx", - srcc[d / 4]); - break; - case R600_ALU_ARGC_SRC0C_YYY: - sprintf(buf, "%s.yyy", - srcc[d / 4]); - break; - case R600_ALU_ARGC_SRC0C_ZZZ: - sprintf(buf, "%s.zzz", - srcc[d / 4]); - break; - } - } else if (d < 15) { - sprintf(buf, "%s.www", srca[d - 12]); - } else if (d == 20) { - sprintf(buf, "0.0"); - } else if (d == 21) { - sprintf(buf, "1.0"); - } else if (d == 22) { - sprintf(buf, "0.5"); - } else if (d >= 23 && d < 32) { - d -= 23; - switch (d / 3) { - case 0: - sprintf(buf, "%s.yzx", - srcc[d % 3]); - break; - case 1: - sprintf(buf, "%s.zxy", - srcc[d % 3]); - break; - case 2: - sprintf(buf, "%s.Wzy", - srcc[d % 3]); - break; - } - } else { - sprintf(buf, "%i", d); - } - - sprintf(argc[j], "%s%s%s%s", - (regc & 32) ? "-" : "", - (regc & 64) ? "|" : "", - buf, (regc & 64) ? "|" : ""); - - d = rega & 31; - if (d < 9) { - sprintf(buf, "%s.%c", srcc[d / 3], - 'x' + (char)(d % 3)); - } else if (d < 12) { - sprintf(buf, "%s.w", srca[d - 9]); - } else if (d == 16) { - sprintf(buf, "0.0"); - } else if (d == 17) { - sprintf(buf, "1.0"); - } else if (d == 18) { - sprintf(buf, "0.5"); - } else { - sprintf(buf, "%i", d); - } - - sprintf(arga[j], "%s%s%s%s", - (rega & 32) ? "-" : "", - (rega & 64) ? "|" : "", - buf, (rega & 64) ? "|" : ""); - } - - fprintf(stderr, " xyz: %8s %8s %8s op: %08x\n" - " w: %8s %8s %8s op: %08x\n", - argc[0], argc[1], argc[2], - code->alu.inst[i].inst0, arga[0], arga[1], - arga[2], code->alu.inst[i].inst2); - } - } -} diff --git a/src/mesa/drivers/dri/r600/r600_fragprog.h b/src/mesa/drivers/dri/r600/r600_fragprog.h deleted file mode 100644 index f6ca5995a27..00000000000 --- a/src/mesa/drivers/dri/r600/r600_fragprog.h +++ /dev/null @@ -1,132 +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. - * - */ - -/* - * Authors: - * Ben Skeggs <[email protected]> - * Jerome Glisse <[email protected]> - */ -#ifndef __R600_FRAGPROG_H_ -#define __R600_FRAGPROG_H_ - -#include "main/glheader.h" -#include "main/macros.h" -#include "main/enums.h" -#include "shader/program.h" -#include "shader/prog_instruction.h" - -#include "r600_context.h" -#include "radeon_program.h" - -#define DRI_CONF_FP_OPTIMIZATION_SPEED 0 -#define DRI_CONF_FP_OPTIMIZATION_QUALITY 1 - -#if 1 - -/** - * Fragment program helper macros - */ - -/* Produce unshifted source selectors */ -#define FP_TMP(idx) (idx) -#define FP_CONST(idx) ((idx) | (1 << 5)) - -/* Produce source/dest selector dword */ -#define FP_SELC_MASK_NO 0 -#define FP_SELC_MASK_X 1 -#define FP_SELC_MASK_Y 2 -#define FP_SELC_MASK_XY 3 -#define FP_SELC_MASK_Z 4 -#define FP_SELC_MASK_XZ 5 -#define FP_SELC_MASK_YZ 6 -#define FP_SELC_MASK_XYZ 7 - -#define FP_SELC(destidx,regmask,outmask,src0,src1,src2) \ - (((destidx) << R600_ALU_DSTC_SHIFT) | \ - (FP_SELC_MASK_##regmask << 23) | \ - (FP_SELC_MASK_##outmask << 26) | \ - ((src0) << R600_ALU_SRC0C_SHIFT) | \ - ((src1) << R600_ALU_SRC1C_SHIFT) | \ - ((src2) << R600_ALU_SRC2C_SHIFT)) - -#define FP_SELA_MASK_NO 0 -#define FP_SELA_MASK_W 1 - -#define FP_SELA(destidx,regmask,outmask,src0,src1,src2) \ - (((destidx) << R600_ALU_DSTA_SHIFT) | \ - (FP_SELA_MASK_##regmask << 23) | \ - (FP_SELA_MASK_##outmask << 24) | \ - ((src0) << R600_ALU_SRC0A_SHIFT) | \ - ((src1) << R600_ALU_SRC1A_SHIFT) | \ - ((src2) << R600_ALU_SRC2A_SHIFT)) - -/* Produce unshifted argument selectors */ -#define FP_ARGC(source) R600_ALU_ARGC_##source -#define FP_ARGA(source) R600_ALU_ARGA_##source -#define FP_ABS(arg) ((arg) | (1 << 6)) -#define FP_NEG(arg) ((arg) ^ (1 << 5)) - -/* Produce instruction dword */ -#define FP_INSTRC(opcode,arg0,arg1,arg2) \ - (R600_ALU_OUTC_##opcode | \ - ((arg0) << R600_ALU_ARG0C_SHIFT) | \ - ((arg1) << R600_ALU_ARG1C_SHIFT) | \ - ((arg2) << R600_ALU_ARG2C_SHIFT)) - -#define FP_INSTRA(opcode,arg0,arg1,arg2) \ - (R600_ALU_OUTA_##opcode | \ - ((arg0) << R600_ALU_ARG0A_SHIFT) | \ - ((arg1) << R600_ALU_ARG1A_SHIFT) | \ - ((arg2) << R600_ALU_ARG2A_SHIFT)) - -#endif - -struct r600_fragment_program; - -extern void r600TranslateFragmentShader(r600ContextPtr r600, - struct r600_fragment_program *fp); - - -/** - * Used internally by the r600 fragment program code to store compile-time - * only data. - */ -struct r600_fragment_program_compiler { - r600ContextPtr r600; - struct r600_fragment_program *fp; - struct r600_fragment_program_code *code; - struct gl_program *program; -}; - -extern GLboolean r600FragmentProgramEmit(struct r600_fragment_program_compiler *compiler); - - -extern void r600FragmentProgramDump( - struct r600_fragment_program *fp, - struct r600_fragment_program_code *code); - -#endif 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 de1e38b816f..00000000000 --- 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 <[email protected]> - * - * \author Jerome Glisse <[email protected]> - * - * \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; -} - diff --git a/src/mesa/drivers/dri/r600/r600_fragprog_swizzle.c b/src/mesa/drivers/dri/r600/r600_fragprog_swizzle.c deleted file mode 100644 index 36136cc8490..00000000000 --- a/src/mesa/drivers/dri/r600/r600_fragprog_swizzle.c +++ /dev/null @@ -1,227 +0,0 @@ -/* - * Copyright (C) 2008 Nicolai Haehnle. - * - * 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 - * Utilities to deal with the somewhat odd restriction on R600 fragment - * program swizzles. - */ - -#include "r600_fragprog_swizzle.h" - -#include "r600_reg.h" -#include "radeon_nqssadce.h" - -#define MAKE_SWZ3(x, y, z) (MAKE_SWIZZLE4(SWIZZLE_##x, SWIZZLE_##y, SWIZZLE_##z, SWIZZLE_ZERO)) - -struct swizzle_data { - GLuint hash; /**< swizzle value this matches */ - GLuint base; /**< base value for hw swizzle */ - GLuint stride; /**< difference in base between arg0/1/2 */ -}; - -static const struct swizzle_data native_swizzles[] = { - {MAKE_SWZ3(X, Y, Z), R600_ALU_ARGC_SRC0C_XYZ, 4}, - {MAKE_SWZ3(X, X, X), R600_ALU_ARGC_SRC0C_XXX, 4}, - {MAKE_SWZ3(Y, Y, Y), R600_ALU_ARGC_SRC0C_YYY, 4}, - {MAKE_SWZ3(Z, Z, Z), R600_ALU_ARGC_SRC0C_ZZZ, 4}, - {MAKE_SWZ3(W, W, W), R600_ALU_ARGC_SRC0A, 1}, - {MAKE_SWZ3(Y, Z, X), R600_ALU_ARGC_SRC0C_YZX, 1}, - {MAKE_SWZ3(Z, X, Y), R600_ALU_ARGC_SRC0C_ZXY, 1}, - {MAKE_SWZ3(W, Z, Y), R600_ALU_ARGC_SRC0CA_WZY, 1}, - {MAKE_SWZ3(ONE, ONE, ONE), R600_ALU_ARGC_ONE, 0}, - {MAKE_SWZ3(ZERO, ZERO, ZERO), R600_ALU_ARGC_ZERO, 0} -}; - -static const int num_native_swizzles = sizeof(native_swizzles)/sizeof(native_swizzles[0]); - - -/** - * Find a native RGB swizzle that matches the given swizzle. - * Returns 0 if none found. - */ -static const struct swizzle_data* lookup_native_swizzle(GLuint swizzle) -{ - int i, comp; - - for(i = 0; i < num_native_swizzles; ++i) { - const struct swizzle_data* sd = &native_swizzles[i]; - for(comp = 0; comp < 3; ++comp) { - GLuint swz = GET_SWZ(swizzle, comp); - if (swz == SWIZZLE_NIL) - continue; - if (swz != GET_SWZ(sd->hash, comp)) - break; - } - if (comp == 3) - return sd; - } - - return 0; -} - - -/** - * Check whether the given instruction supports the swizzle and negate - * combinations in the given source register. - */ -GLboolean r600FPIsNativeSwizzle(GLuint opcode, struct prog_src_register reg) -{ - if (reg.Abs) - reg.NegateBase = 0; - - if (opcode == OPCODE_KIL || - opcode == OPCODE_TEX || - opcode == OPCODE_TXB || - opcode == OPCODE_TXP) { - int j; - - if (reg.Abs || reg.NegateBase != (15*reg.NegateAbs)) - return GL_FALSE; - - for(j = 0; j < 4; ++j) { - GLuint swz = GET_SWZ(reg.Swizzle, j); - if (swz == SWIZZLE_NIL) - continue; - if (swz != j) - return GL_FALSE; - } - - return GL_TRUE; - } - - GLuint relevant = 0; - int j; - - for(j = 0; j < 3; ++j) - if (GET_SWZ(reg.Swizzle, j) != SWIZZLE_NIL) - relevant |= 1 << j; - - if ((reg.NegateBase & relevant) && (reg.NegateBase & relevant) != relevant) - return GL_FALSE; - - if (!lookup_native_swizzle(reg.Swizzle)) - return GL_FALSE; - - return GL_TRUE; -} - - -/** - * Generate MOV dst, src using only native swizzles. - */ -void r600FPBuildSwizzle(struct nqssadce_state *s, struct prog_dst_register dst, struct prog_src_register src) -{ - if (src.Abs) - src.NegateBase = 0; - - while(dst.WriteMask) { - const struct swizzle_data *best_swizzle = 0; - GLuint best_matchcount = 0; - GLuint best_matchmask = 0; - GLboolean rgbnegate; - int i, comp; - - for(i = 0; i < num_native_swizzles; ++i) { - const struct swizzle_data *sd = &native_swizzles[i]; - GLuint matchcount = 0; - GLuint matchmask = 0; - for(comp = 0; comp < 3; ++comp) { - if (!GET_BIT(dst.WriteMask, comp)) - continue; - GLuint swz = GET_SWZ(src.Swizzle, comp); - if (swz == SWIZZLE_NIL) - continue; - if (swz == GET_SWZ(sd->hash, comp)) { - matchcount++; - matchmask |= 1 << comp; - } - } - if (matchcount > best_matchcount) { - best_swizzle = sd; - best_matchcount = matchcount; - best_matchmask = matchmask; - if (matchmask == (dst.WriteMask & WRITEMASK_XYZ)) - break; - } - } - - if ((src.NegateBase & best_matchmask) != 0) { - best_matchmask &= src.NegateBase; - rgbnegate = !src.NegateAbs; - } else { - rgbnegate = src.NegateAbs; - } - - struct prog_instruction *inst; - - _mesa_insert_instructions(s->Program, s->IP, 1); - inst = s->Program->Instructions + s->IP++; - inst->Opcode = OPCODE_MOV; - inst->DstReg = dst; - inst->DstReg.WriteMask &= (best_matchmask | WRITEMASK_W); - inst->SrcReg[0] = src; - /* Note: We rely on NqSSA/DCE to set unused swizzle components to NIL */ - - dst.WriteMask &= ~inst->DstReg.WriteMask; - } -} - - -/** - * Translate an RGB (XYZ) swizzle into the hardware code for the given - * instruction source. - */ -GLuint r600FPTranslateRGBSwizzle(GLuint src, GLuint swizzle) -{ - const struct swizzle_data* sd = lookup_native_swizzle(swizzle); - - if (!sd) { - _mesa_printf("Not a native swizzle: %08x\n", swizzle); - return 0; - } - - return sd->base + src*sd->stride; -} - - -/** - * Translate an Alpha (W) swizzle into the hardware code for the given - * instruction source. - */ -GLuint r600FPTranslateAlphaSwizzle(GLuint src, GLuint swizzle) -{ - if (swizzle < 3) - return swizzle + 3*src; - - switch(swizzle) { - case SWIZZLE_W: return R600_ALU_ARGA_SRC0A + src; - case SWIZZLE_ONE: return R600_ALU_ARGA_ONE; - case SWIZZLE_ZERO: return R600_ALU_ARGA_ZERO; - default: return R600_ALU_ARGA_ONE; - } -} diff --git a/src/mesa/drivers/dri/r600/r600_fragprog_swizzle.h b/src/mesa/drivers/dri/r600/r600_fragprog_swizzle.h deleted file mode 100644 index 721155f8599..00000000000 --- a/src/mesa/drivers/dri/r600/r600_fragprog_swizzle.h +++ /dev/null @@ -1,42 +0,0 @@ -/* - * Copyright (C) 2008 Nicolai Haehnle. - * - * 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. - * - */ - -#ifndef __R600_FRAGPROG_SWIZZLE_H_ -#define __R600_FRAGPROG_SWIZZLE_H_ - -#include "main/glheader.h" -#include "shader/prog_instruction.h" - -struct nqssadce_state; - -GLboolean r600FPIsNativeSwizzle(GLuint opcode, struct prog_src_register reg); -void r600FPBuildSwizzle(struct nqssadce_state*, struct prog_dst_register dst, struct prog_src_register src); - -GLuint r600FPTranslateRGBSwizzle(GLuint src, GLuint swizzle); -GLuint r600FPTranslateAlphaSwizzle(GLuint src, GLuint swizzle); - -#endif /* __R600_FRAGPROG_SWIZZLE_H_ */ diff --git a/src/mesa/drivers/dri/r600/r600_ioctl.c b/src/mesa/drivers/dri/r600/r600_ioctl.c deleted file mode 100644 index f93970e9f5d..00000000000 --- a/src/mesa/drivers/dri/r600/r600_ioctl.c +++ /dev/null @@ -1,565 +0,0 @@ -/* -Copyright (C) The Weather Channel, Inc. 2002. -Copyright (C) 2004 Nicolai Haehnle. -All Rights Reserved. - -The Weather Channel (TM) funded Tungsten Graphics to develop the -initial release of the Radeon 8500 driver under the XFree86 license. -This notice must be preserved. - -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 - * - * \author Keith Whitwell <[email protected]> - * - * \author Nicolai Haehnle <[email protected]> - */ - -#include <sched.h> -#include <errno.h> - -#include "main/glheader.h" -#include "main/imports.h" -#include "main/macros.h" -#include "main/context.h" -#include "swrast/swrast.h" - -#include "radeon_common.h" -#include "radeon_lock.h" -#include "r600_context.h" -#include "r600_ioctl.h" -#include "r600_cmdbuf.h" -#include "r600_state.h" -#include "r600_vertprog.h" -#include "radeon_reg.h" -#include "r600_emit.h" -#include "r600_fragprog.h" -#include "r600_context.h" - -#include "vblank.h" - -#define R200_3D_DRAW_IMMD_2 0xC0003500 - -#define CLEARBUFFER_COLOR 0x1 -#define CLEARBUFFER_DEPTH 0x2 -#define CLEARBUFFER_STENCIL 0x4 - -static void r600EmitClearState(GLcontext * ctx); - -static void r600UserClear(GLcontext *ctx, GLuint mask) -{ - radeon_clear_tris(ctx, mask); -} - -static void r600ClearBuffer(r600ContextPtr r600, int flags, - struct radeon_renderbuffer *rrb, - struct radeon_renderbuffer *rrbd) -{ - BATCH_LOCALS(&r600->radeon); - GLcontext *ctx = r600->radeon.glCtx; - __DRIdrawablePrivate *dPriv = r600->radeon.dri.drawable; - GLuint cbpitch = 0; - r600ContextPtr rmesa = r600; - - if (RADEON_DEBUG & DEBUG_IOCTL) - fprintf(stderr, "%s: buffer %p (%i,%i %ix%i)\n", - __FUNCTION__, rrb, dPriv->x, dPriv->y, - dPriv->w, dPriv->h); - - if (rrb) { - cbpitch = (rrb->pitch / rrb->cpp); - if (rrb->cpp == 4) - cbpitch |= R600_COLOR_FORMAT_ARGB8888; - else - cbpitch |= R600_COLOR_FORMAT_RGB565; - - if (rrb->bo->flags & RADEON_BO_FLAGS_MACRO_TILE){ - cbpitch |= R600_COLOR_TILE_ENABLE; - } - } - - /* TODO in bufmgr */ - cp_wait(&r600->radeon, R300_WAIT_3D | R300_WAIT_3D_CLEAN); - end_3d(&rmesa->radeon); - - if (flags & CLEARBUFFER_COLOR) { - assert(rrb != 0); - BEGIN_BATCH_NO_AUTOSTATE(6); - OUT_BATCH_REGSEQ(R600_RB3D_COLOROFFSET0, 1); - OUT_BATCH_RELOC(0, rrb->bo, 0, 0, RADEON_GEM_DOMAIN_VRAM, 0); - OUT_BATCH_REGVAL(R600_RB3D_COLORPITCH0, cbpitch); - END_BATCH(); - } -#if 1 - if (flags & (CLEARBUFFER_DEPTH | CLEARBUFFER_STENCIL)) { - assert(rrbd != 0); - cbpitch = (rrbd->pitch / rrbd->cpp); - if (rrbd->bo->flags & RADEON_BO_FLAGS_MACRO_TILE){ - cbpitch |= R600_DEPTHMACROTILE_ENABLE; - } - if (rrbd->bo->flags & RADEON_BO_FLAGS_MICRO_TILE){ - cbpitch |= R600_DEPTHMICROTILE_TILED; - } - BEGIN_BATCH_NO_AUTOSTATE(6); - OUT_BATCH_REGSEQ(R600_ZB_DEPTHOFFSET, 1); - OUT_BATCH_RELOC(0, rrbd->bo, 0, 0, RADEON_GEM_DOMAIN_VRAM, 0); - OUT_BATCH_REGVAL(R600_ZB_DEPTHPITCH, cbpitch); - END_BATCH(); - } -#endif - BEGIN_BATCH_NO_AUTOSTATE(6); - OUT_BATCH_REGSEQ(RB3D_COLOR_CHANNEL_MASK, 1); - if (flags & CLEARBUFFER_COLOR) { - OUT_BATCH((ctx->Color.ColorMask[BCOMP] ? RB3D_COLOR_CHANNEL_MASK_BLUE_MASK0 : 0) | - (ctx->Color.ColorMask[GCOMP] ? RB3D_COLOR_CHANNEL_MASK_GREEN_MASK0 : 0) | - (ctx->Color.ColorMask[RCOMP] ? RB3D_COLOR_CHANNEL_MASK_RED_MASK0 : 0) | - (ctx->Color.ColorMask[ACOMP] ? RB3D_COLOR_CHANNEL_MASK_ALPHA_MASK0 : 0)); - } else { - OUT_BATCH(0); - } - - - { - uint32_t t1, t2; - - t1 = 0x0; - t2 = 0x0; - - if (flags & CLEARBUFFER_DEPTH) { - t1 |= R600_Z_ENABLE | R600_Z_WRITE_ENABLE; - t2 |= - (R600_ZS_ALWAYS << R600_Z_FUNC_SHIFT); - } - - if (flags & CLEARBUFFER_STENCIL) { - t1 |= R600_STENCIL_ENABLE; - t2 |= - (R600_ZS_ALWAYS << - R600_S_FRONT_FUNC_SHIFT) | - (R600_ZS_REPLACE << - R600_S_FRONT_SFAIL_OP_SHIFT) | - (R600_ZS_REPLACE << - R600_S_FRONT_ZPASS_OP_SHIFT) | - (R600_ZS_REPLACE << - R600_S_FRONT_ZFAIL_OP_SHIFT); - } - - OUT_BATCH_REGSEQ(R600_ZB_CNTL, 3); - OUT_BATCH(t1); - OUT_BATCH(t2); - OUT_BATCH(((ctx->Stencil.WriteMask[0] & R600_STENCILREF_MASK) << - R600_STENCILWRITEMASK_SHIFT) | - (ctx->Stencil.Clear & R600_STENCILREF_MASK)); - END_BATCH(); - } - - if (!rmesa->radeon.radeonScreen->kernel_mm) { - BEGIN_BATCH_NO_AUTOSTATE(9); - OUT_BATCH(cmdpacket3(r600->radeon.radeonScreen, R300_CMD_PACKET3_CLEAR)); - OUT_BATCH_FLOAT32(dPriv->w / 2.0); - OUT_BATCH_FLOAT32(dPriv->h / 2.0); - OUT_BATCH_FLOAT32(ctx->Depth.Clear); - OUT_BATCH_FLOAT32(1.0); - OUT_BATCH_FLOAT32(ctx->Color.ClearColor[0]); - OUT_BATCH_FLOAT32(ctx->Color.ClearColor[1]); - OUT_BATCH_FLOAT32(ctx->Color.ClearColor[2]); - OUT_BATCH_FLOAT32(ctx->Color.ClearColor[3]); - END_BATCH(); - } else { - OUT_BATCH(CP_PACKET3(R200_3D_DRAW_IMMD_2, 8)); - OUT_BATCH(R600_PRIM_TYPE_POINT | R600_PRIM_WALK_RING | - (1 << R600_PRIM_NUM_VERTICES_SHIFT)); - OUT_BATCH_FLOAT32(dPriv->w / 2.0); - OUT_BATCH_FLOAT32(dPriv->h / 2.0); - OUT_BATCH_FLOAT32(ctx->Depth.Clear); - OUT_BATCH_FLOAT32(1.0); - OUT_BATCH_FLOAT32(ctx->Color.ClearColor[0]); - OUT_BATCH_FLOAT32(ctx->Color.ClearColor[1]); - OUT_BATCH_FLOAT32(ctx->Color.ClearColor[2]); - OUT_BATCH_FLOAT32(ctx->Color.ClearColor[3]); - } - - r600EmitCacheFlush(rmesa); - cp_wait(&r600->radeon, R300_WAIT_3D | R300_WAIT_3D_CLEAN); - - R600_STATECHANGE(r600, cb); - R600_STATECHANGE(r600, cmk); - R600_STATECHANGE(r600, zs); -} - -static void r600EmitClearState(GLcontext * ctx) -{ - r600ContextPtr r600 = R600_CONTEXT(ctx); - BATCH_LOCALS(&r600->radeon); - __DRIdrawablePrivate *dPriv = r600->radeon.dri.drawable; - int i; - GLuint vap_cntl; - - /* State atom dirty tracking is a little subtle here. - * - * On the one hand, we need to make sure base state is emitted - * here if we start with an empty batch buffer, otherwise clear - * works incorrectly with multiple processes. Therefore, the first - * BEGIN_BATCH cannot be a BEGIN_BATCH_NO_AUTOSTATE. - * - * On the other hand, implicit state emission clears the state atom - * dirty bits, so we have to call R600_STATECHANGE later than the - * first BEGIN_BATCH. - * - * The final trickiness is that, because we change state, we need - * to ensure that any stored swtcl primitives are flushed properly - * before we start changing state. See the R600_NEWPRIM in r600Clear - * for this. - */ - BEGIN_BATCH(31); - OUT_BATCH_REGSEQ(R600_VAP_PROG_STREAM_CNTL_0, 1); - - OUT_BATCH(((((0 << R600_DST_VEC_LOC_SHIFT) | R600_DATA_TYPE_FLOAT_4) << R600_DATA_TYPE_0_SHIFT) | - ((R600_LAST_VEC | (1 << R600_DST_VEC_LOC_SHIFT) | R600_DATA_TYPE_FLOAT_4) << R600_DATA_TYPE_1_SHIFT))); - - OUT_BATCH_REGVAL(R600_FG_FOG_BLEND, 0); - OUT_BATCH_REGVAL(R600_VAP_PROG_STREAM_CNTL_EXT_0, - ((((R600_SWIZZLE_SELECT_X << R600_SWIZZLE_SELECT_X_SHIFT) | - (R600_SWIZZLE_SELECT_Y << R600_SWIZZLE_SELECT_Y_SHIFT) | - (R600_SWIZZLE_SELECT_Z << R600_SWIZZLE_SELECT_Z_SHIFT) | - (R600_SWIZZLE_SELECT_W << R600_SWIZZLE_SELECT_W_SHIFT) | - ((R600_WRITE_ENA_X | R600_WRITE_ENA_Y | R600_WRITE_ENA_Z | R600_WRITE_ENA_W) << R600_WRITE_ENA_SHIFT)) - << R600_SWIZZLE0_SHIFT) | - (((R600_SWIZZLE_SELECT_X << R600_SWIZZLE_SELECT_X_SHIFT) | - (R600_SWIZZLE_SELECT_Y << R600_SWIZZLE_SELECT_Y_SHIFT) | - (R600_SWIZZLE_SELECT_Z << R600_SWIZZLE_SELECT_Z_SHIFT) | - (R600_SWIZZLE_SELECT_W << R600_SWIZZLE_SELECT_W_SHIFT) | - ((R600_WRITE_ENA_X | R600_WRITE_ENA_Y | R600_WRITE_ENA_Z | R600_WRITE_ENA_W) << R600_WRITE_ENA_SHIFT)) - << R600_SWIZZLE1_SHIFT))); - - /* R600_VAP_INPUT_CNTL_0, R600_VAP_INPUT_CNTL_1 */ - OUT_BATCH_REGSEQ(R600_VAP_VTX_STATE_CNTL, 2); - OUT_BATCH((R600_SEL_USER_COLOR_0 << R600_COLOR_0_ASSEMBLY_SHIFT)); - OUT_BATCH(R600_INPUT_CNTL_POS | R600_INPUT_CNTL_COLOR | R600_INPUT_CNTL_TC0); - - /* comes from fglrx startup of clear */ - OUT_BATCH_REGSEQ(R600_SE_VTE_CNTL, 2); - OUT_BATCH(R600_VTX_W0_FMT | R600_VPORT_X_SCALE_ENA | - R600_VPORT_X_OFFSET_ENA | R600_VPORT_Y_SCALE_ENA | - R600_VPORT_Y_OFFSET_ENA | R600_VPORT_Z_SCALE_ENA | - R600_VPORT_Z_OFFSET_ENA); - OUT_BATCH(0x8); - - OUT_BATCH_REGVAL(R600_VAP_PSC_SGN_NORM_CNTL, 0xaaaaaaaa); - - OUT_BATCH_REGSEQ(R600_VAP_OUTPUT_VTX_FMT_0, 2); - OUT_BATCH(R600_VAP_OUTPUT_VTX_FMT_0__POS_PRESENT | - R600_VAP_OUTPUT_VTX_FMT_0__COLOR_0_PRESENT); - OUT_BATCH(0); /* no textures */ - - OUT_BATCH_REGVAL(R600_TX_ENABLE, 0); - - OUT_BATCH_REGSEQ(R600_SE_VPORT_XSCALE, 6); - OUT_BATCH_FLOAT32(1.0); - OUT_BATCH_FLOAT32(dPriv->x); - OUT_BATCH_FLOAT32(1.0); - OUT_BATCH_FLOAT32(dPriv->y); - OUT_BATCH_FLOAT32(1.0); - OUT_BATCH_FLOAT32(0.0); - - OUT_BATCH_REGVAL(R600_FG_ALPHA_FUNC, 0); - - OUT_BATCH_REGSEQ(R600_RB3D_CBLEND, 2); - OUT_BATCH(0x0); - OUT_BATCH(0x0); - END_BATCH(); - - R600_STATECHANGE(r600, vir[0]); - R600_STATECHANGE(r600, fogs); - R600_STATECHANGE(r600, vir[1]); - R600_STATECHANGE(r600, vic); - R600_STATECHANGE(r600, vte); - R600_STATECHANGE(r600, vof); - R600_STATECHANGE(r600, txe); - R600_STATECHANGE(r600, vpt); - R600_STATECHANGE(r600, at); - R600_STATECHANGE(r600, bld); - R600_STATECHANGE(r600, ps); - - R600_STATECHANGE(r600, vap_clip_cntl); - - BEGIN_BATCH_NO_AUTOSTATE(2); - OUT_BATCH_REGVAL(R600_VAP_CLIP_CNTL, R600_PS_UCP_MODE_CLIP_AS_TRIFAN | R600_CLIP_DISABLE); - END_BATCH(); - - BEGIN_BATCH_NO_AUTOSTATE(2); - OUT_BATCH_REGVAL(R600_GA_POINT_SIZE, - ((dPriv->w * 6) << R600_POINTSIZE_X_SHIFT) | - ((dPriv->h * 6) << R600_POINTSIZE_Y_SHIFT)); - END_BATCH(); - - - R600_STATECHANGE(r600, ri); - R600_STATECHANGE(r600, rc); - R600_STATECHANGE(r600, rr); - - BEGIN_BATCH(14); - OUT_BATCH_REGSEQ(R600_RS_IP_0, 8); - for (i = 0; i < 8; ++i) - OUT_BATCH(R600_RS_SEL_T(1) | R600_RS_SEL_R(2) | R600_RS_SEL_Q(3)); - - OUT_BATCH_REGSEQ(R600_RS_COUNT, 2); - OUT_BATCH((1 << R600_IC_COUNT_SHIFT) | R600_HIRES_EN); - OUT_BATCH(0x0); - - OUT_BATCH_REGVAL(R600_RS_INST_0, R600_RS_INST_COL_CN_WRITE); - END_BATCH(); - - R600_STATECHANGE(r600, fp); - R600_STATECHANGE(r600, fpi[0]); - R600_STATECHANGE(r600, fpi[1]); - R600_STATECHANGE(r600, fpi[2]); - R600_STATECHANGE(r600, fpi[3]); - - BEGIN_BATCH(17); - OUT_BATCH_REGSEQ(R600_US_CONFIG, 3); - OUT_BATCH(0x0); - OUT_BATCH(0x0); - OUT_BATCH(0x0); - OUT_BATCH_REGSEQ(R600_US_CODE_ADDR_0, 4); - OUT_BATCH(0x0); - OUT_BATCH(0x0); - OUT_BATCH(0x0); - OUT_BATCH(R600_RGBA_OUT); - - OUT_BATCH_REGVAL(R600_US_ALU_RGB_INST_0, - FP_INSTRC(MAD, FP_ARGC(SRC0C_XYZ), FP_ARGC(ONE), FP_ARGC(ZERO))); - OUT_BATCH_REGVAL(R600_US_ALU_RGB_ADDR_0, - FP_SELC(0, NO, XYZ, FP_TMP(0), 0, 0)); - OUT_BATCH_REGVAL(R600_US_ALU_ALPHA_INST_0, - FP_INSTRA(MAD, FP_ARGA(SRC0A), FP_ARGA(ONE), FP_ARGA(ZERO))); - OUT_BATCH_REGVAL(R600_US_ALU_ALPHA_ADDR_0, - FP_SELA(0, NO, W, FP_TMP(0), 0, 0)); - END_BATCH(); - - BEGIN_BATCH(2); - OUT_BATCH_REGVAL(R600_VAP_PVS_STATE_FLUSH_REG, 0); - END_BATCH(); - - vap_cntl = ((10 << R600_PVS_NUM_SLOTS_SHIFT) | - (5 << R600_PVS_NUM_CNTLRS_SHIFT) | - (12 << R600_VF_MAX_VTX_NUM_SHIFT)); - - if (r600->radeon.radeonScreen->chip_family == CHIP_FAMILY_RV515) - vap_cntl |= (2 << R600_PVS_NUM_FPUS_SHIFT); - else if ((r600->radeon.radeonScreen->chip_family == CHIP_FAMILY_RV530) || - (r600->radeon.radeonScreen->chip_family == CHIP_FAMILY_RV560) || - (r600->radeon.radeonScreen->chip_family == CHIP_FAMILY_RV570)) - vap_cntl |= (5 << R600_PVS_NUM_FPUS_SHIFT); - else if ((r600->radeon.radeonScreen->chip_family == CHIP_FAMILY_RV410) || - (r600->radeon.radeonScreen->chip_family == CHIP_FAMILY_R420)) - vap_cntl |= (6 << R600_PVS_NUM_FPUS_SHIFT); - else if ((r600->radeon.radeonScreen->chip_family == CHIP_FAMILY_R520) || - (r600->radeon.radeonScreen->chip_family == CHIP_FAMILY_R580)) - vap_cntl |= (8 << R600_PVS_NUM_FPUS_SHIFT); - else - vap_cntl |= (4 << R600_PVS_NUM_FPUS_SHIFT); - - R600_STATECHANGE(r600, vap_cntl); - - BEGIN_BATCH(2); - OUT_BATCH_REGVAL(R600_VAP_CNTL, vap_cntl); - END_BATCH(); - - { - struct radeon_state_atom vpu; - uint32_t _cmd[10]; - R600_STATECHANGE(r600, pvs); - R600_STATECHANGE(r600, vpi); - - BEGIN_BATCH(4); - OUT_BATCH_REGSEQ(R600_VAP_PVS_CODE_CNTL_0, 3); - OUT_BATCH((0 << R600_PVS_FIRST_INST_SHIFT) | - (0 << R600_PVS_XYZW_VALID_INST_SHIFT) | - (1 << R600_PVS_LAST_INST_SHIFT)); - OUT_BATCH((0 << R600_PVS_CONST_BASE_OFFSET_SHIFT) | - (0 << R600_PVS_MAX_CONST_ADDR_SHIFT)); - OUT_BATCH(1 << R600_PVS_LAST_VTX_SRC_INST_SHIFT); - END_BATCH(); - - vpu.check = check_vpu; - vpu.cmd = _cmd; - vpu.cmd[0] = cmdvpu(r600->radeon.radeonScreen, 0, 2); - - vpu.cmd[1] = PVS_OP_DST_OPERAND(VE_ADD, GL_FALSE, GL_FALSE, - 0, 0xf, PVS_DST_REG_OUT); - vpu.cmd[2] = PVS_SRC_OPERAND(0, PVS_SRC_SELECT_X, PVS_SRC_SELECT_Y, - PVS_SRC_SELECT_Z, PVS_SRC_SELECT_W, - PVS_SRC_REG_INPUT, VSF_FLAG_NONE); - vpu.cmd[3] = PVS_SRC_OPERAND(0, PVS_SRC_SELECT_FORCE_0, - PVS_SRC_SELECT_FORCE_0, - PVS_SRC_SELECT_FORCE_0, - PVS_SRC_SELECT_FORCE_0, - PVS_SRC_REG_INPUT, VSF_FLAG_NONE); - vpu.cmd[4] = 0x0; - - vpu.cmd[5] = PVS_OP_DST_OPERAND(VE_ADD, GL_FALSE, GL_FALSE, 1, 0xf, - PVS_DST_REG_OUT); - vpu.cmd[6] = PVS_SRC_OPERAND(1, PVS_SRC_SELECT_X, - PVS_SRC_SELECT_Y, PVS_SRC_SELECT_Z, - PVS_SRC_SELECT_W, PVS_SRC_REG_INPUT, - - VSF_FLAG_NONE); - vpu.cmd[7] = PVS_SRC_OPERAND(1, PVS_SRC_SELECT_FORCE_0, - PVS_SRC_SELECT_FORCE_0, - PVS_SRC_SELECT_FORCE_0, - PVS_SRC_SELECT_FORCE_0, - PVS_SRC_REG_INPUT, VSF_FLAG_NONE); - vpu.cmd[8] = 0x0; - - r600->vap_flush_needed = GL_TRUE; - emit_vpu(ctx, &vpu); - } -} - -static void r600KernelClear(GLcontext *ctx, GLuint flags) -{ - r600ContextPtr r600 = R600_CONTEXT(ctx); - __DRIdrawablePrivate *dPriv = r600->radeon.dri.drawable; - struct radeon_framebuffer *rfb = dPriv->driverPrivate; - struct radeon_renderbuffer *rrb; - struct radeon_renderbuffer *rrbd; - int bits = 0; - - /* Make sure it fits there. */ - rcommonEnsureCmdBufSpace(&r600->radeon, 421 * 3, __FUNCTION__); - if (flags || bits) - r600EmitClearState(ctx); - rrbd = radeon_get_renderbuffer(&rfb->base, BUFFER_DEPTH); - if (rrbd && (flags & BUFFER_BIT_DEPTH)) - bits |= CLEARBUFFER_DEPTH; - - if (rrbd && (flags & BUFFER_BIT_STENCIL)) - bits |= CLEARBUFFER_STENCIL; - - if (flags & BUFFER_BIT_COLOR0) { - rrb = radeon_get_renderbuffer(&rfb->base, BUFFER_COLOR0); - r600ClearBuffer(r600, CLEARBUFFER_COLOR, rrb, NULL); - bits = 0; - } - - if (flags & BUFFER_BIT_FRONT_LEFT) { - rrb = radeon_get_renderbuffer(&rfb->base, BUFFER_FRONT_LEFT); - r600ClearBuffer(r600, bits | CLEARBUFFER_COLOR, rrb, rrbd); - bits = 0; - } - - if (flags & BUFFER_BIT_BACK_LEFT) { - rrb = radeon_get_renderbuffer(&rfb->base, BUFFER_BACK_LEFT); - r600ClearBuffer(r600, bits | CLEARBUFFER_COLOR, rrb, rrbd); - bits = 0; - } - - if (bits) - r600ClearBuffer(r600, bits, NULL, rrbd); - - COMMIT_BATCH(); -} - -/** - * Buffer clear - */ -static void r600Clear(GLcontext * ctx, GLbitfield mask) -{ - r600ContextPtr r600 = R600_CONTEXT(ctx); - __DRIdrawablePrivate *dPriv = r600->radeon.dri.drawable; - const GLuint colorMask = *((GLuint *) & ctx->Color.ColorMask); - GLbitfield swrast_mask = 0, tri_mask = 0; - int i; - struct gl_framebuffer *fb = ctx->DrawBuffer; - - if (RADEON_DEBUG & DEBUG_IOCTL) - fprintf(stderr, "r600Clear\n"); - - if (!r600->radeon.radeonScreen->driScreen->dri2.enabled) { - LOCK_HARDWARE(&r600->radeon); - UNLOCK_HARDWARE(&r600->radeon); - if (dPriv->numClipRects == 0) - return; - } - - /* Flush swtcl vertices if necessary, because we will change hardware - * state during clear. See also the state-related comment in - * r600EmitClearState. - */ - R600_NEWPRIM(r600); - - if (colorMask == ~0) - tri_mask |= (mask & BUFFER_BITS_COLOR); - - - /* HW stencil */ - if (mask & BUFFER_BIT_STENCIL) { - tri_mask |= BUFFER_BIT_STENCIL; - } - - /* HW depth */ - if (mask & BUFFER_BIT_DEPTH) { - tri_mask |= BUFFER_BIT_DEPTH; - } - - /* If we're doing a tri pass for depth/stencil, include a likely color - * buffer with it. - */ - - for (i = 0; i < BUFFER_COUNT; i++) { - GLuint bufBit = 1 << i; - if ((tri_mask) & bufBit) { - if (!fb->Attachment[i].Renderbuffer->ClassID) { - tri_mask &= ~bufBit; - swrast_mask |= bufBit; - } - } - } - - /* SW fallback clearing */ - swrast_mask = mask & ~tri_mask; - - if (tri_mask) { - if (r600->radeon.radeonScreen->kernel_mm) - r600UserClear(ctx, tri_mask); - else - r600KernelClear(ctx, tri_mask); - } - if (swrast_mask) { - if (RADEON_DEBUG & DEBUG_FALLBACKS) - fprintf(stderr, "%s: swrast clear, mask: %x\n", - __FUNCTION__, swrast_mask); - _swrast_Clear(ctx, swrast_mask); - } -} - - -void r600InitIoctlFuncs(struct dd_function_table *functions) -{ - functions->Clear = r600Clear; - functions->Finish = radeonFinish; - functions->Flush = radeonFlush; -} diff --git a/src/mesa/drivers/dri/r600/r600_ioctl.h b/src/mesa/drivers/dri/r600/r600_ioctl.h deleted file mode 100644 index bef8acf23c4..00000000000 --- a/src/mesa/drivers/dri/r600/r600_ioctl.h +++ /dev/null @@ -1,44 +0,0 @@ -/* -Copyright (C) The Weather Channel, Inc. 2002. All Rights Reserved. - -The Weather Channel (TM) funded Tungsten Graphics to develop the -initial release of the Radeon 8500 driver under the XFree86 license. -This notice must be preserved. - -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. - -**************************************************************************/ - -/* - * Authors: - * Keith Whitwell <[email protected]> - * Nicolai Haehnle <[email protected]> - */ - -#ifndef __R600_IOCTL_H__ -#define __R600_IOCTL_H__ - -#include "r600_context.h" -#include "radeon_drm.h" - -extern void r600InitIoctlFuncs(struct dd_function_table *functions); - -#endif /* __R600_IOCTL_H__ */ diff --git a/src/mesa/drivers/dri/r600/r600_render.c b/src/mesa/drivers/dri/r600/r600_render.c deleted file mode 100644 index 7b4ecccc660..00000000000 --- a/src/mesa/drivers/dri/r600/r600_render.c +++ /dev/null @@ -1,539 +0,0 @@ -/************************************************************************** - -Copyright (C) 2004 Nicolai Haehnle. - -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 -on the rights to use, copy, modify, merge, publish, distribute, sub -license, 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 NON-INFRINGEMENT. IN NO EVENT SHALL -ATI, VA LINUX SYSTEMS AND/OR THEIR 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 - * - * \brief R600 Render (Vertex Buffer Implementation) - * - * The immediate implementation has been removed from CVS in favor of the vertex - * buffer implementation. - * - * The render functions are called by the pipeline manager to render a batch of - * primitives. They return TRUE to pass on to the next stage (i.e. software - * rasterization) or FALSE to indicate that the pipeline has finished after - * rendering something. - * - * When falling back to software TCL still attempt to use hardware - * rasterization. - * - * I am not sure that the cache related registers are setup correctly, but - * obviously this does work... Further investigation is needed. - * - * \author Nicolai Haehnle <[email protected]> - * - * \todo Add immediate implementation back? Perhaps this is useful if there are - * no bugs... - */ - -#include "main/glheader.h" -#include "main/state.h" -#include "main/imports.h" -#include "main/enums.h" -#include "main/macros.h" -#include "main/context.h" -#include "main/dd.h" -#include "main/simple_list.h" -#include "main/api_arrayelt.h" -#include "swrast/swrast.h" -#include "swrast_setup/swrast_setup.h" -#include "vbo/vbo.h" -#include "tnl/tnl.h" -#include "tnl/t_vp_build.h" -#include "radeon_reg.h" -#include "radeon_macros.h" -#include "r600_context.h" -#include "r600_ioctl.h" -#include "r600_state.h" -#include "r600_reg.h" -#include "r600_tex.h" -#include "r600_emit.h" -#include "r600_fragprog.h" -extern int future_hw_tcl_on; - -/** - * \brief Convert a OpenGL primitive type into a R600 primitive type. - */ -int r600PrimitiveType(r600ContextPtr rmesa, int prim) -{ - switch (prim & PRIM_MODE_MASK) { - case GL_POINTS: - return R600_VAP_VF_CNTL__PRIM_POINTS; - break; - case GL_LINES: - return R600_VAP_VF_CNTL__PRIM_LINES; - break; - case GL_LINE_STRIP: - return R600_VAP_VF_CNTL__PRIM_LINE_STRIP; - break; - case GL_LINE_LOOP: - return R600_VAP_VF_CNTL__PRIM_LINE_LOOP; - break; - case GL_TRIANGLES: - return R600_VAP_VF_CNTL__PRIM_TRIANGLES; - break; - case GL_TRIANGLE_STRIP: - return R600_VAP_VF_CNTL__PRIM_TRIANGLE_STRIP; - break; - case GL_TRIANGLE_FAN: - return R600_VAP_VF_CNTL__PRIM_TRIANGLE_FAN; - break; - case GL_QUADS: - return R600_VAP_VF_CNTL__PRIM_QUADS; - break; - case GL_QUAD_STRIP: - return R600_VAP_VF_CNTL__PRIM_QUAD_STRIP; - break; - case GL_POLYGON: - return R600_VAP_VF_CNTL__PRIM_POLYGON; - break; - default: - assert(0); - return -1; - break; - } -} - -int r600NumVerts(r600ContextPtr rmesa, int num_verts, int prim) -{ - int verts_off = 0; - - switch (prim & PRIM_MODE_MASK) { - case GL_POINTS: - verts_off = 0; - break; - case GL_LINES: - verts_off = num_verts % 2; - break; - case GL_LINE_STRIP: - if (num_verts < 2) - verts_off = num_verts; - break; - case GL_LINE_LOOP: - if (num_verts < 2) - verts_off = num_verts; - break; - case GL_TRIANGLES: - verts_off = num_verts % 3; - break; - case GL_TRIANGLE_STRIP: - if (num_verts < 3) - verts_off = num_verts; - break; - case GL_TRIANGLE_FAN: - if (num_verts < 3) - verts_off = num_verts; - break; - case GL_QUADS: - verts_off = num_verts % 4; - break; - case GL_QUAD_STRIP: - if (num_verts < 4) - verts_off = num_verts; - else - verts_off = num_verts % 2; - break; - case GL_POLYGON: - if (num_verts < 3) - verts_off = num_verts; - break; - default: - assert(0); - return -1; - break; - } - - return num_verts - verts_off; -} - -static void r600EmitElts(GLcontext * ctx, void *elts, unsigned long n_elts) -{ - r600ContextPtr rmesa = R600_CONTEXT(ctx); - void *out; - - radeonAllocDmaRegion(&rmesa->radeon, &rmesa->radeon.tcl.elt_dma_bo, - &rmesa->radeon.tcl.elt_dma_offset, n_elts * 4, 4); - radeon_bo_map(rmesa->radeon.tcl.elt_dma_bo, 1); - out = rmesa->radeon.tcl.elt_dma_bo->ptr + rmesa->radeon.tcl.elt_dma_offset; - memcpy(out, elts, n_elts * 4); - radeon_bo_unmap(rmesa->radeon.tcl.elt_dma_bo); -} - -static void r600FireEB(r600ContextPtr rmesa, int vertex_count, int type) -{ - BATCH_LOCALS(&rmesa->radeon); - - if (vertex_count > 0) { - BEGIN_BATCH(10); - OUT_BATCH_PACKET3(R600_PACKET3_3D_DRAW_INDX_2, 0); - OUT_BATCH(R600_VAP_VF_CNTL__PRIM_WALK_INDICES | - ((vertex_count + 0) << 16) | - type | - R600_VAP_VF_CNTL__INDEX_SIZE_32bit); - - if (!rmesa->radeon.radeonScreen->kernel_mm) { - OUT_BATCH_PACKET3(R600_PACKET3_INDX_BUFFER, 2); - OUT_BATCH(R600_INDX_BUFFER_ONE_REG_WR | (0 << R600_INDX_BUFFER_SKIP_SHIFT) | - (R600_VAP_PORT_IDX0 >> 2)); - OUT_BATCH_RELOC(rmesa->radeon.tcl.elt_dma_offset, - rmesa->radeon.tcl.elt_dma_bo, - rmesa->radeon.tcl.elt_dma_offset, - RADEON_GEM_DOMAIN_GTT, 0, 0); - OUT_BATCH(vertex_count); - } else { - OUT_BATCH_PACKET3(R600_PACKET3_INDX_BUFFER, 2); - OUT_BATCH(R600_INDX_BUFFER_ONE_REG_WR | (0 << R600_INDX_BUFFER_SKIP_SHIFT) | - (R600_VAP_PORT_IDX0 >> 2)); - OUT_BATCH(rmesa->radeon.tcl.elt_dma_offset); - OUT_BATCH(vertex_count); - radeon_cs_write_reloc(rmesa->radeon.cmdbuf.cs, - rmesa->radeon.tcl.elt_dma_bo, - RADEON_GEM_DOMAIN_GTT, 0, 0); - } - END_BATCH(); - } -} - -static void r600EmitAOS(r600ContextPtr rmesa, GLuint nr, GLuint offset) -{ - BATCH_LOCALS(&rmesa->radeon); - uint32_t voffset; - int sz = 1 + (nr >> 1) * 3 + (nr & 1) * 2; - int i; - - if (RADEON_DEBUG & DEBUG_VERTS) - fprintf(stderr, "%s: nr=%d, ofs=0x%08x\n", __FUNCTION__, nr, - offset); - - - if (!rmesa->radeon.radeonScreen->kernel_mm) { - BEGIN_BATCH(sz+2+(nr * 2)); - OUT_BATCH_PACKET3(R600_PACKET3_3D_LOAD_VBPNTR, sz - 1); - OUT_BATCH(nr); - - for (i = 0; i + 1 < nr; i += 2) { - OUT_BATCH((rmesa->radeon.tcl.aos[i].components << 0) | - (rmesa->radeon.tcl.aos[i].stride << 8) | - (rmesa->radeon.tcl.aos[i + 1].components << 16) | - (rmesa->radeon.tcl.aos[i + 1].stride << 24)); - - voffset = rmesa->radeon.tcl.aos[i + 0].offset + - offset * 4 * rmesa->radeon.tcl.aos[i + 0].stride; - OUT_BATCH_RELOC(voffset, - rmesa->radeon.tcl.aos[i].bo, - voffset, - RADEON_GEM_DOMAIN_GTT, - 0, 0); - voffset = rmesa->radeon.tcl.aos[i + 1].offset + - offset * 4 * rmesa->radeon.tcl.aos[i + 1].stride; - OUT_BATCH_RELOC(voffset, - rmesa->radeon.tcl.aos[i+1].bo, - voffset, - RADEON_GEM_DOMAIN_GTT, - 0, 0); - } - - if (nr & 1) { - OUT_BATCH((rmesa->radeon.tcl.aos[nr - 1].components << 0) | - (rmesa->radeon.tcl.aos[nr - 1].stride << 8)); - voffset = rmesa->radeon.tcl.aos[nr - 1].offset + - offset * 4 * rmesa->radeon.tcl.aos[nr - 1].stride; - OUT_BATCH_RELOC(voffset, - rmesa->radeon.tcl.aos[nr - 1].bo, - voffset, - RADEON_GEM_DOMAIN_GTT, - 0, 0); - } - END_BATCH(); - } else { - - BEGIN_BATCH(sz+2+(nr * 2)); - OUT_BATCH_PACKET3(R600_PACKET3_3D_LOAD_VBPNTR, sz - 1); - OUT_BATCH(nr); - - for (i = 0; i + 1 < nr; i += 2) { - OUT_BATCH((rmesa->radeon.tcl.aos[i].components << 0) | - (rmesa->radeon.tcl.aos[i].stride << 8) | - (rmesa->radeon.tcl.aos[i + 1].components << 16) | - (rmesa->radeon.tcl.aos[i + 1].stride << 24)); - - voffset = rmesa->radeon.tcl.aos[i + 0].offset + - offset * 4 * rmesa->radeon.tcl.aos[i + 0].stride; - OUT_BATCH(voffset); - voffset = rmesa->radeon.tcl.aos[i + 1].offset + - offset * 4 * rmesa->radeon.tcl.aos[i + 1].stride; - OUT_BATCH(voffset); - } - - if (nr & 1) { - OUT_BATCH((rmesa->radeon.tcl.aos[nr - 1].components << 0) | - (rmesa->radeon.tcl.aos[nr - 1].stride << 8)); - voffset = rmesa->radeon.tcl.aos[nr - 1].offset + - offset * 4 * rmesa->radeon.tcl.aos[nr - 1].stride; - OUT_BATCH(voffset); - } - for (i = 0; i + 1 < nr; i += 2) { - voffset = rmesa->radeon.tcl.aos[i + 0].offset + - offset * 4 * rmesa->radeon.tcl.aos[i + 0].stride; - radeon_cs_write_reloc(rmesa->radeon.cmdbuf.cs, - rmesa->radeon.tcl.aos[i+0].bo, - RADEON_GEM_DOMAIN_GTT, - 0, 0); - voffset = rmesa->radeon.tcl.aos[i + 1].offset + - offset * 4 * rmesa->radeon.tcl.aos[i + 1].stride; - radeon_cs_write_reloc(rmesa->radeon.cmdbuf.cs, - rmesa->radeon.tcl.aos[i+1].bo, - RADEON_GEM_DOMAIN_GTT, - 0, 0); - } - if (nr & 1) { - voffset = rmesa->radeon.tcl.aos[nr - 1].offset + - offset * 4 * rmesa->radeon.tcl.aos[nr - 1].stride; - radeon_cs_write_reloc(rmesa->radeon.cmdbuf.cs, - rmesa->radeon.tcl.aos[nr-1].bo, - RADEON_GEM_DOMAIN_GTT, - 0, 0); - } - END_BATCH(); - } - -} - -static void r600FireAOS(r600ContextPtr rmesa, int vertex_count, int type) -{ - BATCH_LOCALS(&rmesa->radeon); - - BEGIN_BATCH(3); - OUT_BATCH_PACKET3(R600_PACKET3_3D_DRAW_VBUF_2, 0); - OUT_BATCH(R600_VAP_VF_CNTL__PRIM_WALK_VERTEX_LIST | (vertex_count << 16) | type); - END_BATCH(); -} - -static void r600RunRenderPrimitive(r600ContextPtr rmesa, GLcontext * ctx, - int start, int end, int prim) -{ - int type, num_verts; - TNLcontext *tnl = TNL_CONTEXT(ctx); - struct vertex_buffer *vb = &tnl->vb; - - type = r600PrimitiveType(rmesa, prim); - num_verts = r600NumVerts(rmesa, end - start, prim); - - if (type < 0 || num_verts <= 0) - return; - - /* Make space for at least 64 dwords. - * This is supposed to ensure that we can get all rendering - * commands into a single command buffer. - */ - rcommonEnsureCmdBufSpace(&rmesa->radeon, 64, __FUNCTION__); - - if (vb->Elts) { - if (num_verts > 65535) { - /* not implemented yet */ - WARN_ONCE("Too many elts\n"); - return; - } - /* Note: The following is incorrect, but it's the best I can do - * without a major refactoring of how DMA memory is handled. - * The problem: Ensuring that both vertex arrays *and* index - * arrays are at the right position, and then ensuring that - * the LOAD_VBPNTR, DRAW_INDX and INDX_BUFFER packets are emitted - * at once. - * - * So why is the following incorrect? Well, it seems like - * allocating the index array might actually evict the vertex - * arrays. *sigh* - */ - r600EmitElts(ctx, vb->Elts, num_verts); - r600EmitAOS(rmesa, rmesa->radeon.tcl.aos_count, start); - r600FireEB(rmesa, num_verts, type); - } else { - r600EmitAOS(rmesa, rmesa->radeon.tcl.aos_count, start); - r600FireAOS(rmesa, num_verts, type); - } - COMMIT_BATCH(); -} - -static GLboolean r600RunRender(GLcontext * ctx, - struct tnl_pipeline_stage *stage) -{ - r600ContextPtr rmesa = R600_CONTEXT(ctx); - int i; - TNLcontext *tnl = TNL_CONTEXT(ctx); - struct vertex_buffer *vb = &tnl->vb; - - if (RADEON_DEBUG & DEBUG_PRIMS) - fprintf(stderr, "%s\n", __FUNCTION__); - - r600UpdateShaders(rmesa); - if (r600EmitArrays(ctx)) - return GL_TRUE; - - r600UpdateShaderStates(rmesa); - - r600EmitCacheFlush(rmesa); - radeonEmitState(&rmesa->radeon); - - for (i = 0; i < vb->PrimitiveCount; i++) { - GLuint prim = _tnl_translate_prim(&vb->Primitive[i]); - GLuint start = vb->Primitive[i].start; - GLuint end = vb->Primitive[i].start + vb->Primitive[i].count; - r600RunRenderPrimitive(rmesa, ctx, start, end, prim); - } - - r600EmitCacheFlush(rmesa); - - radeonReleaseArrays(ctx, ~0); - - return GL_FALSE; -} - -#define FALLBACK_IF(expr) \ - do { \ - if (expr) { \ - if (1 || RADEON_DEBUG & DEBUG_FALLBACKS) \ - WARN_ONCE("Software fallback:%s\n", \ - #expr); \ - return R600_FALLBACK_RAST; \ - } \ - } while(0) - -static int r600Fallback(GLcontext * ctx) -{ - r600ContextPtr r600 = R600_CONTEXT(ctx); - const unsigned back = ctx->Stencil._BackFace; - - FALLBACK_IF(r600->radeon.Fallback); - /* Do we need to use new-style shaders? - * Also is there a better way to do this? */ - { - struct r600_fragment_program *fp = (struct r600_fragment_program *) - (char *)ctx->FragmentProgram._Current; - if (fp) { - if (!fp->translated) { - r600TranslateFragmentShader(r600, fp); - FALLBACK_IF(!fp->translated); - } - } - } - - FALLBACK_IF(ctx->RenderMode != GL_RENDER); - - /* If GL_EXT_stencil_two_side is disabled, this fallback check can - * be removed. - */ - FALLBACK_IF(ctx->Stencil.Ref[0] != ctx->Stencil.Ref[back] - || ctx->Stencil.ValueMask[0] != - ctx->Stencil.ValueMask[back] - || ctx->Stencil.WriteMask[0] != - ctx->Stencil.WriteMask[back]); - - if (ctx->Extensions.NV_point_sprite || ctx->Extensions.ARB_point_sprite) - FALLBACK_IF(ctx->Point.PointSprite); - - if (!r600->disable_lowimpact_fallback) { - FALLBACK_IF(ctx->Polygon.StippleFlag); - FALLBACK_IF(ctx->Multisample._Enabled); - FALLBACK_IF(ctx->Line.StippleFlag); - FALLBACK_IF(ctx->Line.SmoothFlag); - FALLBACK_IF(ctx->Point.SmoothFlag); - } - - return R600_FALLBACK_NONE; -} - -static GLboolean r600RunNonTCLRender(GLcontext * ctx, - struct tnl_pipeline_stage *stage) -{ - r600ContextPtr rmesa = R600_CONTEXT(ctx); - - if (RADEON_DEBUG & DEBUG_PRIMS) - fprintf(stderr, "%s\n", __FUNCTION__); - - if (r600Fallback(ctx) >= R600_FALLBACK_RAST) - return GL_TRUE; - - if (!(rmesa->radeon.radeonScreen->chip_flags & RADEON_CHIPSET_TCL)) - return GL_TRUE; - - if (!r600ValidateBuffers(ctx)) - return GL_TRUE; - - return r600RunRender(ctx, stage); -} - -static GLboolean r600RunTCLRender(GLcontext * ctx, - struct tnl_pipeline_stage *stage) -{ - r600ContextPtr rmesa = R600_CONTEXT(ctx); - struct r600_vertex_program *vp; - - hw_tcl_on = future_hw_tcl_on; - - if (RADEON_DEBUG & DEBUG_PRIMS) - fprintf(stderr, "%s\n", __FUNCTION__); - - if (hw_tcl_on == GL_FALSE) - return GL_TRUE; - - if (r600Fallback(ctx) >= R600_FALLBACK_TCL) { - hw_tcl_on = GL_FALSE; - return GL_TRUE; - } - - if (!r600ValidateBuffers(ctx)) - return GL_TRUE; - - r600UpdateShaders(rmesa); - - vp = (struct r600_vertex_program *)CURRENT_VERTEX_SHADER(ctx); - if (vp->native == GL_FALSE) { - hw_tcl_on = GL_FALSE; - return GL_TRUE; - } - - return r600RunRender(ctx, stage); -} - -const struct tnl_pipeline_stage _r600_render_stage = { - "r600 Hardware Rasterization", - NULL, - NULL, - NULL, - NULL, - r600RunNonTCLRender -}; - -const struct tnl_pipeline_stage _r600_tcl_stage = { - "r600 Hardware Transform, Clipping and Lighting", - NULL, - NULL, - NULL, - NULL, - r600RunTCLRender -}; diff --git a/src/mesa/drivers/dri/r600/r600_shader.c b/src/mesa/drivers/dri/r600/r600_shader.c deleted file mode 100644 index 7d054e4fb0d..00000000000 --- a/src/mesa/drivers/dri/r600/r600_shader.c +++ /dev/null @@ -1,74 +0,0 @@ - -#include "main/glheader.h" - -#include "shader/program.h" -#include "tnl/tnl.h" -#include "r600_context.h" -#include "r600_fragprog.h" - -static struct gl_program *r600NewProgram(GLcontext * ctx, GLenum target, - GLuint id) -{ - r600ContextPtr rmesa = R600_CONTEXT(ctx); - struct r600_vertex_program_cont *vp; - struct r600_fragment_program *r600_fp; - - switch (target) { - case GL_VERTEX_STATE_PROGRAM_NV: - case GL_VERTEX_PROGRAM_ARB: - vp = CALLOC_STRUCT(r600_vertex_program_cont); - return _mesa_init_vertex_program(ctx, &vp->mesa_program, - target, id); - case GL_FRAGMENT_PROGRAM_ARB: - r600_fp = CALLOC_STRUCT(r600_fragment_program); - return _mesa_init_fragment_program(ctx, &r600_fp->mesa_program, - target, id); - case GL_FRAGMENT_PROGRAM_NV: - r600_fp = CALLOC_STRUCT(r600_fragment_program); - return _mesa_init_fragment_program(ctx, &r600_fp->mesa_program, - target, id); - default: - _mesa_problem(ctx, "Bad target in r600NewProgram"); - } - - return NULL; -} - -static void r600DeleteProgram(GLcontext * ctx, struct gl_program *prog) -{ - _mesa_delete_program(ctx, prog); -} - -static void -r600ProgramStringNotify(GLcontext * ctx, GLenum target, struct gl_program *prog) -{ - r600ContextPtr rmesa = R600_CONTEXT(ctx); - struct r600_vertex_program_cont *vp = (void *)prog; - struct r600_fragment_program *r600_fp = (struct r600_fragment_program *)prog; - - switch (target) { - case GL_VERTEX_PROGRAM_ARB: - vp->progs = NULL; - break; - case GL_FRAGMENT_PROGRAM_ARB: - r600_fp->translated = GL_FALSE; - break; - } - - /* need this for tcl fallbacks */ - _tnl_program_string(ctx, target, prog); -} - -static GLboolean -r600IsProgramNative(GLcontext * ctx, GLenum target, struct gl_program *prog) -{ - return GL_TRUE; -} - -void r600InitShaderFuncs(struct dd_function_table *functions) -{ - functions->NewProgram = r600NewProgram; - functions->DeleteProgram = r600DeleteProgram; - functions->ProgramStringNotify = r600ProgramStringNotify; - functions->IsProgramNative = r600IsProgramNative; -} diff --git a/src/mesa/drivers/dri/r600/r600_state.c b/src/mesa/drivers/dri/r600/r600_state.c deleted file mode 100644 index 5150f0c6026..00000000000 --- a/src/mesa/drivers/dri/r600/r600_state.c +++ /dev/null @@ -1,2248 +0,0 @@ -/* -Copyright (C) The Weather Channel, Inc. 2002. -Copyright (C) 2004 Nicolai Haehnle. -All Rights Reserved. - -The Weather Channel (TM) funded Tungsten Graphics to develop the -initial release of the Radeon 8500 driver under the XFree86 license. -This notice must be preserved. - -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 - * - * \author Nicolai Haehnle <[email protected]> - */ - -#include "main/glheader.h" -#include "main/state.h" -#include "main/imports.h" -#include "main/enums.h" -#include "main/macros.h" -#include "main/context.h" -#include "main/dd.h" -#include "main/framebuffer.h" -#include "main/simple_list.h" -#include "main/api_arrayelt.h" -#include "main/texformat.h" - -#include "swrast/swrast.h" -#include "swrast_setup/swrast_setup.h" -#include "shader/prog_parameter.h" -#include "shader/prog_statevars.h" -#include "vbo/vbo.h" -#include "tnl/tnl.h" - -#include "r600_context.h" -#include "r600_ioctl.h" -#include "r600_state.h" -#include "r600_reg.h" -#include "r600_emit.h" -#include "r600_fragprog.h" -#include "r600_tex.h" - -#include "drirenderbuffer.h" - -extern int future_hw_tcl_on; -extern void _tnl_UpdateFixedFunctionProgram(GLcontext * ctx); - -static void r600BlendColor(GLcontext * ctx, const GLfloat cf[4]) -{ - r600ContextPtr rmesa = R600_CONTEXT(ctx); - GLubyte color[4]; - - R600_STATECHANGE(rmesa, blend_color); - - CLAMPED_FLOAT_TO_UBYTE(color[0], cf[0]); - CLAMPED_FLOAT_TO_UBYTE(color[1], cf[1]); - CLAMPED_FLOAT_TO_UBYTE(color[2], cf[2]); - CLAMPED_FLOAT_TO_UBYTE(color[3], cf[3]); - - rmesa->hw.blend_color.cmd[1] = PACK_COLOR_8888(color[3], color[0], - color[1], color[2]); -} - -/** - * Calculate the hardware blend factor setting. This same function is used - * for source and destination of both alpha and RGB. - * - * \returns - * The hardware register value for the specified blend factor. This value - * will need to be shifted into the correct position for either source or - * destination factor. - * - * \todo - * Since the two cases where source and destination are handled differently - * are essentially error cases, they should never happen. Determine if these - * cases can be removed. - */ -static int blend_factor(GLenum factor, GLboolean is_src) -{ - switch (factor) { - case GL_ZERO: - return R600_BLEND_GL_ZERO; - break; - case GL_ONE: - return R600_BLEND_GL_ONE; - break; - case GL_DST_COLOR: - return R600_BLEND_GL_DST_COLOR; - break; - case GL_ONE_MINUS_DST_COLOR: - return R600_BLEND_GL_ONE_MINUS_DST_COLOR; - break; - case GL_SRC_COLOR: - return R600_BLEND_GL_SRC_COLOR; - break; - case GL_ONE_MINUS_SRC_COLOR: - return R600_BLEND_GL_ONE_MINUS_SRC_COLOR; - break; - case GL_SRC_ALPHA: - return R600_BLEND_GL_SRC_ALPHA; - break; - case GL_ONE_MINUS_SRC_ALPHA: - return R600_BLEND_GL_ONE_MINUS_SRC_ALPHA; - break; - case GL_DST_ALPHA: - return R600_BLEND_GL_DST_ALPHA; - break; - case GL_ONE_MINUS_DST_ALPHA: - return R600_BLEND_GL_ONE_MINUS_DST_ALPHA; - break; - case GL_SRC_ALPHA_SATURATE: - return (is_src) ? R600_BLEND_GL_SRC_ALPHA_SATURATE : - R600_BLEND_GL_ZERO; - break; - case GL_CONSTANT_COLOR: - return R600_BLEND_GL_CONST_COLOR; - break; - case GL_ONE_MINUS_CONSTANT_COLOR: - return R600_BLEND_GL_ONE_MINUS_CONST_COLOR; - break; - case GL_CONSTANT_ALPHA: - return R600_BLEND_GL_CONST_ALPHA; - break; - case GL_ONE_MINUS_CONSTANT_ALPHA: - return R600_BLEND_GL_ONE_MINUS_CONST_ALPHA; - break; - default: - fprintf(stderr, "unknown blend factor %x\n", factor); - return (is_src) ? R600_BLEND_GL_ONE : R600_BLEND_GL_ZERO; - break; - } -} - -/** - * Sets both the blend equation and the blend function. - * This is done in a single - * function because some blend equations (i.e., \c GL_MIN and \c GL_MAX) - * change the interpretation of the blend function. - * Also, make sure that blend function and blend equation are set to their - * default value if color blending is not enabled, since at least blend - * equations GL_MIN and GL_FUNC_REVERSE_SUBTRACT will cause wrong results - * otherwise for unknown reasons. - */ - -/* helper function */ -static void r600SetBlendCntl(r600ContextPtr r600, int func, int eqn, - int cbits, int funcA, int eqnA) -{ - GLuint new_ablend, new_cblend; - -#if 0 - fprintf(stderr, - "eqnA=%08x funcA=%08x eqn=%08x func=%08x cbits=%08x\n", - eqnA, funcA, eqn, func, cbits); -#endif - new_ablend = eqnA | funcA; - new_cblend = eqn | func; - - /* Some blend factor combinations don't seem to work when the - * BLEND_NO_SEPARATE bit is set. - * - * Especially problematic candidates are the ONE_MINUS_* flags, - * but I can't see a real pattern. - */ -#if 0 - if (new_ablend == new_cblend) { - new_cblend |= R600_DISCARD_SRC_PIXELS_SRC_ALPHA_0; - } -#endif - new_cblend |= cbits; - - if ((new_ablend != r600->hw.bld.cmd[R600_BLD_ABLEND]) || - (new_cblend != r600->hw.bld.cmd[R600_BLD_CBLEND])) { - R600_STATECHANGE(r600, bld); - r600->hw.bld.cmd[R600_BLD_ABLEND] = new_ablend; - r600->hw.bld.cmd[R600_BLD_CBLEND] = new_cblend; - } -} - -static void r600SetBlendState(GLcontext * ctx) -{ - r600ContextPtr r600 = R600_CONTEXT(ctx); - int func = (R600_BLEND_GL_ONE << R600_SRC_BLEND_SHIFT) | - (R600_BLEND_GL_ZERO << R600_DST_BLEND_SHIFT); - int eqn = R600_COMB_FCN_ADD_CLAMP; - int funcA = (R600_BLEND_GL_ONE << R600_SRC_BLEND_SHIFT) | - (R600_BLEND_GL_ZERO << R600_DST_BLEND_SHIFT); - int eqnA = R600_COMB_FCN_ADD_CLAMP; - - if (RGBA_LOGICOP_ENABLED(ctx) || !ctx->Color.BlendEnabled) { - r600SetBlendCntl(r600, func, eqn, 0, func, eqn); - return; - } - - func = - (blend_factor(ctx->Color.BlendSrcRGB, GL_TRUE) << - R600_SRC_BLEND_SHIFT) | (blend_factor(ctx->Color.BlendDstRGB, - GL_FALSE) << - R600_DST_BLEND_SHIFT); - - switch (ctx->Color.BlendEquationRGB) { - case GL_FUNC_ADD: - eqn = R600_COMB_FCN_ADD_CLAMP; - break; - - case GL_FUNC_SUBTRACT: - eqn = R600_COMB_FCN_SUB_CLAMP; - break; - - case GL_FUNC_REVERSE_SUBTRACT: - eqn = R600_COMB_FCN_RSUB_CLAMP; - break; - - case GL_MIN: - eqn = R600_COMB_FCN_MIN; - func = (R600_BLEND_GL_ONE << R600_SRC_BLEND_SHIFT) | - (R600_BLEND_GL_ONE << R600_DST_BLEND_SHIFT); - break; - - case GL_MAX: - eqn = R600_COMB_FCN_MAX; - func = (R600_BLEND_GL_ONE << R600_SRC_BLEND_SHIFT) | - (R600_BLEND_GL_ONE << R600_DST_BLEND_SHIFT); - break; - - default: - fprintf(stderr, - "[%s:%u] Invalid RGB blend equation (0x%04x).\n", - __FUNCTION__, __LINE__, ctx->Color.BlendEquationRGB); - return; - } - - funcA = - (blend_factor(ctx->Color.BlendSrcA, GL_TRUE) << - R600_SRC_BLEND_SHIFT) | (blend_factor(ctx->Color.BlendDstA, - GL_FALSE) << - R600_DST_BLEND_SHIFT); - - switch (ctx->Color.BlendEquationA) { - case GL_FUNC_ADD: - eqnA = R600_COMB_FCN_ADD_CLAMP; - break; - - case GL_FUNC_SUBTRACT: - eqnA = R600_COMB_FCN_SUB_CLAMP; - break; - - case GL_FUNC_REVERSE_SUBTRACT: - eqnA = R600_COMB_FCN_RSUB_CLAMP; - break; - - case GL_MIN: - eqnA = R600_COMB_FCN_MIN; - funcA = (R600_BLEND_GL_ONE << R600_SRC_BLEND_SHIFT) | - (R600_BLEND_GL_ONE << R600_DST_BLEND_SHIFT); - break; - - case GL_MAX: - eqnA = R600_COMB_FCN_MAX; - funcA = (R600_BLEND_GL_ONE << R600_SRC_BLEND_SHIFT) | - (R600_BLEND_GL_ONE << R600_DST_BLEND_SHIFT); - break; - - default: - fprintf(stderr, - "[%s:%u] Invalid A blend equation (0x%04x).\n", - __FUNCTION__, __LINE__, ctx->Color.BlendEquationA); - return; - } - - r600SetBlendCntl(r600, - func, eqn, - (R600_SEPARATE_ALPHA_ENABLE | - R600_READ_ENABLE | - R600_ALPHA_BLEND_ENABLE), funcA, eqnA); -} - -static void r600BlendEquationSeparate(GLcontext * ctx, - GLenum modeRGB, GLenum modeA) -{ - r600SetBlendState(ctx); -} - -static void r600BlendFuncSeparate(GLcontext * ctx, - GLenum sfactorRGB, GLenum dfactorRGB, - GLenum sfactorA, GLenum dfactorA) -{ - r600SetBlendState(ctx); -} - -/** - * Translate LogicOp enums into hardware representation. - * Both use a very logical bit-wise layout, but unfortunately the order - * of bits is reversed. - */ -static GLuint translate_logicop(GLenum logicop) -{ - GLuint bits = logicop - GL_CLEAR; - bits = ((bits & 1) << 3) | ((bits & 2) << 1) | ((bits & 4) >> 1) | ((bits & 8) >> 3); - return bits << R600_RB3D_ROPCNTL_ROP_SHIFT; -} - -/** - * Used internally to update the r600->hw hardware state to match the - * current OpenGL state. - */ -static void r600SetLogicOpState(GLcontext *ctx) -{ - r600ContextPtr r600 = R600_CONTEXT(ctx); - R600_STATECHANGE(r600, rop); - if (RGBA_LOGICOP_ENABLED(ctx)) { - r600->hw.rop.cmd[1] = R600_RB3D_ROPCNTL_ROP_ENABLE | - translate_logicop(ctx->Color.LogicOp); - } else { - r600->hw.rop.cmd[1] = 0; - } -} - -/** - * Called by Mesa when an application program changes the LogicOp state - * via glLogicOp. - */ -static void r600LogicOpcode(GLcontext *ctx, GLenum logicop) -{ - if (RGBA_LOGICOP_ENABLED(ctx)) - r600SetLogicOpState(ctx); -} - -static void r600ClipPlane( GLcontext *ctx, GLenum plane, const GLfloat *eq ) -{ - r600ContextPtr rmesa = R600_CONTEXT(ctx); - GLint p; - GLint *ip; - - p = (GLint) plane - (GLint) GL_CLIP_PLANE0; - ip = (GLint *)ctx->Transform._ClipUserPlane[p]; - - R600_STATECHANGE( rmesa, vpucp[p] ); - rmesa->hw.vpucp[p].cmd[R600_VPUCP_X] = ip[0]; - rmesa->hw.vpucp[p].cmd[R600_VPUCP_Y] = ip[1]; - rmesa->hw.vpucp[p].cmd[R600_VPUCP_Z] = ip[2]; - rmesa->hw.vpucp[p].cmd[R600_VPUCP_W] = ip[3]; -} - -static void r600SetClipPlaneState(GLcontext * ctx, GLenum cap, GLboolean state) -{ - r600ContextPtr r600 = R600_CONTEXT(ctx); - GLuint p; - - p = cap - GL_CLIP_PLANE0; - R600_STATECHANGE(r600, vap_clip_cntl); - if (state) { - r600->hw.vap_clip_cntl.cmd[1] |= (R600_VAP_UCP_ENABLE_0 << p); - r600ClipPlane(ctx, cap, NULL); - } else { - r600->hw.vap_clip_cntl.cmd[1] &= ~(R600_VAP_UCP_ENABLE_0 << p); - } -} - -/** - * Update our tracked culling state based on Mesa's state. - */ -static void r600UpdateCulling(GLcontext * ctx) -{ - r600ContextPtr r600 = R600_CONTEXT(ctx); - uint32_t val = 0; - - if (ctx->Polygon.CullFlag) { - switch (ctx->Polygon.CullFaceMode) { - case GL_FRONT: - val = R600_CULL_FRONT; - break; - case GL_BACK: - val = R600_CULL_BACK; - break; - case GL_FRONT_AND_BACK: - val = R600_CULL_FRONT | R600_CULL_BACK; - break; - default: - break; - } - } - - switch (ctx->Polygon.FrontFace) { - case GL_CW: - val |= R600_FRONT_FACE_CW; - break; - case GL_CCW: - val |= R600_FRONT_FACE_CCW; - break; - default: - break; - } - - R600_STATECHANGE(r600, cul); - r600->hw.cul.cmd[R600_CUL_CULL] = val; -} - -static void r600SetPolygonOffsetState(GLcontext * ctx, GLboolean state) -{ - r600ContextPtr r600 = R600_CONTEXT(ctx); - - R600_STATECHANGE(r600, occlusion_cntl); - if (state) { - r600->hw.occlusion_cntl.cmd[1] |= (3 << 0); - } else { - r600->hw.occlusion_cntl.cmd[1] &= ~(3 << 0); - } -} - -static GLboolean current_fragment_program_writes_depth(GLcontext* ctx) -{ - r600ContextPtr r600 = R600_CONTEXT(ctx); - - struct r600_fragment_program *fp = (struct r600_fragment_program *) - (char *)ctx->FragmentProgram._Current; - return (fp && fp->WritesDepth); - -} - -static void r600SetEarlyZState(GLcontext * ctx) -{ - r600ContextPtr r600 = R600_CONTEXT(ctx); - GLuint topZ = R600_ZTOP_ENABLE; - - if (ctx->Color.AlphaEnabled && ctx->Color.AlphaFunc != GL_ALWAYS) - topZ = R600_ZTOP_DISABLE; - if (current_fragment_program_writes_depth(ctx)) - topZ = R600_ZTOP_DISABLE; - - if (topZ != r600->hw.zstencil_format.cmd[2]) { - /* Note: This completely reemits the stencil format. - * I have not tested whether this is strictly necessary, - * or if emitting a write to ZB_ZTOP is enough. - */ - R600_STATECHANGE(r600, zstencil_format); - r600->hw.zstencil_format.cmd[2] = topZ; - } -} - -static void r600SetAlphaState(GLcontext * ctx) -{ - r600ContextPtr r600 = R600_CONTEXT(ctx); - GLubyte refByte; - uint32_t pp_misc = 0x0; - GLboolean really_enabled = ctx->Color.AlphaEnabled; - - CLAMPED_FLOAT_TO_UBYTE(refByte, ctx->Color.AlphaRef); - - switch (ctx->Color.AlphaFunc) { - case GL_NEVER: - pp_misc |= R600_FG_ALPHA_FUNC_NEVER; - break; - case GL_LESS: - pp_misc |= R600_FG_ALPHA_FUNC_LESS; - break; - case GL_EQUAL: - pp_misc |= R600_FG_ALPHA_FUNC_EQUAL; - break; - case GL_LEQUAL: - pp_misc |= R600_FG_ALPHA_FUNC_LE; - break; - case GL_GREATER: - pp_misc |= R600_FG_ALPHA_FUNC_GREATER; - break; - case GL_NOTEQUAL: - pp_misc |= R600_FG_ALPHA_FUNC_NOTEQUAL; - break; - case GL_GEQUAL: - pp_misc |= R600_FG_ALPHA_FUNC_GE; - break; - case GL_ALWAYS: - /*pp_misc |= FG_ALPHA_FUNC_ALWAYS; */ - really_enabled = GL_FALSE; - break; - } - - if (really_enabled) { - pp_misc |= R600_FG_ALPHA_FUNC_ENABLE; - pp_misc |= (refByte & R600_FG_ALPHA_FUNC_VAL_MASK); - } else { - pp_misc = 0x0; - } - - R600_STATECHANGE(r600, at); - r600->hw.at.cmd[R600_AT_ALPHA_TEST] = pp_misc; - r600->hw.at.cmd[R600_AT_UNKNOWN] = 0; - - r600SetEarlyZState(ctx); -} - -static void r600AlphaFunc(GLcontext * ctx, GLenum func, GLfloat ref) -{ - (void)func; - (void)ref; - r600SetAlphaState(ctx); -} - -static int translate_func(int func) -{ - switch (func) { - case GL_NEVER: - return R600_ZS_NEVER; - case GL_LESS: - return R600_ZS_LESS; - case GL_EQUAL: - return R600_ZS_EQUAL; - case GL_LEQUAL: - return R600_ZS_LEQUAL; - case GL_GREATER: - return R600_ZS_GREATER; - case GL_NOTEQUAL: - return R600_ZS_NOTEQUAL; - case GL_GEQUAL: - return R600_ZS_GEQUAL; - case GL_ALWAYS: - return R600_ZS_ALWAYS; - } - return 0; -} - -static void r600SetDepthState(GLcontext * ctx) -{ - r600ContextPtr r600 = R600_CONTEXT(ctx); - - R600_STATECHANGE(r600, zs); - r600->hw.zs.cmd[R600_ZS_CNTL_0] &= R600_STENCIL_ENABLE|R600_STENCIL_FRONT_BACK; - r600->hw.zs.cmd[R600_ZS_CNTL_1] &= ~(R600_ZS_MASK << R600_Z_FUNC_SHIFT); - - if (ctx->Depth.Test) { - r600->hw.zs.cmd[R600_ZS_CNTL_0] |= R600_Z_ENABLE; - if (ctx->Depth.Mask) - r600->hw.zs.cmd[R600_ZS_CNTL_0] |= R600_Z_WRITE_ENABLE; - r600->hw.zs.cmd[R600_ZS_CNTL_1] |= - translate_func(ctx->Depth.Func) << R600_Z_FUNC_SHIFT; - } - - r600SetEarlyZState(ctx); -} - -static void r600SetStencilState(GLcontext * ctx, GLboolean state) -{ - r600ContextPtr r600 = R600_CONTEXT(ctx); - GLboolean hw_stencil = GL_FALSE; - if (ctx->DrawBuffer) { - struct radeon_renderbuffer *rrbStencil - = radeon_get_renderbuffer(ctx->DrawBuffer, BUFFER_STENCIL); - hw_stencil = (rrbStencil && rrbStencil->bo); - } - - if (hw_stencil) { - R600_STATECHANGE(r600, zs); - if (state) { - r600->hw.zs.cmd[R600_ZS_CNTL_0] |= - R600_STENCIL_ENABLE; - } else { - r600->hw.zs.cmd[R600_ZS_CNTL_0] &= - ~R600_STENCIL_ENABLE; - } - } else { -#if R200_MERGED - FALLBACK(&r600->radeon, RADEON_FALLBACK_STENCIL, state); -#endif - } -} - -static void r600UpdatePolygonMode(GLcontext * ctx) -{ - r600ContextPtr r600 = R600_CONTEXT(ctx); - uint32_t hw_mode = R600_GA_POLY_MODE_DISABLE; - - /* Only do something if a polygon mode is wanted, default is GL_FILL */ - if (ctx->Polygon.FrontMode != GL_FILL || - ctx->Polygon.BackMode != GL_FILL) { - GLenum f, b; - - /* Handle GL_CW (clock wise and GL_CCW (counter clock wise) - * correctly by selecting the correct front and back face - */ - if (ctx->Polygon.FrontFace == GL_CCW) { - f = ctx->Polygon.FrontMode; - b = ctx->Polygon.BackMode; - } else { - f = ctx->Polygon.BackMode; - b = ctx->Polygon.FrontMode; - } - - /* Enable polygon mode */ - hw_mode |= R600_GA_POLY_MODE_DUAL; - - switch (f) { - case GL_LINE: - hw_mode |= R600_GA_POLY_MODE_FRONT_PTYPE_LINE; - break; - case GL_POINT: - hw_mode |= R600_GA_POLY_MODE_FRONT_PTYPE_POINT; - break; - case GL_FILL: - hw_mode |= R600_GA_POLY_MODE_FRONT_PTYPE_TRI; - break; - } - - switch (b) { - case GL_LINE: - hw_mode |= R600_GA_POLY_MODE_BACK_PTYPE_LINE; - break; - case GL_POINT: - hw_mode |= R600_GA_POLY_MODE_BACK_PTYPE_POINT; - break; - case GL_FILL: - hw_mode |= R600_GA_POLY_MODE_BACK_PTYPE_TRI; - break; - } - } - - if (r600->hw.polygon_mode.cmd[1] != hw_mode) { - R600_STATECHANGE(r600, polygon_mode); - r600->hw.polygon_mode.cmd[1] = hw_mode; - } - - r600->hw.polygon_mode.cmd[2] = 0x00000001; - r600->hw.polygon_mode.cmd[3] = 0x00000000; -} - -/** - * Change the culling mode. - * - * \note Mesa already filters redundant calls to this function. - */ -static void r600CullFace(GLcontext * ctx, GLenum mode) -{ - (void)mode; - - r600UpdateCulling(ctx); -} - -/** - * Change the polygon orientation. - * - * \note Mesa already filters redundant calls to this function. - */ -static void r600FrontFace(GLcontext * ctx, GLenum mode) -{ - (void)mode; - - r600UpdateCulling(ctx); - r600UpdatePolygonMode(ctx); -} - -/** - * Change the depth testing function. - * - * \note Mesa already filters redundant calls to this function. - */ -static void r600DepthFunc(GLcontext * ctx, GLenum func) -{ - (void)func; - r600SetDepthState(ctx); -} - -/** - * Enable/Disable depth writing. - * - * \note Mesa already filters redundant calls to this function. - */ -static void r600DepthMask(GLcontext * ctx, GLboolean mask) -{ - (void)mask; - r600SetDepthState(ctx); -} - -/** - * Handle glColorMask() - */ -static void r600ColorMask(GLcontext * ctx, - GLboolean r, GLboolean g, GLboolean b, GLboolean a) -{ - r600ContextPtr r600 = R600_CONTEXT(ctx); - int mask = (r ? RB3D_COLOR_CHANNEL_MASK_RED_MASK0 : 0) | - (g ? RB3D_COLOR_CHANNEL_MASK_GREEN_MASK0 : 0) | - (b ? RB3D_COLOR_CHANNEL_MASK_BLUE_MASK0 : 0) | - (a ? RB3D_COLOR_CHANNEL_MASK_ALPHA_MASK0 : 0); - - if (mask != r600->hw.cmk.cmd[R600_CMK_COLORMASK]) { - R600_STATECHANGE(r600, cmk); - r600->hw.cmk.cmd[R600_CMK_COLORMASK] = mask; - } -} - -/* ============================================================= - * Point state - */ -static void r600PointSize(GLcontext * ctx, GLfloat size) -{ - r600ContextPtr r600 = R600_CONTEXT(ctx); - /* same size limits for AA, non-AA points */ - size = CLAMP(size, ctx->Const.MinPointSize, ctx->Const.MaxPointSize); - - R600_STATECHANGE(r600, ps); - r600->hw.ps.cmd[R600_PS_POINTSIZE] = - ((int)(size * 6) << R600_POINTSIZE_X_SHIFT) | - ((int)(size * 6) << R600_POINTSIZE_Y_SHIFT); -} - -static void r600PointParameter(GLcontext * ctx, GLenum pname, const GLfloat * param) -{ - r600ContextPtr r600 = R600_CONTEXT(ctx); - - switch (pname) { - case GL_POINT_SIZE_MIN: - R600_STATECHANGE(r600, ga_point_minmax); - r600->hw.ga_point_minmax.cmd[1] &= ~R600_GA_POINT_MINMAX_MIN_MASK; - r600->hw.ga_point_minmax.cmd[1] |= (GLuint)(ctx->Point.MinSize * 6.0); - break; - case GL_POINT_SIZE_MAX: - R600_STATECHANGE(r600, ga_point_minmax); - r600->hw.ga_point_minmax.cmd[1] &= ~R600_GA_POINT_MINMAX_MAX_MASK; - r600->hw.ga_point_minmax.cmd[1] |= (GLuint)(ctx->Point.MaxSize * 6.0) - << R600_GA_POINT_MINMAX_MAX_SHIFT; - break; - case GL_POINT_DISTANCE_ATTENUATION: - break; - case GL_POINT_FADE_THRESHOLD_SIZE: - break; - default: - break; - } -} - -/* ============================================================= - * Line state - */ -static void r600LineWidth(GLcontext * ctx, GLfloat widthf) -{ - r600ContextPtr r600 = R600_CONTEXT(ctx); - - widthf = CLAMP(widthf, - ctx->Const.MinPointSize, - ctx->Const.MaxPointSize); - R600_STATECHANGE(r600, lcntl); - r600->hw.lcntl.cmd[1] = - R600_LINE_CNT_HO | R600_LINE_CNT_VE | (int)(widthf * 6.0); -} - -static void r600PolygonMode(GLcontext * ctx, GLenum face, GLenum mode) -{ - (void)face; - (void)mode; - - r600UpdatePolygonMode(ctx); -} - -/* ============================================================= - * Stencil - */ - -static int translate_stencil_op(int op) -{ - switch (op) { - case GL_KEEP: - return R600_ZS_KEEP; - case GL_ZERO: - return R600_ZS_ZERO; - case GL_REPLACE: - return R600_ZS_REPLACE; - case GL_INCR: - return R600_ZS_INCR; - case GL_DECR: - return R600_ZS_DECR; - case GL_INCR_WRAP_EXT: - return R600_ZS_INCR_WRAP; - case GL_DECR_WRAP_EXT: - return R600_ZS_DECR_WRAP; - case GL_INVERT: - return R600_ZS_INVERT; - default: - WARN_ONCE("Do not know how to translate stencil op"); - return R600_ZS_KEEP; - } - return 0; -} - -static void r600ShadeModel(GLcontext * ctx, GLenum mode) -{ - r600ContextPtr rmesa = R600_CONTEXT(ctx); - - R600_STATECHANGE(rmesa, shade); - rmesa->hw.shade.cmd[1] = 0x00000002; - switch (mode) { - case GL_FLAT: - rmesa->hw.shade.cmd[2] = R600_RE_SHADE_MODEL_FLAT; - break; - case GL_SMOOTH: - rmesa->hw.shade.cmd[2] = R600_RE_SHADE_MODEL_SMOOTH; - break; - default: - return; - } - rmesa->hw.shade.cmd[3] = 0x00000000; - rmesa->hw.shade.cmd[4] = 0x00000000; -} - -static void r600StencilFuncSeparate(GLcontext * ctx, GLenum face, - GLenum func, GLint ref, GLuint mask) -{ - r600ContextPtr rmesa = R600_CONTEXT(ctx); - GLuint refmask = - ((ctx->Stencil.Ref[0] & 0xff) << R600_STENCILREF_SHIFT) - | ((ctx->Stencil.ValueMask[0] & 0xff) << R600_STENCILMASK_SHIFT); - const unsigned back = ctx->Stencil._BackFace; - GLuint flag; - - R600_STATECHANGE(rmesa, zs); - rmesa->hw.zs.cmd[R600_ZS_CNTL_0] |= R600_STENCIL_FRONT_BACK; - rmesa->hw.zs.cmd[R600_ZS_CNTL_1] &= ~((R600_ZS_MASK << - R600_S_FRONT_FUNC_SHIFT) - | (R600_ZS_MASK << - R600_S_BACK_FUNC_SHIFT)); - - rmesa->hw.zs.cmd[R600_ZS_CNTL_2] &= - ~((R600_STENCILREF_MASK << R600_STENCILREF_SHIFT) | - (R600_STENCILREF_MASK << R600_STENCILMASK_SHIFT)); - - flag = translate_func(ctx->Stencil.Function[0]); - rmesa->hw.zs.cmd[R600_ZS_CNTL_1] |= - (flag << R600_S_FRONT_FUNC_SHIFT); - - flag = translate_func(ctx->Stencil.Function[back]); - - rmesa->hw.zs.cmd[R600_ZS_CNTL_1] |= - (flag << R600_S_BACK_FUNC_SHIFT); - rmesa->hw.zs.cmd[R600_ZS_CNTL_2] |= refmask; -} - -static void r600StencilMaskSeparate(GLcontext * ctx, GLenum face, GLuint mask) -{ - r600ContextPtr rmesa = R600_CONTEXT(ctx); - - R600_STATECHANGE(rmesa, zs); - rmesa->hw.zs.cmd[R600_ZS_CNTL_2] &= - ~(R600_STENCILREF_MASK << - R600_STENCILWRITEMASK_SHIFT); - rmesa->hw.zs.cmd[R600_ZS_CNTL_2] |= - (ctx->Stencil. - WriteMask[0] & R600_STENCILREF_MASK) << - R600_STENCILWRITEMASK_SHIFT; -} - -static void r600StencilOpSeparate(GLcontext * ctx, GLenum face, - GLenum fail, GLenum zfail, GLenum zpass) -{ - r600ContextPtr rmesa = R600_CONTEXT(ctx); - const unsigned back = ctx->Stencil._BackFace; - - R600_STATECHANGE(rmesa, zs); - /* It is easier to mask what's left.. */ - rmesa->hw.zs.cmd[R600_ZS_CNTL_1] &= - (R600_ZS_MASK << R600_Z_FUNC_SHIFT) | - (R600_ZS_MASK << R600_S_FRONT_FUNC_SHIFT) | - (R600_ZS_MASK << R600_S_BACK_FUNC_SHIFT); - - rmesa->hw.zs.cmd[R600_ZS_CNTL_1] |= - (translate_stencil_op(ctx->Stencil.FailFunc[0]) << - R600_S_FRONT_SFAIL_OP_SHIFT) - | (translate_stencil_op(ctx->Stencil.ZFailFunc[0]) << - R600_S_FRONT_ZFAIL_OP_SHIFT) - | (translate_stencil_op(ctx->Stencil.ZPassFunc[0]) << - R600_S_FRONT_ZPASS_OP_SHIFT); - - rmesa->hw.zs.cmd[R600_ZS_CNTL_1] |= - (translate_stencil_op(ctx->Stencil.FailFunc[back]) << - R600_S_BACK_SFAIL_OP_SHIFT) - | (translate_stencil_op(ctx->Stencil.ZFailFunc[back]) << - R600_S_BACK_ZFAIL_OP_SHIFT) - | (translate_stencil_op(ctx->Stencil.ZPassFunc[back]) << - R600_S_BACK_ZPASS_OP_SHIFT); -} - -/* ============================================================= - * Window position and viewport transformation - */ - -/* - * To correctly position primitives: - */ -#define SUBPIXEL_X 0.125 -#define SUBPIXEL_Y 0.125 - -static void r600UpdateWindow(GLcontext * ctx) -{ - r600ContextPtr rmesa = R600_CONTEXT(ctx); - __DRIdrawablePrivate *dPriv = rmesa->radeon.dri.drawable; - GLfloat xoffset = dPriv ? (GLfloat) dPriv->x : 0; - GLfloat yoffset = dPriv ? (GLfloat) dPriv->y + dPriv->h : 0; - const GLfloat *v = ctx->Viewport._WindowMap.m; - const GLfloat depthScale = 1.0F / ctx->DrawBuffer->_DepthMaxF; - const GLboolean render_to_fbo = (ctx->DrawBuffer->Name != 0); - GLfloat y_scale, y_bias; - - if (render_to_fbo) { - y_scale = 1.0; - y_bias = 0; - } else { - y_scale = -1.0; - y_bias = yoffset; - } - - GLfloat sx = v[MAT_SX]; - GLfloat tx = v[MAT_TX] + xoffset + SUBPIXEL_X; - GLfloat sy = v[MAT_SY] * y_scale; - GLfloat ty = (v[MAT_TY] * y_scale) + y_bias + SUBPIXEL_Y; - GLfloat sz = v[MAT_SZ] * depthScale; - GLfloat tz = v[MAT_TZ] * depthScale; - - R600_STATECHANGE(rmesa, vpt); - - rmesa->hw.vpt.cmd[R600_VPT_XSCALE] = r600PackFloat32(sx); - rmesa->hw.vpt.cmd[R600_VPT_XOFFSET] = r600PackFloat32(tx); - rmesa->hw.vpt.cmd[R600_VPT_YSCALE] = r600PackFloat32(sy); - rmesa->hw.vpt.cmd[R600_VPT_YOFFSET] = r600PackFloat32(ty); - rmesa->hw.vpt.cmd[R600_VPT_ZSCALE] = r600PackFloat32(sz); - rmesa->hw.vpt.cmd[R600_VPT_ZOFFSET] = r600PackFloat32(tz); -} - -static void r600Viewport(GLcontext * ctx, GLint x, GLint y, - GLsizei width, GLsizei height) -{ - /* Don't pipeline viewport changes, conflict with window offset - * setting below. Could apply deltas to rescue pipelined viewport - * values, or keep the originals hanging around. - */ - r600UpdateWindow(ctx); - - radeon_viewport(ctx, x, y, width, height); -} - -static void r600DepthRange(GLcontext * ctx, GLclampd nearval, GLclampd farval) -{ - r600UpdateWindow(ctx); -} - -void r600UpdateViewportOffset(GLcontext * ctx) -{ - r600ContextPtr rmesa = R600_CONTEXT(ctx); - __DRIdrawablePrivate *dPriv = ((radeonContextPtr) rmesa)->dri.drawable; - GLfloat xoffset = (GLfloat) dPriv->x; - GLfloat yoffset = (GLfloat) dPriv->y + dPriv->h; - const GLfloat *v = ctx->Viewport._WindowMap.m; - - GLfloat tx = v[MAT_TX] + xoffset + SUBPIXEL_X; - GLfloat ty = (-v[MAT_TY]) + yoffset + SUBPIXEL_Y; - - if (rmesa->hw.vpt.cmd[R600_VPT_XOFFSET] != r600PackFloat32(tx) || - rmesa->hw.vpt.cmd[R600_VPT_YOFFSET] != r600PackFloat32(ty)) { - /* Note: this should also modify whatever data the context reset - * code uses... - */ - R600_STATECHANGE(rmesa, vpt); - rmesa->hw.vpt.cmd[R600_VPT_XOFFSET] = r600PackFloat32(tx); - rmesa->hw.vpt.cmd[R600_VPT_YOFFSET] = r600PackFloat32(ty); - - } - - radeonUpdateScissor(ctx); -} - -static void -r600FetchStateParameter(GLcontext * ctx, - const gl_state_index state[STATE_LENGTH], - GLfloat * value) -{ - r600ContextPtr r600 = R600_CONTEXT(ctx); - - switch (state[0]) { - case STATE_INTERNAL: - switch (state[1]) { - case STATE_R600_WINDOW_DIMENSION: - value[0] = r600->radeon.dri.drawable->w * 0.5f; /* width*0.5 */ - value[1] = r600->radeon.dri.drawable->h * 0.5f; /* height*0.5 */ - value[2] = 0.5F; /* for moving range [-1 1] -> [0 1] */ - value[3] = 1.0F; /* not used */ - break; - - case STATE_R600_TEXRECT_FACTOR:{ - struct gl_texture_object *t = - ctx->Texture.Unit[state[2]].CurrentTex[TEXTURE_RECT_INDEX]; - - if (t && t->Image[0][t->BaseLevel]) { - struct gl_texture_image *image = - t->Image[0][t->BaseLevel]; - value[0] = 1.0 / image->Width2; - value[1] = 1.0 / image->Height2; - } else { - value[0] = 1.0; - value[1] = 1.0; - } - value[2] = 1.0; - value[3] = 1.0; - break; - } - - default: - break; - } - break; - - default: - break; - } -} - -/** - * Update R600's own internal state parameters. - * For now just STATE_R600_WINDOW_DIMENSION - */ -void r600UpdateStateParameters(GLcontext * ctx, GLuint new_state) -{ - struct r600_fragment_program *fp; - struct gl_program_parameter_list *paramList; - GLuint i; - - if (!(new_state & (_NEW_BUFFERS | _NEW_PROGRAM))) - return; - - fp = (struct r600_fragment_program *)ctx->FragmentProgram._Current; - if (!fp) - return; - - paramList = fp->mesa_program.Base.Parameters; - - if (!paramList) - return; - - for (i = 0; i < paramList->NumParameters; i++) { - if (paramList->Parameters[i].Type == PROGRAM_STATE_VAR) { - r600FetchStateParameter(ctx, - paramList->Parameters[i]. - StateIndexes, - paramList->ParameterValues[i]); - } - } -} - -/* ============================================================= - * Polygon state - */ -static void r600PolygonOffset(GLcontext * ctx, GLfloat factor, GLfloat units) -{ - r600ContextPtr rmesa = R600_CONTEXT(ctx); - GLfloat constant = units; - - switch (ctx->Visual.depthBits) { - case 16: - constant *= 4.0; - break; - case 24: - constant *= 2.0; - break; - } - - factor *= 12.0; - -/* fprintf(stderr, "%s f:%f u:%f\n", __FUNCTION__, factor, constant); */ - - R600_STATECHANGE(rmesa, zbs); - rmesa->hw.zbs.cmd[R600_ZBS_T_FACTOR] = r600PackFloat32(factor); - rmesa->hw.zbs.cmd[R600_ZBS_T_CONSTANT] = r600PackFloat32(constant); - rmesa->hw.zbs.cmd[R600_ZBS_W_FACTOR] = r600PackFloat32(factor); - rmesa->hw.zbs.cmd[R600_ZBS_W_CONSTANT] = r600PackFloat32(constant); -} - -/* Routing and texture-related */ - -/* r600 doesnt handle GL_CLAMP and GL_MIRROR_CLAMP_EXT correctly when filter is NEAREST. - * Since texwrap produces same results for GL_CLAMP and GL_CLAMP_TO_EDGE we use them instead. - * We need to recalculate wrap modes whenever filter mode is changed because someone might do: - * glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); - * glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP); - * glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); - * Since r600 completely ignores R600_TX_CLAMP when either min or mag is nearest it cant handle - * combinations where only one of them is nearest. - */ -static unsigned long gen_fixed_filter(unsigned long f) -{ - unsigned long mag, min, needs_fixing = 0; - //return f; - - /* We ignore MIRROR bit so we dont have to do everything twice */ - if ((f & ((7 - 1) << R600_TX_WRAP_S_SHIFT)) == - (R600_TX_CLAMP << R600_TX_WRAP_S_SHIFT)) { - needs_fixing |= 1; - } - if ((f & ((7 - 1) << R600_TX_WRAP_T_SHIFT)) == - (R600_TX_CLAMP << R600_TX_WRAP_T_SHIFT)) { - needs_fixing |= 2; - } - if ((f & ((7 - 1) << R600_TX_WRAP_R_SHIFT)) == - (R600_TX_CLAMP << R600_TX_WRAP_R_SHIFT)) { - needs_fixing |= 4; - } - - if (!needs_fixing) - return f; - - mag = f & R600_TX_MAG_FILTER_MASK; - min = f & (R600_TX_MIN_FILTER_MASK|R600_TX_MIN_FILTER_MIP_MASK); - - /* TODO: Check for anisto filters too */ - if ((mag != R600_TX_MAG_FILTER_NEAREST) - && (min != R600_TX_MIN_FILTER_NEAREST)) - return f; - - /* r600 cant handle these modes hence we force nearest to linear */ - if ((mag == R600_TX_MAG_FILTER_NEAREST) - && (min != R600_TX_MIN_FILTER_NEAREST)) { - f &= ~R600_TX_MAG_FILTER_NEAREST; - f |= R600_TX_MAG_FILTER_LINEAR; - return f; - } - - if ((min == R600_TX_MIN_FILTER_NEAREST) - && (mag != R600_TX_MAG_FILTER_NEAREST)) { - f &= ~R600_TX_MIN_FILTER_NEAREST; - f |= R600_TX_MIN_FILTER_LINEAR; - return f; - } - - /* Both are nearest */ - if (needs_fixing & 1) { - f &= ~((7 - 1) << R600_TX_WRAP_S_SHIFT); - f |= R600_TX_CLAMP_TO_EDGE << R600_TX_WRAP_S_SHIFT; - } - if (needs_fixing & 2) { - f &= ~((7 - 1) << R600_TX_WRAP_T_SHIFT); - f |= R600_TX_CLAMP_TO_EDGE << R600_TX_WRAP_T_SHIFT; - } - if (needs_fixing & 4) { - f &= ~((7 - 1) << R600_TX_WRAP_R_SHIFT); - f |= R600_TX_CLAMP_TO_EDGE << R600_TX_WRAP_R_SHIFT; - } - return f; -} - -static void r600SetupFragmentShaderTextures(GLcontext *ctx, int *tmu_mappings) -{ - r600ContextPtr r600 = R600_CONTEXT(ctx); - int i; - struct r600_fragment_program *fp = (struct r600_fragment_program *) - (char *)ctx->FragmentProgram._Current; - struct r600_fragment_program_code *code = &fp->code; - - R600_STATECHANGE(r600, fpt); - - for (i = 0; i < code->tex.length; i++) { - int unit; - int opcode; - unsigned long val; - - unit = code->tex.inst[i] >> R600_TEX_ID_SHIFT; - unit &= 15; - - val = code->tex.inst[i]; - val &= ~R600_TEX_ID_MASK; - - opcode = - (val & R600_TEX_INST_MASK) >> R600_TEX_INST_SHIFT; - if (opcode == R600_TEX_OP_KIL) { - r600->hw.fpt.cmd[R600_FPT_INSTR_0 + i] = val; - } else { - if (tmu_mappings[unit] >= 0) { - val |= - tmu_mappings[unit] << - R600_TEX_ID_SHIFT; - r600->hw.fpt.cmd[R600_FPT_INSTR_0 + i] = val; - } else { - // We get here when the corresponding texture image is incomplete - // (e.g. incomplete mipmaps etc.) - r600->hw.fpt.cmd[R600_FPT_INSTR_0 + i] = val; - } - } - } - - r600->hw.fpt.cmd[R600_FPT_CMD_0] = - cmdpacket0(r600->radeon.radeonScreen, - R600_US_TEX_INST_0, code->tex.length); -} - -static GLuint translate_lod_bias(GLfloat bias) -{ - GLint b = (int)(bias*32); - if (b >= (1 << 9)) - b = (1 << 9)-1; - else if (b < -(1 << 9)) - b = -(1 << 9); - return (((GLuint)b) << R600_LOD_BIAS_SHIFT) & R600_LOD_BIAS_MASK; -} - -static void r600SetupTextures(GLcontext * ctx) -{ - int i, mtu; - struct radeon_tex_obj *t; - r600ContextPtr r600 = R600_CONTEXT(ctx); - int hw_tmu = 0; - int last_hw_tmu = -1; /* -1 translates into no setup costs for fields */ - int tmu_mappings[R600_MAX_TEXTURE_UNITS] = { -1, }; - struct r600_fragment_program *fp = (struct r600_fragment_program *) - (char *)ctx->FragmentProgram._Current; - - R600_STATECHANGE(r600, txe); - R600_STATECHANGE(r600, tex.filter); - R600_STATECHANGE(r600, tex.filter_1); - R600_STATECHANGE(r600, tex.size); - R600_STATECHANGE(r600, tex.format); - R600_STATECHANGE(r600, tex.pitch); - R600_STATECHANGE(r600, tex.offset); - R600_STATECHANGE(r600, tex.chroma_key); - R600_STATECHANGE(r600, tex.border_color); - - r600->hw.txe.cmd[R600_TXE_ENABLE] = 0x0; - - mtu = r600->radeon.glCtx->Const.MaxTextureUnits; - if (RADEON_DEBUG & DEBUG_STATE) - fprintf(stderr, "mtu=%d\n", mtu); - - if (mtu > R600_MAX_TEXTURE_UNITS) { - fprintf(stderr, - "Aiiee ! mtu=%d is greater than R600_MAX_TEXTURE_UNITS=%d\n", - mtu, R600_MAX_TEXTURE_UNITS); - _mesa_exit(-1); - } - - /* We cannot let disabled tmu offsets pass DRM */ - for (i = 0; i < mtu; i++) { - if (ctx->Texture.Unit[i]._ReallyEnabled) { - tmu_mappings[i] = hw_tmu; - - t = radeon_tex_obj(ctx->Texture.Unit[i]._Current); - if (!t) - continue; - - if ((t->pp_txformat & 0xffffff00) == 0xffffff00) { - WARN_ONCE - ("unknown texture format (entry %x) encountered. Help me !\n", - t->pp_txformat & 0xff); - } - - if (RADEON_DEBUG & DEBUG_STATE) - fprintf(stderr, - "Activating texture unit %d\n", i); - - r600->hw.txe.cmd[R600_TXE_ENABLE] |= (1 << hw_tmu); - - r600->hw.tex.filter.cmd[R600_TEX_VALUE_0 + - hw_tmu] = - gen_fixed_filter(t->pp_txfilter) | (hw_tmu << 28); - /* Note: There is a LOD bias per texture unit and a LOD bias - * per texture object. We add them here to get the correct behaviour. - * (The per-texture object LOD bias was introduced in OpenGL 1.4 - * and is not present in the EXT_texture_object extension). - */ - r600->hw.tex.filter_1.cmd[R600_TEX_VALUE_0 + hw_tmu] = - t->pp_txfilter_1 | - translate_lod_bias(ctx->Texture.Unit[i].LodBias + t->base.LodBias); - r600->hw.tex.size.cmd[R600_TEX_VALUE_0 + hw_tmu] = - t->pp_txsize; - r600->hw.tex.format.cmd[R600_TEX_VALUE_0 + - hw_tmu] = t->pp_txformat; - r600->hw.tex.pitch.cmd[R600_TEX_VALUE_0 + hw_tmu] = - t->pp_txpitch; - r600->hw.textures[hw_tmu] = t; - - if (t->tile_bits & R600_TXO_MACRO_TILE) { - WARN_ONCE("macro tiling enabled!\n"); - } - - if (t->tile_bits & R600_TXO_MICRO_TILE) { - WARN_ONCE("micro tiling enabled!\n"); - } - - r600->hw.tex.chroma_key.cmd[R600_TEX_VALUE_0 + - hw_tmu] = 0x0; - r600->hw.tex.border_color.cmd[R600_TEX_VALUE_0 + - hw_tmu] = - t->pp_border_color; - - last_hw_tmu = hw_tmu; - - hw_tmu++; - } - } - - r600->hw.tex.filter.cmd[R600_TEX_CMD_0] = - cmdpacket0(r600->radeon.radeonScreen, R600_TX_FILTER0_0, last_hw_tmu + 1); - r600->hw.tex.filter_1.cmd[R600_TEX_CMD_0] = - cmdpacket0(r600->radeon.radeonScreen, R600_TX_FILTER1_0, last_hw_tmu + 1); - r600->hw.tex.size.cmd[R600_TEX_CMD_0] = - cmdpacket0(r600->radeon.radeonScreen, R600_TX_SIZE_0, last_hw_tmu + 1); - r600->hw.tex.format.cmd[R600_TEX_CMD_0] = - cmdpacket0(r600->radeon.radeonScreen, R600_TX_FORMAT_0, last_hw_tmu + 1); - r600->hw.tex.pitch.cmd[R600_TEX_CMD_0] = - cmdpacket0(r600->radeon.radeonScreen, R600_TX_FORMAT2_0, last_hw_tmu + 1); - r600->hw.tex.offset.cmd[R600_TEX_CMD_0] = - cmdpacket0(r600->radeon.radeonScreen, R600_TX_OFFSET_0, last_hw_tmu + 1); - r600->hw.tex.chroma_key.cmd[R600_TEX_CMD_0] = - cmdpacket0(r600->radeon.radeonScreen, R600_TX_CHROMA_KEY_0, last_hw_tmu + 1); - r600->hw.tex.border_color.cmd[R600_TEX_CMD_0] = - cmdpacket0(r600->radeon.radeonScreen, R600_TX_BORDER_COLOR_0, last_hw_tmu + 1); - - if (!fp) /* should only happenen once, just after context is created */ - return; - - if (fp->mesa_program.UsesKill && last_hw_tmu < 0) { - // The KILL operation requires the first texture unit - // to be enabled. - r600->hw.txe.cmd[R600_TXE_ENABLE] |= 1; - r600->hw.tex.filter.cmd[R600_TEX_VALUE_0] = 0; - r600->hw.tex.filter.cmd[R600_TEX_CMD_0] = - cmdpacket0(r600->radeon.radeonScreen, R600_TX_FILTER0_0, 1); - } - r600SetupFragmentShaderTextures(ctx, tmu_mappings); - - if (RADEON_DEBUG & DEBUG_STATE) - fprintf(stderr, "TX_ENABLE: %08x last_hw_tmu=%d\n", - r600->hw.txe.cmd[R600_TXE_ENABLE], last_hw_tmu); -} - -union r600_outputs_written { - GLuint vp_outputs; /* hw_tcl_on */ - DECLARE_RENDERINPUTS(index_bitset); /* !hw_tcl_on */ -}; - -#define R600_OUTPUTS_WRITTEN_TEST(ow, vp_result, tnl_attrib) \ - ((hw_tcl_on) ? (ow).vp_outputs & (1 << (vp_result)) : \ - RENDERINPUTS_TEST( (ow.index_bitset), (tnl_attrib) )) - -static void r600SetupRSUnit(GLcontext * ctx) -{ - r600ContextPtr r600 = R600_CONTEXT(ctx); - TNLcontext *tnl = TNL_CONTEXT(ctx); - struct vertex_buffer *VB = &tnl->vb; - union r600_outputs_written OutputsWritten; - GLuint InputsRead; - int fp_reg, high_rr; - int col_ip, tex_ip; - int rs_tex_count = 0; - int i, count, col_fmt; - - if (hw_tcl_on) - OutputsWritten.vp_outputs = CURRENT_VERTEX_SHADER(ctx)->key.OutputsWritten; - else - RENDERINPUTS_COPY(OutputsWritten.index_bitset, r600->state.render_inputs_bitset); - - if (ctx->FragmentProgram._Current) - InputsRead = ctx->FragmentProgram._Current->Base.InputsRead; - else { - fprintf(stderr, "No ctx->FragmentProgram._Current!!\n"); - return; /* This should only ever happen once.. */ - } - - R600_STATECHANGE(r600, ri); - R600_STATECHANGE(r600, rc); - R600_STATECHANGE(r600, rr); - - fp_reg = col_ip = tex_ip = col_fmt = 0; - - r600->hw.rc.cmd[1] = 0; - r600->hw.rc.cmd[2] = 0; - for (i=0; i<R600_RR_CMDSIZE-1; ++i) - r600->hw.rr.cmd[R600_RR_INST_0 + i] = 0; - - for (i=0; i<R600_RI_CMDSIZE-1; ++i) - r600->hw.ri.cmd[R600_RI_INTERP_0 + i] = 0; - - - if (InputsRead & FRAG_BIT_COL0) { - if (R600_OUTPUTS_WRITTEN_TEST(OutputsWritten, VERT_RESULT_COL0, _TNL_ATTRIB_COLOR0)) { - count = VB->AttribPtr[_TNL_ATTRIB_COLOR0]->size; - if (count == 4) - col_fmt = R600_RS_COL_FMT_RGBA; - else if (count == 3) - col_fmt = R600_RS_COL_FMT_RGB1; - else - col_fmt = R600_RS_COL_FMT_0001; - - r600->hw.ri.cmd[R600_RI_INTERP_0 + col_ip] = R600_RS_COL_PTR(col_ip) | R600_RS_COL_FMT(col_fmt); - r600->hw.rr.cmd[R600_RR_INST_0 + col_ip] = R600_RS_INST_COL_ID(col_ip) | R600_RS_INST_COL_CN_WRITE | R600_RS_INST_COL_ADDR(fp_reg); - InputsRead &= ~FRAG_BIT_COL0; - ++col_ip; - ++fp_reg; - } else { - WARN_ONCE("fragprog wants col0, vp doesn't provide it\n"); - } - } - - if (InputsRead & FRAG_BIT_COL1) { - if (R600_OUTPUTS_WRITTEN_TEST(OutputsWritten, VERT_RESULT_COL1, _TNL_ATTRIB_COLOR1)) { - count = VB->AttribPtr[_TNL_ATTRIB_COLOR1]->size; - if (count == 4) - col_fmt = R600_RS_COL_FMT_RGBA; - else if (count == 3) - col_fmt = R600_RS_COL_FMT_RGB1; - else - col_fmt = R600_RS_COL_FMT_0001; - - r600->hw.ri.cmd[R600_RI_INTERP_0 + col_ip] = R600_RS_COL_PTR(col_ip) | R600_RS_COL_FMT(col_fmt); - r600->hw.rr.cmd[R600_RR_INST_0 + col_ip] = R600_RS_INST_COL_ID(col_ip) | R600_RS_INST_COL_CN_WRITE | R600_RS_INST_COL_ADDR(fp_reg); - InputsRead &= ~FRAG_BIT_COL1; - ++col_ip; - ++fp_reg; - } else { - WARN_ONCE("fragprog wants col1, vp doesn't provide it\n"); - } - } - - for (i = 0; i < ctx->Const.MaxTextureUnits; i++) { - if (! ( InputsRead & FRAG_BIT_TEX(i) ) ) - continue; - - if (!R600_OUTPUTS_WRITTEN_TEST(OutputsWritten, VERT_RESULT_TEX0 + i, _TNL_ATTRIB_TEX(i))) { - WARN_ONCE("fragprog wants coords for tex%d, vp doesn't provide them!\n", i); - continue; - } - - int swiz; - - /* with TCL we always seem to route 4 components */ - if (hw_tcl_on) - count = 4; - else - count = VB->AttribPtr[_TNL_ATTRIB_TEX(i)]->size; - - switch(count) { - case 4: swiz = R600_RS_SEL_S(0) | R600_RS_SEL_T(1) | R600_RS_SEL_R(2) | R600_RS_SEL_Q(3); break; - case 3: swiz = R600_RS_SEL_S(0) | R600_RS_SEL_T(1) | R600_RS_SEL_R(2) | R600_RS_SEL_Q(R600_RS_SEL_K1); break; - default: - case 1: - case 2: swiz = R600_RS_SEL_S(0) | R600_RS_SEL_T(1) | R600_RS_SEL_R(R600_RS_SEL_K0) | R600_RS_SEL_Q(R600_RS_SEL_K1); break; - }; - - r600->hw.ri.cmd[R600_RI_INTERP_0 + tex_ip] |= swiz | R600_RS_TEX_PTR(rs_tex_count); - r600->hw.rr.cmd[R600_RR_INST_0 + tex_ip] |= R600_RS_INST_TEX_ID(tex_ip) | R600_RS_INST_TEX_CN_WRITE | R600_RS_INST_TEX_ADDR(fp_reg); - InputsRead &= ~(FRAG_BIT_TEX0 << i); - rs_tex_count += count; - ++tex_ip; - ++fp_reg; - } - - if (InputsRead & FRAG_BIT_FOGC) { - if (R600_OUTPUTS_WRITTEN_TEST(OutputsWritten, VERT_RESULT_FOGC, _TNL_ATTRIB_FOG)) { - r600->hw.ri.cmd[R600_RI_INTERP_0 + tex_ip] |= R600_RS_SEL_S(0) | R600_RS_SEL_T(1) | R600_RS_SEL_R(2) | R600_RS_SEL_Q(3) | R600_RS_TEX_PTR(rs_tex_count); - r600->hw.rr.cmd[R600_RR_INST_0 + tex_ip] |= R600_RS_INST_TEX_ID(tex_ip) | R600_RS_INST_TEX_CN_WRITE | R600_RS_INST_TEX_ADDR(fp_reg); - InputsRead &= ~FRAG_BIT_FOGC; - rs_tex_count += 4; - ++tex_ip; - ++fp_reg; - } else { - WARN_ONCE("fragprog wants fogc, vp doesn't provide it\n"); - } - } - - if (InputsRead & FRAG_BIT_WPOS) { - r600->hw.ri.cmd[R600_RI_INTERP_0 + tex_ip] |= R600_RS_SEL_S(0) | R600_RS_SEL_T(1) | R600_RS_SEL_R(2) | R600_RS_SEL_Q(3) | R600_RS_TEX_PTR(rs_tex_count); - r600->hw.rr.cmd[R600_RR_INST_0 + tex_ip] |= R600_RS_INST_TEX_ID(tex_ip) | R600_RS_INST_TEX_CN_WRITE | R600_RS_INST_TEX_ADDR(fp_reg); - InputsRead &= ~FRAG_BIT_WPOS; - rs_tex_count += 4; - ++tex_ip; - ++fp_reg; - } - InputsRead &= ~FRAG_BIT_WPOS; - - /* Setup default color if no color or tex was set */ - if (rs_tex_count == 0 && col_ip == 0) { - r600->hw.rr.cmd[R600_RR_INST_0] = R600_RS_INST_COL_ID(0) | R600_RS_INST_COL_CN_WRITE | R600_RS_INST_COL_ADDR(0) | R600_RS_COL_FMT(R600_RS_COL_FMT_0001); - ++col_ip; - } - - high_rr = (col_ip > tex_ip) ? col_ip : tex_ip; - r600->hw.rc.cmd[1] |= (rs_tex_count << R600_IT_COUNT_SHIFT) | (col_ip << R600_IC_COUNT_SHIFT) | R600_HIRES_EN; - r600->hw.rc.cmd[2] |= high_rr - 1; - - r600->hw.rr.cmd[R600_RR_CMD_0] = cmdpacket0(r600->radeon.radeonScreen, R600_RS_INST_0, high_rr); - - if (InputsRead) - WARN_ONCE("Don't know how to satisfy InputsRead=0x%08x\n", InputsRead); -} - -#define bump_vpu_count(ptr, new_count) do{\ - drm_r300_cmd_header_t* _p=((drm_r300_cmd_header_t*)(ptr));\ - int _nc=(new_count)/4; \ - assert(_nc < 256); \ - if(_nc>_p->vpu.count)_p->vpu.count=_nc;\ - }while(0) - -static INLINE void r600SetupVertexProgramFragment(r600ContextPtr r600, int dest, struct r600_vertex_shader_fragment *vsf) -{ - int i; - - if (vsf->length == 0) - return; - - if (vsf->length & 0x3) { - fprintf(stderr, "VERTEX_SHADER_FRAGMENT must have length divisible by 4\n"); - _mesa_exit(-1); - } - - switch ((dest >> 8) & 0xf) { - case 0: - R600_STATECHANGE(r600, vpi); - for (i = 0; i < vsf->length; i++) - r600->hw.vpi.cmd[R600_VPI_INSTR_0 + i + 4 * (dest & 0xff)] = (vsf->body.d[i]); - bump_vpu_count(r600->hw.vpi.cmd, vsf->length + 4 * (dest & 0xff)); - break; - - case 2: - R600_STATECHANGE(r600, vpp); - for (i = 0; i < vsf->length; i++) - r600->hw.vpp.cmd[R600_VPP_PARAM_0 + i + 4 * (dest & 0xff)] = (vsf->body.d[i]); - bump_vpu_count(r600->hw.vpp.cmd, vsf->length + 4 * (dest & 0xff)); - break; - case 4: - R600_STATECHANGE(r600, vps); - for (i = 0; i < vsf->length; i++) - r600->hw.vps.cmd[1 + i + 4 * (dest & 0xff)] = (vsf->body.d[i]); - bump_vpu_count(r600->hw.vps.cmd, vsf->length + 4 * (dest & 0xff)); - break; - default: - fprintf(stderr, "%s:%s don't know how to handle dest %04x\n", __FILE__, __FUNCTION__, dest); - _mesa_exit(-1); - } -} - -#define MIN3(a, b, c) ((a) < (b) ? MIN2(a, c) : MIN2(b, c)) - - -static void r600VapCntl(r600ContextPtr rmesa, GLuint input_count, - GLuint output_count, GLuint temp_count) -{ - int vtx_mem_size; - int pvs_num_slots; - int pvs_num_cntrls; - - /* Flush PVS engine before changing PVS_NUM_SLOTS, PVS_NUM_CNTRLS. - * See r500 docs 6.5.2 - done in emit */ - - /* avoid division by zero */ - if (input_count == 0) input_count = 1; - if (output_count == 0) output_count = 1; - if (temp_count == 0) temp_count = 1; - - if (rmesa->radeon.radeonScreen->chip_family >= CHIP_FAMILY_RV515) - vtx_mem_size = 128; - else - vtx_mem_size = 72; - - pvs_num_slots = MIN3(10, vtx_mem_size/input_count, vtx_mem_size/output_count); - pvs_num_cntrls = MIN2(6, vtx_mem_size/temp_count); - - R600_STATECHANGE(rmesa, vap_cntl); - if (rmesa->radeon.radeonScreen->chip_flags & RADEON_CHIPSET_TCL) { - rmesa->hw.vap_cntl.cmd[R600_VAP_CNTL_INSTR] = - (pvs_num_slots << R600_PVS_NUM_SLOTS_SHIFT) | - (pvs_num_cntrls << R600_PVS_NUM_CNTLRS_SHIFT) | - (12 << R600_VF_MAX_VTX_NUM_SHIFT); - } else - /* not sure about non-tcl */ - rmesa->hw.vap_cntl.cmd[R600_VAP_CNTL_INSTR] = ((10 << R600_PVS_NUM_SLOTS_SHIFT) | - (5 << R600_PVS_NUM_CNTLRS_SHIFT) | - (5 << R600_VF_MAX_VTX_NUM_SHIFT)); - - if (rmesa->radeon.radeonScreen->chip_family == CHIP_FAMILY_RV515) - rmesa->hw.vap_cntl.cmd[R600_VAP_CNTL_INSTR] |= (2 << R600_PVS_NUM_FPUS_SHIFT); - else if ((rmesa->radeon.radeonScreen->chip_family == CHIP_FAMILY_RV530) || - (rmesa->radeon.radeonScreen->chip_family == CHIP_FAMILY_RV560) || - (rmesa->radeon.radeonScreen->chip_family == CHIP_FAMILY_RV570)) - rmesa->hw.vap_cntl.cmd[R600_VAP_CNTL_INSTR] |= (5 << R600_PVS_NUM_FPUS_SHIFT); - else if ((rmesa->radeon.radeonScreen->chip_family == CHIP_FAMILY_RV410) || - (rmesa->radeon.radeonScreen->chip_family == CHIP_FAMILY_R420)) - rmesa->hw.vap_cntl.cmd[R600_VAP_CNTL_INSTR] |= (6 << R600_PVS_NUM_FPUS_SHIFT); - else if ((rmesa->radeon.radeonScreen->chip_family == CHIP_FAMILY_R520) || - (rmesa->radeon.radeonScreen->chip_family == CHIP_FAMILY_R580)) - rmesa->hw.vap_cntl.cmd[R600_VAP_CNTL_INSTR] |= (8 << R600_PVS_NUM_FPUS_SHIFT); - else - rmesa->hw.vap_cntl.cmd[R600_VAP_CNTL_INSTR] |= (4 << R600_PVS_NUM_FPUS_SHIFT); - -} - -static void r600SetupDefaultVertexProgram(r600ContextPtr rmesa) -{ - struct r600_vertex_shader_state *prog = &(rmesa->state.vertex_shader); - GLuint o_reg = 0; - GLuint i_reg = 0; - int i; - int inst_count = 0; - int param_count = 0; - int program_end = 0; - - for (i = VERT_ATTRIB_POS; i < VERT_ATTRIB_MAX; i++) { - if (rmesa->state.sw_tcl_inputs[i] != -1) { - prog->program.body.i[program_end + 0] = PVS_OP_DST_OPERAND(VE_MULTIPLY, GL_FALSE, GL_FALSE, o_reg++, VSF_FLAG_ALL, PVS_DST_REG_OUT); - prog->program.body.i[program_end + 1] = PVS_SRC_OPERAND(rmesa->state.sw_tcl_inputs[i], PVS_SRC_SELECT_X, PVS_SRC_SELECT_Y, PVS_SRC_SELECT_Z, PVS_SRC_SELECT_W, PVS_SRC_REG_INPUT, VSF_FLAG_NONE); - prog->program.body.i[program_end + 2] = PVS_SRC_OPERAND(rmesa->state.sw_tcl_inputs[i], PVS_SRC_SELECT_FORCE_1, PVS_SRC_SELECT_FORCE_1, PVS_SRC_SELECT_FORCE_1, PVS_SRC_SELECT_FORCE_1, PVS_SRC_REG_INPUT, VSF_FLAG_NONE); - prog->program.body.i[program_end + 3] = PVS_SRC_OPERAND(rmesa->state.sw_tcl_inputs[i], PVS_SRC_SELECT_FORCE_1, PVS_SRC_SELECT_FORCE_1, PVS_SRC_SELECT_FORCE_1, PVS_SRC_SELECT_FORCE_1, PVS_SRC_REG_INPUT, VSF_FLAG_NONE); - program_end += 4; - i_reg++; - } - } - - prog->program.length = program_end; - - r600SetupVertexProgramFragment(rmesa, R600_PVS_CODE_START, - &(prog->program)); - inst_count = (prog->program.length / 4) - 1; - - r600VapCntl(rmesa, i_reg, o_reg, 0); - - R600_STATECHANGE(rmesa, pvs); - rmesa->hw.pvs.cmd[R600_PVS_CNTL_1] = - (0 << R600_PVS_FIRST_INST_SHIFT) | - (inst_count << R600_PVS_XYZW_VALID_INST_SHIFT) | - (inst_count << R600_PVS_LAST_INST_SHIFT); - rmesa->hw.pvs.cmd[R600_PVS_CNTL_2] = - (0 << R600_PVS_CONST_BASE_OFFSET_SHIFT) | - (param_count << R600_PVS_MAX_CONST_ADDR_SHIFT); - rmesa->hw.pvs.cmd[R600_PVS_CNTL_3] = - (inst_count << R600_PVS_LAST_VTX_SRC_INST_SHIFT); -} - -static int bit_count (int x) -{ - x = ((x & 0xaaaaaaaaU) >> 1) + (x & 0x55555555U); - x = ((x & 0xccccccccU) >> 2) + (x & 0x33333333U); - x = (x >> 16) + (x & 0xffff); - x = ((x & 0xf0f0) >> 4) + (x & 0x0f0f); - return (x >> 8) + (x & 0x00ff); -} - -static void r600SetupRealVertexProgram(r600ContextPtr rmesa) -{ - GLcontext *ctx = rmesa->radeon.glCtx; - struct r600_vertex_program *prog = (struct r600_vertex_program *)CURRENT_VERTEX_SHADER(ctx); - int inst_count = 0; - int param_count = 0; - - /* FIXME: r600SetupVertexProgramFragment */ - R600_STATECHANGE(rmesa, vpp); - param_count = - r600VertexProgUpdateParams(ctx, - (struct r600_vertex_program_cont *) - ctx->VertexProgram._Current, - (float *)&rmesa->hw.vpp. - cmd[R600_VPP_PARAM_0]); - bump_vpu_count(rmesa->hw.vpp.cmd, param_count); - param_count /= 4; - - r600SetupVertexProgramFragment(rmesa, R600_PVS_CODE_START, &(prog->program)); - inst_count = (prog->program.length / 4) - 1; - - r600VapCntl(rmesa, bit_count(prog->key.InputsRead), - bit_count(prog->key.OutputsWritten), prog->num_temporaries); - - R600_STATECHANGE(rmesa, pvs); - rmesa->hw.pvs.cmd[R600_PVS_CNTL_1] = - (0 << R600_PVS_FIRST_INST_SHIFT) | - (inst_count << R600_PVS_XYZW_VALID_INST_SHIFT) | - (inst_count << R600_PVS_LAST_INST_SHIFT); - rmesa->hw.pvs.cmd[R600_PVS_CNTL_2] = - (0 << R600_PVS_CONST_BASE_OFFSET_SHIFT) | - (param_count << R600_PVS_MAX_CONST_ADDR_SHIFT); - rmesa->hw.pvs.cmd[R600_PVS_CNTL_3] = - (inst_count << R600_PVS_LAST_VTX_SRC_INST_SHIFT); -} - - -static void r600SetupVertexProgram(r600ContextPtr rmesa) -{ - GLcontext *ctx = rmesa->radeon.glCtx; - - /* Reset state, in case we don't use something */ - ((drm_r300_cmd_header_t *) rmesa->hw.vpp.cmd)->vpu.count = 0; - ((drm_r300_cmd_header_t *) rmesa->hw.vpi.cmd)->vpu.count = 0; - ((drm_r300_cmd_header_t *) rmesa->hw.vps.cmd)->vpu.count = 0; - - /* Not sure why this doesnt work... - 0x400 area might have something to do with pixel shaders as it appears right after pfs programming. - 0x406 is set to { 0.0, 0.0, 1.0, 0.0 } most of the time but should change with smooth points and in other rare cases. */ - //setup_vertex_shader_fragment(rmesa, 0x406, &unk4); - if (hw_tcl_on && ((struct r600_vertex_program *)CURRENT_VERTEX_SHADER(ctx))->translated) { - r600SetupRealVertexProgram(rmesa); - } else { - /* FIXME: This needs to be replaced by vertex shader generation code. */ - r600SetupDefaultVertexProgram(rmesa); - } - -} - -/** - * Enable/Disable states. - * - * \note Mesa already filters redundant calls to this function. - */ -static void r600Enable(GLcontext * ctx, GLenum cap, GLboolean state) -{ - r600ContextPtr rmesa = R600_CONTEXT(ctx); - if (RADEON_DEBUG & DEBUG_STATE) - fprintf(stderr, "%s( %s = %s )\n", __FUNCTION__, - _mesa_lookup_enum_by_nr(cap), - state ? "GL_TRUE" : "GL_FALSE"); - - switch (cap) { - case GL_TEXTURE_1D: - case GL_TEXTURE_2D: - case GL_TEXTURE_3D: - /* empty */ - break; - case GL_FOG: - /* empty */ - break; - case GL_ALPHA_TEST: - r600SetAlphaState(ctx); - break; - case GL_COLOR_LOGIC_OP: - r600SetLogicOpState(ctx); - /* fall-through, because logic op overrides blending */ - case GL_BLEND: - r600SetBlendState(ctx); - break; - case GL_CLIP_PLANE0: - case GL_CLIP_PLANE1: - case GL_CLIP_PLANE2: - case GL_CLIP_PLANE3: - case GL_CLIP_PLANE4: - case GL_CLIP_PLANE5: - r600SetClipPlaneState(ctx, cap, state); - break; - case GL_DEPTH_TEST: - r600SetDepthState(ctx); - break; - case GL_STENCIL_TEST: - r600SetStencilState(ctx, state); - break; - case GL_CULL_FACE: - r600UpdateCulling(ctx); - break; - case GL_POLYGON_OFFSET_POINT: - case GL_POLYGON_OFFSET_LINE: - case GL_POLYGON_OFFSET_FILL: - r600SetPolygonOffsetState(ctx, state); - break; - case GL_SCISSOR_TEST: - radeon_firevertices(&rmesa->radeon); - rmesa->radeon.state.scissor.enabled = state; - radeonUpdateScissor( ctx ); - break; - default: - break; - } -} - -/** - * Completely recalculates hardware state based on the Mesa state. - */ -static void r600ResetHwState(r600ContextPtr r600) -{ - GLcontext *ctx = r600->radeon.glCtx; - - if (RADEON_DEBUG & DEBUG_STATE) - fprintf(stderr, "%s\n", __FUNCTION__); - - radeon_firevertices(&r600->radeon); - - r600ColorMask(ctx, - ctx->Color.ColorMask[RCOMP], - ctx->Color.ColorMask[GCOMP], - ctx->Color.ColorMask[BCOMP], ctx->Color.ColorMask[ACOMP]); - - r600Enable(ctx, GL_DEPTH_TEST, ctx->Depth.Test); - r600DepthMask(ctx, ctx->Depth.Mask); - r600DepthFunc(ctx, ctx->Depth.Func); - - /* stencil */ - r600Enable(ctx, GL_STENCIL_TEST, ctx->Stencil._Enabled); - r600StencilMaskSeparate(ctx, 0, ctx->Stencil.WriteMask[0]); - r600StencilFuncSeparate(ctx, 0, ctx->Stencil.Function[0], - ctx->Stencil.Ref[0], ctx->Stencil.ValueMask[0]); - r600StencilOpSeparate(ctx, 0, ctx->Stencil.FailFunc[0], - ctx->Stencil.ZFailFunc[0], - ctx->Stencil.ZPassFunc[0]); - - r600UpdateCulling(ctx); - - r600SetBlendState(ctx); - r600SetLogicOpState(ctx); - - r600AlphaFunc(ctx, ctx->Color.AlphaFunc, ctx->Color.AlphaRef); - r600Enable(ctx, GL_ALPHA_TEST, ctx->Color.AlphaEnabled); - - r600->hw.vte.cmd[1] = R600_VPORT_X_SCALE_ENA - | R600_VPORT_X_OFFSET_ENA - | R600_VPORT_Y_SCALE_ENA - | R600_VPORT_Y_OFFSET_ENA - | R600_VPORT_Z_SCALE_ENA - | R600_VPORT_Z_OFFSET_ENA | R600_VTX_W0_FMT; - r600->hw.vte.cmd[2] = 0x00000008; - - r600->hw.vap_vf_max_vtx_indx.cmd[1] = 0x00FFFFFF; - r600->hw.vap_vf_max_vtx_indx.cmd[2] = 0x00000000; - -#ifdef MESA_LITTLE_ENDIAN - r600->hw.vap_cntl_status.cmd[1] = R600_VC_NO_SWAP; -#else - r600->hw.vap_cntl_status.cmd[1] = R600_VC_32BIT_SWAP; -#endif - - r600->hw.vap_psc_sgn_norm_cntl.cmd[1] = 0xAAAAAAAA; - - r600->hw.vap_clip_cntl.cmd[1] = R600_PS_UCP_MODE_DIST_COP; - - r600->hw.vap_clip.cmd[1] = r600PackFloat32(1.0); /* X */ - r600->hw.vap_clip.cmd[2] = r600PackFloat32(1.0); /* X */ - r600->hw.vap_clip.cmd[3] = r600PackFloat32(1.0); /* Y */ - r600->hw.vap_clip.cmd[4] = r600PackFloat32(1.0); /* Y */ - - switch (r600->radeon.radeonScreen->chip_family) { - case CHIP_FAMILY_R600: - r600->hw.vap_pvs_vtx_timeout_reg.cmd[1] = R600_2288_R600; - break; - default: - r600->hw.vap_pvs_vtx_timeout_reg.cmd[1] = R600_2288_RV350; - break; - } - - r600->hw.gb_enable.cmd[1] = R600_GB_POINT_STUFF_ENABLE - | R600_GB_LINE_STUFF_ENABLE - | R600_GB_TRIANGLE_STUFF_ENABLE; - - r600->hw.gb_misc.cmd[R600_GB_MISC_MSPOS_0] = 0x66666666; - r600->hw.gb_misc.cmd[R600_GB_MISC_MSPOS_1] = 0x06666666; - - r600->hw.gb_misc.cmd[R600_GB_MISC_TILE_CONFIG] = - R600_GB_TILE_ENABLE | R600_GB_TILE_SIZE_16 /*| R600_GB_SUBPIXEL_1_16*/; - switch (r600->radeon.radeonScreen->num_gb_pipes) { - case 1: - default: - r600->hw.gb_misc.cmd[R600_GB_MISC_TILE_CONFIG] |= - R600_GB_TILE_PIPE_COUNT_RV300; - break; - case 2: - r600->hw.gb_misc.cmd[R600_GB_MISC_TILE_CONFIG] |= - R600_GB_TILE_PIPE_COUNT_R600; - break; - case 3: - r600->hw.gb_misc.cmd[R600_GB_MISC_TILE_CONFIG] |= - R600_GB_TILE_PIPE_COUNT_R420_3P; - break; - case 4: - r600->hw.gb_misc.cmd[R600_GB_MISC_TILE_CONFIG] |= - R600_GB_TILE_PIPE_COUNT_R420; - break; - } - - /* XXX: Enable anti-aliasing? */ - r600->hw.gb_misc.cmd[R600_GB_MISC_AA_CONFIG] = GB_AA_CONFIG_AA_DISABLE; - r600->hw.gb_misc.cmd[R600_GB_MISC_SELECT] = 0; - - r600->hw.ga_point_s0.cmd[1] = r600PackFloat32(0.0); - r600->hw.ga_point_s0.cmd[2] = r600PackFloat32(0.0); - r600->hw.ga_point_s0.cmd[3] = r600PackFloat32(1.0); - r600->hw.ga_point_s0.cmd[4] = r600PackFloat32(1.0); - - r600->hw.ga_triangle_stipple.cmd[1] = 0x00050005; - - r600PointSize(ctx, 1.0); - - r600->hw.ga_point_minmax.cmd[1] = 0x18000006; - r600->hw.ga_point_minmax.cmd[2] = 0x00020006; - r600->hw.ga_point_minmax.cmd[3] = r600PackFloat32(1.0 / 192.0); - - r600LineWidth(ctx, 1.0); - - r600->hw.ga_line_stipple.cmd[1] = 0; - r600->hw.ga_line_stipple.cmd[2] = r600PackFloat32(0.0); - r600->hw.ga_line_stipple.cmd[3] = r600PackFloat32(1.0); - - r600ShadeModel(ctx, ctx->Light.ShadeModel); - - r600PolygonMode(ctx, GL_FRONT, ctx->Polygon.FrontMode); - r600PolygonMode(ctx, GL_BACK, ctx->Polygon.BackMode); - r600->hw.zbias_cntl.cmd[1] = 0x00000000; - - r600PolygonOffset(ctx, ctx->Polygon.OffsetFactor, - ctx->Polygon.OffsetUnits); - r600Enable(ctx, GL_POLYGON_OFFSET_POINT, ctx->Polygon.OffsetPoint); - r600Enable(ctx, GL_POLYGON_OFFSET_LINE, ctx->Polygon.OffsetLine); - r600Enable(ctx, GL_POLYGON_OFFSET_FILL, ctx->Polygon.OffsetFill); - - r600->hw.su_depth_scale.cmd[1] = 0x4B7FFFFF; - r600->hw.su_depth_scale.cmd[2] = 0x00000000; - - r600->hw.sc_hyperz.cmd[1] = 0x0000001C; - r600->hw.sc_hyperz.cmd[2] = 0x2DA49525; - - r600->hw.sc_screendoor.cmd[1] = 0x00FFFFFF; - - r600->hw.us_out_fmt.cmd[5] = R600_W_FMT_W0 | R600_W_SRC_US; - - /* disable fog unit */ - r600->hw.fogs.cmd[R600_FOGS_STATE] = 0; - r600->hw.fg_depth_src.cmd[1] = R600_FG_DEPTH_SRC_SCAN; - - r600->hw.rb3d_cctl.cmd[1] = 0; - - r600BlendColor(ctx, ctx->Color.BlendColor); - - r600->hw.rb3d_dither_ctl.cmd[1] = 0; - r600->hw.rb3d_dither_ctl.cmd[2] = 0; - r600->hw.rb3d_dither_ctl.cmd[3] = 0; - r600->hw.rb3d_dither_ctl.cmd[4] = 0; - r600->hw.rb3d_dither_ctl.cmd[5] = 0; - r600->hw.rb3d_dither_ctl.cmd[6] = 0; - r600->hw.rb3d_dither_ctl.cmd[7] = 0; - r600->hw.rb3d_dither_ctl.cmd[8] = 0; - r600->hw.rb3d_dither_ctl.cmd[9] = 0; - - r600->hw.rb3d_aaresolve_ctl.cmd[1] = 0; - - r600->hw.zb_depthclearvalue.cmd[1] = 0; - - r600->hw.zstencil_format.cmd[2] = R600_ZTOP_DISABLE; - r600->hw.zstencil_format.cmd[3] = 0x00000003; - r600->hw.zstencil_format.cmd[4] = 0x00000000; - r600SetEarlyZState(ctx); - - r600->hw.unk4F30.cmd[1] = 0; - r600->hw.unk4F30.cmd[2] = 0; - - r600->hw.zb_hiz_offset.cmd[1] = 0; - - r600->hw.zb_hiz_pitch.cmd[1] = 0; - - r600VapCntl(r600, 0, 0, 0); - - r600->hw.vps.cmd[R600_VPS_ZERO_0] = 0; - r600->hw.vps.cmd[R600_VPS_ZERO_1] = 0; - r600->hw.vps.cmd[R600_VPS_POINTSIZE] = r600PackFloat32(1.0); - r600->hw.vps.cmd[R600_VPS_ZERO_3] = 0; - - r600->radeon.hw.all_dirty = GL_TRUE; -} - -void r600UpdateShaders(r600ContextPtr rmesa) -{ - GLcontext *ctx; - struct r600_vertex_program *vp; - int i; - - ctx = rmesa->radeon.glCtx; - - if (rmesa->radeon.NewGLState && hw_tcl_on) { - rmesa->radeon.NewGLState = 0; - - for (i = _TNL_FIRST_MAT; i <= _TNL_LAST_MAT; i++) { - rmesa->temp_attrib[i] = - TNL_CONTEXT(ctx)->vb.AttribPtr[i]; - TNL_CONTEXT(ctx)->vb.AttribPtr[i] = - &rmesa->dummy_attrib[i]; - } - - _tnl_UpdateFixedFunctionProgram(ctx); - - for (i = _TNL_FIRST_MAT; i <= _TNL_LAST_MAT; i++) { - TNL_CONTEXT(ctx)->vb.AttribPtr[i] = - rmesa->temp_attrib[i]; - } - - r600SelectVertexShader(rmesa); - vp = (struct r600_vertex_program *) - CURRENT_VERTEX_SHADER(ctx); - /*if (vp->translated == GL_FALSE) - r600TranslateVertexShader(vp); */ - if (vp->translated == GL_FALSE) { - fprintf(stderr, "Failing back to sw-tcl\n"); - hw_tcl_on = future_hw_tcl_on = 0; - r600ResetHwState(rmesa); - - r600UpdateStateParameters(ctx, _NEW_PROGRAM); - return; - } - } - r600UpdateStateParameters(ctx, _NEW_PROGRAM); -} - -static const GLfloat *get_fragmentprogram_constant(GLcontext *ctx, - struct gl_program *program, struct prog_src_register srcreg) -{ - static const GLfloat dummy[4] = { 0, 0, 0, 0 }; - - switch(srcreg.File) { - case PROGRAM_LOCAL_PARAM: - return program->LocalParams[srcreg.Index]; - case PROGRAM_ENV_PARAM: - return ctx->FragmentProgram.Parameters[srcreg.Index]; - case PROGRAM_STATE_VAR: - case PROGRAM_NAMED_PARAM: - case PROGRAM_CONSTANT: - return program->Parameters->ParameterValues[srcreg.Index]; - default: - _mesa_problem(ctx, "get_fragmentprogram_constant: Unknown\n"); - return dummy; - } -} - - -static void r600SetupPixelShader(r600ContextPtr rmesa) -{ - GLcontext *ctx = rmesa->radeon.glCtx; - struct r600_fragment_program *fp = (struct r600_fragment_program *) - (char *)ctx->FragmentProgram._Current; - struct r600_fragment_program_code *code; - int i, k; - - if (!fp) /* should only happenen once, just after context is created */ - return; - - r600TranslateFragmentShader(rmesa, fp); - if (!fp->translated) { - fprintf(stderr, "%s: No valid fragment shader, exiting\n", - __FUNCTION__); - return; - } - code = &fp->code; - - r600SetupTextures(ctx); - - R600_STATECHANGE(rmesa, fpi[0]); - R600_STATECHANGE(rmesa, fpi[1]); - R600_STATECHANGE(rmesa, fpi[2]); - R600_STATECHANGE(rmesa, fpi[3]); - rmesa->hw.fpi[0].cmd[R600_FPI_CMD_0] = cmdpacket0(rmesa->radeon.radeonScreen, R600_US_ALU_RGB_INST_0, code->alu.length); - rmesa->hw.fpi[1].cmd[R600_FPI_CMD_0] = cmdpacket0(rmesa->radeon.radeonScreen, R600_US_ALU_RGB_ADDR_0, code->alu.length); - rmesa->hw.fpi[2].cmd[R600_FPI_CMD_0] = cmdpacket0(rmesa->radeon.radeonScreen, R600_US_ALU_ALPHA_INST_0, code->alu.length); - rmesa->hw.fpi[3].cmd[R600_FPI_CMD_0] = cmdpacket0(rmesa->radeon.radeonScreen, R600_US_ALU_ALPHA_ADDR_0, code->alu.length); - for (i = 0; i < code->alu.length; i++) { - rmesa->hw.fpi[0].cmd[R600_FPI_INSTR_0 + i] = code->alu.inst[i].inst0; - rmesa->hw.fpi[1].cmd[R600_FPI_INSTR_0 + i] = code->alu.inst[i].inst1; - rmesa->hw.fpi[2].cmd[R600_FPI_INSTR_0 + i] = code->alu.inst[i].inst2; - rmesa->hw.fpi[3].cmd[R600_FPI_INSTR_0 + i] = code->alu.inst[i].inst3; - } - - R600_STATECHANGE(rmesa, fp); - rmesa->hw.fp.cmd[R600_FP_CNTL0] = code->cur_node | (code->first_node_has_tex << 3); - rmesa->hw.fp.cmd[R600_FP_CNTL1] = code->max_temp_idx; - rmesa->hw.fp.cmd[R600_FP_CNTL2] = - (0 << R600_PFS_CNTL_ALU_OFFSET_SHIFT) | - ((code->alu.length-1) << R600_PFS_CNTL_ALU_END_SHIFT) | - (0 << R600_PFS_CNTL_TEX_OFFSET_SHIFT) | - ((code->tex.length ? code->tex.length-1 : 0) << R600_PFS_CNTL_TEX_END_SHIFT); - /* I just want to say, the way these nodes are stored.. weird.. */ - for (i = 0, k = (4 - (code->cur_node + 1)); i < 4; i++, k++) { - if (i < (code->cur_node + 1)) { - rmesa->hw.fp.cmd[R600_FP_NODE0 + k] = - (code->node[i].alu_offset << R600_ALU_START_SHIFT) | - (code->node[i].alu_end << R600_ALU_SIZE_SHIFT) | - (code->node[i].tex_offset << R600_TEX_START_SHIFT) | - (code->node[i].tex_end << R600_TEX_SIZE_SHIFT) | - code->node[i].flags; - } else { - rmesa->hw.fp.cmd[R600_FP_NODE0 + (3 - i)] = 0; - } - } - - R600_STATECHANGE(rmesa, fpp); - rmesa->hw.fpp.cmd[R600_FPP_CMD_0] = cmdpacket0(rmesa->radeon.radeonScreen, R600_PFS_PARAM_0_X, code->const_nr * 4); - for (i = 0; i < code->const_nr; i++) { - const GLfloat *constant = get_fragmentprogram_constant(ctx, - &fp->mesa_program.Base, code->constant[i]); - rmesa->hw.fpp.cmd[R600_FPP_PARAM_0 + 4 * i + 0] = r600PackFloat24(constant[0]); - rmesa->hw.fpp.cmd[R600_FPP_PARAM_0 + 4 * i + 1] = r600PackFloat24(constant[1]); - rmesa->hw.fpp.cmd[R600_FPP_PARAM_0 + 4 * i + 2] = r600PackFloat24(constant[2]); - rmesa->hw.fpp.cmd[R600_FPP_PARAM_0 + 4 * i + 3] = r600PackFloat24(constant[3]); - } -} - -void r600UpdateShaderStates(r600ContextPtr rmesa) -{ - GLcontext *ctx; - ctx = rmesa->radeon.glCtx; - - r600SetEarlyZState(ctx); - - /* w_fmt value is set to get best performance - * see p.130 R5xx 3D acceleration guide v1.3 */ - GLuint w_fmt, fgdepthsrc; - if (current_fragment_program_writes_depth(ctx)) { - fgdepthsrc = R600_FG_DEPTH_SRC_SHADER; - w_fmt = R600_W_FMT_W24 | R600_W_SRC_US; - } else { - fgdepthsrc = R600_FG_DEPTH_SRC_SCAN; - w_fmt = R600_W_FMT_W0 | R600_W_SRC_US; - } - - if (w_fmt != rmesa->hw.us_out_fmt.cmd[5]) { - R600_STATECHANGE(rmesa, us_out_fmt); - rmesa->hw.us_out_fmt.cmd[5] = w_fmt; - } - - if (fgdepthsrc != rmesa->hw.fg_depth_src.cmd[1]) { - R600_STATECHANGE(rmesa, fg_depth_src); - rmesa->hw.fg_depth_src.cmd[1] = fgdepthsrc; - } - - r600SetupPixelShader(rmesa); - - r600SetupRSUnit(ctx); - - r600SetupVertexProgram(rmesa); - -} - -/** - * Called by Mesa after an internal state update. - */ -static void r600InvalidateState(GLcontext * ctx, GLuint new_state) -{ - r600ContextPtr r600 = R600_CONTEXT(ctx); - - _swrast_InvalidateState(ctx, new_state); - _swsetup_InvalidateState(ctx, new_state); - _vbo_InvalidateState(ctx, new_state); - _tnl_InvalidateState(ctx, new_state); - _ae_invalidate_state(ctx, new_state); - - if (new_state & (_NEW_BUFFERS | _NEW_COLOR | _NEW_PIXEL)) { - _mesa_update_framebuffer(ctx); - /* this updates the DrawBuffer's Width/Height if it's a FBO */ - _mesa_update_draw_buffer_bounds(ctx); - - R600_STATECHANGE(r600, cb); - } - - r600UpdateStateParameters(ctx, new_state); - - r600->radeon.NewGLState |= new_state; -} - -/** - * Calculate initial hardware state and register state functions. - * Assumes that the command buffer and state atoms have been - * initialized already. - */ -void r600InitState(r600ContextPtr r600) -{ - memset(&(r600->state.texture), 0, sizeof(r600->state.texture)); - - r600ResetHwState(r600); -} - -static void r600RenderMode(GLcontext * ctx, GLenum mode) -{ - r600ContextPtr rmesa = R600_CONTEXT(ctx); - (void)rmesa; - (void)mode; -} - -void r600UpdateClipPlanes( GLcontext *ctx ) -{ - r600ContextPtr rmesa = R600_CONTEXT(ctx); - GLuint p; - - for (p = 0; p < ctx->Const.MaxClipPlanes; p++) { - if (ctx->Transform.ClipPlanesEnabled & (1 << p)) { - GLint *ip = (GLint *)ctx->Transform._ClipUserPlane[p]; - - R600_STATECHANGE( rmesa, vpucp[p] ); - rmesa->hw.vpucp[p].cmd[R600_VPUCP_X] = ip[0]; - rmesa->hw.vpucp[p].cmd[R600_VPUCP_Y] = ip[1]; - rmesa->hw.vpucp[p].cmd[R600_VPUCP_Z] = ip[2]; - rmesa->hw.vpucp[p].cmd[R600_VPUCP_W] = ip[3]; - } - } -} - -/** - * Initialize driver's state callback functions - */ -void r600InitStateFuncs(struct dd_function_table *functions) -{ - - functions->UpdateState = r600InvalidateState; - functions->AlphaFunc = r600AlphaFunc; - functions->BlendColor = r600BlendColor; - functions->BlendEquationSeparate = r600BlendEquationSeparate; - functions->BlendFuncSeparate = r600BlendFuncSeparate; - functions->Enable = r600Enable; - functions->ColorMask = r600ColorMask; - functions->DepthFunc = r600DepthFunc; - functions->DepthMask = r600DepthMask; - functions->CullFace = r600CullFace; - functions->FrontFace = r600FrontFace; - functions->ShadeModel = r600ShadeModel; - functions->LogicOpcode = r600LogicOpcode; - - /* ARB_point_parameters */ - functions->PointParameterfv = r600PointParameter; - - /* Stencil related */ - functions->StencilFuncSeparate = r600StencilFuncSeparate; - functions->StencilMaskSeparate = r600StencilMaskSeparate; - functions->StencilOpSeparate = r600StencilOpSeparate; - - /* Viewport related */ - functions->Viewport = r600Viewport; - functions->DepthRange = r600DepthRange; - functions->PointSize = r600PointSize; - functions->LineWidth = r600LineWidth; - - functions->PolygonOffset = r600PolygonOffset; - functions->PolygonMode = r600PolygonMode; - - functions->RenderMode = r600RenderMode; - - functions->ClipPlane = r600ClipPlane; - functions->Scissor = radeonScissor; - - functions->DrawBuffer = radeonDrawBuffer; - functions->ReadBuffer = radeonReadBuffer; -} diff --git a/src/mesa/drivers/dri/r600/r600_state.h b/src/mesa/drivers/dri/r600/r600_state.h deleted file mode 100644 index 2aca95ca251..00000000000 --- a/src/mesa/drivers/dri/r600/r600_state.h +++ /dev/null @@ -1,65 +0,0 @@ -/* -Copyright (C) The Weather Channel, Inc. 2002. All Rights Reserved. - -The Weather Channel (TM) funded Tungsten Graphics to develop the -initial release of the Radeon 8500 driver under the XFree86 license. -This notice must be preserved. - -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. - -**************************************************************************/ - -/* - * Authors: - * Nicolai Haehnle <[email protected]> - */ - -#ifndef __R600_STATE_H__ -#define __R600_STATE_H__ - -#include "r600_context.h" - -#define R600_NEWPRIM( rmesa ) \ - do { \ - if ( rmesa->radeon.dma.flush ) \ - rmesa->radeon.dma.flush( rmesa->radeon.glCtx ); \ - } while (0) - -#define R600_STATECHANGE(r600, atom) \ - do { \ - R600_NEWPRIM(r600); \ - r600->hw.atom.dirty = GL_TRUE; \ - r600->radeon.hw.is_dirty = GL_TRUE; \ - } while(0) - -// r600_state.c -extern int future_hw_tcl_on; -void _tnl_UpdateFixedFunctionProgram (GLcontext * ctx); -void r600UpdateViewportOffset (GLcontext * ctx); -void r600UpdateDrawBuffer (GLcontext * ctx); -void r600UpdateStateParameters (GLcontext * ctx, GLuint new_state); -void r600UpdateShaders (r600ContextPtr rmesa); -void r600UpdateShaderStates (r600ContextPtr rmesa); -void r600InitState (r600ContextPtr r600); -void r600UpdateClipPlanes (GLcontext * ctx); -void r600InitStateFuncs (struct dd_function_table *functions); - -#endif /* __R600_STATE_H__ */ diff --git a/src/mesa/drivers/dri/r600/r600_tex.c b/src/mesa/drivers/dri/r600/r600_tex.c deleted file mode 100644 index a057e039f21..00000000000 --- a/src/mesa/drivers/dri/r600/r600_tex.c +++ /dev/null @@ -1,347 +0,0 @@ -/* -Copyright (C) The Weather Channel, Inc. 2002. All Rights Reserved. - -The Weather Channel (TM) funded Tungsten Graphics to develop the -initial release of the Radeon 8500 driver under the XFree86 license. -This notice must be preserved. - -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 - * - * \author Keith Whitwell <[email protected]> - */ - -#include "main/glheader.h" -#include "main/imports.h" -#include "main/colormac.h" -#include "main/context.h" -#include "main/enums.h" -#include "main/image.h" -#include "main/mipmap.h" -#include "main/simple_list.h" -#include "main/texformat.h" -#include "main/texstore.h" -#include "main/teximage.h" -#include "main/texobj.h" - -#include "texmem.h" - -#include "r600_context.h" -#include "r600_state.h" -#include "r600_ioctl.h" -#include "radeon_mipmap_tree.h" -#include "r600_tex.h" - -#include "xmlpool.h" - - -static unsigned int translate_wrap_mode(GLenum wrapmode) -{ - switch(wrapmode) { - case GL_REPEAT: return R600_TX_REPEAT; - case GL_CLAMP: return R600_TX_CLAMP; - case GL_CLAMP_TO_EDGE: return R600_TX_CLAMP_TO_EDGE; - case GL_CLAMP_TO_BORDER: return R600_TX_CLAMP_TO_BORDER; - case GL_MIRRORED_REPEAT: return R600_TX_REPEAT | R600_TX_MIRRORED; - case GL_MIRROR_CLAMP_EXT: return R600_TX_CLAMP | R600_TX_MIRRORED; - case GL_MIRROR_CLAMP_TO_EDGE_EXT: return R600_TX_CLAMP_TO_EDGE | R600_TX_MIRRORED; - case GL_MIRROR_CLAMP_TO_BORDER_EXT: return R600_TX_CLAMP_TO_BORDER | R600_TX_MIRRORED; - default: - _mesa_problem(NULL, "bad wrap mode in %s", __FUNCTION__); - return 0; - } -} - - -/** - * Update the cached hardware registers based on the current texture wrap modes. - * - * \param t Texture object whose wrap modes are to be set - */ -static void r600UpdateTexWrap(radeonTexObjPtr t) -{ - struct gl_texture_object *tObj = &t->base; - - t->pp_txfilter &= - ~(R600_TX_WRAP_S_MASK | R600_TX_WRAP_T_MASK | R600_TX_WRAP_R_MASK); - - t->pp_txfilter |= translate_wrap_mode(tObj->WrapS) << R600_TX_WRAP_S_SHIFT; - - if (tObj->Target != GL_TEXTURE_1D) { - t->pp_txfilter |= translate_wrap_mode(tObj->WrapT) << R600_TX_WRAP_T_SHIFT; - - if (tObj->Target == GL_TEXTURE_3D) - t->pp_txfilter |= translate_wrap_mode(tObj->WrapR) << R600_TX_WRAP_R_SHIFT; - } -} - -static GLuint aniso_filter(GLfloat anisotropy) -{ - if (anisotropy >= 16.0) { - return R600_TX_MAX_ANISO_16_TO_1; - } else if (anisotropy >= 8.0) { - return R600_TX_MAX_ANISO_8_TO_1; - } else if (anisotropy >= 4.0) { - return R600_TX_MAX_ANISO_4_TO_1; - } else if (anisotropy >= 2.0) { - return R600_TX_MAX_ANISO_2_TO_1; - } else { - return R600_TX_MAX_ANISO_1_TO_1; - } -} - -/** - * Set the texture magnification and minification modes. - * - * \param t Texture whose filter modes are to be set - * \param minf Texture minification mode - * \param magf Texture magnification mode - * \param anisotropy Maximum anisotropy level - */ -static void r600SetTexFilter(radeonTexObjPtr t, GLenum minf, GLenum magf, GLfloat anisotropy) -{ - /* Force revalidation to account for switches from/to mipmapping. */ - t->validated = GL_FALSE; - - t->pp_txfilter &= ~(R600_TX_MIN_FILTER_MASK | R600_TX_MIN_FILTER_MIP_MASK | R600_TX_MAG_FILTER_MASK | R600_TX_MAX_ANISO_MASK); - t->pp_txfilter_1 &= ~R600_EDGE_ANISO_EDGE_ONLY; - - /* Note that EXT_texture_filter_anisotropic is extremely vague about - * how anisotropic filtering interacts with the "normal" filter modes. - * When anisotropic filtering is enabled, we override min and mag - * filter settings completely. This includes driconf's settings. - */ - if (anisotropy >= 2.0 && (minf != GL_NEAREST) && (magf != GL_NEAREST)) { - t->pp_txfilter |= R600_TX_MAG_FILTER_ANISO - | R600_TX_MIN_FILTER_ANISO - | R600_TX_MIN_FILTER_MIP_LINEAR - | aniso_filter(anisotropy); - if (RADEON_DEBUG & DEBUG_TEXTURE) - fprintf(stderr, "Using maximum anisotropy of %f\n", anisotropy); - return; - } - - switch (minf) { - case GL_NEAREST: - t->pp_txfilter |= R600_TX_MIN_FILTER_NEAREST; - break; - case GL_LINEAR: - t->pp_txfilter |= R600_TX_MIN_FILTER_LINEAR; - break; - case GL_NEAREST_MIPMAP_NEAREST: - t->pp_txfilter |= R600_TX_MIN_FILTER_NEAREST|R600_TX_MIN_FILTER_MIP_NEAREST; - break; - case GL_NEAREST_MIPMAP_LINEAR: - t->pp_txfilter |= R600_TX_MIN_FILTER_NEAREST|R600_TX_MIN_FILTER_MIP_LINEAR; - break; - case GL_LINEAR_MIPMAP_NEAREST: - t->pp_txfilter |= R600_TX_MIN_FILTER_LINEAR|R600_TX_MIN_FILTER_MIP_NEAREST; - break; - case GL_LINEAR_MIPMAP_LINEAR: - t->pp_txfilter |= R600_TX_MIN_FILTER_LINEAR|R600_TX_MIN_FILTER_MIP_LINEAR; - break; - } - - /* Note we don't have 3D mipmaps so only use the mag filter setting - * to set the 3D texture filter mode. - */ - switch (magf) { - case GL_NEAREST: - t->pp_txfilter |= R600_TX_MAG_FILTER_NEAREST; - break; - case GL_LINEAR: - t->pp_txfilter |= R600_TX_MAG_FILTER_LINEAR; - break; - } -} - -static void r600SetTexBorderColor(radeonTexObjPtr t, GLubyte c[4]) -{ - t->pp_border_color = PACK_COLOR_8888(c[3], c[0], c[1], c[2]); -} - -/** - * Changes variables and flags for a state update, which will happen at the - * next UpdateTextureState - */ - -static void r600TexParameter(GLcontext * ctx, GLenum target, - struct gl_texture_object *texObj, - GLenum pname, const GLfloat * params) -{ - radeonTexObj* t = radeon_tex_obj(texObj); - - if (RADEON_DEBUG & (DEBUG_STATE | DEBUG_TEXTURE)) { - fprintf(stderr, "%s( %s )\n", __FUNCTION__, - _mesa_lookup_enum_by_nr(pname)); - } - - switch (pname) { - case GL_TEXTURE_MIN_FILTER: - case GL_TEXTURE_MAG_FILTER: - case GL_TEXTURE_MAX_ANISOTROPY_EXT: - r600SetTexFilter(t, texObj->MinFilter, texObj->MagFilter, texObj->MaxAnisotropy); - break; - - case GL_TEXTURE_WRAP_S: - case GL_TEXTURE_WRAP_T: - case GL_TEXTURE_WRAP_R: - r600UpdateTexWrap(t); - break; - - case GL_TEXTURE_BORDER_COLOR: - r600SetTexBorderColor(t, texObj->BorderColor); - break; - - case GL_TEXTURE_BASE_LEVEL: - case GL_TEXTURE_MAX_LEVEL: - case GL_TEXTURE_MIN_LOD: - case GL_TEXTURE_MAX_LOD: - /* This isn't the most efficient solution but there doesn't appear to - * be a nice alternative. Since there's no LOD clamping, - * we just have to rely on loading the right subset of mipmap levels - * to simulate a clamped LOD. - */ - if (t->mt) { - radeon_miptree_unreference(t->mt); - t->mt = 0; - t->validated = GL_FALSE; - } - break; - - case GL_DEPTH_TEXTURE_MODE: - if (!texObj->Image[0][texObj->BaseLevel]) - return; - if (texObj->Image[0][texObj->BaseLevel]->TexFormat->BaseFormat - == GL_DEPTH_COMPONENT) { - r600SetDepthTexMode(texObj); - break; - } else { - /* If the texture isn't a depth texture, changing this - * state won't cause any changes to the hardware. - * Don't force a flush of texture state. - */ - return; - } - - default: - return; - } -} - -static void r600DeleteTexture(GLcontext * ctx, struct gl_texture_object *texObj) -{ - r600ContextPtr rmesa = R600_CONTEXT(ctx); - radeonTexObj* t = radeon_tex_obj(texObj); - - if (RADEON_DEBUG & (DEBUG_STATE | DEBUG_TEXTURE)) { - fprintf(stderr, "%s( %p (target = %s) )\n", __FUNCTION__, - (void *)texObj, - _mesa_lookup_enum_by_nr(texObj->Target)); - } - - if (rmesa) { - int i; - radeon_firevertices(&rmesa->radeon); - - for(i = 0; i < R600_MAX_TEXTURE_UNITS; ++i) - if (rmesa->hw.textures[i] == t) - rmesa->hw.textures[i] = 0; - } - - if (t->bo) { - radeon_bo_unref(t->bo); - t->bo = NULL; - } - - if (t->mt) { - radeon_miptree_unreference(t->mt); - t->mt = 0; - } - _mesa_delete_texture_object(ctx, texObj); -} - -/** - * Allocate a new texture object. - * Called via ctx->Driver.NewTextureObject. - * Note: this function will be called during context creation to - * allocate the default texture objects. - * Fixup MaxAnisotropy according to user preference. - */ -static struct gl_texture_object *r600NewTextureObject(GLcontext * ctx, - GLuint name, - GLenum target) -{ - r600ContextPtr rmesa = R600_CONTEXT(ctx); - radeonTexObj* t = CALLOC_STRUCT(radeon_tex_obj); - - - if (RADEON_DEBUG & (DEBUG_STATE | DEBUG_TEXTURE)) { - fprintf(stderr, "%s( %p (target = %s) )\n", __FUNCTION__, - t, _mesa_lookup_enum_by_nr(target)); - } - - _mesa_initialize_texture_object(&t->base, name, target); - t->base.MaxAnisotropy = rmesa->radeon.initialMaxAnisotropy; - - /* Initialize hardware state */ - r600UpdateTexWrap(t); - r600SetTexFilter(t, t->base.MinFilter, t->base.MagFilter, t->base.MaxAnisotropy); - r600SetTexBorderColor(t, t->base.BorderColor); - - return &t->base; -} - -void r600InitTextureFuncs(struct dd_function_table *functions) -{ - /* Note: we only plug in the functions we implement in the driver - * since _mesa_init_driver_functions() was already called. - */ - functions->NewTextureImage = radeonNewTextureImage; - functions->FreeTexImageData = radeonFreeTexImageData; - functions->MapTexture = radeonMapTexture; - functions->UnmapTexture = radeonUnmapTexture; - - functions->ChooseTextureFormat = radeonChooseTextureFormat_mesa; - functions->TexImage1D = radeonTexImage1D; - functions->TexImage2D = radeonTexImage2D; - functions->TexImage3D = radeonTexImage3D; - functions->TexSubImage1D = radeonTexSubImage1D; - functions->TexSubImage2D = radeonTexSubImage2D; - functions->TexSubImage3D = radeonTexSubImage3D; - functions->GetTexImage = radeonGetTexImage; - functions->GetCompressedTexImage = radeonGetCompressedTexImage; - functions->NewTextureObject = r600NewTextureObject; - functions->DeleteTexture = r600DeleteTexture; - functions->IsTextureResident = driIsTextureResident; - - functions->TexParameter = r600TexParameter; - - functions->CompressedTexImage2D = radeonCompressedTexImage2D; - functions->CompressedTexSubImage2D = radeonCompressedTexSubImage2D; - - functions->GenerateMipmap = radeonGenerateMipmap; - - driInitTextureFormats(); -} diff --git a/src/mesa/drivers/dri/r600/r600_tex.h b/src/mesa/drivers/dri/r600/r600_tex.h deleted file mode 100644 index a1d50ec6986..00000000000 --- a/src/mesa/drivers/dri/r600/r600_tex.h +++ /dev/null @@ -1,54 +0,0 @@ -/* -Copyright (C) The Weather Channel, Inc. 2002. All Rights Reserved. - -The Weather Channel (TM) funded Tungsten Graphics to develop the -initial release of the Radeon 8500 driver under the XFree86 license. -This notice must be preserved. - -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. - -**************************************************************************/ - -/* - * Authors: - * Keith Whitwell <[email protected]> - */ - -#ifndef __r600_TEX_H__ -#define __r600_TEX_H__ - -extern void r600SetDepthTexMode(struct gl_texture_object *tObj); - -extern void r600SetTexBuffer(__DRIcontext *pDRICtx, GLint target, - __DRIdrawable *dPriv); - -extern void r600SetTexBuffer2(__DRIcontext *pDRICtx, GLint target, - GLint format, __DRIdrawable *dPriv); - -extern void r600SetTexOffset(__DRIcontext *pDRICtx, GLint texname, - unsigned long long offset, GLint depth, - GLuint pitch); - -extern GLboolean r600ValidateBuffers(GLcontext * ctx); - -extern void r600InitTextureFuncs(struct dd_function_table *functions); - -#endif /* __r600_TEX_H__ */ diff --git a/src/mesa/drivers/dri/r600/r600_texstate.c b/src/mesa/drivers/dri/r600/r600_texstate.c deleted file mode 100644 index e9fbdf32b0f..00000000000 --- a/src/mesa/drivers/dri/r600/r600_texstate.c +++ /dev/null @@ -1,476 +0,0 @@ -/* -Copyright (C) The Weather Channel, Inc. 2002. All Rights Reserved. - -The Weather Channel (TM) funded Tungsten Graphics to develop the -initial release of the Radeon 8500 driver under the XFree86 license. -This notice must be preserved. - -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 - * - * \author Keith Whitwell <[email protected]> - * - * \todo Enable R600 texture tiling code? - */ - -#include "main/glheader.h" -#include "main/imports.h" -#include "main/context.h" -#include "main/macros.h" -#include "main/texformat.h" -#include "main/teximage.h" -#include "main/texobj.h" -#include "main/enums.h" - -#include "r600_context.h" -#include "r600_state.h" -#include "r600_ioctl.h" -#include "radeon_mipmap_tree.h" -#include "r600_tex.h" -#include "r600_reg.h" - -#define VALID_FORMAT(f) ( ((f) <= MESA_FORMAT_RGBA_DXT5 \ - || ((f) >= MESA_FORMAT_RGBA_FLOAT32 && \ - (f) <= MESA_FORMAT_INTENSITY_FLOAT16)) \ - && tx_table[f].flag ) - -#define _ASSIGN(entry, format) \ - [ MESA_FORMAT_ ## entry ] = { format, 0, 1} - -/* - * Note that the _REV formats are the same as the non-REV formats. This is - * because the REV and non-REV formats are identical as a byte string, but - * differ when accessed as 16-bit or 32-bit words depending on the endianness of - * the host. Since the textures are transferred to the R600 as a byte string - * (i.e. without any byte-swapping), the R600 sees the REV and non-REV formats - * identically. -- paulus - */ - -static const struct tx_table { - GLuint format, filter, flag; -} tx_table[] = { - /* *INDENT-OFF* */ -#ifdef MESA_LITTLE_ENDIAN - _ASSIGN(RGBA8888, R600_EASY_TX_FORMAT(Y, Z, W, X, W8Z8Y8X8)), - _ASSIGN(RGBA8888_REV, R600_EASY_TX_FORMAT(Z, Y, X, W, W8Z8Y8X8)), - _ASSIGN(ARGB8888, R600_EASY_TX_FORMAT(X, Y, Z, W, W8Z8Y8X8)), - _ASSIGN(ARGB8888_REV, R600_EASY_TX_FORMAT(W, Z, Y, X, W8Z8Y8X8)), -#else - _ASSIGN(RGBA8888, R600_EASY_TX_FORMAT(Z, Y, X, W, W8Z8Y8X8)), - _ASSIGN(RGBA8888_REV, R600_EASY_TX_FORMAT(Y, Z, W, X, W8Z8Y8X8)), - _ASSIGN(ARGB8888, R600_EASY_TX_FORMAT(W, Z, Y, X, W8Z8Y8X8)), - _ASSIGN(ARGB8888_REV, R600_EASY_TX_FORMAT(X, Y, Z, W, W8Z8Y8X8)), -#endif - _ASSIGN(RGB888, R600_EASY_TX_FORMAT(X, Y, Z, ONE, W8Z8Y8X8)), - _ASSIGN(RGB565, R600_EASY_TX_FORMAT(X, Y, Z, ONE, Z5Y6X5)), - _ASSIGN(RGB565_REV, R600_EASY_TX_FORMAT(X, Y, Z, ONE, Z5Y6X5)), - _ASSIGN(ARGB4444, R600_EASY_TX_FORMAT(X, Y, Z, W, W4Z4Y4X4)), - _ASSIGN(ARGB4444_REV, R600_EASY_TX_FORMAT(X, Y, Z, W, W4Z4Y4X4)), - _ASSIGN(ARGB1555, R600_EASY_TX_FORMAT(X, Y, Z, W, W1Z5Y5X5)), - _ASSIGN(ARGB1555_REV, R600_EASY_TX_FORMAT(X, Y, Z, W, W1Z5Y5X5)), - _ASSIGN(AL88, R600_EASY_TX_FORMAT(X, X, X, Y, Y8X8)), - _ASSIGN(AL88_REV, R600_EASY_TX_FORMAT(X, X, X, Y, Y8X8)), - _ASSIGN(RGB332, R600_EASY_TX_FORMAT(X, Y, Z, ONE, Z3Y3X2)), - _ASSIGN(A8, R600_EASY_TX_FORMAT(ZERO, ZERO, ZERO, X, X8)), - _ASSIGN(L8, R600_EASY_TX_FORMAT(X, X, X, ONE, X8)), - _ASSIGN(I8, R600_EASY_TX_FORMAT(X, X, X, X, X8)), - _ASSIGN(CI8, R600_EASY_TX_FORMAT(X, X, X, X, X8)), - _ASSIGN(YCBCR, R600_EASY_TX_FORMAT(X, Y, Z, ONE, G8R8_G8B8) | R600_TX_FORMAT_YUV_MODE), - _ASSIGN(YCBCR_REV, R600_EASY_TX_FORMAT(X, Y, Z, ONE, G8R8_G8B8) | R600_TX_FORMAT_YUV_MODE), - _ASSIGN(RGB_DXT1, R600_EASY_TX_FORMAT(X, Y, Z, ONE, DXT1)), - _ASSIGN(RGBA_DXT1, R600_EASY_TX_FORMAT(X, Y, Z, W, DXT1)), - _ASSIGN(RGBA_DXT3, R600_EASY_TX_FORMAT(X, Y, Z, W, DXT3)), - _ASSIGN(RGBA_DXT5, R600_EASY_TX_FORMAT(Y, Z, W, X, DXT5)), - _ASSIGN(RGBA_FLOAT32, R600_EASY_TX_FORMAT(Z, Y, X, W, FL_R32G32B32A32)), - _ASSIGN(RGBA_FLOAT16, R600_EASY_TX_FORMAT(Z, Y, X, W, FL_R16G16B16A16)), - _ASSIGN(RGB_FLOAT32, 0xffffffff), - _ASSIGN(RGB_FLOAT16, 0xffffffff), - _ASSIGN(ALPHA_FLOAT32, R600_EASY_TX_FORMAT(ZERO, ZERO, ZERO, X, FL_I32)), - _ASSIGN(ALPHA_FLOAT16, R600_EASY_TX_FORMAT(ZERO, ZERO, ZERO, X, FL_I16)), - _ASSIGN(LUMINANCE_FLOAT32, R600_EASY_TX_FORMAT(X, X, X, ONE, FL_I32)), - _ASSIGN(LUMINANCE_FLOAT16, R600_EASY_TX_FORMAT(X, X, X, ONE, FL_I16)), - _ASSIGN(LUMINANCE_ALPHA_FLOAT32, R600_EASY_TX_FORMAT(X, X, X, Y, FL_I32A32)), - _ASSIGN(LUMINANCE_ALPHA_FLOAT16, R600_EASY_TX_FORMAT(X, X, X, Y, FL_I16A16)), - _ASSIGN(INTENSITY_FLOAT32, R600_EASY_TX_FORMAT(X, X, X, X, FL_I32)), - _ASSIGN(INTENSITY_FLOAT16, R600_EASY_TX_FORMAT(X, X, X, X, FL_I16)), - _ASSIGN(Z16, R600_EASY_TX_FORMAT(X, X, X, X, X16)), - _ASSIGN(Z24_S8, R600_EASY_TX_FORMAT(X, X, X, X, X24_Y8)), - _ASSIGN(Z32, R600_EASY_TX_FORMAT(X, X, X, X, X32)), - /* *INDENT-ON* */ -}; - -#undef _ASSIGN - -void r600SetDepthTexMode(struct gl_texture_object *tObj) -{ - static const GLuint formats[3][3] = { - { - R600_EASY_TX_FORMAT(X, X, X, ONE, X16), - R600_EASY_TX_FORMAT(X, X, X, X, X16), - R600_EASY_TX_FORMAT(ZERO, ZERO, ZERO, X, X16), - }, - { - R600_EASY_TX_FORMAT(X, X, X, ONE, X24_Y8), - R600_EASY_TX_FORMAT(X, X, X, X, X24_Y8), - R600_EASY_TX_FORMAT(ZERO, ZERO, ZERO, X, X24_Y8), - }, - { - R600_EASY_TX_FORMAT(X, X, X, ONE, X32), - R600_EASY_TX_FORMAT(X, X, X, X, X32), - R600_EASY_TX_FORMAT(ZERO, ZERO, ZERO, X, X32), - }, - }; - const GLuint *format; - radeonTexObjPtr t; - - if (!tObj) - return; - - t = radeon_tex_obj(tObj); - - switch (tObj->Image[0][tObj->BaseLevel]->TexFormat->MesaFormat) { - case MESA_FORMAT_Z16: - format = formats[0]; - break; - case MESA_FORMAT_Z24_S8: - format = formats[1]; - break; - case MESA_FORMAT_Z32: - format = formats[2]; - break; - default: - /* Error...which should have already been caught by higher - * levels of Mesa. - */ - ASSERT(0); - return; - } - - switch (tObj->DepthMode) { - case GL_LUMINANCE: - t->pp_txformat = format[0]; - break; - case GL_INTENSITY: - t->pp_txformat = format[1]; - break; - case GL_ALPHA: - t->pp_txformat = format[2]; - break; - default: - /* Error...which should have already been caught by higher - * levels of Mesa. - */ - ASSERT(0); - return; - } -} - - -/** - * Compute the cached hardware register values for the given texture object. - * - * \param rmesa Context pointer - * \param t the r600 texture object - */ -static void setup_hardware_state(r600ContextPtr rmesa, radeonTexObj *t) -{ - const struct gl_texture_image *firstImage; - int firstlevel = t->mt ? t->mt->firstLevel : 0; - - firstImage = t->base.Image[0][firstlevel]; - - if (!t->image_override - && VALID_FORMAT(firstImage->TexFormat->MesaFormat)) { - if (firstImage->TexFormat->BaseFormat == GL_DEPTH_COMPONENT) { - r600SetDepthTexMode(&t->base); - } else { - t->pp_txformat = tx_table[firstImage->TexFormat->MesaFormat].format; - } - - t->pp_txfilter |= tx_table[firstImage->TexFormat->MesaFormat].filter; - } else if (!t->image_override) { - _mesa_problem(NULL, "unexpected texture format in %s", - __FUNCTION__); - return; - } - - if (t->image_override && t->bo) - return; - - t->pp_txsize = (((firstImage->Width - 1) << R600_TX_WIDTHMASK_SHIFT) - | ((firstImage->Height - 1) << R600_TX_HEIGHTMASK_SHIFT) - | ((firstImage->DepthLog2) << R600_TX_DEPTHMASK_SHIFT) - | ((t->mt->lastLevel - t->mt->firstLevel) << R600_TX_MAX_MIP_LEVEL_SHIFT)); - - t->tile_bits = 0; - - if (t->base.Target == GL_TEXTURE_CUBE_MAP) - t->pp_txformat |= R600_TX_FORMAT_CUBIC_MAP; - if (t->base.Target == GL_TEXTURE_3D) - t->pp_txformat |= R600_TX_FORMAT_3D; - - - if (t->base.Target == GL_TEXTURE_RECTANGLE_NV) { - unsigned int align = (64 / t->mt->bpp) - 1; - t->pp_txsize |= R600_TX_SIZE_TXPITCH_EN; - if (!t->image_override) - t->pp_txpitch = ((firstImage->Width + align) & ~align) - 1; - } - -} - -/** - * Ensure the given texture is ready for rendering. - * - * Mostly this means populating the texture object's mipmap tree. - */ -static GLboolean r600_validate_texture(GLcontext * ctx, struct gl_texture_object *texObj) -{ - r600ContextPtr rmesa = R600_CONTEXT(ctx); - radeonTexObj *t = radeon_tex_obj(texObj); - - if (!radeon_validate_texture_miptree(ctx, texObj)) - return GL_FALSE; - - /* Configure the hardware registers (more precisely, the cached version - * of the hardware registers). */ - setup_hardware_state(rmesa, t); - - t->validated = GL_TRUE; - return GL_TRUE; -} - -/** - * Ensure all enabled and complete textures are uploaded along with any buffers being used. - */ -GLboolean r600ValidateBuffers(GLcontext * ctx) -{ - r600ContextPtr rmesa = R600_CONTEXT(ctx); - struct radeon_renderbuffer *rrb; - int i; - - radeon_validate_reset_bos(&rmesa->radeon); - - rrb = radeon_get_colorbuffer(&rmesa->radeon); - /* color buffer */ - if (rrb && rrb->bo) { - radeon_validate_bo(&rmesa->radeon, rrb->bo, - 0, RADEON_GEM_DOMAIN_VRAM); - } - - /* depth buffer */ - rrb = radeon_get_depthbuffer(&rmesa->radeon); - if (rrb && rrb->bo) { - radeon_validate_bo(&rmesa->radeon, rrb->bo, - 0, RADEON_GEM_DOMAIN_VRAM); - } - - for (i = 0; i < ctx->Const.MaxTextureImageUnits; ++i) { - radeonTexObj *t; - - if (!ctx->Texture.Unit[i]._ReallyEnabled) - continue; - - if (!r600_validate_texture(ctx, ctx->Texture.Unit[i]._Current)) { - _mesa_warning(ctx, - "failed to validate texture for unit %d.\n", - i); - } - t = radeon_tex_obj(ctx->Texture.Unit[i]._Current); - if (t->image_override && t->bo) - radeon_validate_bo(&rmesa->radeon, t->bo, - RADEON_GEM_DOMAIN_GTT | RADEON_GEM_DOMAIN_VRAM, 0); - - else if (t->mt->bo) - radeon_validate_bo(&rmesa->radeon, t->mt->bo, - RADEON_GEM_DOMAIN_GTT | RADEON_GEM_DOMAIN_VRAM, 0); - } - if (rmesa->radeon.dma.current) - radeon_validate_bo(&rmesa->radeon, rmesa->radeon.dma.current, RADEON_GEM_DOMAIN_GTT, 0); - - return radeon_revalidate_bos(ctx); -} - -void r600SetTexOffset(__DRIcontext * pDRICtx, GLint texname, - unsigned long long offset, GLint depth, GLuint pitch) -{ - r600ContextPtr rmesa = pDRICtx->driverPrivate; - struct gl_texture_object *tObj = - _mesa_lookup_texture(rmesa->radeon.glCtx, texname); - radeonTexObjPtr t = radeon_tex_obj(tObj); - uint32_t pitch_val; - - if (!tObj) - return; - - t->image_override = GL_TRUE; - - if (!offset) - return; - - t->bo = NULL; - t->override_offset = offset; - t->pp_txpitch &= (1 << 13) -1; - pitch_val = pitch; - - switch (depth) { - case 32: - t->pp_txformat = R600_EASY_TX_FORMAT(X, Y, Z, W, W8Z8Y8X8); - t->pp_txfilter |= tx_table[2].filter; - pitch_val /= 4; - break; - case 24: - default: - t->pp_txformat = R600_EASY_TX_FORMAT(X, Y, Z, ONE, W8Z8Y8X8); - t->pp_txfilter |= tx_table[4].filter; - pitch_val /= 4; - break; - case 16: - t->pp_txformat = R600_EASY_TX_FORMAT(X, Y, Z, ONE, Z5Y6X5); - t->pp_txfilter |= tx_table[5].filter; - pitch_val /= 2; - break; - } - pitch_val--; - - t->pp_txpitch |= pitch_val; -} - -void r600SetTexBuffer2(__DRIcontext *pDRICtx, GLint target, GLint glx_texture_format, __DRIdrawable *dPriv) -{ - struct gl_texture_unit *texUnit; - struct gl_texture_object *texObj; - struct gl_texture_image *texImage; - struct radeon_renderbuffer *rb; - radeon_texture_image *rImage; - radeonContextPtr radeon; - r600ContextPtr rmesa; - struct radeon_framebuffer *rfb; - radeonTexObjPtr t; - uint32_t pitch_val; - uint32_t internalFormat, type, format; - - type = GL_BGRA; - format = GL_UNSIGNED_BYTE; - internalFormat = (glx_texture_format == GLX_TEXTURE_FORMAT_RGB_EXT ? 3 : 4); - - radeon = pDRICtx->driverPrivate; - rmesa = pDRICtx->driverPrivate; - - rfb = dPriv->driverPrivate; - texUnit = &radeon->glCtx->Texture.Unit[radeon->glCtx->Texture.CurrentUnit]; - texObj = _mesa_select_tex_object(radeon->glCtx, texUnit, target); - texImage = _mesa_get_tex_image(radeon->glCtx, texObj, target, 0); - - rImage = get_radeon_texture_image(texImage); - t = radeon_tex_obj(texObj); - if (t == NULL) { - return; - } - - radeon_update_renderbuffers(pDRICtx, dPriv); - /* back & depth buffer are useless free them right away */ - rb = (void*)rfb->base.Attachment[BUFFER_DEPTH].Renderbuffer; - if (rb && rb->bo) { - radeon_bo_unref(rb->bo); - rb->bo = NULL; - } - rb = (void*)rfb->base.Attachment[BUFFER_BACK_LEFT].Renderbuffer; - if (rb && rb->bo) { - radeon_bo_unref(rb->bo); - rb->bo = NULL; - } - rb = rfb->color_rb[0]; - if (rb->bo == NULL) { - /* Failed to BO for the buffer */ - return; - } - - _mesa_lock_texture(radeon->glCtx, texObj); - if (t->bo) { - radeon_bo_unref(t->bo); - t->bo = NULL; - } - if (rImage->bo) { - radeon_bo_unref(rImage->bo); - rImage->bo = NULL; - } - if (t->mt) { - radeon_miptree_unreference(t->mt); - t->mt = NULL; - } - if (rImage->mt) { - radeon_miptree_unreference(rImage->mt); - rImage->mt = NULL; - } - fprintf(stderr,"settexbuf %dx%d@%d %d targ %x format %x\n", rb->width, rb->height, rb->cpp, rb->pitch, target, format); - _mesa_init_teximage_fields(radeon->glCtx, target, texImage, - rb->width, rb->height, 1, 0, rb->cpp); - texImage->RowStride = rb->pitch / rb->cpp; - texImage->TexFormat = radeonChooseTextureFormat(radeon->glCtx, - internalFormat, - type, format, 0); - rImage->bo = rb->bo; - radeon_bo_ref(rImage->bo); - t->bo = rb->bo; - radeon_bo_ref(t->bo); - t->tile_bits = 0; - t->image_override = GL_TRUE; - t->override_offset = 0; - t->pp_txpitch &= (1 << 13) -1; - pitch_val = rb->pitch; - switch (rb->cpp) { - case 4: - t->pp_txformat = R600_EASY_TX_FORMAT(X, Y, Z, W, W8Z8Y8X8); - t->pp_txfilter |= tx_table[2].filter; - pitch_val /= 4; - break; - case 3: - default: - t->pp_txformat = R600_EASY_TX_FORMAT(X, Y, Z, ONE, W8Z8Y8X8); - t->pp_txfilter |= tx_table[4].filter; - pitch_val /= 4; - break; - case 2: - t->pp_txformat = R600_EASY_TX_FORMAT(X, Y, Z, ONE, Z5Y6X5); - t->pp_txfilter |= tx_table[5].filter; - pitch_val /= 2; - break; - } - pitch_val--; - t->pp_txsize = ((rb->width - 1) << R600_TX_WIDTHMASK_SHIFT) | - ((rb->height - 1) << R600_TX_HEIGHTMASK_SHIFT); - t->pp_txsize |= R600_TX_SIZE_TXPITCH_EN; - t->pp_txpitch |= pitch_val; - - t->validated = GL_TRUE; - _mesa_unlock_texture(radeon->glCtx, texObj); - return; -} - -void r600SetTexBuffer(__DRIcontext *pDRICtx, GLint target, __DRIdrawable *dPriv) -{ - r600SetTexBuffer2(pDRICtx, target, GLX_TEXTURE_FORMAT_RGBA_EXT, dPriv); -} diff --git a/src/mesa/drivers/dri/r600/r600_vertprog.c b/src/mesa/drivers/dri/r600/r600_vertprog.c deleted file mode 100644 index 8e4506403ff..00000000000 --- a/src/mesa/drivers/dri/r600/r600_vertprog.c +++ /dev/null @@ -1,1479 +0,0 @@ -/************************************************************************** - -Copyright (C) 2005 Aapo Tahkola <[email protected]> -Copyright (C) 2008 Oliver McFadden <[email protected]> - -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 -on the rights to use, copy, modify, merge, publish, distribute, sub -license, 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 NON-INFRINGEMENT. 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. - -**************************************************************************/ - -/* Radeon R5xx Acceleration, Revision 1.2 */ - -#include "main/glheader.h" -#include "main/macros.h" -#include "main/enums.h" -#include "shader/program.h" -#include "shader/prog_instruction.h" -#include "shader/prog_parameter.h" -#include "shader/prog_statevars.h" -#include "tnl/tnl.h" - -#include "r600_context.h" - -/* TODO: Get rid of t_src_class call */ -#define CMP_SRCS(a, b) ((a.RelAddr != b.RelAddr) || (a.Index != b.Index && \ - ((t_src_class(a.File) == PVS_SRC_REG_CONSTANT && \ - t_src_class(b.File) == PVS_SRC_REG_CONSTANT) || \ - (t_src_class(a.File) == PVS_SRC_REG_INPUT && \ - t_src_class(b.File) == PVS_SRC_REG_INPUT)))) \ - -/* - * Take an already-setup and valid source then swizzle it appropriately to - * obtain a constant ZERO or ONE source. - */ -#define __CONST(x, y) \ - (PVS_SRC_OPERAND(t_src_index(vp, &src[x]), \ - t_swizzle(y), \ - t_swizzle(y), \ - t_swizzle(y), \ - t_swizzle(y), \ - t_src_class(src[x].File), \ - VSF_FLAG_NONE) | (src[x].RelAddr << 4)) - -#define FREE_TEMPS() \ - do { \ - int u_temp_used = (VSF_MAX_FRAGMENT_TEMPS - 1) - u_temp_i; \ - if((vp->num_temporaries + u_temp_used) > VSF_MAX_FRAGMENT_TEMPS) { \ - WARN_ONCE("Ran out of temps, num temps %d, us %d\n", vp->num_temporaries, u_temp_used); \ - vp->native = GL_FALSE; \ - } \ - u_temp_i=VSF_MAX_FRAGMENT_TEMPS-1; \ - } while (0) - -int r600VertexProgUpdateParams(GLcontext * ctx, - struct r600_vertex_program_cont *vp, float *dst) -{ - int pi; - struct gl_vertex_program *mesa_vp = &vp->mesa_program; - float *dst_o = dst; - struct gl_program_parameter_list *paramList; - - if (mesa_vp->IsNVProgram) { - _mesa_load_tracked_matrices(ctx); - - for (pi = 0; pi < MAX_NV_VERTEX_PROGRAM_PARAMS; pi++) { - *dst++ = ctx->VertexProgram.Parameters[pi][0]; - *dst++ = ctx->VertexProgram.Parameters[pi][1]; - *dst++ = ctx->VertexProgram.Parameters[pi][2]; - *dst++ = ctx->VertexProgram.Parameters[pi][3]; - } - return dst - dst_o; - } - - assert(mesa_vp->Base.Parameters); - _mesa_load_state_parameters(ctx, mesa_vp->Base.Parameters); - - if (mesa_vp->Base.Parameters->NumParameters * 4 > - VSF_MAX_FRAGMENT_LENGTH) { - fprintf(stderr, "%s:Params exhausted\n", __FUNCTION__); - _mesa_exit(-1); - } - - paramList = mesa_vp->Base.Parameters; - for (pi = 0; pi < paramList->NumParameters; pi++) { - switch (paramList->Parameters[pi].Type) { - case PROGRAM_STATE_VAR: - case PROGRAM_NAMED_PARAM: - //fprintf(stderr, "%s", vp->Parameters->Parameters[pi].Name); - case PROGRAM_CONSTANT: - *dst++ = paramList->ParameterValues[pi][0]; - *dst++ = paramList->ParameterValues[pi][1]; - *dst++ = paramList->ParameterValues[pi][2]; - *dst++ = paramList->ParameterValues[pi][3]; - break; - default: - _mesa_problem(NULL, "Bad param type in %s", - __FUNCTION__); - } - - } - - return dst - dst_o; -} - -static unsigned long t_dst_mask(GLuint mask) -{ - /* WRITEMASK_* is equivalent to VSF_FLAG_* */ - return mask & VSF_FLAG_ALL; -} - -static unsigned long t_dst_class(gl_register_file file) -{ - - switch (file) { - case PROGRAM_TEMPORARY: - return PVS_DST_REG_TEMPORARY; - case PROGRAM_OUTPUT: - return PVS_DST_REG_OUT; - case PROGRAM_ADDRESS: - return PVS_DST_REG_A0; - /* - case PROGRAM_INPUT: - case PROGRAM_LOCAL_PARAM: - case PROGRAM_ENV_PARAM: - case PROGRAM_NAMED_PARAM: - case PROGRAM_STATE_VAR: - case PROGRAM_WRITE_ONLY: - case PROGRAM_ADDRESS: - */ - default: - fprintf(stderr, "problem in %s", __FUNCTION__); - _mesa_exit(-1); - return -1; - } -} - -static unsigned long t_dst_index(struct r600_vertex_program *vp, - struct prog_dst_register *dst) -{ - if (dst->File == PROGRAM_OUTPUT) - return vp->outputs[dst->Index]; - - return dst->Index; -} - -static unsigned long t_src_class(gl_register_file file) -{ - switch (file) { - case PROGRAM_TEMPORARY: - return PVS_SRC_REG_TEMPORARY; - case PROGRAM_INPUT: - return PVS_SRC_REG_INPUT; - case PROGRAM_LOCAL_PARAM: - case PROGRAM_ENV_PARAM: - case PROGRAM_NAMED_PARAM: - case PROGRAM_CONSTANT: - case PROGRAM_STATE_VAR: - return PVS_SRC_REG_CONSTANT; - /* - case PROGRAM_OUTPUT: - case PROGRAM_WRITE_ONLY: - case PROGRAM_ADDRESS: - */ - default: - fprintf(stderr, "problem in %s", __FUNCTION__); - _mesa_exit(-1); - return -1; - } -} - -static INLINE unsigned long t_swizzle(GLubyte swizzle) -{ -/* this is in fact a NOP as the Mesa SWIZZLE_* are all identical to VSF_IN_COMPONENT_* */ - return swizzle; -} - -#if 0 -static void vp_dump_inputs(struct r600_vertex_program *vp, char *caller) -{ - int i; - - if (vp == NULL) { - fprintf(stderr, "vp null in call to %s from %s\n", __FUNCTION__, - caller); - return; - } - - fprintf(stderr, "%s:<", caller); - for (i = 0; i < VERT_ATTRIB_MAX; i++) - fprintf(stderr, "%d ", vp->inputs[i]); - fprintf(stderr, ">\n"); - -} -#endif - -static unsigned long t_src_index(struct r600_vertex_program *vp, - struct prog_src_register *src) -{ - int i; - int max_reg = -1; - - if (src->File == PROGRAM_INPUT) { - if (vp->inputs[src->Index] != -1) - return vp->inputs[src->Index]; - - for (i = 0; i < VERT_ATTRIB_MAX; i++) - if (vp->inputs[i] > max_reg) - max_reg = vp->inputs[i]; - - vp->inputs[src->Index] = max_reg + 1; - - //vp_dump_inputs(vp, __FUNCTION__); - - return vp->inputs[src->Index]; - } else { - if (src->Index < 0) { - fprintf(stderr, - "negative offsets for indirect addressing do not work.\n"); - return 0; - } - return src->Index; - } -} - -/* these two functions should probably be merged... */ - -static unsigned long t_src(struct r600_vertex_program *vp, - struct prog_src_register *src) -{ - /* src->NegateBase uses the NEGATE_ flags from program_instruction.h, - * which equal our VSF_FLAGS_ values, so it's safe to just pass it here. - */ - return PVS_SRC_OPERAND(t_src_index(vp, src), - t_swizzle(GET_SWZ(src->Swizzle, 0)), - t_swizzle(GET_SWZ(src->Swizzle, 1)), - t_swizzle(GET_SWZ(src->Swizzle, 2)), - t_swizzle(GET_SWZ(src->Swizzle, 3)), - t_src_class(src->File), - src->NegateBase) | (src->RelAddr << 4); -} - -static unsigned long t_src_scalar(struct r600_vertex_program *vp, - struct prog_src_register *src) -{ - /* src->NegateBase uses the NEGATE_ flags from program_instruction.h, - * which equal our VSF_FLAGS_ values, so it's safe to just pass it here. - */ - return PVS_SRC_OPERAND(t_src_index(vp, src), - t_swizzle(GET_SWZ(src->Swizzle, 0)), - t_swizzle(GET_SWZ(src->Swizzle, 0)), - t_swizzle(GET_SWZ(src->Swizzle, 0)), - t_swizzle(GET_SWZ(src->Swizzle, 0)), - t_src_class(src->File), - src-> - NegateBase ? VSF_FLAG_ALL : VSF_FLAG_NONE) | - (src->RelAddr << 4); -} - -static GLboolean valid_dst(struct r600_vertex_program *vp, - struct prog_dst_register *dst) -{ - if (dst->File == PROGRAM_OUTPUT && vp->outputs[dst->Index] == -1) { - return GL_FALSE; - } else if (dst->File == PROGRAM_ADDRESS) { - assert(dst->Index == 0); - } - - return GL_TRUE; -} - -static GLuint *r600TranslateOpcodeABS(struct r600_vertex_program *vp, - struct prog_instruction *vpi, - GLuint * inst, - struct prog_src_register src[3]) -{ - //MAX RESULT 1.X Y Z W PARAM 0{} {X Y Z W} PARAM 0{X Y Z W } {X Y Z W} neg Xneg Yneg Zneg W - - inst[0] = PVS_OP_DST_OPERAND(VE_MAXIMUM, - GL_FALSE, - GL_FALSE, - t_dst_index(vp, &vpi->DstReg), - t_dst_mask(vpi->DstReg.WriteMask), - t_dst_class(vpi->DstReg.File)); - inst[1] = t_src(vp, &src[0]); - inst[2] = PVS_SRC_OPERAND(t_src_index(vp, &src[0]), - t_swizzle(GET_SWZ(src[0].Swizzle, 0)), - t_swizzle(GET_SWZ(src[0].Swizzle, 1)), - t_swizzle(GET_SWZ(src[0].Swizzle, 2)), - t_swizzle(GET_SWZ(src[0].Swizzle, 3)), - t_src_class(src[0].File), - (!src[0]. - NegateBase) ? VSF_FLAG_ALL : VSF_FLAG_NONE) | - (src[0].RelAddr << 4); - inst[3] = 0; - - return inst; -} - -static GLuint *r600TranslateOpcodeADD(struct r600_vertex_program *vp, - struct prog_instruction *vpi, - GLuint * inst, - struct prog_src_register src[3]) -{ - inst[0] = PVS_OP_DST_OPERAND(VE_ADD, - GL_FALSE, - GL_FALSE, - t_dst_index(vp, &vpi->DstReg), - t_dst_mask(vpi->DstReg.WriteMask), - t_dst_class(vpi->DstReg.File)); - inst[1] = t_src(vp, &src[0]); - inst[2] = t_src(vp, &src[1]); - inst[3] = __CONST(1, SWIZZLE_ZERO); - - return inst; -} - -static GLuint *r600TranslateOpcodeARL(struct r600_vertex_program *vp, - struct prog_instruction *vpi, - GLuint * inst, - struct prog_src_register src[3]) -{ - inst[0] = PVS_OP_DST_OPERAND(VE_FLT2FIX_DX, - GL_FALSE, - GL_FALSE, - t_dst_index(vp, &vpi->DstReg), - t_dst_mask(vpi->DstReg.WriteMask), - t_dst_class(vpi->DstReg.File)); - inst[1] = t_src(vp, &src[0]); - inst[2] = __CONST(0, SWIZZLE_ZERO); - inst[3] = __CONST(0, SWIZZLE_ZERO); - - return inst; -} - -static GLuint *r600TranslateOpcodeDP3(struct r600_vertex_program *vp, - struct prog_instruction *vpi, - GLuint * inst, - struct prog_src_register src[3]) -{ - //DOT RESULT 1.X Y Z W PARAM 0{} {X Y Z ZERO} PARAM 0{} {X Y Z ZERO} - - inst[0] = PVS_OP_DST_OPERAND(VE_DOT_PRODUCT, - GL_FALSE, - GL_FALSE, - t_dst_index(vp, &vpi->DstReg), - t_dst_mask(vpi->DstReg.WriteMask), - t_dst_class(vpi->DstReg.File)); - inst[1] = PVS_SRC_OPERAND(t_src_index(vp, &src[0]), - t_swizzle(GET_SWZ(src[0].Swizzle, 0)), - t_swizzle(GET_SWZ(src[0].Swizzle, 1)), - t_swizzle(GET_SWZ(src[0].Swizzle, 2)), - SWIZZLE_ZERO, - t_src_class(src[0].File), - src[0]. - NegateBase ? VSF_FLAG_XYZ : VSF_FLAG_NONE) | - (src[0].RelAddr << 4); - inst[2] = - PVS_SRC_OPERAND(t_src_index(vp, &src[1]), - t_swizzle(GET_SWZ(src[1].Swizzle, 0)), - t_swizzle(GET_SWZ(src[1].Swizzle, 1)), - t_swizzle(GET_SWZ(src[1].Swizzle, 2)), SWIZZLE_ZERO, - t_src_class(src[1].File), - src[1]. - NegateBase ? VSF_FLAG_XYZ : VSF_FLAG_NONE) | - (src[1].RelAddr << 4); - inst[3] = __CONST(1, SWIZZLE_ZERO); - - return inst; -} - -static GLuint *r600TranslateOpcodeDP4(struct r600_vertex_program *vp, - struct prog_instruction *vpi, - GLuint * inst, - struct prog_src_register src[3]) -{ - inst[0] = PVS_OP_DST_OPERAND(VE_DOT_PRODUCT, - GL_FALSE, - GL_FALSE, - t_dst_index(vp, &vpi->DstReg), - t_dst_mask(vpi->DstReg.WriteMask), - t_dst_class(vpi->DstReg.File)); - inst[1] = t_src(vp, &src[0]); - inst[2] = t_src(vp, &src[1]); - inst[3] = __CONST(1, SWIZZLE_ZERO); - - return inst; -} - -static GLuint *r600TranslateOpcodeDPH(struct r600_vertex_program *vp, - struct prog_instruction *vpi, - GLuint * inst, - struct prog_src_register src[3]) -{ - //DOT RESULT 1.X Y Z W PARAM 0{} {X Y Z ONE} PARAM 0{} {X Y Z W} - inst[0] = PVS_OP_DST_OPERAND(VE_DOT_PRODUCT, - GL_FALSE, - GL_FALSE, - t_dst_index(vp, &vpi->DstReg), - t_dst_mask(vpi->DstReg.WriteMask), - t_dst_class(vpi->DstReg.File)); - inst[1] = PVS_SRC_OPERAND(t_src_index(vp, &src[0]), - t_swizzle(GET_SWZ(src[0].Swizzle, 0)), - t_swizzle(GET_SWZ(src[0].Swizzle, 1)), - t_swizzle(GET_SWZ(src[0].Swizzle, 2)), - PVS_SRC_SELECT_FORCE_1, - t_src_class(src[0].File), - src[0]. - NegateBase ? VSF_FLAG_XYZ : VSF_FLAG_NONE) | - (src[0].RelAddr << 4); - inst[2] = t_src(vp, &src[1]); - inst[3] = __CONST(1, SWIZZLE_ZERO); - - return inst; -} - -static GLuint *r600TranslateOpcodeDST(struct r600_vertex_program *vp, - struct prog_instruction *vpi, - GLuint * inst, - struct prog_src_register src[3]) -{ - inst[0] = PVS_OP_DST_OPERAND(VE_DISTANCE_VECTOR, - GL_FALSE, - GL_FALSE, - t_dst_index(vp, &vpi->DstReg), - t_dst_mask(vpi->DstReg.WriteMask), - t_dst_class(vpi->DstReg.File)); - inst[1] = t_src(vp, &src[0]); - inst[2] = t_src(vp, &src[1]); - inst[3] = __CONST(1, SWIZZLE_ZERO); - - return inst; -} - -static GLuint *r600TranslateOpcodeEX2(struct r600_vertex_program *vp, - struct prog_instruction *vpi, - GLuint * inst, - struct prog_src_register src[3]) -{ - inst[0] = PVS_OP_DST_OPERAND(ME_EXP_BASE2_FULL_DX, - GL_TRUE, - GL_FALSE, - t_dst_index(vp, &vpi->DstReg), - t_dst_mask(vpi->DstReg.WriteMask), - t_dst_class(vpi->DstReg.File)); - inst[1] = t_src_scalar(vp, &src[0]); - inst[2] = __CONST(0, SWIZZLE_ZERO); - inst[3] = __CONST(0, SWIZZLE_ZERO); - - return inst; -} - -static GLuint *r600TranslateOpcodeEXP(struct r600_vertex_program *vp, - struct prog_instruction *vpi, - GLuint * inst, - struct prog_src_register src[3]) -{ - inst[0] = PVS_OP_DST_OPERAND(ME_EXP_BASE2_DX, - GL_TRUE, - GL_FALSE, - t_dst_index(vp, &vpi->DstReg), - t_dst_mask(vpi->DstReg.WriteMask), - t_dst_class(vpi->DstReg.File)); - inst[1] = t_src_scalar(vp, &src[0]); - inst[2] = __CONST(0, SWIZZLE_ZERO); - inst[3] = __CONST(0, SWIZZLE_ZERO); - - return inst; -} - -static GLuint *r600TranslateOpcodeFLR(struct r600_vertex_program *vp, - struct prog_instruction *vpi, - GLuint * inst, - struct prog_src_register src[3], - int *u_temp_i) -{ - /* FRC TMP 0.X Y Z W PARAM 0{} {X Y Z W} - ADD RESULT 1.X Y Z W PARAM 0{} {X Y Z W} TMP 0{X Y Z W } {X Y Z W} neg Xneg Yneg Zneg W */ - - inst[0] = PVS_OP_DST_OPERAND(VE_FRACTION, - GL_FALSE, - GL_FALSE, - *u_temp_i, - t_dst_mask(vpi->DstReg.WriteMask), - PVS_DST_REG_TEMPORARY); - inst[1] = t_src(vp, &src[0]); - inst[2] = __CONST(0, SWIZZLE_ZERO); - inst[3] = __CONST(0, SWIZZLE_ZERO); - inst += 4; - - inst[0] = PVS_OP_DST_OPERAND(VE_ADD, - GL_FALSE, - GL_FALSE, - t_dst_index(vp, &vpi->DstReg), - t_dst_mask(vpi->DstReg.WriteMask), - t_dst_class(vpi->DstReg.File)); - inst[1] = t_src(vp, &src[0]); - inst[2] = PVS_SRC_OPERAND(*u_temp_i, - PVS_SRC_SELECT_X, - PVS_SRC_SELECT_Y, - PVS_SRC_SELECT_Z, - PVS_SRC_SELECT_W, PVS_SRC_REG_TEMPORARY, - /* Not 100% sure about this */ - (!src[0]. - NegateBase) ? VSF_FLAG_ALL : VSF_FLAG_NONE - /*VSF_FLAG_ALL */ ); - inst[3] = __CONST(0, SWIZZLE_ZERO); - (*u_temp_i)--; - - return inst; -} - -static GLuint *r600TranslateOpcodeFRC(struct r600_vertex_program *vp, - struct prog_instruction *vpi, - GLuint * inst, - struct prog_src_register src[3]) -{ - inst[0] = PVS_OP_DST_OPERAND(VE_FRACTION, - GL_FALSE, - GL_FALSE, - t_dst_index(vp, &vpi->DstReg), - t_dst_mask(vpi->DstReg.WriteMask), - t_dst_class(vpi->DstReg.File)); - inst[1] = t_src(vp, &src[0]); - inst[2] = __CONST(0, SWIZZLE_ZERO); - inst[3] = __CONST(0, SWIZZLE_ZERO); - - return inst; -} - -static GLuint *r600TranslateOpcodeLG2(struct r600_vertex_program *vp, - struct prog_instruction *vpi, - GLuint * inst, - struct prog_src_register src[3]) -{ - // LG2 RESULT 1.X Y Z W PARAM 0{} {X X X X} - - inst[0] = PVS_OP_DST_OPERAND(ME_LOG_BASE2_FULL_DX, - GL_TRUE, - GL_FALSE, - t_dst_index(vp, &vpi->DstReg), - t_dst_mask(vpi->DstReg.WriteMask), - t_dst_class(vpi->DstReg.File)); - inst[1] = PVS_SRC_OPERAND(t_src_index(vp, &src[0]), - t_swizzle(GET_SWZ(src[0].Swizzle, 0)), - t_swizzle(GET_SWZ(src[0].Swizzle, 0)), - t_swizzle(GET_SWZ(src[0].Swizzle, 0)), - t_swizzle(GET_SWZ(src[0].Swizzle, 0)), - t_src_class(src[0].File), - src[0]. - NegateBase ? VSF_FLAG_ALL : VSF_FLAG_NONE) | - (src[0].RelAddr << 4); - inst[2] = __CONST(0, SWIZZLE_ZERO); - inst[3] = __CONST(0, SWIZZLE_ZERO); - - return inst; -} - -static GLuint *r600TranslateOpcodeLIT(struct r600_vertex_program *vp, - struct prog_instruction *vpi, - GLuint * inst, - struct prog_src_register src[3]) -{ - //LIT TMP 1.Y Z TMP 1{} {X W Z Y} TMP 1{} {Y W Z X} TMP 1{} {Y X Z W} - - inst[0] = PVS_OP_DST_OPERAND(ME_LIGHT_COEFF_DX, - GL_TRUE, - GL_FALSE, - t_dst_index(vp, &vpi->DstReg), - t_dst_mask(vpi->DstReg.WriteMask), - t_dst_class(vpi->DstReg.File)); - /* NOTE: Users swizzling might not work. */ - inst[1] = PVS_SRC_OPERAND(t_src_index(vp, &src[0]), t_swizzle(GET_SWZ(src[0].Swizzle, 0)), // X - t_swizzle(GET_SWZ(src[0].Swizzle, 3)), // W - PVS_SRC_SELECT_FORCE_0, // Z - t_swizzle(GET_SWZ(src[0].Swizzle, 1)), // Y - t_src_class(src[0].File), - src[0]. - NegateBase ? VSF_FLAG_ALL : VSF_FLAG_NONE) | - (src[0].RelAddr << 4); - inst[2] = PVS_SRC_OPERAND(t_src_index(vp, &src[0]), t_swizzle(GET_SWZ(src[0].Swizzle, 1)), // Y - t_swizzle(GET_SWZ(src[0].Swizzle, 3)), // W - PVS_SRC_SELECT_FORCE_0, // Z - t_swizzle(GET_SWZ(src[0].Swizzle, 0)), // X - t_src_class(src[0].File), - src[0]. - NegateBase ? VSF_FLAG_ALL : VSF_FLAG_NONE) | - (src[0].RelAddr << 4); - inst[3] = PVS_SRC_OPERAND(t_src_index(vp, &src[0]), t_swizzle(GET_SWZ(src[0].Swizzle, 1)), // Y - t_swizzle(GET_SWZ(src[0].Swizzle, 0)), // X - PVS_SRC_SELECT_FORCE_0, // Z - t_swizzle(GET_SWZ(src[0].Swizzle, 3)), // W - t_src_class(src[0].File), - src[0]. - NegateBase ? VSF_FLAG_ALL : VSF_FLAG_NONE) | - (src[0].RelAddr << 4); - - return inst; -} - -static GLuint *r600TranslateOpcodeLOG(struct r600_vertex_program *vp, - struct prog_instruction *vpi, - GLuint * inst, - struct prog_src_register src[3]) -{ - inst[0] = PVS_OP_DST_OPERAND(ME_LOG_BASE2_DX, - GL_TRUE, - GL_FALSE, - t_dst_index(vp, &vpi->DstReg), - t_dst_mask(vpi->DstReg.WriteMask), - t_dst_class(vpi->DstReg.File)); - inst[1] = t_src_scalar(vp, &src[0]); - inst[2] = __CONST(0, SWIZZLE_ZERO); - inst[3] = __CONST(0, SWIZZLE_ZERO); - - return inst; -} - -static GLuint *r600TranslateOpcodeMAD(struct r600_vertex_program *vp, - struct prog_instruction *vpi, - GLuint * inst, - struct prog_src_register src[3]) -{ - inst[0] = PVS_OP_DST_OPERAND(PVS_MACRO_OP_2CLK_MADD, - GL_FALSE, - GL_TRUE, - t_dst_index(vp, &vpi->DstReg), - t_dst_mask(vpi->DstReg.WriteMask), - t_dst_class(vpi->DstReg.File)); - inst[1] = t_src(vp, &src[0]); - inst[2] = t_src(vp, &src[1]); - inst[3] = t_src(vp, &src[2]); - - return inst; -} - -static GLuint *r600TranslateOpcodeMAX(struct r600_vertex_program *vp, - struct prog_instruction *vpi, - GLuint * inst, - struct prog_src_register src[3]) -{ - inst[0] = PVS_OP_DST_OPERAND(VE_MAXIMUM, - GL_FALSE, - GL_FALSE, - t_dst_index(vp, &vpi->DstReg), - t_dst_mask(vpi->DstReg.WriteMask), - t_dst_class(vpi->DstReg.File)); - inst[1] = t_src(vp, &src[0]); - inst[2] = t_src(vp, &src[1]); - inst[3] = __CONST(1, SWIZZLE_ZERO); - - return inst; -} - -static GLuint *r600TranslateOpcodeMIN(struct r600_vertex_program *vp, - struct prog_instruction *vpi, - GLuint * inst, - struct prog_src_register src[3]) -{ - inst[0] = PVS_OP_DST_OPERAND(VE_MINIMUM, - GL_FALSE, - GL_FALSE, - t_dst_index(vp, &vpi->DstReg), - t_dst_mask(vpi->DstReg.WriteMask), - t_dst_class(vpi->DstReg.File)); - inst[1] = t_src(vp, &src[0]); - inst[2] = t_src(vp, &src[1]); - inst[3] = __CONST(1, SWIZZLE_ZERO); - - return inst; -} - -static GLuint *r600TranslateOpcodeMOV(struct r600_vertex_program *vp, - struct prog_instruction *vpi, - GLuint * inst, - struct prog_src_register src[3]) -{ - //ADD RESULT 1.X Y Z W PARAM 0{} {X Y Z W} PARAM 0{} {ZERO ZERO ZERO ZERO} - - inst[0] = PVS_OP_DST_OPERAND(VE_ADD, - GL_FALSE, - GL_FALSE, - t_dst_index(vp, &vpi->DstReg), - t_dst_mask(vpi->DstReg.WriteMask), - t_dst_class(vpi->DstReg.File)); - inst[1] = t_src(vp, &src[0]); - inst[2] = __CONST(0, SWIZZLE_ZERO); - inst[3] = __CONST(0, SWIZZLE_ZERO); - - return inst; -} - -static GLuint *r600TranslateOpcodeMUL(struct r600_vertex_program *vp, - struct prog_instruction *vpi, - GLuint * inst, - struct prog_src_register src[3]) -{ - inst[0] = PVS_OP_DST_OPERAND(VE_MULTIPLY, - GL_FALSE, - GL_FALSE, - t_dst_index(vp, &vpi->DstReg), - t_dst_mask(vpi->DstReg.WriteMask), - t_dst_class(vpi->DstReg.File)); - inst[1] = t_src(vp, &src[0]); - inst[2] = t_src(vp, &src[1]); - inst[3] = __CONST(1, SWIZZLE_ZERO); - - return inst; -} - -static GLuint *r600TranslateOpcodePOW(struct r600_vertex_program *vp, - struct prog_instruction *vpi, - GLuint * inst, - struct prog_src_register src[3]) -{ - inst[0] = PVS_OP_DST_OPERAND(ME_POWER_FUNC_FF, - GL_TRUE, - GL_FALSE, - t_dst_index(vp, &vpi->DstReg), - t_dst_mask(vpi->DstReg.WriteMask), - t_dst_class(vpi->DstReg.File)); - inst[1] = t_src_scalar(vp, &src[0]); - inst[2] = __CONST(0, SWIZZLE_ZERO); - inst[3] = t_src_scalar(vp, &src[1]); - - return inst; -} - -static GLuint *r600TranslateOpcodeRCP(struct r600_vertex_program *vp, - struct prog_instruction *vpi, - GLuint * inst, - struct prog_src_register src[3]) -{ - inst[0] = PVS_OP_DST_OPERAND(ME_RECIP_DX, - GL_TRUE, - GL_FALSE, - t_dst_index(vp, &vpi->DstReg), - t_dst_mask(vpi->DstReg.WriteMask), - t_dst_class(vpi->DstReg.File)); - inst[1] = t_src_scalar(vp, &src[0]); - inst[2] = __CONST(0, SWIZZLE_ZERO); - inst[3] = __CONST(0, SWIZZLE_ZERO); - - return inst; -} - -static GLuint *r600TranslateOpcodeRSQ(struct r600_vertex_program *vp, - struct prog_instruction *vpi, - GLuint * inst, - struct prog_src_register src[3]) -{ - inst[0] = PVS_OP_DST_OPERAND(ME_RECIP_SQRT_DX, - GL_TRUE, - GL_FALSE, - t_dst_index(vp, &vpi->DstReg), - t_dst_mask(vpi->DstReg.WriteMask), - t_dst_class(vpi->DstReg.File)); - inst[1] = t_src_scalar(vp, &src[0]); - inst[2] = __CONST(0, SWIZZLE_ZERO); - inst[3] = __CONST(0, SWIZZLE_ZERO); - - return inst; -} - -static GLuint *r600TranslateOpcodeSGE(struct r600_vertex_program *vp, - struct prog_instruction *vpi, - GLuint * inst, - struct prog_src_register src[3]) -{ - inst[0] = PVS_OP_DST_OPERAND(VE_SET_GREATER_THAN_EQUAL, - GL_FALSE, - GL_FALSE, - t_dst_index(vp, &vpi->DstReg), - t_dst_mask(vpi->DstReg.WriteMask), - t_dst_class(vpi->DstReg.File)); - inst[1] = t_src(vp, &src[0]); - inst[2] = t_src(vp, &src[1]); - inst[3] = __CONST(1, SWIZZLE_ZERO); - - return inst; -} - -static GLuint *r600TranslateOpcodeSLT(struct r600_vertex_program *vp, - struct prog_instruction *vpi, - GLuint * inst, - struct prog_src_register src[3]) -{ - inst[0] = PVS_OP_DST_OPERAND(VE_SET_LESS_THAN, - GL_FALSE, - GL_FALSE, - t_dst_index(vp, &vpi->DstReg), - t_dst_mask(vpi->DstReg.WriteMask), - t_dst_class(vpi->DstReg.File)); - inst[1] = t_src(vp, &src[0]); - inst[2] = t_src(vp, &src[1]); - inst[3] = __CONST(1, SWIZZLE_ZERO); - - return inst; -} - -static GLuint *r600TranslateOpcodeSUB(struct r600_vertex_program *vp, - struct prog_instruction *vpi, - GLuint * inst, - struct prog_src_register src[3]) -{ - //ADD RESULT 1.X Y Z W TMP 0{} {X Y Z W} PARAM 1{X Y Z W } {X Y Z W} neg Xneg Yneg Zneg W - -#if 0 - inst[0] = PVS_OP_DST_OPERAND(VE_ADD, - GL_FALSE, - GL_FALSE, - t_dst_index(vp, &vpi->DstReg), - t_dst_mask(vpi->DstReg.WriteMask), - t_dst_class(vpi->DstReg.File)); - inst[1] = t_src(vp, &src[0]); - inst[2] = PVS_SRC_OPERAND(t_src_index(vp, &src[1]), - t_swizzle(GET_SWZ(src[1].Swizzle, 0)), - t_swizzle(GET_SWZ(src[1].Swizzle, 1)), - t_swizzle(GET_SWZ(src[1].Swizzle, 2)), - t_swizzle(GET_SWZ(src[1].Swizzle, 3)), - t_src_class(src[1].File), - (!src[1]. - NegateBase) ? VSF_FLAG_ALL : VSF_FLAG_NONE) | - (src[1].RelAddr << 4); - inst[3] = 0; -#else - inst[0] = - PVS_OP_DST_OPERAND(VE_MULTIPLY_ADD, - GL_FALSE, - GL_FALSE, - t_dst_index(vp, &vpi->DstReg), - t_dst_mask(vpi->DstReg.WriteMask), - t_dst_class(vpi->DstReg.File)); - inst[1] = t_src(vp, &src[0]); - inst[2] = __CONST(0, SWIZZLE_ONE); - inst[3] = PVS_SRC_OPERAND(t_src_index(vp, &src[1]), - t_swizzle(GET_SWZ(src[1].Swizzle, 0)), - t_swizzle(GET_SWZ(src[1].Swizzle, 1)), - t_swizzle(GET_SWZ(src[1].Swizzle, 2)), - t_swizzle(GET_SWZ(src[1].Swizzle, 3)), - t_src_class(src[1].File), - (!src[1]. - NegateBase) ? VSF_FLAG_ALL : VSF_FLAG_NONE) | - (src[1].RelAddr << 4); -#endif - - return inst; -} - -static GLuint *r600TranslateOpcodeSWZ(struct r600_vertex_program *vp, - struct prog_instruction *vpi, - GLuint * inst, - struct prog_src_register src[3]) -{ - //ADD RESULT 1.X Y Z W PARAM 0{} {X Y Z W} PARAM 0{} {ZERO ZERO ZERO ZERO} - - inst[0] = PVS_OP_DST_OPERAND(VE_ADD, - GL_FALSE, - GL_FALSE, - t_dst_index(vp, &vpi->DstReg), - t_dst_mask(vpi->DstReg.WriteMask), - t_dst_class(vpi->DstReg.File)); - inst[1] = t_src(vp, &src[0]); - inst[2] = __CONST(0, SWIZZLE_ZERO); - inst[3] = __CONST(0, SWIZZLE_ZERO); - - return inst; -} - -static GLuint *r600TranslateOpcodeXPD(struct r600_vertex_program *vp, - struct prog_instruction *vpi, - GLuint * inst, - struct prog_src_register src[3], - int *u_temp_i) -{ - /* mul r0, r1.yzxw, r2.zxyw - mad r0, -r2.yzxw, r1.zxyw, r0 - */ - - inst[0] = PVS_OP_DST_OPERAND(VE_MULTIPLY_ADD, - GL_FALSE, - GL_FALSE, - *u_temp_i, - t_dst_mask(vpi->DstReg.WriteMask), - PVS_DST_REG_TEMPORARY); - inst[1] = PVS_SRC_OPERAND(t_src_index(vp, &src[0]), t_swizzle(GET_SWZ(src[0].Swizzle, 1)), // Y - t_swizzle(GET_SWZ(src[0].Swizzle, 2)), // Z - t_swizzle(GET_SWZ(src[0].Swizzle, 0)), // X - t_swizzle(GET_SWZ(src[0].Swizzle, 3)), // W - t_src_class(src[0].File), - src[0]. - NegateBase ? VSF_FLAG_ALL : VSF_FLAG_NONE) | - (src[0].RelAddr << 4); - inst[2] = PVS_SRC_OPERAND(t_src_index(vp, &src[1]), t_swizzle(GET_SWZ(src[1].Swizzle, 2)), // Z - t_swizzle(GET_SWZ(src[1].Swizzle, 0)), // X - t_swizzle(GET_SWZ(src[1].Swizzle, 1)), // Y - t_swizzle(GET_SWZ(src[1].Swizzle, 3)), // W - t_src_class(src[1].File), - src[1]. - NegateBase ? VSF_FLAG_ALL : VSF_FLAG_NONE) | - (src[1].RelAddr << 4); - inst[3] = __CONST(1, SWIZZLE_ZERO); - inst += 4; - - inst[0] = PVS_OP_DST_OPERAND(VE_MULTIPLY_ADD, - GL_FALSE, - GL_FALSE, - t_dst_index(vp, &vpi->DstReg), - t_dst_mask(vpi->DstReg.WriteMask), - t_dst_class(vpi->DstReg.File)); - inst[1] = PVS_SRC_OPERAND(t_src_index(vp, &src[1]), t_swizzle(GET_SWZ(src[1].Swizzle, 1)), // Y - t_swizzle(GET_SWZ(src[1].Swizzle, 2)), // Z - t_swizzle(GET_SWZ(src[1].Swizzle, 0)), // X - t_swizzle(GET_SWZ(src[1].Swizzle, 3)), // W - t_src_class(src[1].File), - (!src[1]. - NegateBase) ? VSF_FLAG_ALL : VSF_FLAG_NONE) | - (src[1].RelAddr << 4); - inst[2] = PVS_SRC_OPERAND(t_src_index(vp, &src[0]), t_swizzle(GET_SWZ(src[0].Swizzle, 2)), // Z - t_swizzle(GET_SWZ(src[0].Swizzle, 0)), // X - t_swizzle(GET_SWZ(src[0].Swizzle, 1)), // Y - t_swizzle(GET_SWZ(src[0].Swizzle, 3)), // W - t_src_class(src[0].File), - src[0]. - NegateBase ? VSF_FLAG_ALL : VSF_FLAG_NONE) | - (src[0].RelAddr << 4); - inst[3] = - PVS_SRC_OPERAND(*u_temp_i, PVS_SRC_SELECT_X, PVS_SRC_SELECT_Y, - PVS_SRC_SELECT_Z, PVS_SRC_SELECT_W, - PVS_SRC_REG_TEMPORARY, VSF_FLAG_NONE); - - (*u_temp_i)--; - - return inst; -} - -static void t_inputs_outputs(struct r600_vertex_program *vp) -{ - int i; - int cur_reg = 0; - - for (i = 0; i < VERT_ATTRIB_MAX; i++) - vp->inputs[i] = -1; - - for (i = 0; i < VERT_RESULT_MAX; i++) - vp->outputs[i] = -1; - - assert(vp->key.OutputsWritten & (1 << VERT_RESULT_HPOS)); - - if (vp->key.OutputsWritten & (1 << VERT_RESULT_HPOS)) { - vp->outputs[VERT_RESULT_HPOS] = cur_reg++; - } - - if (vp->key.OutputsWritten & (1 << VERT_RESULT_PSIZ)) { - vp->outputs[VERT_RESULT_PSIZ] = cur_reg++; - } - - if (vp->key.OutputsWritten & (1 << VERT_RESULT_COL0)) { - vp->outputs[VERT_RESULT_COL0] = cur_reg++; - } - - if (vp->key.OutputsWritten & (1 << VERT_RESULT_COL1)) { - vp->outputs[VERT_RESULT_COL1] = - vp->outputs[VERT_RESULT_COL0] + 1; - cur_reg = vp->outputs[VERT_RESULT_COL1] + 1; - } - - if (vp->key.OutputsWritten & (1 << VERT_RESULT_BFC0)) { - vp->outputs[VERT_RESULT_BFC0] = - vp->outputs[VERT_RESULT_COL0] + 2; - cur_reg = vp->outputs[VERT_RESULT_BFC0] + 2; - } - - if (vp->key.OutputsWritten & (1 << VERT_RESULT_BFC1)) { - vp->outputs[VERT_RESULT_BFC1] = - vp->outputs[VERT_RESULT_COL0] + 3; - cur_reg = vp->outputs[VERT_RESULT_BFC1] + 1; - } - - for (i = VERT_RESULT_TEX0; i <= VERT_RESULT_TEX7; i++) { - if (vp->key.OutputsWritten & (1 << i)) { - vp->outputs[i] = cur_reg++; - } - } - - if (vp->key.OutputsWritten & (1 << VERT_RESULT_FOGC)) { - vp->outputs[VERT_RESULT_FOGC] = cur_reg++; - } -} - -static void r600TranslateVertexShader(struct r600_vertex_program *vp, - struct prog_instruction *vpi) -{ - int i; - GLuint *inst; - unsigned long num_operands; - /* Initial value should be last tmp reg that hw supports. - Strangely enough r600 doesnt mind even though these would be out of range. - Smart enough to realize that it doesnt need it? */ - int u_temp_i = VSF_MAX_FRAGMENT_TEMPS - 1; - struct prog_src_register src[3]; - - vp->pos_end = 0; /* Not supported yet */ - vp->program.length = 0; - /*vp->num_temporaries=mesa_vp->Base.NumTemporaries; */ - vp->translated = GL_TRUE; - vp->native = GL_TRUE; - - t_inputs_outputs(vp); - - for (inst = vp->program.body.i; vpi->Opcode != OPCODE_END; - vpi++, inst += 4) { - - FREE_TEMPS(); - - if (!valid_dst(vp, &vpi->DstReg)) { - /* redirect result to unused temp */ - vpi->DstReg.File = PROGRAM_TEMPORARY; - vpi->DstReg.Index = u_temp_i; - } - - num_operands = _mesa_num_inst_src_regs(vpi->Opcode); - - /* copy the sources (src) from mesa into a local variable... is this needed? */ - for (i = 0; i < num_operands; i++) { - src[i] = vpi->SrcReg[i]; - } - - if (num_operands == 3) { /* TODO: scalars */ - if (CMP_SRCS(src[1], src[2]) - || CMP_SRCS(src[0], src[2])) { - inst[0] = PVS_OP_DST_OPERAND(VE_ADD, - GL_FALSE, - GL_FALSE, - u_temp_i, - VSF_FLAG_ALL, - PVS_DST_REG_TEMPORARY); - inst[1] = - PVS_SRC_OPERAND(t_src_index(vp, &src[2]), - SWIZZLE_X, - SWIZZLE_Y, - SWIZZLE_Z, - SWIZZLE_W, - t_src_class(src[2].File), - VSF_FLAG_NONE) | (src[2]. - RelAddr << - 4); - inst[2] = __CONST(2, SWIZZLE_ZERO); - inst[3] = __CONST(2, SWIZZLE_ZERO); - inst += 4; - - src[2].File = PROGRAM_TEMPORARY; - src[2].Index = u_temp_i; - src[2].RelAddr = 0; - u_temp_i--; - } - } - - if (num_operands >= 2) { - if (CMP_SRCS(src[1], src[0])) { - inst[0] = PVS_OP_DST_OPERAND(VE_ADD, - GL_FALSE, - GL_FALSE, - u_temp_i, - VSF_FLAG_ALL, - PVS_DST_REG_TEMPORARY); - inst[1] = - PVS_SRC_OPERAND(t_src_index(vp, &src[0]), - SWIZZLE_X, - SWIZZLE_Y, - SWIZZLE_Z, - SWIZZLE_W, - t_src_class(src[0].File), - VSF_FLAG_NONE) | (src[0]. - RelAddr << - 4); - inst[2] = __CONST(0, SWIZZLE_ZERO); - inst[3] = __CONST(0, SWIZZLE_ZERO); - inst += 4; - - src[0].File = PROGRAM_TEMPORARY; - src[0].Index = u_temp_i; - src[0].RelAddr = 0; - u_temp_i--; - } - } - - switch (vpi->Opcode) { - case OPCODE_ABS: - inst = r600TranslateOpcodeABS(vp, vpi, inst, src); - break; - case OPCODE_ADD: - inst = r600TranslateOpcodeADD(vp, vpi, inst, src); - break; - case OPCODE_ARL: - inst = r600TranslateOpcodeARL(vp, vpi, inst, src); - break; - case OPCODE_DP3: - inst = r600TranslateOpcodeDP3(vp, vpi, inst, src); - break; - case OPCODE_DP4: - inst = r600TranslateOpcodeDP4(vp, vpi, inst, src); - break; - case OPCODE_DPH: - inst = r600TranslateOpcodeDPH(vp, vpi, inst, src); - break; - case OPCODE_DST: - inst = r600TranslateOpcodeDST(vp, vpi, inst, src); - break; - case OPCODE_EX2: - inst = r600TranslateOpcodeEX2(vp, vpi, inst, src); - break; - case OPCODE_EXP: - inst = r600TranslateOpcodeEXP(vp, vpi, inst, src); - break; - case OPCODE_FLR: - inst = r600TranslateOpcodeFLR(vp, vpi, inst, src, /* FIXME */ - &u_temp_i); - break; - case OPCODE_FRC: - inst = r600TranslateOpcodeFRC(vp, vpi, inst, src); - break; - case OPCODE_LG2: - inst = r600TranslateOpcodeLG2(vp, vpi, inst, src); - break; - case OPCODE_LIT: - inst = r600TranslateOpcodeLIT(vp, vpi, inst, src); - break; - case OPCODE_LOG: - inst = r600TranslateOpcodeLOG(vp, vpi, inst, src); - break; - case OPCODE_MAD: - inst = r600TranslateOpcodeMAD(vp, vpi, inst, src); - break; - case OPCODE_MAX: - inst = r600TranslateOpcodeMAX(vp, vpi, inst, src); - break; - case OPCODE_MIN: - inst = r600TranslateOpcodeMIN(vp, vpi, inst, src); - break; - case OPCODE_MOV: - inst = r600TranslateOpcodeMOV(vp, vpi, inst, src); - break; - case OPCODE_MUL: - inst = r600TranslateOpcodeMUL(vp, vpi, inst, src); - break; - case OPCODE_POW: - inst = r600TranslateOpcodePOW(vp, vpi, inst, src); - break; - case OPCODE_RCP: - inst = r600TranslateOpcodeRCP(vp, vpi, inst, src); - break; - case OPCODE_RSQ: - inst = r600TranslateOpcodeRSQ(vp, vpi, inst, src); - break; - case OPCODE_SGE: - inst = r600TranslateOpcodeSGE(vp, vpi, inst, src); - break; - case OPCODE_SLT: - inst = r600TranslateOpcodeSLT(vp, vpi, inst, src); - break; - case OPCODE_SUB: - inst = r600TranslateOpcodeSUB(vp, vpi, inst, src); - break; - case OPCODE_SWZ: - inst = r600TranslateOpcodeSWZ(vp, vpi, inst, src); - break; - case OPCODE_XPD: - inst = r600TranslateOpcodeXPD(vp, vpi, inst, src, /* FIXME */ - &u_temp_i); - break; - default: - assert(0); - break; - } - } - - /* Some outputs may be artificially added, to match the inputs - of the fragment program. Blank the outputs here. */ - for (i = 0; i < VERT_RESULT_MAX; i++) { - if (vp->key.OutputsAdded & (1 << i)) { - inst[0] = PVS_OP_DST_OPERAND(VE_ADD, - GL_FALSE, - GL_FALSE, - vp->outputs[i], - VSF_FLAG_ALL, - PVS_DST_REG_OUT); - inst[1] = __CONST(0, SWIZZLE_ZERO); - inst[2] = __CONST(0, SWIZZLE_ZERO); - inst[3] = __CONST(0, SWIZZLE_ZERO); - inst += 4; - } - } - - vp->program.length = (inst - vp->program.body.i); - if (vp->program.length >= VSF_MAX_FRAGMENT_LENGTH) { - vp->program.length = 0; - vp->native = GL_FALSE; - } -#if 0 - fprintf(stderr, "hw program:\n"); - for (i = 0; i < vp->program.length; i++) - fprintf(stderr, "%08x\n", vp->program.body.d[i]); -#endif -} - -/* DP4 version seems to trigger some hw peculiarity */ -//#define PREFER_DP4 - -static void position_invariant(struct gl_program *prog) -{ - struct prog_instruction *vpi; - struct gl_program_parameter_list *paramList; - int i; - - gl_state_index tokens[STATE_LENGTH] = { STATE_MVP_MATRIX, 0, 0, 0, 0 }; - - /* tokens[4] = matrix modifier */ -#ifdef PREFER_DP4 - tokens[4] = 0; /* not transposed or inverted */ -#else - tokens[4] = STATE_MATRIX_TRANSPOSE; -#endif - paramList = prog->Parameters; - - vpi = _mesa_alloc_instructions(prog->NumInstructions + 4); - _mesa_init_instructions(vpi, prog->NumInstructions + 4); - - for (i = 0; i < 4; i++) { - GLint idx; - tokens[2] = tokens[3] = i; /* matrix row[i]..row[i] */ - idx = _mesa_add_state_reference(paramList, tokens); -#ifdef PREFER_DP4 - vpi[i].Opcode = OPCODE_DP4; - vpi[i].StringPos = 0; - vpi[i].Data = 0; - - vpi[i].DstReg.File = PROGRAM_OUTPUT; - vpi[i].DstReg.Index = VERT_RESULT_HPOS; - vpi[i].DstReg.WriteMask = 1 << i; - vpi[i].DstReg.CondMask = COND_TR; - - vpi[i].SrcReg[0].File = PROGRAM_STATE_VAR; - vpi[i].SrcReg[0].Index = idx; - vpi[i].SrcReg[0].Swizzle = SWIZZLE_XYZW; - - vpi[i].SrcReg[1].File = PROGRAM_INPUT; - vpi[i].SrcReg[1].Index = VERT_ATTRIB_POS; - vpi[i].SrcReg[1].Swizzle = SWIZZLE_XYZW; -#else - if (i == 0) - vpi[i].Opcode = OPCODE_MUL; - else - vpi[i].Opcode = OPCODE_MAD; - - vpi[i].Data = 0; - - if (i == 3) - vpi[i].DstReg.File = PROGRAM_OUTPUT; - else - vpi[i].DstReg.File = PROGRAM_TEMPORARY; - vpi[i].DstReg.Index = 0; - vpi[i].DstReg.WriteMask = 0xf; - vpi[i].DstReg.CondMask = COND_TR; - - vpi[i].SrcReg[0].File = PROGRAM_STATE_VAR; - vpi[i].SrcReg[0].Index = idx; - vpi[i].SrcReg[0].Swizzle = SWIZZLE_XYZW; - - vpi[i].SrcReg[1].File = PROGRAM_INPUT; - vpi[i].SrcReg[1].Index = VERT_ATTRIB_POS; - vpi[i].SrcReg[1].Swizzle = MAKE_SWIZZLE4(i, i, i, i); - - if (i > 0) { - vpi[i].SrcReg[2].File = PROGRAM_TEMPORARY; - vpi[i].SrcReg[2].Index = 0; - vpi[i].SrcReg[2].Swizzle = SWIZZLE_XYZW; - } -#endif - } - - _mesa_copy_instructions(&vpi[i], prog->Instructions, - prog->NumInstructions); - - free(prog->Instructions); - - prog->Instructions = vpi; - - prog->NumInstructions += 4; - vpi = &prog->Instructions[prog->NumInstructions - 1]; - - assert(vpi->Opcode == OPCODE_END); -} - -static void insert_wpos(struct r600_vertex_program *vp, struct gl_program *prog, - GLuint temp_index) -{ - struct prog_instruction *vpi; - struct prog_instruction *vpi_insert; - int i = 0; - - vpi = _mesa_alloc_instructions(prog->NumInstructions + 2); - _mesa_init_instructions(vpi, prog->NumInstructions + 2); - /* all but END */ - _mesa_copy_instructions(vpi, prog->Instructions, - prog->NumInstructions - 1); - /* END */ - _mesa_copy_instructions(&vpi[prog->NumInstructions + 1], - &prog->Instructions[prog->NumInstructions - 1], - 1); - vpi_insert = &vpi[prog->NumInstructions - 1]; - - vpi_insert[i].Opcode = OPCODE_MOV; - - vpi_insert[i].DstReg.File = PROGRAM_OUTPUT; - vpi_insert[i].DstReg.Index = VERT_RESULT_HPOS; - vpi_insert[i].DstReg.WriteMask = WRITEMASK_XYZW; - vpi_insert[i].DstReg.CondMask = COND_TR; - - vpi_insert[i].SrcReg[0].File = PROGRAM_TEMPORARY; - vpi_insert[i].SrcReg[0].Index = temp_index; - vpi_insert[i].SrcReg[0].Swizzle = SWIZZLE_XYZW; - i++; - - vpi_insert[i].Opcode = OPCODE_MOV; - - vpi_insert[i].DstReg.File = PROGRAM_OUTPUT; - vpi_insert[i].DstReg.Index = VERT_RESULT_TEX0 + vp->wpos_idx; - vpi_insert[i].DstReg.WriteMask = WRITEMASK_XYZW; - vpi_insert[i].DstReg.CondMask = COND_TR; - - vpi_insert[i].SrcReg[0].File = PROGRAM_TEMPORARY; - vpi_insert[i].SrcReg[0].Index = temp_index; - vpi_insert[i].SrcReg[0].Swizzle = SWIZZLE_XYZW; - i++; - - free(prog->Instructions); - - prog->Instructions = vpi; - - prog->NumInstructions += i; - vpi = &prog->Instructions[prog->NumInstructions - 1]; - - assert(vpi->Opcode == OPCODE_END); -} - -static void pos_as_texcoord(struct r600_vertex_program *vp, - struct gl_program *prog) -{ - struct prog_instruction *vpi; - GLuint tempregi = prog->NumTemporaries; - /* should do something else if no temps left... */ - prog->NumTemporaries++; - - for (vpi = prog->Instructions; vpi->Opcode != OPCODE_END; vpi++) { - if (vpi->DstReg.File == PROGRAM_OUTPUT - && vpi->DstReg.Index == VERT_RESULT_HPOS) { - vpi->DstReg.File = PROGRAM_TEMPORARY; - vpi->DstReg.Index = tempregi; - } - } - insert_wpos(vp, prog, tempregi); -} - -static struct r600_vertex_program *build_program(struct r600_vertex_program_key - *wanted_key, struct gl_vertex_program - *mesa_vp, GLint wpos_idx) -{ - struct r600_vertex_program *vp; - - vp = _mesa_calloc(sizeof(*vp)); - _mesa_memcpy(&vp->key, wanted_key, sizeof(vp->key)); - vp->wpos_idx = wpos_idx; - - if (mesa_vp->IsPositionInvariant) { - position_invariant(&mesa_vp->Base); - } - - if (wpos_idx > -1) { - pos_as_texcoord(vp, &mesa_vp->Base); - } - - assert(mesa_vp->Base.NumInstructions); - vp->num_temporaries = mesa_vp->Base.NumTemporaries; - r600TranslateVertexShader(vp, mesa_vp->Base.Instructions); - - return vp; -} - -static void add_outputs(struct r600_vertex_program_key *key, GLint vert) -{ - if (key->OutputsWritten & (1 << vert)) - return; - - key->OutputsWritten |= 1 << vert; - key->OutputsAdded |= 1 << vert; -} - -void r600SelectVertexShader(r600ContextPtr r600) -{ - GLcontext *ctx = ctx = r600->radeon.glCtx; - GLuint InputsRead; - struct r600_vertex_program_key wanted_key = { 0 }; - GLint i; - struct r600_vertex_program_cont *vpc; - struct r600_vertex_program *vp; - GLint wpos_idx; - - vpc = (struct r600_vertex_program_cont *)ctx->VertexProgram._Current; - wanted_key.InputsRead = vpc->mesa_program.Base.InputsRead; - wanted_key.OutputsWritten = vpc->mesa_program.Base.OutputsWritten; - InputsRead = ctx->FragmentProgram._Current->Base.InputsRead; - - wpos_idx = -1; - if (InputsRead & FRAG_BIT_WPOS) { - for (i = 0; i < ctx->Const.MaxTextureUnits; i++) - if (!(InputsRead & (FRAG_BIT_TEX0 << i))) - break; - - if (i == ctx->Const.MaxTextureUnits) { - fprintf(stderr, "\tno free texcoord found\n"); - _mesa_exit(-1); - } - - wanted_key.OutputsWritten |= 1 << (VERT_RESULT_TEX0 + i); - wpos_idx = i; - } - - add_outputs(&wanted_key, VERT_RESULT_HPOS); - - if (InputsRead & FRAG_BIT_COL0) { - add_outputs(&wanted_key, VERT_RESULT_COL0); - } - - if (InputsRead & FRAG_BIT_COL1) { - add_outputs(&wanted_key, VERT_RESULT_COL1); - } - - for (i = 0; i < ctx->Const.MaxTextureUnits; i++) { - if (InputsRead & (FRAG_BIT_TEX0 << i)) { - add_outputs(&wanted_key, VERT_RESULT_TEX0 + i); - } - } - - if (vpc->mesa_program.IsPositionInvariant) { - /* we wan't position don't we ? */ - wanted_key.InputsRead |= (1 << VERT_ATTRIB_POS); - } - - for (vp = vpc->progs; vp; vp = vp->next) - if (_mesa_memcmp(&vp->key, &wanted_key, sizeof(wanted_key)) - == 0) { - r600->selected_vp = vp; - return; - } - //_mesa_print_program(&vpc->mesa_program.Base); - - vp = build_program(&wanted_key, &vpc->mesa_program, wpos_idx); - vp->next = vpc->progs; - vpc->progs = vp; - r600->selected_vp = vp; -} diff --git a/src/mesa/drivers/dri/r600/r600_vertprog.h b/src/mesa/drivers/dri/r600/r600_vertprog.h deleted file mode 100644 index 48c97face45..00000000000 --- a/src/mesa/drivers/dri/r600/r600_vertprog.h +++ /dev/null @@ -1,35 +0,0 @@ -#ifndef __R600_VERTPROG_H_ -#define __R600_VERTPROG_H_ - -#include "r600_reg.h" - -#define PVS_OP_DST_OPERAND(opcode, math_inst, macro_inst, reg_index, reg_writemask, reg_class) \ - (((opcode & PVS_DST_OPCODE_MASK) << PVS_DST_OPCODE_SHIFT) \ - | ((math_inst & PVS_DST_MATH_INST_MASK) << PVS_DST_MATH_INST_SHIFT) \ - | ((macro_inst & PVS_DST_MACRO_INST_MASK) << PVS_DST_MACRO_INST_SHIFT) \ - | ((reg_index & PVS_DST_OFFSET_MASK) << PVS_DST_OFFSET_SHIFT) \ - | ((reg_writemask & 0xf) << PVS_DST_WE_X_SHIFT) /* X Y Z W */ \ - | ((reg_class & PVS_DST_REG_TYPE_MASK) << PVS_DST_REG_TYPE_SHIFT)) - -#define PVS_SRC_OPERAND(in_reg_index, comp_x, comp_y, comp_z, comp_w, reg_class, negate) \ - (((in_reg_index & PVS_SRC_OFFSET_MASK) << PVS_SRC_OFFSET_SHIFT) \ - | ((comp_x & PVS_SRC_SWIZZLE_X_MASK) << PVS_SRC_SWIZZLE_X_SHIFT) \ - | ((comp_y & PVS_SRC_SWIZZLE_Y_MASK) << PVS_SRC_SWIZZLE_Y_SHIFT) \ - | ((comp_z & PVS_SRC_SWIZZLE_Z_MASK) << PVS_SRC_SWIZZLE_Z_SHIFT) \ - | ((comp_w & PVS_SRC_SWIZZLE_W_MASK) << PVS_SRC_SWIZZLE_W_SHIFT) \ - | ((negate & 0xf) << PVS_SRC_MODIFIER_X_SHIFT) /* X Y Z W */ \ - | ((reg_class & PVS_SRC_REG_TYPE_MASK) << PVS_SRC_REG_TYPE_SHIFT)) - -#if 1 - -#define VSF_FLAG_X 1 -#define VSF_FLAG_Y 2 -#define VSF_FLAG_Z 4 -#define VSF_FLAG_W 8 -#define VSF_FLAG_XYZ (VSF_FLAG_X | VSF_FLAG_Y | VSF_FLAG_Z) -#define VSF_FLAG_ALL 0xf -#define VSF_FLAG_NONE 0 - -#endif - -#endif |