⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 s_atifragshader.c

📁 winNT技术操作系统,国外开放的原代码和LIUX一样
💻 C
📖 第 1 页 / 共 2 页
字号:
/*
 *
 * Copyright (C) 2004  David Airlie   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 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
 * DAVID AIRLIE 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.
 */

#include "glheader.h"
#include "colormac.h"
#include "context.h"
#include "atifragshader.h"
#include "macros.h"
#include "program.h"

#include "s_atifragshader.h"
#include "s_nvfragprog.h"
#include "s_span.h"
#include "s_texture.h"

/**
 * Fetch a texel.
 */
static void
fetch_texel(GLcontext * ctx, const GLfloat texcoord[4], GLfloat lambda,
	    GLuint unit, GLfloat color[4])
{
   GLchan rgba[4];
   SWcontext *swrast = SWRAST_CONTEXT(ctx);

   /* XXX use a float-valued TextureSample routine here!!! */
   swrast->TextureSample[unit] (ctx, unit, ctx->Texture.Unit[unit]._Current,
				1, (const GLfloat(*)[4]) texcoord,
				&lambda, &rgba);
   color[0] = CHAN_TO_FLOAT(rgba[0]);
   color[1] = CHAN_TO_FLOAT(rgba[1]);
   color[2] = CHAN_TO_FLOAT(rgba[2]);
   color[3] = CHAN_TO_FLOAT(rgba[3]);
}

static void
apply_swizzle(struct atifs_machine *machine, GLuint reg, GLuint swizzle)
{
   GLfloat s, t, r, q;

   s = machine->Registers[reg][0];
   t = machine->Registers[reg][1];
   r = machine->Registers[reg][2];
   q = machine->Registers[reg][3];

   switch (swizzle) {
   case GL_SWIZZLE_STR_ATI:
      machine->Registers[reg][0] = s;
      machine->Registers[reg][1] = t;
      machine->Registers[reg][2] = r;
      break;
   case GL_SWIZZLE_STQ_ATI:
      machine->Registers[reg][0] = s;
      machine->Registers[reg][1] = t;
      machine->Registers[reg][2] = q;
      break;
   case GL_SWIZZLE_STR_DR_ATI:
      machine->Registers[reg][0] = s / r;
      machine->Registers[reg][1] = t / r;
      machine->Registers[reg][2] = 1 / r;
      break;
   case GL_SWIZZLE_STQ_DQ_ATI:
      machine->Registers[reg][0] = s / q;
      machine->Registers[reg][1] = t / q;
      machine->Registers[reg][2] = 1 / q;
      break;
   }
   machine->Registers[reg][3] = 0.0;
}

static void
apply_src_rep(GLint optype, GLuint rep, GLfloat * val)
{
   GLint i;
   GLint start, end;
   if (!rep)
      return;

   start = optype ? 3 : 0;
   end = optype ? 4 : 3;

   for (i = start; i < end; i++) {
      switch (rep) {
      case GL_RED:
	 val[i] = val[0];
	 break;
      case GL_GREEN:
	 val[i] = val[1];
	 break;
      case GL_BLUE:
	 val[i] = val[2];
	 break;
      case GL_ALPHA:
	 val[i] = val[3];
	 break;
      }
   }
}

static void
apply_src_mod(GLint optype, GLuint mod, GLfloat * val)
{
   GLint i;
   GLint start, end;

   if (!mod)
      return;

   start = optype ? 3 : 0;
   end = optype ? 4 : 3;

   for (i = start; i < end; i++) {
      if (mod & GL_COMP_BIT_ATI)
	 val[i] = 1 - val[i];

      if (mod & GL_BIAS_BIT_ATI)
	 val[i] = val[i] - 0.5;

      if (mod & GL_2X_BIT_ATI)
	 val[i] = 2 * val[i];

      if (mod & GL_NEGATE_BIT_ATI)
	 val[i] = -val[i];
   }
}

static void
apply_dst_mod(GLuint optype, GLuint mod, GLfloat * val)
{
   GLint i;
   GLint has_sat = mod & GL_SATURATE_BIT_ATI;
   GLint start, end;

   mod &= ~GL_SATURATE_BIT_ATI;

   start = optype ? 3 : 0;
   end = optype ? 4 : 3;

   for (i = start; i < end; i++) {
      switch (mod) {
      case GL_2X_BIT_ATI:
	 val[i] = 2 * val[i];
	 break;
      case GL_4X_BIT_ATI:
	 val[i] = 4 * val[i];
	 break;
      case GL_8X_BIT_ATI:
	 val[i] = 8 * val[i];
	 break;
      case GL_HALF_BIT_ATI:
	 val[i] = val[i] * 0.5;
	 break;
      case GL_QUARTER_BIT_ATI:
	 val[i] = val[i] * 0.25;
	 break;
      case GL_EIGHTH_BIT_ATI:
	 val[i] = val[i] * 0.125;
	 break;
      }

      if (has_sat) {
	 if (val[i] < 0.0)
	    val[i] = 0;
	 else if (val[i] > 1.0)
	    val[i] = 1.0;
      }
      else {
	 if (val[i] < -8.0)
	    val[i] = -8.0;
	 else if (val[i] > 8.0)
	    val[i] = 8.0;
      }
   }
}


static void
write_dst_addr(GLuint optype, GLuint mod, GLuint mask, GLfloat * src,
	       GLfloat * dst)
{
   GLint i;
   apply_dst_mod(optype, mod, src);

   if (optype == ATI_FRAGMENT_SHADER_COLOR_OP) {
      if (mask) {
	 if (mask & GL_RED_BIT_ATI)
	    dst[0] = src[0];

	 if (mask & GL_GREEN_BIT_ATI)
	    dst[1] = src[1];

	 if (mask & GL_BLUE_BIT_ATI)
	    dst[2] = src[2];
      }
      else {
	 for (i = 0; i < 3; i++)
	    dst[i] = src[i];
      }
   }
   else
      dst[3] = src[3];
}

static void
finish_pass(struct atifs_machine *machine)
{
   GLint i;

   for (i = 0; i < 6; i++) {
      COPY_4V(machine->PrevPassRegisters[i], machine->Registers[i]);
   }
}

/**
 * Execute the given fragment shader
 * NOTE: we do everything in single-precision floating point; we don't
 * currently observe the single/half/fixed-precision qualifiers.
 * \param ctx - rendering context
 * \param program - the fragment program to execute
 * \param machine - machine state (register file)
 * \param maxInst - max number of instructions to execute
 * \return GL_TRUE if program completed or GL_FALSE if program executed KIL.
 */

struct ati_fs_opcode_st ati_fs_opcodes[] = {
   {GL_ADD_ATI, 2},
   {GL_SUB_ATI, 2},
   {GL_MUL_ATI, 2},
   {GL_MAD_ATI, 3},
   {GL_LERP_ATI, 3},
   {GL_MOV_ATI, 1},
   {GL_CND_ATI, 3},
   {GL_CND0_ATI, 3},
   {GL_DOT2_ADD_ATI, 3},
   {GL_DOT3_ATI, 2},
   {GL_DOT4_ATI, 2}
};



static void
handle_pass_op(struct atifs_machine *machine, struct atifs_instruction *inst,
	       const struct sw_span *span, GLuint column)
{
   GLuint idx = inst->DstReg[0].Index - GL_REG_0_ATI;
   GLuint swizzle = inst->DstReg[0].Swizzle;
   GLuint pass_tex = inst->SrcReg[0][0].Index;

   /* if we get here after passing pass one then we are starting pass two - backup the registers */
   if (machine->pass == 1) {
      finish_pass(machine);
      machine->pass = 2;
   }
   if (pass_tex >= GL_TEXTURE0_ARB && pass_tex <= GL_TEXTURE7_ARB) {
      pass_tex -= GL_TEXTURE0_ARB;
      COPY_4V(machine->Registers[idx],
	      span->array->texcoords[pass_tex][column]);
   }
   else if (pass_tex >= GL_REG_0_ATI && pass_tex <= GL_REG_5_ATI
	    && machine->pass == 2) {
      pass_tex -= GL_REG_0_ATI;
      COPY_4V(machine->Registers[idx], machine->PrevPassRegisters[pass_tex]);
   }
   apply_swizzle(machine, idx, swizzle);

}

static void
handle_sample_op(GLcontext * ctx, struct atifs_machine *machine,
		 struct atifs_instruction *inst, const struct sw_span *span,
		 GLuint column)
{
   GLuint idx = inst->DstReg[0].Index - GL_REG_0_ATI;
   GLuint swizzle = inst->DstReg[0].Swizzle;
   GLuint sample_tex = inst->SrcReg[0][0].Index;

   /* if we get here after passing pass one then we are starting pass two - backup the registers */
   if (machine->pass == 1) {
      finish_pass(machine);
      machine->pass = 2;
   }

   if (sample_tex >= GL_TEXTURE0_ARB && sample_tex <= GL_TEXTURE7_ARB) {
      sample_tex -= GL_TEXTURE0_ARB;
      fetch_texel(ctx, span->array->texcoords[sample_tex][column], 0.0F,
		  sample_tex, machine->Registers[idx]);
   }
   else if (sample_tex >= GL_REG_0_ATI && sample_tex <= GL_REG_5_ATI) {
      /* this is wrong... */
      sample_tex -= GL_REG_0_ATI;
      fetch_texel(ctx, machine->Registers[sample_tex], 0, sample_tex,
		  machine->Registers[idx]);
   }

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -