r300: Further reduced the radeon_span.c diff.
[mesa.git] / src / mesa / swrast / s_fragprog.c
index dbfc1b8c0cc00d8f35604a258d4b67e7c2c14857..b1501221cadfa4ee7ee1b4c8d21ac1e611c62d21 100644 (file)
@@ -25,7 +25,6 @@
 #include "glheader.h"
 #include "colormac.h"
 #include "context.h"
-#include "prog_execute.h"
 #include "prog_instruction.h"
 
 #include "s_fragprog.h"
@@ -114,8 +113,14 @@ init_machine(GLcontext *ctx, struct gl_program_machine *machine,
    /* Setup pointer to input attributes */
    machine->Attribs = span->array->attribs;
 
-   /* Store front/back facing value in register FOGC.Y */
-   machine->Attribs[FRAG_ATTRIB_FOGC][col][1] = (GLfloat) ctx->_Facing;
+   machine->DerivX = (GLfloat (*)[4]) span->attrStepX;
+   machine->DerivY = (GLfloat (*)[4]) span->attrStepY;
+   machine->NumDeriv = FRAG_ATTRIB_MAX;
+
+   if (ctx->Shader.CurrentProgram) {
+      /* Store front/back facing value in register FOGC.Y */
+      machine->Attribs[FRAG_ATTRIB_FOGC][col][1] = (GLfloat) ctx->_Facing;
+   }
 
    machine->CurElement = col;
 
@@ -139,22 +144,40 @@ init_machine(GLcontext *ctx, struct gl_program_machine *machine,
 static void
 run_program(GLcontext *ctx, SWspan *span, GLuint start, GLuint end)
 {
+   SWcontext *swrast = SWRAST_CONTEXT(ctx);
    const struct gl_fragment_program *program = ctx->FragmentProgram._Current;
-   struct gl_program_machine machine;
+   const GLbitfield outputsWritten = program->Base.OutputsWritten;
+   struct gl_program_machine *machine = &swrast->FragProgMachine;
    GLuint i;
 
    for (i = start; i < end; i++) {
       if (span->array->mask[i]) {
-         init_machine(ctx, &machine, program, span, i);
+         init_machine(ctx, machine, program, span, i);
+
+         if (_mesa_execute_program(ctx, &program->Base, machine)) {
 
-         if (_mesa_execute_program(ctx, &program->Base, &machine)) {
             /* Store result color */
-            COPY_4V(span->array->attribs[FRAG_ATTRIB_COL0][i],
-                    machine.Outputs[FRAG_RESULT_COLR]);
+            if (outputsWritten & (1 << FRAG_RESULT_COLR)) {
+               COPY_4V(span->array->attribs[FRAG_ATTRIB_COL0][i],
+                       machine->Outputs[FRAG_RESULT_COLR]);
+            }
+            else {
+               /* Multiple drawbuffers / render targets
+                * Note that colors beyond 0 and 1 will overwrite other
+                * attributes, such as FOGC, TEX0, TEX1, etc.  That's OK.
+                */
+               GLuint output;
+               for (output = 0; output < swrast->_NumColorOutputs; output++) {
+                  if (outputsWritten & (1 << (FRAG_RESULT_DATA0 + output))) {
+                     COPY_4V(span->array->attribs[FRAG_ATTRIB_COL0+output][i],
+                             machine->Outputs[FRAG_RESULT_DATA0 + output]);
+                  }
+               }
+            }
 
             /* Store result depth/z */
-            if (program->Base.OutputsWritten & (1 << FRAG_RESULT_DEPR)) {
-               const GLfloat depth = machine.Outputs[FRAG_RESULT_DEPR][2];
+            if (outputsWritten & (1 << FRAG_RESULT_DEPR)) {
+               const GLfloat depth = machine->Outputs[FRAG_RESULT_DEPR][2];
                if (depth <= 0.0)
                   span->array->z[i] = 0;
                else if (depth >= 1.0)
@@ -183,12 +206,19 @@ _swrast_exec_fragment_program( GLcontext *ctx, SWspan *span )
    const struct gl_fragment_program *program = ctx->FragmentProgram._Current;
 
    /* incoming colors should be floats */
-   ASSERT(span->array->ChanType == GL_FLOAT);
+   if (program->Base.InputsRead & FRAG_BIT_COL0) {
+      ASSERT(span->array->ChanType == GL_FLOAT);
+   }
 
    ctx->_CurrentProgram = GL_FRAGMENT_PROGRAM_ARB; /* or NV, doesn't matter */
 
    run_program(ctx, span, 0, span->end);
 
+   if (program->Base.OutputsWritten & (1 << FRAG_RESULT_COLR)) {
+      span->interpMask &= ~SPAN_RGBA;
+      span->arrayMask |= SPAN_RGBA;
+   }
+
    if (program->Base.OutputsWritten & (1 << FRAG_RESULT_DEPR)) {
       span->interpMask &= ~SPAN_Z;
       span->arrayMask |= SPAN_Z;