#include "glheader.h"
#include "colormac.h"
#include "context.h"
-#include "prog_execute.h"
#include "prog_instruction.h"
-#include "prog_parameter.h"
-#include "prog_print.h"
-#include "program.h"
#include "s_fragprog.h"
#include "s_span.h"
-#include "slang_library_noise.h"
/**
/* Setup pointer to input attributes */
machine->Attribs = span->array->attribs;
+
+ 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;
/* init condition codes */
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)
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;