summaryrefslogtreecommitdiffstats
path: root/src/mesa/swrast/s_atifragshader.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/mesa/swrast/s_atifragshader.c')
-rw-r--r--src/mesa/swrast/s_atifragshader.c108
1 files changed, 52 insertions, 56 deletions
diff --git a/src/mesa/swrast/s_atifragshader.c b/src/mesa/swrast/s_atifragshader.c
index 08640e146b5..75df50b0baa 100644
--- a/src/mesa/swrast/s_atifragshader.c
+++ b/src/mesa/swrast/s_atifragshader.c
@@ -31,6 +31,18 @@
/**
+ * 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 */
+};
+
+
+
+/**
* Fetch a texel.
*/
static void
@@ -230,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},
@@ -259,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;
@@ -279,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 */
@@ -304,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;
@@ -542,73 +553,58 @@ 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]);
+ 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);
- /* can't really happen... */
- if (!execute_shader(ctx, shader, ~0,
- &ctx->ATIFragmentShader.Machine, span, i)) {
- span->array->mask[i] = GL_FALSE;
- span->writeAll = GL_FALSE;
- }
+ init_machine(ctx, &machine, shader, span, i);
+
+ 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);
}
}
}