#include "s_atifragshader.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 */
+};
+
+
+
/**
* Fetch a texel.
*/
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 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]);
+ if (span->array->ChanType == GL_UNSIGNED_BYTE) {
+ GLubyte (*rgba)[4] = span->array->color.sz1.rgba;
+ GLubyte (*spec)[4] = span->array->color.sz1.spec;
+ inputs[ATI_FS_INPUT_PRIMARY][0] = UBYTE_TO_FLOAT(rgba[col][0]);
+ inputs[ATI_FS_INPUT_PRIMARY][1] = UBYTE_TO_FLOAT(rgba[col][1]);
+ inputs[ATI_FS_INPUT_PRIMARY][2] = UBYTE_TO_FLOAT(rgba[col][2]);
+ inputs[ATI_FS_INPUT_PRIMARY][3] = UBYTE_TO_FLOAT(rgba[col][3]);
+ inputs[ATI_FS_INPUT_SECONDARY][0] = UBYTE_TO_FLOAT(spec[col][0]);
+ inputs[ATI_FS_INPUT_SECONDARY][1] = UBYTE_TO_FLOAT(spec[col][1]);
+ inputs[ATI_FS_INPUT_SECONDARY][2] = UBYTE_TO_FLOAT(spec[col][2]);
+ inputs[ATI_FS_INPUT_SECONDARY][3] = UBYTE_TO_FLOAT(spec[col][3]);
+ }
+ else if (span->array->ChanType == GL_UNSIGNED_SHORT) {
+ GLushort (*rgba)[4] = span->array->color.sz2.rgba;
+ GLushort (*spec)[4] = span->array->color.sz2.spec;
+ inputs[ATI_FS_INPUT_PRIMARY][0] = USHORT_TO_FLOAT(rgba[col][0]);
+ inputs[ATI_FS_INPUT_PRIMARY][1] = USHORT_TO_FLOAT(rgba[col][1]);
+ inputs[ATI_FS_INPUT_PRIMARY][2] = USHORT_TO_FLOAT(rgba[col][2]);
+ inputs[ATI_FS_INPUT_PRIMARY][3] = USHORT_TO_FLOAT(rgba[col][3]);
+ inputs[ATI_FS_INPUT_SECONDARY][0] = USHORT_TO_FLOAT(spec[col][0]);
+ inputs[ATI_FS_INPUT_SECONDARY][1] = USHORT_TO_FLOAT(spec[col][1]);
+ inputs[ATI_FS_INPUT_SECONDARY][2] = USHORT_TO_FLOAT(spec[col][2]);
+ inputs[ATI_FS_INPUT_SECONDARY][3] = USHORT_TO_FLOAT(spec[col][3]);
+ }
+ else {
+ GLfloat (*rgba)[4] = span->array->color.sz4.rgba;
+ GLfloat (*spec)[4] = span->array->color.sz4.spec;
+ COPY_4V(inputs[ATI_FS_INPUT_PRIMARY], rgba[col]);
+ COPY_4V(inputs[ATI_FS_INPUT_SECONDARY], 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, SWspan *span)
{
const struct ati_fragment_shader *shader = ctx->ATIFragmentShader.Current;
+ struct atifs_machine machine;
GLuint i;
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);
/* can't really happen... */
- if (!execute_shader(ctx, shader, ~0,
- &ctx->ATIFragmentShader.Machine, span, i)) {
+ if (!execute_shader(ctx, shader, ~0, &machine, span, i)) {
span->array->mask[i] = GL_FALSE;
span->writeAll = GL_FALSE;
}
+ /* 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]); */
+ if (span->array->ChanType == GL_UNSIGNED_BYTE) {
+ GLubyte (*rgba)[4] = span->array->color.sz1.rgba;
+ UNCLAMPED_FLOAT_TO_UBYTE(rgba[i][RCOMP], colOut[0]);
+ UNCLAMPED_FLOAT_TO_UBYTE(rgba[i][GCOMP], colOut[1]);
+ UNCLAMPED_FLOAT_TO_UBYTE(rgba[i][BCOMP], colOut[2]);
+ UNCLAMPED_FLOAT_TO_UBYTE(rgba[i][ACOMP], colOut[3]);
+ }
+ else if (span->array->ChanType == GL_UNSIGNED_SHORT) {
+ GLushort (*rgba)[4] = span->array->color.sz2.rgba;
+ UNCLAMPED_FLOAT_TO_USHORT(rgba[i][RCOMP], colOut[0]);
+ UNCLAMPED_FLOAT_TO_USHORT(rgba[i][GCOMP], colOut[1]);
+ UNCLAMPED_FLOAT_TO_USHORT(rgba[i][BCOMP], colOut[2]);
+ UNCLAMPED_FLOAT_TO_USHORT(rgba[i][ACOMP], colOut[3]);
+ }
+ else {
+ GLfloat (*rgba)[4] = span->array->color.sz4.rgba;
+ COPY_4V(rgba[i], colOut);
+ }
}
}
}
if (inputsRead & (1 << FRAG_ATTRIB_COL0)) {
GLfloat *col0 = machine->Inputs[FRAG_ATTRIB_COL0];
ASSERT(span->arrayMask & SPAN_RGBA);
- col0[0] = CHAN_TO_FLOAT(span->array->rgba[col][RCOMP]);
- col0[1] = CHAN_TO_FLOAT(span->array->rgba[col][GCOMP]);
- col0[2] = CHAN_TO_FLOAT(span->array->rgba[col][BCOMP]);
- col0[3] = CHAN_TO_FLOAT(span->array->rgba[col][ACOMP]);
+ if (span->array->ChanType == GL_UNSIGNED_BYTE) {
+ GLubyte (*rgba)[4] = span->array->color.sz1.rgba;
+ col0[0] = UBYTE_TO_FLOAT(rgba[col][RCOMP]);
+ col0[1] = UBYTE_TO_FLOAT(rgba[col][GCOMP]);
+ col0[2] = UBYTE_TO_FLOAT(rgba[col][BCOMP]);
+ col0[3] = UBYTE_TO_FLOAT(rgba[col][ACOMP]);
+ }
+ else if (span->array->ChanType == GL_UNSIGNED_SHORT) {
+ GLushort (*rgba)[4] = span->array->color.sz2.rgba;
+ col0[0] = USHORT_TO_FLOAT(rgba[col][RCOMP]);
+ col0[1] = USHORT_TO_FLOAT(rgba[col][GCOMP]);
+ col0[2] = USHORT_TO_FLOAT(rgba[col][BCOMP]);
+ col0[3] = USHORT_TO_FLOAT(rgba[col][ACOMP]);
+ }
+ else {
+ GLfloat (*rgba)[4] = span->array->color.sz4.rgba;
+ COPY_4V(col0, rgba[col]);
+ }
}
if (inputsRead & (1 << FRAG_ATTRIB_COL1)) {
GLfloat *col1 = machine->Inputs[FRAG_ATTRIB_COL1];
- col1[0] = CHAN_TO_FLOAT(span->array->spec[col][RCOMP]);
- col1[1] = CHAN_TO_FLOAT(span->array->spec[col][GCOMP]);
- col1[2] = CHAN_TO_FLOAT(span->array->spec[col][BCOMP]);
- col1[3] = CHAN_TO_FLOAT(span->array->spec[col][ACOMP]);
+ if (span->array->ChanType == GL_UNSIGNED_BYTE) {
+ GLubyte (*rgba)[4] = span->array->color.sz1.spec;
+ col1[0] = UBYTE_TO_FLOAT(rgba[col][RCOMP]);
+ col1[1] = UBYTE_TO_FLOAT(rgba[col][GCOMP]);
+ col1[2] = UBYTE_TO_FLOAT(rgba[col][BCOMP]);
+ col1[3] = UBYTE_TO_FLOAT(rgba[col][ACOMP]);
+ }
+ else if (span->array->ChanType == GL_UNSIGNED_SHORT) {
+ GLushort (*rgba)[4] = span->array->color.sz2.spec;
+ col1[0] = USHORT_TO_FLOAT(rgba[col][RCOMP]);
+ col1[1] = USHORT_TO_FLOAT(rgba[col][GCOMP]);
+ col1[2] = USHORT_TO_FLOAT(rgba[col][BCOMP]);
+ col1[3] = USHORT_TO_FLOAT(rgba[col][ACOMP]);
+ }
+ else {
+ GLfloat (*rgba)[4] = span->array->color.sz4.spec;
+ COPY_4V(col1, rgba[col]);
+ }
}
if (inputsRead & (1 << FRAG_ATTRIB_FOGC)) {
GLfloat *fogc = machine->Inputs[FRAG_ATTRIB_FOGC];
/* Store output registers */
{
const GLfloat *colOut = machine.Outputs[FRAG_RESULT_COLR];
- 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]);
+ if (span->array->ChanType == GL_UNSIGNED_BYTE) {
+ GLubyte (*rgba)[4] = span->array->color.sz1.rgba;
+ UNCLAMPED_FLOAT_TO_UBYTE(rgba[i][RCOMP], colOut[0]);
+ UNCLAMPED_FLOAT_TO_UBYTE(rgba[i][GCOMP], colOut[1]);
+ UNCLAMPED_FLOAT_TO_UBYTE(rgba[i][BCOMP], colOut[2]);
+ UNCLAMPED_FLOAT_TO_UBYTE(rgba[i][ACOMP], colOut[3]);
+ }
+ else if (span->array->ChanType == GL_UNSIGNED_BYTE) {
+ GLushort (*rgba)[4] = span->array->color.sz2.rgba;
+ UNCLAMPED_FLOAT_TO_USHORT(rgba[i][RCOMP], colOut[0]);
+ UNCLAMPED_FLOAT_TO_USHORT(rgba[i][GCOMP], colOut[1]);
+ UNCLAMPED_FLOAT_TO_USHORT(rgba[i][BCOMP], colOut[2]);
+ UNCLAMPED_FLOAT_TO_USHORT(rgba[i][ACOMP], colOut[3]);
+ }
+ else {
+ GLfloat (*rgba)[4] = span->array->color.sz4.rgba;
+ COPY_4V(rgba[i], colOut);
+ }
}
/* depth value */
if (program->Base.OutputsWritten & (1 << FRAG_RESULT_DEPR)) {
}
}
}
+
CurrentMachine = NULL;
}