summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/gallium/auxiliary/tgsi/tgsi_exec.c72
-rw-r--r--src/gallium/auxiliary/tgsi/tgsi_exec.h11
2 files changed, 79 insertions, 4 deletions
diff --git a/src/gallium/auxiliary/tgsi/tgsi_exec.c b/src/gallium/auxiliary/tgsi/tgsi_exec.c
index d191ded3993..2a599bde040 100644
--- a/src/gallium/auxiliary/tgsi/tgsi_exec.c
+++ b/src/gallium/auxiliary/tgsi/tgsi_exec.c
@@ -1324,6 +1324,12 @@ tgsi_exec_machine_create(enum pipe_shader_type shader_type)
goto fail;
}
+ if (shader_type == PIPE_SHADER_FRAGMENT) {
+ mach->InputSampleOffsetApply = align_malloc(sizeof(apply_sample_offset_func) * PIPE_MAX_SHADER_INPUTS, 16);
+ if (!mach->InputSampleOffsetApply)
+ goto fail;
+ }
+
/* Setup constants needed by the SSE2 executor. */
for( i = 0; i < 4; i++ ) {
mach->Temps[TGSI_EXEC_TEMP_00000000_I].xyzw[TGSI_EXEC_TEMP_00000000_C].u[i] = 0x00000000;
@@ -1348,6 +1354,7 @@ tgsi_exec_machine_create(enum pipe_shader_type shader_type)
fail:
if (mach) {
+ align_free(mach->InputSampleOffsetApply);
align_free(mach->Inputs);
align_free(mach->Outputs);
align_free(mach);
@@ -1364,6 +1371,7 @@ tgsi_exec_machine_destroy(struct tgsi_exec_machine *mach)
FREE(mach->Declarations);
FREE(mach->Imms);
+ align_free(mach->InputSampleOffsetApply);
align_free(mach->Inputs);
align_free(mach->Outputs);
@@ -2924,21 +2932,50 @@ eval_constant_coef(
}
}
+static void
+interp_constant_offset(
+ UNUSED const struct tgsi_exec_machine *mach,
+ UNUSED unsigned attrib,
+ UNUSED unsigned chan,
+ UNUSED float ofs_x,
+ UNUSED float ofs_y,
+ UNUSED union tgsi_exec_channel *out_chan)
+{
+}
+
/**
* Evaluate a linear-valued coefficient at the position of the
* current quad.
*/
static void
-eval_linear_coef(
- struct tgsi_exec_machine *mach,
- unsigned attrib,
- unsigned chan )
+interp_linear_offset(
+ const struct tgsi_exec_machine *mach,
+ unsigned attrib,
+ unsigned chan,
+ float ofs_x,
+ float ofs_y,
+ union tgsi_exec_channel *out_chan)
+{
+ const float dadx = mach->InterpCoefs[attrib].dadx[chan];
+ const float dady = mach->InterpCoefs[attrib].dady[chan];
+ const float delta = ofs_x * dadx + ofs_y * dady;
+ out_chan->f[0] += delta;
+ out_chan->f[1] += delta;
+ out_chan->f[2] += delta;
+ out_chan->f[3] += delta;
+}
+
+static void
+eval_linear_coef(struct tgsi_exec_machine *mach,
+ unsigned attrib,
+ unsigned chan)
{
const float x = mach->QuadPos.xyzw[0].f[0];
const float y = mach->QuadPos.xyzw[1].f[0];
const float dadx = mach->InterpCoefs[attrib].dadx[chan];
const float dady = mach->InterpCoefs[attrib].dady[chan];
const float a0 = mach->InterpCoefs[attrib].a0[chan] + dadx * x + dady * y;
+
mach->Inputs[attrib].xyzw[chan].f[0] = a0;
mach->Inputs[attrib].xyzw[chan].f[1] = a0 + dadx;
mach->Inputs[attrib].xyzw[chan].f[2] = a0 + dady;
@@ -2949,6 +2986,26 @@ eval_linear_coef(
* Evaluate a perspective-valued coefficient at the position of the
* current quad.
*/
+
+static void
+interp_perspective_offset(
+ const struct tgsi_exec_machine *mach,
+ unsigned attrib,
+ unsigned chan,
+ float ofs_x,
+ float ofs_y,
+ union tgsi_exec_channel *out_chan)
+{
+ const float dadx = mach->InterpCoefs[attrib].dadx[chan];
+ const float dady = mach->InterpCoefs[attrib].dady[chan];
+ const float *w = mach->QuadPos.xyzw[3].f;
+ const float delta = ofs_x * dadx + ofs_y * dady;
+ out_chan->f[0] += delta / w[0];
+ out_chan->f[1] += delta / w[1];
+ out_chan->f[2] += delta / w[2];
+ out_chan->f[3] += delta / w[3];
+}
+
static void
eval_perspective_coef(
struct tgsi_exec_machine *mach,
@@ -3009,19 +3066,23 @@ exec_declaration(struct tgsi_exec_machine *mach,
}
} else {
eval_coef_func eval;
+ apply_sample_offset_func interp;
uint i, j;
switch (decl->Interp.Interpolate) {
case TGSI_INTERPOLATE_CONSTANT:
eval = eval_constant_coef;
+ interp = interp_constant_offset;
break;
case TGSI_INTERPOLATE_LINEAR:
eval = eval_linear_coef;
+ interp = interp_linear_offset;
break;
case TGSI_INTERPOLATE_PERSPECTIVE:
eval = eval_perspective_coef;
+ interp = interp_perspective_offset;
break;
case TGSI_INTERPOLATE_COLOR:
@@ -3033,6 +3094,9 @@ exec_declaration(struct tgsi_exec_machine *mach,
return;
}
+ for (i = first; i <= last; i++)
+ mach->InputSampleOffsetApply[i] = interp;
+
for (j = 0; j < TGSI_NUM_CHANNELS; j++) {
if (mask & (1 << j)) {
for (i = first; i <= last; i++) {
diff --git a/src/gallium/auxiliary/tgsi/tgsi_exec.h b/src/gallium/auxiliary/tgsi/tgsi_exec.h
index a11b79c6553..3ebcf7c9b69 100644
--- a/src/gallium/auxiliary/tgsi/tgsi_exec.h
+++ b/src/gallium/auxiliary/tgsi/tgsi_exec.h
@@ -351,6 +351,16 @@ enum tgsi_break_type {
typedef float float4[4];
+struct tgsi_exec_machine;
+
+typedef void (* apply_sample_offset_func)(
+ const struct tgsi_exec_machine *mach,
+ unsigned attrib,
+ unsigned chan,
+ float ofs_x,
+ float ofs_y,
+ union tgsi_exec_channel *out_chan);
+
/**
* Run-time virtual machine state for executing TGSI shader.
*/
@@ -366,6 +376,7 @@ struct tgsi_exec_machine
struct tgsi_exec_vector *Inputs;
struct tgsi_exec_vector *Outputs;
+ apply_sample_offset_func *InputSampleOffsetApply;
/* System values */
unsigned SysSemanticToIndex[TGSI_SEMANTIC_COUNT];