ARB_Occlusion_query should support multiple query at same time
[mesa.git] / src / mesa / swrast / s_atifragshader.c
index 292f00e9465e096b3719620134c0951f4cc3f9c8..75df50b0baa0a60cc4001cef8dc90d983a54fccf 100644 (file)
 #include "program.h"
 
 #include "s_atifragshader.h"
-#include "s_nvfragprog.h"
-#include "s_span.h"
+
+
+/**
+ * State for executing ATI fragment shader.
+ */
+struct atifs_machine
+{
+   GLfloat Registers[6][4];         /** six temporary registers */
+   GLfloat PrevPassRegisters[6][4];
+   GLfloat Inputs[2][4];   /** Primary, secondary input colors */
+};
+
 
 
 /**
@@ -43,9 +53,9 @@ fetch_texel(GLcontext * ctx, const GLfloat texcoord[4], GLfloat lambda,
    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);
+   swrast->TextureSample[unit](ctx, 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]);
@@ -232,17 +242,6 @@ finish_pass(struct atifs_machine *machine)
    }
 }
 
-/**
- * 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},
@@ -261,7 +260,7 @@ struct ati_fs_opcode_st ati_fs_opcodes[] = {
 
 static void
 handle_pass_op(struct atifs_machine *machine, struct atifs_setupinst *texinst,
-              const struct sw_span *span, GLuint column, GLuint idx)
+              const SWspan *span, GLuint column, GLuint idx)
 {
    GLuint swizzle = texinst->swizzle;
    GLuint pass_tex = texinst->src;
@@ -281,7 +280,7 @@ handle_pass_op(struct atifs_machine *machine, struct atifs_setupinst *texinst,
 
 static void
 handle_sample_op(GLcontext * ctx, struct atifs_machine *machine,
-                struct atifs_setupinst *texinst, const struct sw_span *span,
+                struct atifs_setupinst *texinst, const SWspan *span,
                 GLuint column, GLuint idx)
 {
 /* sample from unit idx using texinst->src as coords */
@@ -306,11 +305,21 @@ do {                                              \
    COPY_4V(src[optype][i], x);                         \
 } while (0)
 
-static GLboolean
-execute_shader(GLcontext * ctx,
-              const struct ati_fragment_shader *shader, GLuint maxInst,
-              struct atifs_machine *machine, const struct sw_span *span,
-              GLuint column)
+
+
+/**
+ * Execute the given fragment shader.
+ * NOTE: we do everything in single-precision floating point
+ * \param ctx - rendering context
+ * \param shader - the shader to execute
+ * \param machine - virtual machine state
+ * \param span - the SWspan we're operating on
+ * \param column - which pixel [i] we're operating on in the span
+ */
+static void
+execute_shader(GLcontext *ctx, const struct ati_fragment_shader *shader,
+              struct atifs_machine *machine, const SWspan *span,
+               GLuint column)
 {
    GLuint pc;
    struct atifs_instruction *inst;
@@ -346,12 +355,12 @@ execute_shader(GLcontext * ctx,
                  SETUP_SRC_REG(optype, i,
                                machine->Registers[index - GL_REG_0_ATI]);
               else if (index >= GL_CON_0_ATI && index <= GL_CON_7_ATI) {
-                 if (shader->localConstDef & (1 << (index - GL_CON_0_ATI))) {
+                 if (shader->LocalConstDef & (1 << (index - GL_CON_0_ATI))) {
                     SETUP_SRC_REG(optype, i,
                                shader->Constants[index - GL_CON_0_ATI]);
                  } else {
                     SETUP_SRC_REG(optype, i,
-                               ctx->ATIFragmentShader.globalConstants[index - GL_CON_0_ATI]);
+                               ctx->ATIFragmentShader.GlobalConstants[index - GL_CON_0_ATI]);
                  }
               }
               else if (index == GL_ONE)
@@ -544,81 +553,61 @@ execute_shader(GLcontext * ctx,
         }
       }
    }
-   return GL_TRUE;
 }
 
+
+/**
+ * Init fragment shader virtual machine state.
+ */
 static void
 init_machine(GLcontext * ctx, struct atifs_machine *machine,
             const struct ati_fragment_shader *shader,
-            const struct sw_span *span, GLuint col)
+            const SWspan *span, GLuint col)
 {
+   GLfloat (*inputs)[4] = machine->Inputs;
    GLint i, j;
 
    for (i = 0; i < 6; i++) {
       for (j = 0; j < 4; j++)
-        ctx->ATIFragmentShader.Machine.Registers[i][j] = 0.0;
-
+        machine->Registers[i][j] = 0.0;
    }
 
-   ctx->ATIFragmentShader.Machine.Inputs[ATI_FS_INPUT_PRIMARY][0] =
-      CHAN_TO_FLOAT(span->array->rgba[col][0]);
-   ctx->ATIFragmentShader.Machine.Inputs[ATI_FS_INPUT_PRIMARY][1] =
-      CHAN_TO_FLOAT(span->array->rgba[col][1]);
-   ctx->ATIFragmentShader.Machine.Inputs[ATI_FS_INPUT_PRIMARY][2] =
-      CHAN_TO_FLOAT(span->array->rgba[col][2]);
-   ctx->ATIFragmentShader.Machine.Inputs[ATI_FS_INPUT_PRIMARY][3] =
-      CHAN_TO_FLOAT(span->array->rgba[col][3]);
-
-   ctx->ATIFragmentShader.Machine.Inputs[ATI_FS_INPUT_SECONDARY][0] =
-      CHAN_TO_FLOAT(span->array->spec[col][0]);
-   ctx->ATIFragmentShader.Machine.Inputs[ATI_FS_INPUT_SECONDARY][1] =
-      CHAN_TO_FLOAT(span->array->spec[col][1]);
-   ctx->ATIFragmentShader.Machine.Inputs[ATI_FS_INPUT_SECONDARY][2] =
-      CHAN_TO_FLOAT(span->array->spec[col][2]);
-   ctx->ATIFragmentShader.Machine.Inputs[ATI_FS_INPUT_SECONDARY][3] =
-      CHAN_TO_FLOAT(span->array->spec[col][3]);
-
-   ctx->ATIFragmentShader.Machine.pass = 0;
+   COPY_4V(inputs[ATI_FS_INPUT_PRIMARY], span->array->color.sz4.rgba[col]);
+   COPY_4V(inputs[ATI_FS_INPUT_SECONDARY], span->array->color.sz4.spec[col]);
 }
 
 
 
 /**
- * Execute the current fragment program, operating on the given span.
+ * Execute the current ATI shader program, operating on the given span.
  */
 void
-_swrast_exec_fragment_shader(GLcontext * ctx, struct sw_span *span)
+_swrast_exec_fragment_shader(GLcontext * ctx, SWspan *span)
 {
    const struct ati_fragment_shader *shader = ctx->ATIFragmentShader.Current;
+   struct atifs_machine machine;
    GLuint i;
 
+   /* incoming colors should be floats */
+   ASSERT(span->array->ChanType == GL_FLOAT);
+
    ctx->_CurrentProgram = GL_FRAGMENT_SHADER_ATI;
 
    for (i = 0; i < span->end; i++) {
       if (span->array->mask[i]) {
-        init_machine(ctx, &ctx->ATIFragmentShader.Machine,
-                     ctx->ATIFragmentShader.Current, span, i);
+        init_machine(ctx, &machine, shader, span, i);
 
-        if (execute_shader(ctx, shader, ~0,
-                           &ctx->ATIFragmentShader.Machine, span, i)) {
-           span->array->mask[i] = GL_FALSE;
-        }
+        execute_shader(ctx, shader, &machine, span, i);
 
+         /* store result color */
         {
-           const GLfloat *colOut =
-              ctx->ATIFragmentShader.Machine.Registers[0];
-
-           /*fprintf(stderr,"outputs %f %f %f %f\n", colOut[0], colOut[1], colOut[2], colOut[3]); */
-           UNCLAMPED_FLOAT_TO_CHAN(span->array->rgba[i][RCOMP], colOut[0]);
-           UNCLAMPED_FLOAT_TO_CHAN(span->array->rgba[i][GCOMP], colOut[1]);
-           UNCLAMPED_FLOAT_TO_CHAN(span->array->rgba[i][BCOMP], colOut[2]);
-           UNCLAMPED_FLOAT_TO_CHAN(span->array->rgba[i][ACOMP], colOut[3]);
+           const GLfloat *colOut = machine.Registers[0];
+            /*fprintf(stderr,"outputs %f %f %f %f\n",
+              colOut[0], colOut[1], colOut[2], colOut[3]); */
+            COPY_4V(span->array->color.sz4.rgba[i], colOut);
         }
       }
-
    }
 
-
    ctx->_CurrentProgram = 0;
-
 }