/**************************************************************************
*
- * Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas.
+ * Copyright 2003 VMware, Inc.
* All Rights Reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
- * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
+ * IN NO EVENT SHALL VMWARE AND/OR ITS SUPPLIERS BE LIABLE FOR
* ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-1.0 / (6 * 5 * 4 * 3 * 2 * 1)
};
+/* texcoord_mapping[unit] = index | TEXCOORD_{TEX,VAR} */
+#define TEXCOORD_TEX (0<<7)
+#define TEXCOORD_VAR (1<<7)
+
+static unsigned
+get_texcoord_mapping(struct i915_fragment_program *p, uint8_t texcoord)
+{
+ for (unsigned i = 0; i < p->ctx->Const.MaxTextureCoordUnits; i++) {
+ if (p->texcoord_mapping[i] == texcoord)
+ return i;
+ }
+
+ /* blah */
+ return p->ctx->Const.MaxTextureCoordUnits - 1;
+}
+
/**
* Retrieve a ureg for the given source register. Will emit
* constants, apply swizzling and negation as needed.
const struct gl_fragment_program *program)
{
GLuint src;
+ unsigned unit;
switch (source->File) {
case VARYING_SLOT_TEX5:
case VARYING_SLOT_TEX6:
case VARYING_SLOT_TEX7:
+ unit = get_texcoord_mapping(p, (source->Index -
+ VARYING_SLOT_TEX0) | TEXCOORD_TEX);
src = i915_emit_decl(p, REG_TYPE_T,
- T_TEX0 + (source->Index - VARYING_SLOT_TEX0),
+ T_TEX0 + unit,
D0_CHANNEL_ALL);
break;
case VARYING_SLOT_VAR0 + 5:
case VARYING_SLOT_VAR0 + 6:
case VARYING_SLOT_VAR0 + 7:
+ unit = get_texcoord_mapping(p, (source->Index -
+ VARYING_SLOT_VAR0) | TEXCOORD_VAR);
src = i915_emit_decl(p, REG_TYPE_T,
- T_TEX0 + (source->Index - VARYING_SLOT_VAR0),
+ T_TEX0 + unit,
D0_CHANNEL_ALL);
break;
case PROGRAM_OUTPUT:
switch (source->Index) {
case FRAG_RESULT_COLOR:
+ case FRAG_RESULT_DATA0:
src = UREG(REG_TYPE_OC, 0);
break;
case FRAG_RESULT_DEPTH:
{
GLuint flags = 0;
- if (inst->SaturateMode == SATURATE_ZERO_ONE)
+ if (inst->Saturate)
flags |= A0_DEST_SATURATE;
if (inst->DstReg.WriteMask & WRITEMASK_X)
flags |= A0_DEST_CHANNEL_X;
break;
case OPCODE_MIN:
- src0 = src_vector(p, &inst->SrcReg[0], program);
- src1 = src_vector(p, &inst->SrcReg[1], program);
- tmp = i915_get_utemp(p);
- flags = get_result_flags(inst);
-
- i915_emit_arith(p,
- A0_MAX,
- tmp, flags & A0_DEST_CHANNEL_ALL, 0,
- negate(src0, 1, 1, 1, 1),
- negate(src1, 1, 1, 1, 1), 0);
-
- i915_emit_arith(p,
- A0_MOV,
- get_result_vector(p, inst),
- flags, 0, negate(tmp, 1, 1, 1, 1), 0, 0);
+ EMIT_2ARG_ARITH(A0_MIN);
break;
case OPCODE_MOV:
}
}
+static void
+check_texcoord_mapping(struct i915_fragment_program *p)
+{
+ GLbitfield64 inputs = p->FragProg.Base.InputsRead;
+ unsigned unit = 0;
+
+ for (unsigned i = 0; i < p->ctx->Const.MaxTextureCoordUnits; i++) {
+ if (inputs & VARYING_BIT_TEX(i)) {
+ if (unit >= p->ctx->Const.MaxTextureCoordUnits) {
+ unit++;
+ break;
+ }
+ p->texcoord_mapping[unit++] = i | TEXCOORD_TEX;
+ }
+ if (inputs & VARYING_BIT_VAR(i)) {
+ if (unit >= p->ctx->Const.MaxTextureCoordUnits) {
+ unit++;
+ break;
+ }
+ p->texcoord_mapping[unit++] = i | TEXCOORD_VAR;
+ }
+ }
+
+ if (unit > p->ctx->Const.MaxTextureCoordUnits)
+ i915_program_error(p, "Too many texcoord units");
+}
static void
check_wpos(struct i915_fragment_program *p)
{
GLbitfield64 inputs = p->FragProg.Base.InputsRead;
GLint i;
+ unsigned unit = 0;
p->wpos_tex = -1;
+ if ((inputs & VARYING_BIT_POS) == 0)
+ return;
+
for (i = 0; i < p->ctx->Const.MaxTextureCoordUnits; i++) {
- if (inputs & (VARYING_BIT_TEX(i) | VARYING_BIT_VAR(i)))
- continue;
- else if (inputs & VARYING_BIT_POS) {
- p->wpos_tex = i;
- inputs &= ~VARYING_BIT_POS;
- }
+ unit += !!(inputs & VARYING_BIT_TEX(i));
+ unit += !!(inputs & VARYING_BIT_VAR(i));
}
- if (inputs & VARYING_BIT_POS) {
+ if (unit < p->ctx->Const.MaxTextureCoordUnits)
+ p->wpos_tex = unit;
+ else
i915_program_error(p, "No free texcoord for wpos value");
- }
}
}
i915_init_program(i915, p);
+ check_texcoord_mapping(p);
check_wpos(p);
upload_program(p);
fixup_depth_write(p);
for (i = 0; i < p->ctx->Const.MaxTextureCoordUnits; i++) {
if (inputsRead & VARYING_BIT_TEX(i)) {
+ int unit = get_texcoord_mapping(p, i | TEXCOORD_TEX);
int sz = VB->AttribPtr[_TNL_ATTRIB_TEX0 + i]->size;
- s2 &= ~S2_TEXCOORD_FMT(i, S2_TEXCOORD_FMT0_MASK);
- s2 |= S2_TEXCOORD_FMT(i, SZ_TO_HW(sz));
+ s2 &= ~S2_TEXCOORD_FMT(unit, S2_TEXCOORD_FMT0_MASK);
+ s2 |= S2_TEXCOORD_FMT(unit, SZ_TO_HW(sz));
EMIT_ATTR(_TNL_ATTRIB_TEX0 + i, EMIT_SZ(sz), 0, sz * 4);
}
- else if (inputsRead & VARYING_BIT_VAR(i)) {
+ if (inputsRead & VARYING_BIT_VAR(i)) {
+ int unit = get_texcoord_mapping(p, i | TEXCOORD_VAR);
int sz = VB->AttribPtr[_TNL_ATTRIB_GENERIC0 + i]->size;
- s2 &= ~S2_TEXCOORD_FMT(i, S2_TEXCOORD_FMT0_MASK);
- s2 |= S2_TEXCOORD_FMT(i, SZ_TO_HW(sz));
+ s2 &= ~S2_TEXCOORD_FMT(unit, S2_TEXCOORD_FMT0_MASK);
+ s2 |= S2_TEXCOORD_FMT(unit, SZ_TO_HW(sz));
EMIT_ATTR(_TNL_ATTRIB_GENERIC0 + i, EMIT_SZ(sz), 0, sz * 4);
}
- else if (i == p->wpos_tex) {
+ if (i == p->wpos_tex) {
int wpos_size = 4 * sizeof(float);
/* If WPOS is required, duplicate the XYZ position data in an
* unused texture coordinate:
if (s2 != i915->state.Ctx[I915_CTXREG_LIS2] ||
s4 != i915->state.Ctx[I915_CTXREG_LIS4]) {
- int k;
-
I915_STATECHANGE(i915, I915_UPLOAD_CTX);
/* Must do this *after* statechange, so as not to affect
i915->state.Ctx[I915_CTXREG_LIS2] = s2;
i915->state.Ctx[I915_CTXREG_LIS4] = s4;
- k = intel->vtbl.check_vertex_size(intel, intel->vertex_size);
- assert(k);
+ assert(intel->vtbl.check_vertex_size(intel, intel->vertex_size));
}
if (!p->params_uptodate)