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